Merge branch 'maint'
[kdbg.git] / kdbg / valarray.h
blob2eaa424bc45ec326dbc1bc1f990af845f6866356
1 /*
2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
5 */
7 // an array template class that holds values (not pointers to values)
9 #ifndef VALARRAY_H
10 #define VALARRAY_H
12 // need a placement new
13 #include "config.h"
14 #ifdef HAVE_PLACEMENT_NEW
15 #include <new>
16 #else
17 inline void* operator new(size_t, void* p) { return p; }
18 #endif
20 template<class T>
21 class ValArray
23 public:
24 ValArray() : m_pData(0), m_size(0), m_space(0) { }
25 ~ValArray();
26 void operator=(const ValArray<T>& src);
27 const T& operator[](int i) const { return m_pData[i]; }
28 T& operator[](int i) { return m_pData[i]; }
29 void setSize(int newSize);
30 int size() const { return m_size; }
31 void append(const T& newElem, int count = 1) { expand(newElem, m_size+count); }
32 void insertAt(int start, const T& newElem, int count = 1);
33 void insertAt(int start, const ValArray<T>& newElems);
34 void removeAt(int start, int count = 1);
36 protected:
37 T* m_pData;
38 int m_size;
39 int m_space;
41 void expand(const T& newElem, int newSize);
44 template<class T>
45 ValArray<T>::~ValArray()
47 setSize(0);
48 delete[] reinterpret_cast<char*>(m_pData);
51 template<class T>
52 void ValArray<T>::operator=(const ValArray<T>& src)
54 setSize(src.size());
55 for (int i = 0; i < src.size(); i++) {
56 m_pData[i] = src.m_pData[i];
60 template<class T>
61 void ValArray<T>::setSize(int newSize)
63 if (newSize == m_size) return;
64 if (newSize > m_size) {
65 expand(T(), newSize);
66 } else {
67 do {
68 m_size--;
69 m_pData[m_size].~T();
70 } while (m_size > newSize);
74 template<class T>
75 void ValArray<T>::expand(const T& newElem, int newSize)
77 if (newSize > m_space) {
78 // reallocate
79 int newSpace = m_space + m_space;
80 if (newSpace < 8) newSpace = 8;
81 if (newSpace < newSize) newSpace = newSize;
82 T* newData = reinterpret_cast<T*>(new char[newSpace * sizeof(T)]);
83 // care about exception safety as much as possible
84 // copy-construct the elements into the new array
85 // TODO: clean up when exception is thrown here
86 for (int i = 0; i < m_size; i++) {
87 new(&newData[i]) T(m_pData[i]);
89 // replace the pointer
90 T* oldData = m_pData;
91 m_pData = newData;
92 m_space = newSpace;
93 // destruct the old data
94 for (int i = m_size-1; i >= 0; i--) {
95 oldData[i].~T();
97 delete[] reinterpret_cast<char*>(oldData);
99 // copy the new element into the new space
100 while (m_size < newSize) {
101 new(&m_pData[m_size]) T(newElem);
102 m_size++;
106 template<class T>
107 void ValArray<T>::removeAt(int start, int count)
109 if (count <= 0)
110 return;
111 // move elements down
112 int nMove = m_size-start-count;
113 for (int src = start+count; nMove > 0; src++, start++, nMove--) {
114 // first destruct destination
115 m_pData[start].~T();
116 // copy-construct source to destination
117 new(&m_pData[start]) T(m_pData[src]);
119 setSize(start);
122 template<class T>
123 void ValArray<T>::insertAt(int start, const T& newElem, int count)
125 if (count <= 0)
126 return;
128 int nMove = m_size - start;
129 int src = m_size-1;
130 setSize(m_size+count);
131 for (int dest = m_size-1; nMove > 0; src--, dest--, nMove--) {
132 // first destruct destination
133 m_pData[dest].~T();
134 // copy-construct source to destination
135 new(&m_pData[dest]) T(m_pData[src]);
137 // copy new elements (after destruction destination)
138 for (; count > 0; start++, count--) {
139 m_pData[start].~T();
140 new(&m_pData[start]) T(newElem);
144 template<class T>
145 void ValArray<T>::insertAt(int start, const ValArray<T>& newElems)
147 int count = newElems.size();
148 if (count <= 0)
149 return;
151 int nMove = m_size - start;
152 int src = m_size-1;
153 setSize(m_size+count);
154 for (int dest = m_size-1; nMove > 0; src--, dest--, nMove--) {
155 // first destruct destination
156 m_pData[dest].~T();
157 // copy-construct source to destination
158 new(&m_pData[dest]) T(m_pData[src]);
160 // copy new elements (after destruction destination)
161 for (int i = 0; count > 0; i++, start++, count--) {
162 m_pData[start].~T();
163 new(&m_pData[start]) T(newElems[i]);
167 #endif // VALARRAY_H