]>
Commit | Line | Data |
---|---|---|
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 | #include "wx/utils.h" | |
25 | ||
26 | template<typename T> | |
27 | class wxVector | |
28 | { | |
29 | public: | |
30 | typedef size_t size_type; | |
31 | typedef T value_type; | |
32 | typedef value_type* iterator; | |
33 | typedef const value_type* const_iterator; | |
34 | typedef value_type& reference; | |
35 | ||
36 | wxVector() : m_size(0), m_capacity(0), m_values(NULL) {} | |
37 | ||
38 | wxVector(const wxVector& c) | |
39 | { | |
40 | Copy(c); | |
41 | } | |
42 | ||
43 | ~wxVector() | |
44 | { | |
45 | clear(); | |
46 | } | |
47 | ||
48 | void clear() | |
49 | { | |
50 | delete[] m_values; | |
51 | m_values = NULL; | |
52 | m_size = m_capacity = 0; | |
53 | } | |
54 | ||
55 | void reserve(size_type n) | |
56 | { | |
57 | if ( n <= m_capacity ) | |
58 | return; | |
59 | ||
60 | // increase the size twice, unless we're already too big or unless | |
61 | // more is requested | |
62 | // | |
63 | // NB: casts to size_t are needed to suppress mingw32 warnings about | |
64 | // mixing enums and ints in the same expression | |
65 | const size_type increment = m_size > 0 | |
66 | ? wxMin(m_size, (size_type)ALLOC_MAX_SIZE) | |
67 | : (size_type)ALLOC_INITIAL_SIZE; | |
68 | if ( m_capacity + increment > n ) | |
69 | n = m_capacity + increment; | |
70 | ||
71 | value_type *mem = new value_type[n]; | |
72 | ||
73 | if ( m_values ) | |
74 | { | |
75 | for ( size_type i = 0; i < m_size; ++i ) | |
76 | mem[i] = m_values[i]; | |
77 | delete[] m_values; | |
78 | } | |
79 | ||
80 | m_values = mem; | |
81 | m_capacity = n; | |
82 | } | |
83 | ||
84 | size_type size() const | |
85 | { | |
86 | return m_size; | |
87 | } | |
88 | ||
89 | size_type capacity() const | |
90 | { | |
91 | return m_capacity; | |
92 | } | |
93 | ||
94 | bool empty() const | |
95 | { | |
96 | return size() == 0; | |
97 | } | |
98 | ||
99 | wxVector& operator=(const wxVector& vb) | |
100 | { | |
101 | Copy(vb); | |
102 | return *this; | |
103 | } | |
104 | ||
105 | void push_back(const value_type& v) | |
106 | { | |
107 | reserve(size() + 1); | |
108 | m_values[m_size++] = v; | |
109 | } | |
110 | ||
111 | void pop_back() | |
112 | { | |
113 | erase(end() - 1); | |
114 | } | |
115 | ||
116 | const value_type& at(size_type idx) const | |
117 | { | |
118 | wxASSERT(idx < m_size); | |
119 | return m_values[idx]; | |
120 | } | |
121 | ||
122 | value_type& at(size_type idx) | |
123 | { | |
124 | wxASSERT(idx < m_size); | |
125 | return m_values[idx]; | |
126 | } | |
127 | ||
128 | const value_type& operator[](size_type idx) const { return at(idx); } | |
129 | value_type& operator[](size_type idx) { return at(idx); } | |
130 | const value_type& front() const { return at(0); } | |
131 | value_type& front() { return at(0); } | |
132 | const value_type& back() const { return at(size() - 1); } | |
133 | value_type& back() { return at(size() - 1); } | |
134 | ||
135 | const_iterator begin() const { return m_values; } | |
136 | iterator begin() { return m_values; } | |
137 | const_iterator end() const { return m_values + size(); } | |
138 | iterator end() { return m_values + size(); } | |
139 | ||
140 | iterator insert(iterator it, const value_type& v = value_type()) | |
141 | { | |
142 | size_t idx = it - begin(); | |
143 | ||
144 | reserve(size() + 1); | |
145 | ||
146 | // unless we're inserting at the end, move following values out of | |
147 | // the way: | |
148 | for ( size_t n = m_size; n != idx; --n ) | |
149 | m_values[n] = m_values[n-1]; | |
150 | ||
151 | m_values[idx] = v; | |
152 | m_size++; | |
153 | ||
154 | return begin() + idx; | |
155 | } | |
156 | ||
157 | iterator erase(iterator it) | |
158 | { | |
159 | return erase(it, it + 1); | |
160 | } | |
161 | ||
162 | iterator erase(iterator first, iterator last) | |
163 | { | |
164 | if ( first == last ) | |
165 | return first; | |
166 | wxASSERT( first < end() && last <= end() ); | |
167 | ||
168 | size_type index = first - begin(); | |
169 | size_type count = last - first; | |
170 | ||
171 | // move the remaining values over to the freed space: | |
172 | for ( iterator i = last; i < end(); ++i ) | |
173 | *(i - count) = *i; | |
174 | ||
175 | // erase items behind the new end of m_values: | |
176 | for ( iterator j = end() - count; j < end(); ++j ) | |
177 | *j = value_type(); | |
178 | ||
179 | m_size -= count; | |
180 | ||
181 | return begin() + index; | |
182 | } | |
183 | ||
184 | #if WXWIN_COMPATIBILITY_2_8 | |
185 | wxDEPRECATED( size_type erase(size_type n) ); | |
186 | #endif // WXWIN_COMPATIBILITY_2_8 | |
187 | ||
188 | private: | |
189 | // VC6 can't compile static const int members | |
190 | enum { ALLOC_INITIAL_SIZE = 16 }; | |
191 | enum { ALLOC_MAX_SIZE = 4096 }; | |
192 | ||
193 | void Copy(const wxVector& vb) | |
194 | { | |
195 | clear(); | |
196 | reserve(vb.size()); | |
197 | ||
198 | for ( const_iterator i = vb.begin(); i != vb.end(); ++i ) | |
199 | push_back(*i); | |
200 | } | |
201 | ||
202 | private: | |
203 | size_type m_size, | |
204 | m_capacity; | |
205 | value_type *m_values; | |
206 | }; | |
207 | ||
208 | #if WXWIN_COMPATIBILITY_2_8 | |
209 | template<typename T> | |
210 | typename wxVector<T>::size_type wxVector<T>::erase(size_type n) | |
211 | { | |
212 | erase(begin() + n); | |
213 | return n; | |
214 | } | |
215 | #endif // WXWIN_COMPATIBILITY_2_8 | |
216 | ||
217 | #endif // wxUSE_STL/!wxUSE_STL | |
218 | ||
219 | #if WXWIN_COMPATIBILITY_2_8 | |
220 | #define WX_DECLARE_VECTORBASE(obj, cls) typedef wxVector<obj> cls | |
221 | #define _WX_DECLARE_VECTOR(obj, cls, exp) WX_DECLARE_VECTORBASE(obj, cls) | |
222 | #define WX_DECLARE_VECTOR(obj, cls) WX_DECLARE_VECTORBASE(obj, cls) | |
223 | #endif // WXWIN_COMPATIBILITY_2_8 | |
224 | ||
225 | #endif // _WX_VECTOR_H_ |