|
1 /* |
|
2 ********************************************************************** |
|
3 * Copyright (C) 1999-2010, International Business Machines |
|
4 * Corporation and others. All Rights Reserved. |
|
5 ********************************************************************** |
|
6 */ |
|
7 |
|
8 // |
|
9 // UVector64 is a class implementing a vector of 64 bit integers. |
|
10 // It is similar to UVector32, but holds int64_t values rather than int32_t. |
|
11 // Most of the code is unchanged from UVector. |
|
12 // |
|
13 |
|
14 #ifndef UVECTOR64_H |
|
15 #define UVECTOR64_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 an <tt>int64_t</tt> vector |
|
28 * that has a subset of methods from UVector32 |
|
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 */ |
|
58 class U_COMMON_API UVector64 : public UObject { |
|
59 private: |
|
60 int32_t count; |
|
61 |
|
62 int32_t capacity; |
|
63 |
|
64 int32_t maxCapacity; // Limit beyond which capacity is not permitted to grow. |
|
65 |
|
66 int64_t* elements; |
|
67 |
|
68 public: |
|
69 UVector64(UErrorCode &status); |
|
70 |
|
71 UVector64(int32_t initialCapacity, UErrorCode &status); |
|
72 |
|
73 virtual ~UVector64(); |
|
74 |
|
75 /** |
|
76 * Assign this object to another (make this a copy of 'other'). |
|
77 * Use the 'assign' function to assign each element. |
|
78 */ |
|
79 void assign(const UVector64& other, UErrorCode &ec); |
|
80 |
|
81 /** |
|
82 * Compare this vector with another. They will be considered |
|
83 * equal if they are of the same size and all elements are equal, |
|
84 * as compared using this object's comparer. |
|
85 */ |
|
86 UBool operator==(const UVector64& other); |
|
87 |
|
88 /** |
|
89 * Equivalent to !operator==() |
|
90 */ |
|
91 inline UBool operator!=(const UVector64& other); |
|
92 |
|
93 //------------------------------------------------------------ |
|
94 // subset of java.util.Vector API |
|
95 //------------------------------------------------------------ |
|
96 |
|
97 void addElement(int64_t elem, UErrorCode &status); |
|
98 |
|
99 void setElementAt(int64_t elem, int32_t index); |
|
100 |
|
101 void insertElementAt(int64_t elem, int32_t index, UErrorCode &status); |
|
102 |
|
103 int64_t elementAti(int32_t index) const; |
|
104 |
|
105 //UBool equals(const UVector64 &other) const; |
|
106 |
|
107 int64_t lastElementi(void) const; |
|
108 |
|
109 //int32_t indexOf(int64_t elem, int32_t startIndex = 0) const; |
|
110 |
|
111 //UBool contains(int64_t elem) const; |
|
112 |
|
113 //UBool containsAll(const UVector64& other) const; |
|
114 |
|
115 //UBool removeAll(const UVector64& other); |
|
116 |
|
117 //UBool retainAll(const UVector64& other); |
|
118 |
|
119 //void removeElementAt(int32_t index); |
|
120 |
|
121 void removeAllElements(); |
|
122 |
|
123 int32_t size(void) const; |
|
124 |
|
125 //UBool isEmpty(void) const; |
|
126 |
|
127 // Inline. Use this one for speedy size check. |
|
128 inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status); |
|
129 |
|
130 // Out-of-line, handles actual growth. Called by ensureCapacity() when necessary. |
|
131 UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status); |
|
132 |
|
133 /** |
|
134 * Change the size of this vector as follows: If newSize is |
|
135 * smaller, then truncate the array, possibly deleting held |
|
136 * elements for i >= newSize. If newSize is larger, grow the |
|
137 * array, filling in new slows with zero. |
|
138 */ |
|
139 void setSize(int32_t newSize); |
|
140 |
|
141 //------------------------------------------------------------ |
|
142 // New API |
|
143 //------------------------------------------------------------ |
|
144 |
|
145 //UBool containsNone(const UVector64& other) const; |
|
146 |
|
147 |
|
148 //void sortedInsert(int64_t elem, UErrorCode& ec); |
|
149 |
|
150 /** |
|
151 * Returns a pointer to the internal array holding the vector. |
|
152 */ |
|
153 int64_t *getBuffer() const; |
|
154 |
|
155 /** |
|
156 * Set the maximum allowed buffer capacity for this vector/stack. |
|
157 * Default with no limit set is unlimited, go until malloc() fails. |
|
158 * A Limit of zero means unlimited capacity. |
|
159 * Units are vector elements (64 bits each), not bytes. |
|
160 */ |
|
161 void setMaxCapacity(int32_t limit); |
|
162 |
|
163 /** |
|
164 * ICU "poor man's RTTI", returns a UClassID for this class. |
|
165 */ |
|
166 static UClassID U_EXPORT2 getStaticClassID(); |
|
167 |
|
168 /** |
|
169 * ICU "poor man's RTTI", returns a UClassID for the actual class. |
|
170 */ |
|
171 virtual UClassID getDynamicClassID() const; |
|
172 |
|
173 private: |
|
174 void _init(int32_t initialCapacity, UErrorCode &status); |
|
175 |
|
176 // Disallow |
|
177 UVector64(const UVector64&); |
|
178 |
|
179 // Disallow |
|
180 UVector64& operator=(const UVector64&); |
|
181 |
|
182 |
|
183 // API Functions for Stack operations. |
|
184 // In the original UVector, these were in a separate derived class, UStack. |
|
185 // Here in UVector64, they are all together. |
|
186 public: |
|
187 //UBool empty(void) const; // TODO: redundant, same as empty(). Remove it? |
|
188 |
|
189 //int64_t peeki(void) const; |
|
190 |
|
191 int64_t popi(void); |
|
192 |
|
193 int64_t push(int64_t i, UErrorCode &status); |
|
194 |
|
195 int64_t *reserveBlock(int32_t size, UErrorCode &status); |
|
196 int64_t *popFrame(int32_t size); |
|
197 }; |
|
198 |
|
199 |
|
200 // UVector64 inlines |
|
201 |
|
202 inline UBool UVector64::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { |
|
203 if ((minimumCapacity >= 0) && (capacity >= minimumCapacity)) { |
|
204 return TRUE; |
|
205 } else { |
|
206 return expandCapacity(minimumCapacity, status); |
|
207 } |
|
208 } |
|
209 |
|
210 inline int64_t UVector64::elementAti(int32_t index) const { |
|
211 return (0 <= index && index < count) ? elements[index] : 0; |
|
212 } |
|
213 |
|
214 |
|
215 inline void UVector64::addElement(int64_t elem, UErrorCode &status) { |
|
216 if (ensureCapacity(count + 1, status)) { |
|
217 elements[count] = elem; |
|
218 count++; |
|
219 } |
|
220 } |
|
221 |
|
222 inline int64_t *UVector64::reserveBlock(int32_t size, UErrorCode &status) { |
|
223 if (ensureCapacity(count+size, status) == FALSE) { |
|
224 return NULL; |
|
225 } |
|
226 int64_t *rp = elements+count; |
|
227 count += size; |
|
228 return rp; |
|
229 } |
|
230 |
|
231 inline int64_t *UVector64::popFrame(int32_t size) { |
|
232 U_ASSERT(count >= size); |
|
233 count -= size; |
|
234 if (count < 0) { |
|
235 count = 0; |
|
236 } |
|
237 return elements+count-size; |
|
238 } |
|
239 |
|
240 |
|
241 |
|
242 inline int32_t UVector64::size(void) const { |
|
243 return count; |
|
244 } |
|
245 |
|
246 inline int64_t UVector64::lastElementi(void) const { |
|
247 return elementAti(count-1); |
|
248 } |
|
249 |
|
250 inline UBool UVector64::operator!=(const UVector64& other) { |
|
251 return !operator==(other); |
|
252 } |
|
253 |
|
254 inline int64_t *UVector64::getBuffer() const { |
|
255 return elements; |
|
256 } |
|
257 |
|
258 |
|
259 // UStack inlines |
|
260 |
|
261 inline int64_t UVector64::push(int64_t i, UErrorCode &status) { |
|
262 addElement(i, status); |
|
263 return i; |
|
264 } |
|
265 |
|
266 inline int64_t UVector64::popi(void) { |
|
267 int64_t result = 0; |
|
268 if (count > 0) { |
|
269 count--; |
|
270 result = elements[count]; |
|
271 } |
|
272 return result; |
|
273 } |
|
274 |
|
275 U_NAMESPACE_END |
|
276 |
|
277 #endif |