]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ********************************************************************** | |
4388f060 | 3 | * Copyright (C) 1999-2011, International Business Machines |
b75a7d8f A |
4 | * Corporation and others. All Rights Reserved. |
5 | ********************************************************************** | |
6 | */ | |
7 | ||
8 | // | |
9 | // UVector32 is a class implementing a vector of 32 bit integers. | |
10 | // It is similar to UVector, but holds int32_t values rather than pointers. | |
11 | // Most of the code is unchanged from UVector. | |
12 | // | |
13 | ||
14 | #ifndef UVECTOR32_H | |
15 | #define UVECTOR32_H | |
16 | ||
17 | #include "unicode/utypes.h" | |
18 | #include "unicode/uobject.h" | |
19 | #include "uhash.h" | |
20 | #include "uassert.h" | |
21 | ||
22 | U_NAMESPACE_BEGIN | |
23 | ||
24 | ||
25 | ||
26 | /** | |
27 | * <p>Ultralightweight C++ implementation of a <tt>void*</tt> vector | |
28 | * that is (mostly) compatible with java.util.Vector. | |
29 | * | |
30 | * <p>This is a very simple implementation, written to satisfy an | |
31 | * immediate porting need. As such, it is not completely fleshed out, | |
32 | * and it aims for simplicity and conformity. Nonetheless, it serves | |
33 | * its purpose (porting code from java that uses java.util.Vector) | |
34 | * well, and it could be easily made into a more robust vector class. | |
35 | * | |
36 | * <p><b>Design notes</b> | |
37 | * | |
38 | * <p>There is index bounds checking, but little is done about it. If | |
39 | * indices are out of bounds, either nothing happens, or zero is | |
40 | * returned. We <em>do</em> avoid indexing off into the weeds. | |
41 | * | |
42 | * <p>There is detection of out of memory, but the handling is very | |
43 | * coarse-grained -- similar to UnicodeString's protocol, but even | |
44 | * coarser. The class contains <em>one static flag</em> that is set | |
45 | * when any call to <tt>new</tt> returns zero. This allows the caller | |
46 | * to use several vectors and make just one check at the end to see if | |
47 | * a memory failure occurred. This is more efficient than making a | |
48 | * check after each call on each vector when doing many operations on | |
49 | * multiple vectors. The single static flag works best when memory | |
50 | * failures are infrequent, and when recovery options are limited or | |
51 | * nonexistent. | |
52 | * | |
53 | * <p><b>To do</b> | |
54 | * | |
55 | * <p>Improve the handling of index out of bounds errors. | |
56 | * | |
57 | * @author Alan Liu | |
58 | */ | |
59 | class U_COMMON_API UVector32 : public UObject { | |
60 | private: | |
61 | int32_t count; | |
62 | ||
63 | int32_t capacity; | |
46f4442e A |
64 | |
65 | int32_t maxCapacity; // Limit beyond which capacity is not permitted to grow. | |
b75a7d8f A |
66 | |
67 | int32_t* elements; | |
68 | ||
69 | public: | |
70 | UVector32(UErrorCode &status); | |
71 | ||
72 | UVector32(int32_t initialCapacity, UErrorCode &status); | |
73 | ||
73c04bcf | 74 | virtual ~UVector32(); |
b75a7d8f A |
75 | |
76 | /** | |
77 | * Assign this object to another (make this a copy of 'other'). | |
78 | * Use the 'assign' function to assign each element. | |
79 | */ | |
80 | void assign(const UVector32& other, UErrorCode &ec); | |
81 | ||
82 | /** | |
83 | * Compare this vector with another. They will be considered | |
84 | * equal if they are of the same size and all elements are equal, | |
85 | * as compared using this object's comparer. | |
86 | */ | |
87 | UBool operator==(const UVector32& other); | |
88 | ||
89 | /** | |
90 | * Equivalent to !operator==() | |
91 | */ | |
92 | inline UBool operator!=(const UVector32& other); | |
93 | ||
94 | //------------------------------------------------------------ | |
95 | // java.util.Vector API | |
96 | //------------------------------------------------------------ | |
97 | ||
98 | void addElement(int32_t elem, UErrorCode &status); | |
99 | ||
100 | void setElementAt(int32_t elem, int32_t index); | |
101 | ||
102 | void insertElementAt(int32_t elem, int32_t index, UErrorCode &status); | |
103 | ||
104 | int32_t elementAti(int32_t index) const; | |
105 | ||
106 | UBool equals(const UVector32 &other) const; | |
107 | ||
108 | int32_t lastElementi(void) const; | |
109 | ||
374ca955 | 110 | int32_t indexOf(int32_t elem, int32_t startIndex = 0) const; |
b75a7d8f | 111 | |
374ca955 | 112 | UBool contains(int32_t elem) const; |
b75a7d8f A |
113 | |
114 | UBool containsAll(const UVector32& other) const; | |
115 | ||
116 | UBool removeAll(const UVector32& other); | |
117 | ||
118 | UBool retainAll(const UVector32& other); | |
119 | ||
120 | void removeElementAt(int32_t index); | |
121 | ||
122 | void removeAllElements(); | |
123 | ||
124 | int32_t size(void) const; | |
125 | ||
126 | UBool isEmpty(void) const; | |
127 | ||
128 | // Inline. Use this one for speedy size check. | |
129 | inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status); | |
130 | ||
131 | // Out-of-line, handles actual growth. Called by ensureCapacity() when necessary. | |
132 | UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status); | |
133 | ||
134 | /** | |
135 | * Change the size of this vector as follows: If newSize is | |
136 | * smaller, then truncate the array, possibly deleting held | |
137 | * elements for i >= newSize. If newSize is larger, grow the | |
138 | * array, filling in new slows with zero. | |
139 | */ | |
140 | void setSize(int32_t newSize); | |
141 | ||
142 | //------------------------------------------------------------ | |
143 | // New API | |
144 | //------------------------------------------------------------ | |
145 | ||
146 | /** | |
147 | * Returns true if this vector contains none of the elements | |
148 | * of the given vector. | |
149 | * @param other vector to be checked for containment | |
150 | * @return true if the test condition is met | |
151 | */ | |
152 | UBool containsNone(const UVector32& other) const; | |
153 | ||
154 | ||
155 | /** | |
156 | * Insert the given integer into this vector at its sorted position. | |
157 | * The current elements are assumed to be sorted already. | |
158 | */ | |
374ca955 | 159 | void sortedInsert(int32_t elem, UErrorCode& ec); |
b75a7d8f A |
160 | |
161 | /** | |
162 | * Returns a pointer to the internal array holding the vector. | |
163 | */ | |
164 | int32_t *getBuffer() const; | |
165 | ||
46f4442e A |
166 | /** |
167 | * Set the maximum allowed buffer capacity for this vector/stack. | |
168 | * Default with no limit set is unlimited, go until malloc() fails. | |
169 | * A Limit of zero means unlimited capacity. | |
170 | * Units are vector elements (32 bits each), not bytes. | |
171 | */ | |
172 | void setMaxCapacity(int32_t limit); | |
173 | ||
b75a7d8f A |
174 | /** |
175 | * ICU "poor man's RTTI", returns a UClassID for this class. | |
b75a7d8f | 176 | */ |
374ca955 | 177 | static UClassID U_EXPORT2 getStaticClassID(); |
b75a7d8f A |
178 | |
179 | /** | |
180 | * ICU "poor man's RTTI", returns a UClassID for the actual class. | |
b75a7d8f | 181 | */ |
374ca955 | 182 | virtual UClassID getDynamicClassID() const; |
b75a7d8f A |
183 | |
184 | private: | |
185 | void _init(int32_t initialCapacity, UErrorCode &status); | |
186 | ||
187 | // Disallow | |
188 | UVector32(const UVector32&); | |
189 | ||
190 | // Disallow | |
191 | UVector32& operator=(const UVector32&); | |
192 | ||
b75a7d8f A |
193 | |
194 | // API Functions for Stack operations. | |
195 | // In the original UVector, these were in a separate derived class, UStack. | |
196 | // Here in UVector32, they are all together. | |
197 | public: | |
374ca955 | 198 | UBool empty(void) const; // TODO: redundant, same as empty(). Remove it? |
b75a7d8f A |
199 | |
200 | int32_t peeki(void) const; | |
201 | ||
202 | int32_t popi(void); | |
203 | ||
204 | int32_t push(int32_t i, UErrorCode &status); | |
205 | ||
206 | int32_t *reserveBlock(int32_t size, UErrorCode &status); | |
207 | int32_t *popFrame(int32_t size); | |
208 | }; | |
209 | ||
210 | ||
211 | // UVector32 inlines | |
212 | ||
213 | inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { | |
729e4ab9 | 214 | if ((minimumCapacity >= 0) && (capacity >= minimumCapacity)) { |
b75a7d8f A |
215 | return TRUE; |
216 | } else { | |
217 | return expandCapacity(minimumCapacity, status); | |
218 | } | |
219 | } | |
220 | ||
221 | inline int32_t UVector32::elementAti(int32_t index) const { | |
4388f060 | 222 | return (index >= 0 && count > 0 && count - index > 0) ? elements[index] : 0; |
b75a7d8f A |
223 | } |
224 | ||
225 | ||
226 | inline void UVector32::addElement(int32_t elem, UErrorCode &status) { | |
227 | if (ensureCapacity(count + 1, status)) { | |
228 | elements[count] = elem; | |
229 | count++; | |
230 | } | |
231 | } | |
232 | ||
233 | inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) { | |
46f4442e A |
234 | if (ensureCapacity(count+size, status) == FALSE) { |
235 | return NULL; | |
236 | } | |
b75a7d8f A |
237 | int32_t *rp = elements+count; |
238 | count += size; | |
239 | return rp; | |
240 | } | |
241 | ||
242 | inline int32_t *UVector32::popFrame(int32_t size) { | |
243 | U_ASSERT(count >= size); | |
244 | count -= size; | |
245 | if (count < 0) { | |
246 | count = 0; | |
247 | } | |
248 | return elements+count-size; | |
249 | } | |
250 | ||
251 | ||
252 | ||
253 | inline int32_t UVector32::size(void) const { | |
254 | return count; | |
255 | } | |
256 | ||
257 | inline UBool UVector32::isEmpty(void) const { | |
258 | return count == 0; | |
259 | } | |
260 | ||
261 | inline UBool UVector32::contains(int32_t obj) const { | |
262 | return indexOf(obj) >= 0; | |
263 | } | |
264 | ||
265 | inline int32_t UVector32::lastElementi(void) const { | |
266 | return elementAti(count-1); | |
267 | } | |
268 | ||
269 | inline UBool UVector32::operator!=(const UVector32& other) { | |
270 | return !operator==(other); | |
271 | } | |
272 | ||
273 | inline int32_t *UVector32::getBuffer() const { | |
274 | return elements; | |
73c04bcf | 275 | } |
b75a7d8f A |
276 | |
277 | ||
278 | // UStack inlines | |
279 | ||
280 | inline UBool UVector32::empty(void) const { | |
281 | return isEmpty(); | |
282 | } | |
283 | ||
284 | inline int32_t UVector32::peeki(void) const { | |
285 | return lastElementi(); | |
286 | } | |
287 | ||
288 | inline int32_t UVector32::push(int32_t i, UErrorCode &status) { | |
289 | addElement(i, status); | |
290 | return i; | |
291 | } | |
292 | ||
293 | inline int32_t UVector32::popi(void) { | |
294 | int32_t result = 0; | |
295 | if (count > 0) { | |
296 | count--; | |
297 | result = elements[count]; | |
298 | } | |
299 | return result; | |
300 | } | |
301 | ||
302 | U_NAMESPACE_END | |
303 | ||
304 | #endif |