3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 // an array template class that holds values (not pointers to values)
11 // need a placement new
13 #ifdef HAVE_PLACEMENT_NEW
16 inline void* operator new(size_t, void* p
) { return p
; }
23 ValArray() : m_pData(0), m_size(0), m_space(0) { }
25 void operator=(const ValArray
<T
>& src
);
26 const T
& operator[](int i
) const { return m_pData
[i
]; }
27 T
& operator[](int i
) { return m_pData
[i
]; }
28 void setSize(int newSize
);
29 int size() const { return m_size
; }
30 void append(const T
& newElem
, int count
= 1) { expand(newElem
, m_size
+count
); }
31 void insertAt(int start
, const T
& newElem
, int count
= 1);
32 void insertAt(int start
, const ValArray
<T
>& newElems
);
33 void removeAt(int start
, int count
= 1);
40 void expand(const T
& newElem
, int newSize
);
44 ValArray
<T
>::~ValArray()
47 delete[] reinterpret_cast<char*>(m_pData
);
51 void ValArray
<T
>::operator=(const ValArray
<T
>& src
)
54 for (int i
= 0; i
< src
.size(); i
++) {
55 m_pData
[i
] = src
.m_pData
[i
];
60 void ValArray
<T
>::setSize(int newSize
)
62 if (newSize
== m_size
) return;
63 if (newSize
> m_size
) {
69 } while (m_size
> newSize
);
74 void ValArray
<T
>::expand(const T
& newElem
, int newSize
)
76 if (newSize
> m_space
) {
78 int newSpace
= m_space
+ m_space
;
79 if (newSpace
< 8) newSpace
= 8;
80 if (newSpace
< newSize
) newSpace
= newSize
;
81 T
* newData
= reinterpret_cast<T
*>(new char[newSpace
* sizeof(T
)]);
82 // care about exception safety as much as possible
83 // copy-construct the elements into the new array
84 // TODO: clean up when exception is thrown here
85 for (int i
= 0; i
< m_size
; i
++) {
86 new(&newData
[i
]) T(m_pData
[i
]);
88 // replace the pointer
92 // destruct the old data
93 for (int i
= m_size
-1; i
>= 0; i
--) {
96 delete[] reinterpret_cast<char*>(oldData
);
98 // copy the new element into the new space
99 while (m_size
< newSize
) {
100 new(&m_pData
[m_size
]) T(newElem
);
106 void ValArray
<T
>::removeAt(int start
, int count
)
110 // move elements down
111 int nMove
= m_size
-start
-count
;
112 for (int src
= start
+count
; nMove
> 0; src
++, start
++, nMove
--) {
113 // first destruct destination
115 // copy-construct source to destination
116 new(&m_pData
[start
]) T(m_pData
[src
]);
122 void ValArray
<T
>::insertAt(int start
, const T
& newElem
, int count
)
127 int nMove
= m_size
- start
;
129 setSize(m_size
+count
);
130 for (int dest
= m_size
-1; nMove
> 0; src
--, dest
--, nMove
--) {
131 // first destruct destination
133 // copy-construct source to destination
134 new(&m_pData
[dest
]) T(m_pData
[src
]);
136 // copy new elements (after destruction destination)
137 for (; count
> 0; start
++, count
--) {
139 new(&m_pData
[start
]) T(newElem
);
144 void ValArray
<T
>::insertAt(int start
, const ValArray
<T
>& newElems
)
146 int count
= newElems
.size();
150 int nMove
= m_size
- start
;
152 setSize(m_size
+count
);
153 for (int dest
= m_size
-1; nMove
> 0; src
--, dest
--, nMove
--) {
154 // first destruct destination
156 // copy-construct source to destination
157 new(&m_pData
[dest
]) T(m_pData
[src
]);
159 // copy new elements (after destruction destination)
160 for (int i
= 0; count
> 0; i
++, start
++, count
--) {
162 new(&m_pData
[start
]) T(newElems
[i
]);