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.
7 // an array template class that holds values (not pointers to values)
12 // need a placement new
14 #ifdef HAVE_PLACEMENT_NEW
17 inline void* operator new(size_t, void* p
) { return p
; }
24 ValArray() : m_pData(0), m_size(0), m_space(0) { }
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);
41 void expand(const T
& newElem
, int newSize
);
45 ValArray
<T
>::~ValArray()
48 delete[] reinterpret_cast<char*>(m_pData
);
52 void ValArray
<T
>::operator=(const ValArray
<T
>& src
)
55 for (int i
= 0; i
< src
.size(); i
++) {
56 m_pData
[i
] = src
.m_pData
[i
];
61 void ValArray
<T
>::setSize(int newSize
)
63 if (newSize
== m_size
) return;
64 if (newSize
> m_size
) {
70 } while (m_size
> newSize
);
75 void ValArray
<T
>::expand(const T
& newElem
, int newSize
)
77 if (newSize
> m_space
) {
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
93 // destruct the old data
94 for (int i
= m_size
-1; i
>= 0; i
--) {
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
);
107 void ValArray
<T
>::removeAt(int start
, int count
)
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
116 // copy-construct source to destination
117 new(&m_pData
[start
]) T(m_pData
[src
]);
123 void ValArray
<T
>::insertAt(int start
, const T
& newElem
, int count
)
128 int nMove
= m_size
- start
;
130 setSize(m_size
+count
);
131 for (int dest
= m_size
-1; nMove
> 0; src
--, dest
--, nMove
--) {
132 // first destruct destination
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
--) {
140 new(&m_pData
[start
]) T(newElem
);
145 void ValArray
<T
>::insertAt(int start
, const ValArray
<T
>& newElems
)
147 int count
= newElems
.size();
151 int nMove
= m_size
- start
;
153 setSize(m_size
+count
);
154 for (int dest
= m_size
-1; nMove
> 0; src
--, dest
--, nMove
--) {
155 // first destruct destination
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
--) {
163 new(&m_pData
[start
]) T(newElems
[i
]);