os/textandloc/fontservices/textshaperplugin/IcuSource/common/uvector.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
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