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