intl/icu/source/common/uvector.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial