]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | ********************************************************************** | |
3 | * Copyright (C) 1999-2006, International Business Machines | |
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; | |
64 | ||
65 | int32_t* elements; | |
66 | ||
67 | public: | |
68 | UVector32(UErrorCode &status); | |
69 | ||
70 | UVector32(int32_t initialCapacity, UErrorCode &status); | |
71 | ||
72 | virtual ~UVector32(); | |
73 | ||
74 | /** | |
75 | * Assign this object to another (make this a copy of 'other'). | |
76 | * Use the 'assign' function to assign each element. | |
77 | */ | |
78 | void assign(const UVector32& other, UErrorCode &ec); | |
79 | ||
80 | /** | |
81 | * Compare this vector with another. They will be considered | |
82 | * equal if they are of the same size and all elements are equal, | |
83 | * as compared using this object's comparer. | |
84 | */ | |
85 | UBool operator==(const UVector32& other); | |
86 | ||
87 | /** | |
88 | * Equivalent to !operator==() | |
89 | */ | |
90 | inline UBool operator!=(const UVector32& other); | |
91 | ||
92 | //------------------------------------------------------------ | |
93 | // java.util.Vector API | |
94 | //------------------------------------------------------------ | |
95 | ||
96 | void addElement(int32_t elem, UErrorCode &status); | |
97 | ||
98 | void setElementAt(int32_t elem, int32_t index); | |
99 | ||
100 | void insertElementAt(int32_t elem, int32_t index, UErrorCode &status); | |
101 | ||
102 | int32_t elementAti(int32_t index) const; | |
103 | ||
104 | UBool equals(const UVector32 &other) const; | |
105 | ||
106 | int32_t lastElementi(void) const; | |
107 | ||
108 | int32_t indexOf(int32_t elem, int32_t startIndex = 0) const; | |
109 | ||
110 | UBool contains(int32_t elem) const; | |
111 | ||
112 | UBool containsAll(const UVector32& other) const; | |
113 | ||
114 | UBool removeAll(const UVector32& other); | |
115 | ||
116 | UBool retainAll(const UVector32& other); | |
117 | ||
118 | void removeElementAt(int32_t index); | |
119 | ||
120 | void removeAllElements(); | |
121 | ||
122 | int32_t size(void) const; | |
123 | ||
124 | UBool isEmpty(void) const; | |
125 | ||
126 | // Inline. Use this one for speedy size check. | |
127 | inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status); | |
128 | ||
129 | // Out-of-line, handles actual growth. Called by ensureCapacity() when necessary. | |
130 | UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status); | |
131 | ||
132 | /** | |
133 | * Change the size of this vector as follows: If newSize is | |
134 | * smaller, then truncate the array, possibly deleting held | |
135 | * elements for i >= newSize. If newSize is larger, grow the | |
136 | * array, filling in new slows with zero. | |
137 | */ | |
138 | void setSize(int32_t newSize); | |
139 | ||
140 | //------------------------------------------------------------ | |
141 | // New API | |
142 | //------------------------------------------------------------ | |
143 | ||
144 | /** | |
145 | * Returns true if this vector contains none of the elements | |
146 | * of the given vector. | |
147 | * @param other vector to be checked for containment | |
148 | * @return true if the test condition is met | |
149 | */ | |
150 | UBool containsNone(const UVector32& other) const; | |
151 | ||
152 | ||
153 | /** | |
154 | * Insert the given integer into this vector at its sorted position. | |
155 | * The current elements are assumed to be sorted already. | |
156 | */ | |
157 | void sortedInsert(int32_t elem, UErrorCode& ec); | |
158 | ||
159 | /** | |
160 | * Returns a pointer to the internal array holding the vector. | |
161 | */ | |
162 | int32_t *getBuffer() const; | |
163 | ||
164 | /** | |
165 | * ICU "poor man's RTTI", returns a UClassID for this class. | |
166 | */ | |
167 | static UClassID U_EXPORT2 getStaticClassID(); | |
168 | ||
169 | /** | |
170 | * ICU "poor man's RTTI", returns a UClassID for the actual class. | |
171 | */ | |
172 | virtual UClassID getDynamicClassID() const; | |
173 | ||
174 | private: | |
175 | void _init(int32_t initialCapacity, UErrorCode &status); | |
176 | ||
177 | // Disallow | |
178 | UVector32(const UVector32&); | |
179 | ||
180 | // Disallow | |
181 | UVector32& operator=(const UVector32&); | |
182 | ||
183 | ||
184 | // API Functions for Stack operations. | |
185 | // In the original UVector, these were in a separate derived class, UStack. | |
186 | // Here in UVector32, they are all together. | |
187 | public: | |
188 | UBool empty(void) const; // TODO: redundant, same as empty(). Remove it? | |
189 | ||
190 | int32_t peeki(void) const; | |
191 | ||
192 | int32_t popi(void); | |
193 | ||
194 | int32_t push(int32_t i, UErrorCode &status); | |
195 | ||
196 | int32_t *reserveBlock(int32_t size, UErrorCode &status); | |
197 | int32_t *popFrame(int32_t size); | |
198 | }; | |
199 | ||
200 | ||
201 | // UVector32 inlines | |
202 | ||
203 | inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { | |
204 | if (capacity >= minimumCapacity) { | |
205 | return TRUE; | |
206 | } else { | |
207 | return expandCapacity(minimumCapacity, status); | |
208 | } | |
209 | } | |
210 | ||
211 | inline int32_t UVector32::elementAti(int32_t index) const { | |
212 | return (0 <= index && index < count) ? elements[index] : 0; | |
213 | } | |
214 | ||
215 | ||
216 | inline void UVector32::addElement(int32_t elem, UErrorCode &status) { | |
217 | if (ensureCapacity(count + 1, status)) { | |
218 | elements[count] = elem; | |
219 | count++; | |
220 | } | |
221 | } | |
222 | ||
223 | inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) { | |
224 | ensureCapacity(count+size, status); | |
225 | int32_t *rp = elements+count; | |
226 | count += size; | |
227 | return rp; | |
228 | } | |
229 | ||
230 | inline int32_t *UVector32::popFrame(int32_t size) { | |
231 | U_ASSERT(count >= size); | |
232 | count -= size; | |
233 | if (count < 0) { | |
234 | count = 0; | |
235 | } | |
236 | return elements+count-size; | |
237 | } | |
238 | ||
239 | ||
240 | ||
241 | inline int32_t UVector32::size(void) const { | |
242 | return count; | |
243 | } | |
244 | ||
245 | inline UBool UVector32::isEmpty(void) const { | |
246 | return count == 0; | |
247 | } | |
248 | ||
249 | inline UBool UVector32::contains(int32_t obj) const { | |
250 | return indexOf(obj) >= 0; | |
251 | } | |
252 | ||
253 | inline int32_t UVector32::lastElementi(void) const { | |
254 | return elementAti(count-1); | |
255 | } | |
256 | ||
257 | inline UBool UVector32::operator!=(const UVector32& other) { | |
258 | return !operator==(other); | |
259 | } | |
260 | ||
261 | inline int32_t *UVector32::getBuffer() const { | |
262 | return elements; | |
263 | } | |
264 | ||
265 | ||
266 | // UStack inlines | |
267 | ||
268 | inline UBool UVector32::empty(void) const { | |
269 | return isEmpty(); | |
270 | } | |
271 | ||
272 | inline int32_t UVector32::peeki(void) const { | |
273 | return lastElementi(); | |
274 | } | |
275 | ||
276 | inline int32_t UVector32::push(int32_t i, UErrorCode &status) { | |
277 | addElement(i, status); | |
278 | return i; | |
279 | } | |
280 | ||
281 | inline int32_t UVector32::popi(void) { | |
282 | int32_t result = 0; | |
283 | if (count > 0) { | |
284 | count--; | |
285 | result = elements[count]; | |
286 | } | |
287 | return result; | |
288 | } | |
289 | ||
290 | U_NAMESPACE_END | |
291 | ||
292 | #endif |