]> git.saurik.com Git - wxWidgets.git/blob - include/wx/vector.h
* Implement the wxMask copy constructor to retain the source object's
[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 iterator insert(iterator it, const value_type& v = value_type())
130 {
131 wxCHECK2(Alloc(size() + 1), return 0);
132 size_type idx = it - begin();
133 InsertAt(new value_type(v), idx);
134 return begin() + idx;
135 }
136
137 private:
138 bool Alloc(size_type sz)
139 {
140 // work in multiples of m_allocsize;
141 sz = (sz / m_allocsize + 1) * m_allocsize;
142 if (sz <= m_capacity)
143 return true;
144
145 // try to realloc
146 void *mem = realloc(m_objects, sizeof(value_type*) * sz);
147 if (! mem)
148 return false; // failed
149 // success
150 m_objects = (value_type **) mem;
151 m_capacity = sz;
152 return true;
153 }
154
155 void Append(value_type *obj)
156 {
157 wxASSERT(m_size < m_capacity);
158 m_objects[m_size] = obj;
159 m_size++;
160 }
161
162 void InsertAt(size_type idx, value_type *obj)
163 {
164 wxASSERT(idx <= m_size);
165 wxASSERT(m_size < m_capacity);
166 if (idx < m_size)
167 memmove(
168 m_objects + idx + 1,
169 m_objects + idx,
170 ( m_size - idx ) * sizeof(value_type*) );
171
172 m_size++;
173 }
174
175 void RemoveAt(size_type idx)
176 {
177 wxASSERT(idx < m_size);
178 delete m_objects[idx];
179 if (idx < m_size - 1)
180 memcpy(
181 m_objects + idx,
182 m_objects + idx + 1,
183 ( m_size - idx - 1 ) * sizeof(value_type*) );
184 m_size--;
185 }
186
187 void RemoveAt(size_type idx, size_type count)
188 {
189 if (count == 0)
190 return;
191 wxASSERT(idx < m_size);
192 size_type i;
193 for (i = 0; i < count; i++)
194 delete m_objects[idx+1];
195 if (idx < m_size - count)
196 memcpy(
197 m_objects + idx,
198 m_objects + idx + count,
199 ( m_size - idx - count ) * sizeof(value_type*) );
200 m_size -= count;
201 }
202 bool Copy(const wxVector& vb)
203 {
204 clear();
205 if (! Alloc(vb.size()))
206 return false;
207
208 for (size_type i = 0; i < vb.size(); i++)
209 {
210 value_type *o = new value_type(vb.at(i));
211 if (! o)
212 return false;
213 Append(o);
214 }
215
216 return true;
217 }
218
219 private:
220 size_type m_allocsize;
221 size_type m_size,
222 m_capacity;
223 value_type **m_objects;
224 };
225
226 #endif // wxUSE_STL/!wxUSE_STL
227
228 #if WXWIN_COMPATIBILITY_2_8
229 #define WX_DECLARE_VECTORBASE(obj, cls) typedef wxVector<obj> cls
230 #define _WX_DECLARE_VECTOR(obj, cls, exp) WX_DECLARE_VECTORBASE(obj, cls)
231 #define WX_DECLARE_VECTOR(obj, cls) WX_DECLARE_VECTORBASE(obj, cls)
232 #endif // WXWIN_COMPATIBILITY_2_8
233
234 #endif // _WX_VECTOR_H_