sl@0
|
1 |
/*
|
sl@0
|
2 |
**********************************************************************
|
sl@0
|
3 |
* Copyright (C) 1999-2004, International Business Machines
|
sl@0
|
4 |
* Corporation and others. All Rights Reserved.
|
sl@0
|
5 |
**********************************************************************
|
sl@0
|
6 |
* Date Name Description
|
sl@0
|
7 |
* 10/22/99 alan Creation. This is an internal header.
|
sl@0
|
8 |
* It should not be exported.
|
sl@0
|
9 |
**********************************************************************
|
sl@0
|
10 |
*/
|
sl@0
|
11 |
|
sl@0
|
12 |
#ifndef UVECTOR_H
|
sl@0
|
13 |
#define UVECTOR_H
|
sl@0
|
14 |
|
sl@0
|
15 |
#include "unicode/utypes.h"
|
sl@0
|
16 |
#include "unicode/uobject.h"
|
sl@0
|
17 |
#include "uhash.h"
|
sl@0
|
18 |
|
sl@0
|
19 |
U_NAMESPACE_BEGIN
|
sl@0
|
20 |
|
sl@0
|
21 |
/**
|
sl@0
|
22 |
* A token comparison function.
|
sl@0
|
23 |
* @param tok1 A token (object or integer)
|
sl@0
|
24 |
* @param tok2 A token (object or integer)
|
sl@0
|
25 |
* @return 0 if the two tokens are equal, -1 if tok1 is < tok2, or
|
sl@0
|
26 |
* +1 if tok1 is > tok2.
|
sl@0
|
27 |
*/
|
sl@0
|
28 |
typedef int8_t U_CALLCONV USortComparator(UHashTok tok1,
|
sl@0
|
29 |
UHashTok tok2);
|
sl@0
|
30 |
|
sl@0
|
31 |
/**
|
sl@0
|
32 |
* A token assignment function. It may copy an integer, copy
|
sl@0
|
33 |
* a pointer, or clone a pointer, as appropriate.
|
sl@0
|
34 |
* @param dst The token to be assigned to
|
sl@0
|
35 |
* @param src The token to assign from
|
sl@0
|
36 |
*/
|
sl@0
|
37 |
typedef void U_CALLCONV UTokenAssigner(UHashTok *dst,
|
sl@0
|
38 |
UHashTok *src);
|
sl@0
|
39 |
|
sl@0
|
40 |
/**
|
sl@0
|
41 |
* <p>Ultralightweight C++ implementation of a <tt>void*</tt> vector
|
sl@0
|
42 |
* that is (mostly) compatible with java.util.Vector.
|
sl@0
|
43 |
*
|
sl@0
|
44 |
* <p>This is a very simple implementation, written to satisfy an
|
sl@0
|
45 |
* immediate porting need. As such, it is not completely fleshed out,
|
sl@0
|
46 |
* and it aims for simplicity and conformity. Nonetheless, it serves
|
sl@0
|
47 |
* its purpose (porting code from java that uses java.util.Vector)
|
sl@0
|
48 |
* well, and it could be easily made into a more robust vector class.
|
sl@0
|
49 |
*
|
sl@0
|
50 |
* <p><b>Design notes</b>
|
sl@0
|
51 |
*
|
sl@0
|
52 |
* <p>There is index bounds checking, but little is done about it. If
|
sl@0
|
53 |
* indices are out of bounds, either nothing happens, or zero is
|
sl@0
|
54 |
* returned. We <em>do</em> avoid indexing off into the weeds.
|
sl@0
|
55 |
*
|
sl@0
|
56 |
* <p>There is detection of out of memory, but the handling is very
|
sl@0
|
57 |
* coarse-grained -- similar to UnicodeString's protocol, but even
|
sl@0
|
58 |
* coarser. The class contains <em>one static flag</em> that is set
|
sl@0
|
59 |
* when any call to <tt>new</tt> returns zero. This allows the caller
|
sl@0
|
60 |
* to use several vectors and make just one check at the end to see if
|
sl@0
|
61 |
* a memory failure occurred. This is more efficient than making a
|
sl@0
|
62 |
* check after each call on each vector when doing many operations on
|
sl@0
|
63 |
* multiple vectors. The single static flag works best when memory
|
sl@0
|
64 |
* failures are infrequent, and when recovery options are limited or
|
sl@0
|
65 |
* nonexistent.
|
sl@0
|
66 |
*
|
sl@0
|
67 |
* <p>Since we don't have garbage collection, UVector was given the
|
sl@0
|
68 |
* option to <em>own</em>its contents. To employ this, set a deleter
|
sl@0
|
69 |
* function. The deleter is called on a void* pointer when that
|
sl@0
|
70 |
* pointer is released by the vector, either when the vector itself is
|
sl@0
|
71 |
* destructed, or when a call to setElementAt() overwrites an element,
|
sl@0
|
72 |
* or when a call to remove() or one of its variants explicitly
|
sl@0
|
73 |
* removes an element. If no deleter is set, or the deleter is set to
|
sl@0
|
74 |
* zero, then it is assumed that the caller will delete elements as
|
sl@0
|
75 |
* needed.
|
sl@0
|
76 |
*
|
sl@0
|
77 |
* <p>In order to implement methods such as contains() and indexOf(),
|
sl@0
|
78 |
* UVector needs a way to compare objects for equality. To do so, it
|
sl@0
|
79 |
* uses a comparison frunction, or "comparer." If the comparer is not
|
sl@0
|
80 |
* set, or is set to zero, then all such methods will act as if the
|
sl@0
|
81 |
* vector contains no element. That is, indexOf() will always return
|
sl@0
|
82 |
* -1, contains() will always return FALSE, etc.
|
sl@0
|
83 |
*
|
sl@0
|
84 |
* <p><b>To do</b>
|
sl@0
|
85 |
*
|
sl@0
|
86 |
* <p>Improve the handling of index out of bounds errors.
|
sl@0
|
87 |
*
|
sl@0
|
88 |
* @author Alan Liu
|
sl@0
|
89 |
*/
|
sl@0
|
90 |
class U_COMMON_API UVector : public UObject {
|
sl@0
|
91 |
// NOTE: UVector uses the UHashKey (union of void* and int32_t) as
|
sl@0
|
92 |
// its basic storage type. It uses UKeyComparator as its
|
sl@0
|
93 |
// comparison function. It uses UObjectDeleter as its deleter
|
sl@0
|
94 |
// function. These are named for hashtables, but used here as-is
|
sl@0
|
95 |
// rather than duplicating the type. This allows sharing of
|
sl@0
|
96 |
// support functions.
|
sl@0
|
97 |
|
sl@0
|
98 |
private:
|
sl@0
|
99 |
int32_t count;
|
sl@0
|
100 |
|
sl@0
|
101 |
int32_t capacity;
|
sl@0
|
102 |
|
sl@0
|
103 |
UHashTok* elements;
|
sl@0
|
104 |
|
sl@0
|
105 |
UObjectDeleter *deleter;
|
sl@0
|
106 |
|
sl@0
|
107 |
UKeyComparator *comparer;
|
sl@0
|
108 |
|
sl@0
|
109 |
public:
|
sl@0
|
110 |
UVector(UErrorCode &status);
|
sl@0
|
111 |
|
sl@0
|
112 |
UVector(int32_t initialCapacity, UErrorCode &status);
|
sl@0
|
113 |
|
sl@0
|
114 |
UVector(UObjectDeleter *d, UKeyComparator *c, UErrorCode &status);
|
sl@0
|
115 |
|
sl@0
|
116 |
UVector(UObjectDeleter *d, UKeyComparator *c, int32_t initialCapacity, UErrorCode &status);
|
sl@0
|
117 |
|
sl@0
|
118 |
virtual ~UVector();
|
sl@0
|
119 |
|
sl@0
|
120 |
/**
|
sl@0
|
121 |
* Assign this object to another (make this a copy of 'other').
|
sl@0
|
122 |
* Use the 'assign' function to assign each element.
|
sl@0
|
123 |
*/
|
sl@0
|
124 |
void assign(const UVector& other, UTokenAssigner *assign, UErrorCode &ec);
|
sl@0
|
125 |
|
sl@0
|
126 |
/**
|
sl@0
|
127 |
* Compare this vector with another. They will be considered
|
sl@0
|
128 |
* equal if they are of the same size and all elements are equal,
|
sl@0
|
129 |
* as compared using this object's comparer.
|
sl@0
|
130 |
*/
|
sl@0
|
131 |
UBool operator==(const UVector& other);
|
sl@0
|
132 |
|
sl@0
|
133 |
/**
|
sl@0
|
134 |
* Equivalent to !operator==()
|
sl@0
|
135 |
*/
|
sl@0
|
136 |
inline UBool operator!=(const UVector& other);
|
sl@0
|
137 |
|
sl@0
|
138 |
//------------------------------------------------------------
|
sl@0
|
139 |
// java.util.Vector API
|
sl@0
|
140 |
//------------------------------------------------------------
|
sl@0
|
141 |
|
sl@0
|
142 |
void addElement(void* obj, UErrorCode &status);
|
sl@0
|
143 |
|
sl@0
|
144 |
void addElement(int32_t elem, UErrorCode &status);
|
sl@0
|
145 |
|
sl@0
|
146 |
void setElementAt(void* obj, int32_t index);
|
sl@0
|
147 |
|
sl@0
|
148 |
void setElementAt(int32_t elem, int32_t index);
|
sl@0
|
149 |
|
sl@0
|
150 |
void insertElementAt(void* obj, int32_t index, UErrorCode &status);
|
sl@0
|
151 |
|
sl@0
|
152 |
void insertElementAt(int32_t elem, int32_t index, UErrorCode &status);
|
sl@0
|
153 |
|
sl@0
|
154 |
void* elementAt(int32_t index) const;
|
sl@0
|
155 |
|
sl@0
|
156 |
int32_t elementAti(int32_t index) const;
|
sl@0
|
157 |
|
sl@0
|
158 |
UBool equals(const UVector &other) const;
|
sl@0
|
159 |
|
sl@0
|
160 |
void* firstElement(void) const;
|
sl@0
|
161 |
|
sl@0
|
162 |
void* lastElement(void) const;
|
sl@0
|
163 |
|
sl@0
|
164 |
int32_t lastElementi(void) const;
|
sl@0
|
165 |
|
sl@0
|
166 |
int32_t indexOf(void* obj, int32_t startIndex = 0) const;
|
sl@0
|
167 |
|
sl@0
|
168 |
int32_t indexOf(int32_t obj, int32_t startIndex = 0) const;
|
sl@0
|
169 |
|
sl@0
|
170 |
UBool contains(void* obj) const;
|
sl@0
|
171 |
|
sl@0
|
172 |
UBool contains(int32_t obj) const;
|
sl@0
|
173 |
|
sl@0
|
174 |
UBool containsAll(const UVector& other) const;
|
sl@0
|
175 |
|
sl@0
|
176 |
UBool removeAll(const UVector& other);
|
sl@0
|
177 |
|
sl@0
|
178 |
UBool retainAll(const UVector& other);
|
sl@0
|
179 |
|
sl@0
|
180 |
void removeElementAt(int32_t index);
|
sl@0
|
181 |
|
sl@0
|
182 |
UBool removeElement(void* obj);
|
sl@0
|
183 |
|
sl@0
|
184 |
void removeAllElements();
|
sl@0
|
185 |
|
sl@0
|
186 |
int32_t size(void) const;
|
sl@0
|
187 |
|
sl@0
|
188 |
UBool isEmpty(void) const;
|
sl@0
|
189 |
|
sl@0
|
190 |
UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status);
|
sl@0
|
191 |
|
sl@0
|
192 |
/**
|
sl@0
|
193 |
* Change the size of this vector as follows: If newSize is
|
sl@0
|
194 |
* smaller, then truncate the array, possibly deleting held
|
sl@0
|
195 |
* elements for i >= newSize. If newSize is larger, grow the
|
sl@0
|
196 |
* array, filling in new slows with NULL.
|
sl@0
|
197 |
*/
|
sl@0
|
198 |
void setSize(int32_t newSize);
|
sl@0
|
199 |
|
sl@0
|
200 |
/**
|
sl@0
|
201 |
* Fill in the given array with all elements of this vector.
|
sl@0
|
202 |
*/
|
sl@0
|
203 |
void** toArray(void** result) const;
|
sl@0
|
204 |
|
sl@0
|
205 |
//------------------------------------------------------------
|
sl@0
|
206 |
// New API
|
sl@0
|
207 |
//------------------------------------------------------------
|
sl@0
|
208 |
|
sl@0
|
209 |
UObjectDeleter *setDeleter(UObjectDeleter *d);
|
sl@0
|
210 |
|
sl@0
|
211 |
UKeyComparator *setComparer(UKeyComparator *c);
|
sl@0
|
212 |
|
sl@0
|
213 |
void* operator[](int32_t index) const;
|
sl@0
|
214 |
|
sl@0
|
215 |
/**
|
sl@0
|
216 |
* Removes the element at the given index from this vector and
|
sl@0
|
217 |
* transfer ownership of it to the caller. After this call, the
|
sl@0
|
218 |
* caller owns the result and must delete it and the vector entry
|
sl@0
|
219 |
* at 'index' is removed, shifting all subsequent entries back by
|
sl@0
|
220 |
* one index and shortening the size of the vector by one. If the
|
sl@0
|
221 |
* index is out of range or if there is no item at the given index
|
sl@0
|
222 |
* then 0 is returned and the vector is unchanged.
|
sl@0
|
223 |
*/
|
sl@0
|
224 |
void* orphanElementAt(int32_t index);
|
sl@0
|
225 |
|
sl@0
|
226 |
/**
|
sl@0
|
227 |
* Returns true if this vector contains none of the elements
|
sl@0
|
228 |
* of the given vector.
|
sl@0
|
229 |
* @param other vector to be checked for containment
|
sl@0
|
230 |
* @return true if the test condition is met
|
sl@0
|
231 |
*/
|
sl@0
|
232 |
UBool containsNone(const UVector& other) const;
|
sl@0
|
233 |
|
sl@0
|
234 |
/**
|
sl@0
|
235 |
* Insert the given object into this vector at its sorted position
|
sl@0
|
236 |
* as defined by 'compare'. The current elements are assumed to
|
sl@0
|
237 |
* be sorted already.
|
sl@0
|
238 |
*/
|
sl@0
|
239 |
void sortedInsert(void* obj, USortComparator *compare, UErrorCode& ec);
|
sl@0
|
240 |
|
sl@0
|
241 |
/**
|
sl@0
|
242 |
* Insert the given integer into this vector at its sorted position
|
sl@0
|
243 |
* as defined by 'compare'. The current elements are assumed to
|
sl@0
|
244 |
* be sorted already.
|
sl@0
|
245 |
*/
|
sl@0
|
246 |
void sortedInsert(int32_t obj, USortComparator *compare, UErrorCode& ec);
|
sl@0
|
247 |
|
sl@0
|
248 |
/**
|
sl@0
|
249 |
* ICU "poor man's RTTI", returns a UClassID for this class.
|
sl@0
|
250 |
*
|
sl@0
|
251 |
* @draft ICU 2.2
|
sl@0
|
252 |
*/
|
sl@0
|
253 |
static UClassID U_EXPORT2 getStaticClassID();
|
sl@0
|
254 |
|
sl@0
|
255 |
/**
|
sl@0
|
256 |
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
sl@0
|
257 |
*
|
sl@0
|
258 |
* @draft ICU 2.2
|
sl@0
|
259 |
*/
|
sl@0
|
260 |
virtual UClassID getDynamicClassID() const;
|
sl@0
|
261 |
|
sl@0
|
262 |
private:
|
sl@0
|
263 |
void _init(int32_t initialCapacity, UErrorCode &status);
|
sl@0
|
264 |
|
sl@0
|
265 |
int32_t indexOf(UHashTok key, int32_t startIndex = 0, int8_t hint = 0) const;
|
sl@0
|
266 |
|
sl@0
|
267 |
void sortedInsert(UHashTok tok, USortComparator *compare, UErrorCode& ec);
|
sl@0
|
268 |
|
sl@0
|
269 |
// Disallow
|
sl@0
|
270 |
UVector(const UVector&);
|
sl@0
|
271 |
|
sl@0
|
272 |
// Disallow
|
sl@0
|
273 |
UVector& operator=(const UVector&);
|
sl@0
|
274 |
|
sl@0
|
275 |
};
|
sl@0
|
276 |
|
sl@0
|
277 |
|
sl@0
|
278 |
/**
|
sl@0
|
279 |
* <p>Ultralightweight C++ implementation of a <tt>void*</tt> stack
|
sl@0
|
280 |
* that is (mostly) compatible with java.util.Stack. As in java, this
|
sl@0
|
281 |
* is merely a paper thin layer around UVector. See the UVector
|
sl@0
|
282 |
* documentation for further information.
|
sl@0
|
283 |
*
|
sl@0
|
284 |
* <p><b>Design notes</b>
|
sl@0
|
285 |
*
|
sl@0
|
286 |
* <p>The element at index <tt>n-1</tt> is (of course) the top of the
|
sl@0
|
287 |
* stack.
|
sl@0
|
288 |
*
|
sl@0
|
289 |
* <p>The poorly named <tt>empty()</tt> method doesn't empty the
|
sl@0
|
290 |
* stack; it determines if the stack is empty.
|
sl@0
|
291 |
*
|
sl@0
|
292 |
* @author Alan Liu
|
sl@0
|
293 |
*/
|
sl@0
|
294 |
class U_COMMON_API UStack : public UVector {
|
sl@0
|
295 |
public:
|
sl@0
|
296 |
UStack(UErrorCode &status);
|
sl@0
|
297 |
|
sl@0
|
298 |
UStack(int32_t initialCapacity, UErrorCode &status);
|
sl@0
|
299 |
|
sl@0
|
300 |
UStack(UObjectDeleter *d, UKeyComparator *c, UErrorCode &status);
|
sl@0
|
301 |
|
sl@0
|
302 |
UStack(UObjectDeleter *d, UKeyComparator *c, int32_t initialCapacity, UErrorCode &status);
|
sl@0
|
303 |
|
sl@0
|
304 |
virtual ~UStack();
|
sl@0
|
305 |
|
sl@0
|
306 |
// It's okay not to have a virtual destructor (in UVector)
|
sl@0
|
307 |
// because UStack has no special cleanup to do.
|
sl@0
|
308 |
|
sl@0
|
309 |
UBool empty(void) const;
|
sl@0
|
310 |
|
sl@0
|
311 |
void* peek(void) const;
|
sl@0
|
312 |
|
sl@0
|
313 |
int32_t peeki(void) const;
|
sl@0
|
314 |
|
sl@0
|
315 |
void* pop(void);
|
sl@0
|
316 |
|
sl@0
|
317 |
int32_t popi(void);
|
sl@0
|
318 |
|
sl@0
|
319 |
void* push(void* obj, UErrorCode &status);
|
sl@0
|
320 |
|
sl@0
|
321 |
int32_t push(int32_t i, UErrorCode &status);
|
sl@0
|
322 |
|
sl@0
|
323 |
/*
|
sl@0
|
324 |
If the object o occurs as an item in this stack,
|
sl@0
|
325 |
this method returns the 1-based distance from the top of the stack.
|
sl@0
|
326 |
*/
|
sl@0
|
327 |
int32_t search(void* obj) const;
|
sl@0
|
328 |
|
sl@0
|
329 |
/**
|
sl@0
|
330 |
* ICU "poor man's RTTI", returns a UClassID for this class.
|
sl@0
|
331 |
*
|
sl@0
|
332 |
* @draft ICU 2.2
|
sl@0
|
333 |
*/
|
sl@0
|
334 |
static UClassID U_EXPORT2 getStaticClassID();
|
sl@0
|
335 |
|
sl@0
|
336 |
/**
|
sl@0
|
337 |
* ICU "poor man's RTTI", returns a UClassID for the actual class.
|
sl@0
|
338 |
*
|
sl@0
|
339 |
* @draft ICU 2.2
|
sl@0
|
340 |
*/
|
sl@0
|
341 |
virtual UClassID getDynamicClassID() const;
|
sl@0
|
342 |
|
sl@0
|
343 |
private:
|
sl@0
|
344 |
// Disallow
|
sl@0
|
345 |
UStack(const UStack&);
|
sl@0
|
346 |
|
sl@0
|
347 |
// Disallow
|
sl@0
|
348 |
UStack& operator=(const UStack&);
|
sl@0
|
349 |
};
|
sl@0
|
350 |
|
sl@0
|
351 |
|
sl@0
|
352 |
// UVector inlines
|
sl@0
|
353 |
|
sl@0
|
354 |
inline int32_t UVector::size(void) const {
|
sl@0
|
355 |
return count;
|
sl@0
|
356 |
}
|
sl@0
|
357 |
|
sl@0
|
358 |
inline UBool UVector::isEmpty(void) const {
|
sl@0
|
359 |
return count == 0;
|
sl@0
|
360 |
}
|
sl@0
|
361 |
|
sl@0
|
362 |
inline UBool UVector::contains(void* obj) const {
|
sl@0
|
363 |
return indexOf(obj) >= 0;
|
sl@0
|
364 |
}
|
sl@0
|
365 |
|
sl@0
|
366 |
inline UBool UVector::contains(int32_t obj) const {
|
sl@0
|
367 |
return indexOf(obj) >= 0;
|
sl@0
|
368 |
}
|
sl@0
|
369 |
|
sl@0
|
370 |
inline void* UVector::firstElement(void) const {
|
sl@0
|
371 |
return elementAt(0);
|
sl@0
|
372 |
}
|
sl@0
|
373 |
|
sl@0
|
374 |
inline void* UVector::lastElement(void) const {
|
sl@0
|
375 |
return elementAt(count-1);
|
sl@0
|
376 |
}
|
sl@0
|
377 |
|
sl@0
|
378 |
inline int32_t UVector::lastElementi(void) const {
|
sl@0
|
379 |
return elementAti(count-1);
|
sl@0
|
380 |
}
|
sl@0
|
381 |
|
sl@0
|
382 |
inline void* UVector::operator[](int32_t index) const {
|
sl@0
|
383 |
return elementAt(index);
|
sl@0
|
384 |
}
|
sl@0
|
385 |
|
sl@0
|
386 |
inline UBool UVector::operator!=(const UVector& other) {
|
sl@0
|
387 |
return !operator==(other);
|
sl@0
|
388 |
}
|
sl@0
|
389 |
|
sl@0
|
390 |
// UStack inlines
|
sl@0
|
391 |
|
sl@0
|
392 |
inline UBool UStack::empty(void) const {
|
sl@0
|
393 |
return isEmpty();
|
sl@0
|
394 |
}
|
sl@0
|
395 |
|
sl@0
|
396 |
inline void* UStack::peek(void) const {
|
sl@0
|
397 |
return lastElement();
|
sl@0
|
398 |
}
|
sl@0
|
399 |
|
sl@0
|
400 |
inline int32_t UStack::peeki(void) const {
|
sl@0
|
401 |
return lastElementi();
|
sl@0
|
402 |
}
|
sl@0
|
403 |
|
sl@0
|
404 |
inline void* UStack::push(void* obj, UErrorCode &status) {
|
sl@0
|
405 |
addElement(obj, status);
|
sl@0
|
406 |
return obj;
|
sl@0
|
407 |
}
|
sl@0
|
408 |
|
sl@0
|
409 |
inline int32_t UStack::push(int32_t i, UErrorCode &status) {
|
sl@0
|
410 |
addElement(i, status);
|
sl@0
|
411 |
return i;
|
sl@0
|
412 |
}
|
sl@0
|
413 |
|
sl@0
|
414 |
U_NAMESPACE_END
|
sl@0
|
415 |
|
sl@0
|
416 |
#endif
|