|
1 /* |
|
2 ********************************************************************** |
|
3 * Copyright (C) 1999-2005, 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 * @draft ICU 2.2 |
|
168 */ |
|
169 static UClassID U_EXPORT2 getStaticClassID(); |
|
170 |
|
171 /** |
|
172 * ICU "poor man's RTTI", returns a UClassID for the actual class. |
|
173 * |
|
174 * @draft ICU 2.2 |
|
175 */ |
|
176 virtual UClassID getDynamicClassID() const; |
|
177 |
|
178 private: |
|
179 void _init(int32_t initialCapacity, UErrorCode &status); |
|
180 |
|
181 // Disallow |
|
182 UVector32(const UVector32&); |
|
183 |
|
184 // Disallow |
|
185 UVector32& operator=(const UVector32&); |
|
186 |
|
187 |
|
188 // API Functions for Stack operations. |
|
189 // In the original UVector, these were in a separate derived class, UStack. |
|
190 // Here in UVector32, they are all together. |
|
191 public: |
|
192 UBool empty(void) const; // TODO: redundant, same as empty(). Remove it? |
|
193 |
|
194 int32_t peeki(void) const; |
|
195 |
|
196 int32_t popi(void); |
|
197 |
|
198 int32_t push(int32_t i, UErrorCode &status); |
|
199 |
|
200 int32_t *reserveBlock(int32_t size, UErrorCode &status); |
|
201 int32_t *popFrame(int32_t size); |
|
202 }; |
|
203 |
|
204 |
|
205 // UVector32 inlines |
|
206 |
|
207 inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { |
|
208 if (capacity >= minimumCapacity) { |
|
209 return TRUE; |
|
210 } else { |
|
211 return expandCapacity(minimumCapacity, status); |
|
212 } |
|
213 } |
|
214 |
|
215 inline int32_t UVector32::elementAti(int32_t index) const { |
|
216 return (0 <= index && index < count) ? elements[index] : 0; |
|
217 } |
|
218 |
|
219 |
|
220 inline void UVector32::addElement(int32_t elem, UErrorCode &status) { |
|
221 if (ensureCapacity(count + 1, status)) { |
|
222 elements[count] = elem; |
|
223 count++; |
|
224 } |
|
225 } |
|
226 |
|
227 inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) { |
|
228 ensureCapacity(count+size, status); |
|
229 int32_t *rp = elements+count; |
|
230 count += size; |
|
231 return rp; |
|
232 } |
|
233 |
|
234 inline int32_t *UVector32::popFrame(int32_t size) { |
|
235 U_ASSERT(count >= size); |
|
236 count -= size; |
|
237 if (count < 0) { |
|
238 count = 0; |
|
239 } |
|
240 return elements+count-size; |
|
241 } |
|
242 |
|
243 |
|
244 |
|
245 inline int32_t UVector32::size(void) const { |
|
246 return count; |
|
247 } |
|
248 |
|
249 inline UBool UVector32::isEmpty(void) const { |
|
250 return count == 0; |
|
251 } |
|
252 |
|
253 inline UBool UVector32::contains(int32_t obj) const { |
|
254 return indexOf(obj) >= 0; |
|
255 } |
|
256 |
|
257 inline int32_t UVector32::lastElementi(void) const { |
|
258 return elementAti(count-1); |
|
259 } |
|
260 |
|
261 inline UBool UVector32::operator!=(const UVector32& other) { |
|
262 return !operator==(other); |
|
263 } |
|
264 |
|
265 inline int32_t *UVector32::getBuffer() const { |
|
266 return elements; |
|
267 } |
|
268 |
|
269 |
|
270 // UStack inlines |
|
271 |
|
272 inline UBool UVector32::empty(void) const { |
|
273 return isEmpty(); |
|
274 } |
|
275 |
|
276 inline int32_t UVector32::peeki(void) const { |
|
277 return lastElementi(); |
|
278 } |
|
279 |
|
280 inline int32_t UVector32::push(int32_t i, UErrorCode &status) { |
|
281 addElement(i, status); |
|
282 return i; |
|
283 } |
|
284 |
|
285 inline int32_t UVector32::popi(void) { |
|
286 int32_t result = 0; |
|
287 if (count > 0) { |
|
288 count--; |
|
289 result = elements[count]; |
|
290 } |
|
291 return result; |
|
292 } |
|
293 |
|
294 U_NAMESPACE_END |
|
295 |
|
296 #endif |