]> git.saurik.com Git - wxWidgets.git/blob - include/wx/vector.h
880dd9bbcda6908c8a3748a4088c3709cf9e7a80
[wxWidgets.git] / include / wx / vector.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/vector.h
3 // Purpose: STL vector clone
4 // Author: Lindsay Mathieson
5 // Modified by: Vaclav Slavik - make it a template
6 // Created: 30.07.2001
7 // Copyright: (c) 2001 Lindsay Mathieson <lindsay@mathieson.org>,
8 // 2007 Vaclav Slavik <vslavik@fastmail.fm>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_VECTOR_H_
13 #define _WX_VECTOR_H_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_STL
18
19 #include <vector>
20 #define wxVector std::vector
21
22 #else // !wxUSE_STL
23
24 template<typename T>
25 class wxVector
26 {
27 public:
28 typedef size_t size_type;
29 typedef T value_type;
30 typedef value_type* iterator;
31 typedef value_type& reference;
32
33 wxVector() : m_allocsize(16), m_size(0), m_capacity(0), m_objects(0) {}
34
35 wxVector(const wxVector& c)
36 {
37 wxCHECK2(Copy(c), return);
38 }
39
40 ~wxVector()
41 {
42 clear();
43 }
44
45 void clear()
46 {
47 for (size_type i = 0; i < size(); i++)
48 delete m_objects[i];
49 free(m_objects);
50 m_objects = 0;
51 m_size = m_capacity = 0;
52 }
53
54 void reserve(size_type n)
55 {
56 if ( !Alloc(n) )
57 {
58 wxFAIL_MSG( _T("out of memory in wxVector::reserve()") );
59 }
60 }
61
62 size_type size() const
63 {
64 return m_size;
65 }
66
67 size_type capacity() const
68 {
69 return m_capacity;
70 }
71
72 bool empty() const
73 {
74 return size() == 0;
75 }
76
77 wxVector& operator=(const wxVector& vb)
78 {
79 wxCHECK(Copy(vb), *this);
80 return *this;
81 }
82
83 void push_back(const value_type& o)
84 {
85 wxCHECK2(Alloc(size() + 1), return);
86 Append(new value_type(o));
87 }
88
89 void pop_back()
90 {
91 RemoveAt(size() - 1);
92 }
93
94 const value_type& at(size_type idx) const
95 {
96 wxASSERT(idx < m_size);
97 return *m_objects[idx];
98 }
99
100 value_type& at(size_type idx)
101 {
102 wxASSERT(idx < m_size);
103 return *m_objects[idx];
104 }
105
106 const value_type& operator[](size_type idx) const { return at(idx); }
107 value_type& operator[](size_type idx) { return at(idx); }
108 const value_type& front() const { return at(0); }
109 value_type& front() { return at(0); }
110 const value_type& back() const { return at(size() - 1); }
111 value_type& back() { return at(size() - 1); }
112
113 iterator begin() { return m_objects[0]; }
114 iterator end() { return m_objects[size()]; }
115
116 iterator erase(iterator first, iterator last)
117 {
118 size_type idx = first - begin();
119 RemoveAt(idx, last - first);
120 return begin() + idx;
121 }
122 iterator erase(iterator it)
123 {
124 size_type idx = it - begin();
125 RemoveAt(idx);
126 return begin() + idx;
127 }
128
129 #if WXWIN_COMPATIBILITY_2_8
130 wxDEPRECATED( size_type erase(size_type n) );
131 #endif // WXWIN_COMPATIBILITY_2_8
132
133 iterator insert(iterator it, const value_type& v = value_type())
134 {
135 wxCHECK2(Alloc(size() + 1), return 0);
136 size_type idx = it - begin();
137 InsertAt(new value_type(v), idx);
138 return begin() + idx;
139 }
140
141 private:
142 bool Alloc(size_type sz)
143 {
144 // work in multiples of m_allocsize;
145 sz = (sz / m_allocsize + 1) * m_allocsize;
146 if (sz <= m_capacity)
147 return true;
148
149 // try to realloc
150 void *mem = realloc(m_objects, sizeof(value_type*) * sz);
151 if (! mem)
152 return false; // failed
153 // success
154 m_objects = (value_type **) mem;
155 m_capacity = sz;
156 return true;
157 }
158
159 void Append(value_type *obj)
160 {
161 wxASSERT(m_size < m_capacity);
162 m_objects[m_size] = obj;
163 m_size++;
164 }
165
166 void InsertAt(size_type idx, value_type *obj)
167 {
168 wxASSERT(idx <= m_size);
169 wxASSERT(m_size < m_capacity);
170 if (idx < m_size)
171 memmove(
172 m_objects + idx + 1,
173 m_objects + idx,
174 ( m_size - idx ) * sizeof(value_type*) );
175
176 m_size++;
177 }
178
179 void RemoveAt(size_type idx)
180 {
181 wxASSERT(idx < m_size);
182 delete m_objects[idx];
183 if (idx < m_size - 1)
184 memcpy(
185 m_objects + idx,
186 m_objects + idx + 1,
187 ( m_size - idx - 1 ) * sizeof(value_type*) );
188 m_size--;
189 }
190
191 void RemoveAt(size_type idx, size_type count)
192 {
193 if (count == 0)
194 return;
195 wxASSERT(idx < m_size);
196 size_type i;
197 for (i = 0; i < count; i++)
198 delete m_objects[idx+1];
199 if (idx < m_size - count)
200 memcpy(
201 m_objects + idx,
202 m_objects + idx + count,
203 ( m_size - idx - count ) * sizeof(value_type*) );
204 m_size -= count;
205 }
206 bool Copy(const wxVector& vb)
207 {
208 clear();
209 if (! Alloc(vb.size()))
210 return false;
211
212 for (size_type i = 0; i < vb.size(); i++)
213 {
214 value_type *o = new value_type(vb.at(i));
215 if (! o)
216 return false;
217 Append(o);
218 }
219
220 return true;
221 }
222
223 private:
224 size_type m_allocsize;
225 size_type m_size,
226 m_capacity;
227 value_type **m_objects;
228 };
229
230 #if WXWIN_COMPATIBILITY_2_8
231 template<typename T>
232 typename wxVector<T>::size_type wxVector<T>::erase(size_type n)
233 {
234 RemoveAt(n);
235 return n;
236 }
237 #endif // WXWIN_COMPATIBILITY_2_8
238
239 #endif // wxUSE_STL/!wxUSE_STL
240
241 #if WXWIN_COMPATIBILITY_2_8
242 #define WX_DECLARE_VECTORBASE(obj, cls) typedef wxVector<obj> cls
243 #define _WX_DECLARE_VECTOR(obj, cls, exp) WX_DECLARE_VECTORBASE(obj, cls)
244 #define WX_DECLARE_VECTOR(obj, cls) WX_DECLARE_VECTORBASE(obj, cls)
245 #endif // WXWIN_COMPATIBILITY_2_8
246
247 #endif // _WX_VECTOR_H_