tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

uvectr64.h (7902B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 **********************************************************************
      5 *   Copyright (C) 1999-2014, International Business Machines
      6 *   Corporation and others.  All Rights Reserved.
      7 **********************************************************************
      8 */
      9 
     10 //
     11 //  UVector64 is a class implementing a vector of 64 bit integers.
     12 //            It is similar to UVector32, but holds int64_t values rather than int32_t.
     13 //            Most of the code is unchanged from UVector.
     14 //
     15 
     16 #ifndef UVECTOR64_H
     17 #define UVECTOR64_H
     18 
     19 #include "unicode/utypes.h"
     20 #include "unicode/uobject.h"
     21 #include "uhash.h"
     22 #include "uassert.h"
     23 
     24 U_NAMESPACE_BEGIN
     25 
     26 
     27 
     28 /**
     29 * <p>Ultralightweight C++ implementation of an <tt>int64_t</tt> vector
     30 * that has a subset of methods from UVector32
     31 *
     32 * <p>This is a very simple implementation, written to satisfy an
     33 * immediate porting need.  As such, it is not completely fleshed out,
     34 * and it aims for simplicity and conformity.  Nonetheless, it serves
     35 * its purpose (porting code from java that uses java.util.Vector)
     36 * well, and it could be easily made into a more robust vector class.
     37 *
     38 * <p><b>Design notes</b>
     39 *
     40 * <p>There is index bounds checking, but little is done about it.  If
     41 * indices are out of bounds, either nothing happens, or zero is
     42 * returned.  We <em>do</em> avoid indexing off into the weeds.
     43 *
     44 * <p>There is detection of out of memory, but the handling is very
     45 * coarse-grained -- similar to UnicodeString's protocol, but even
     46 * coarser.  The class contains <em>one static flag</em> that is set
     47 * when any call to <tt>new</tt> returns zero.  This allows the caller
     48 * to use several vectors and make just one check at the end to see if
     49 * a memory failure occurred.  This is more efficient than making a
     50 * check after each call on each vector when doing many operations on
     51 * multiple vectors.  The single static flag works best when memory
     52 * failures are infrequent, and when recovery options are limited or
     53 * nonexistent.
     54 *
     55 * <p><b>To do</b>
     56 *
     57 * <p>Improve the handling of index out of bounds errors.
     58 *
     59 */
     60 class U_COMMON_API UVector64 : public UObject {
     61 private:
     62    int32_t   count;
     63 
     64    int32_t   capacity;
     65    
     66    int32_t   maxCapacity;   // Limit beyond which capacity is not permitted to grow.
     67 
     68    int64_t*  elements;
     69 
     70 public:
     71    UVector64(UErrorCode &status);
     72 
     73    UVector64(int32_t initialCapacity, UErrorCode &status);
     74 
     75    virtual ~UVector64();
     76 
     77    /**
     78     * Assign this object to another (make this a copy of 'other').
     79     * Use the 'assign' function to assign each element.
     80     */
     81    void assign(const UVector64& other, UErrorCode &ec);
     82 
     83    /**
     84     * Compare this vector with another.  They will be considered
     85     * equal if they are of the same size and all elements are equal,
     86     * as compared using this object's comparer.
     87     */
     88    bool operator==(const UVector64& other);
     89 
     90    /**
     91     * Equivalent to !operator==()
     92     */
     93    inline bool operator!=(const UVector64& other);
     94 
     95    //------------------------------------------------------------
     96    // subset of java.util.Vector API
     97    //------------------------------------------------------------
     98 
     99    inline void addElement(int64_t elem, UErrorCode &status);
    100 
    101    void setElementAt(int64_t elem, int32_t index);
    102 
    103    void insertElementAt(int64_t elem, int32_t index, UErrorCode &status);
    104    
    105    inline int64_t elementAti(int32_t index) const;
    106 
    107    //UBool equals(const UVector64 &other) const;
    108 
    109    inline int64_t lastElementi() const;
    110 
    111    //int32_t indexOf(int64_t elem, int32_t startIndex = 0) const;
    112 
    113    //UBool contains(int64_t elem) const;
    114 
    115    //UBool containsAll(const UVector64& other) const;
    116 
    117    //UBool removeAll(const UVector64& other);
    118 
    119    //UBool retainAll(const UVector64& other);
    120 
    121    //void removeElementAt(int32_t index);
    122 
    123    void removeAllElements();
    124 
    125    inline int32_t size() const;
    126 
    127    inline UBool isEmpty() const { return count == 0; }
    128 
    129    // Inline.  Use this one for speedy size check.
    130    inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status);
    131 
    132    // Out-of-line, handles actual growth.  Called by ensureCapacity() when necessary.
    133    UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status);
    134 
    135    /**
    136     * Change the size of this vector as follows: If newSize is
    137     * smaller, then truncate the array, possibly deleting held
    138     * elements for i >= newSize.  If newSize is larger, grow the
    139     * array, filling in new slows with zero.
    140     */
    141    void setSize(int32_t newSize);
    142 
    143    //------------------------------------------------------------
    144    // New API
    145    //------------------------------------------------------------
    146 
    147    //UBool containsNone(const UVector64& other) const;
    148 
    149 
    150    //void sortedInsert(int64_t elem, UErrorCode& ec);
    151 
    152    /**
    153     * Returns a pointer to the internal array holding the vector.
    154     */
    155    inline int64_t *getBuffer() const;
    156 
    157    /**
    158     * Set the maximum allowed buffer capacity for this vector/stack.
    159     * Default with no limit set is unlimited, go until malloc() fails.
    160     * A Limit of zero means unlimited capacity.
    161     * Units are vector elements (64 bits each), not bytes.
    162     */
    163    void setMaxCapacity(int32_t limit);
    164 
    165    /**
    166     * ICU "poor man's RTTI", returns a UClassID for this class.
    167     */
    168    static UClassID U_EXPORT2 getStaticClassID();
    169 
    170    /**
    171     * ICU "poor man's RTTI", returns a UClassID for the actual class.
    172     */
    173    virtual UClassID getDynamicClassID() const override;
    174 
    175 private:
    176    void _init(int32_t initialCapacity, UErrorCode &status);
    177 
    178    // Disallow
    179    UVector64(const UVector64&) = delete;
    180 
    181    // Disallow
    182    UVector64& operator=(const UVector64&) = delete;
    183 
    184 
    185    //  API Functions for Stack operations.
    186    //  In the original UVector, these were in a separate derived class, UStack.
    187    //  Here in UVector64, they are all together.
    188 public:
    189    //UBool empty() const;   // TODO:  redundant, same as empty().  Remove it?
    190 
    191    //int64_t peeki() const;
    192    
    193    inline int64_t popi();
    194    
    195    inline int64_t push(int64_t i, UErrorCode &status);
    196 
    197    inline int64_t *reserveBlock(int32_t size, UErrorCode &status);
    198    inline int64_t *popFrame(int32_t size);
    199 };
    200 
    201 
    202 // UVector64 inlines
    203 
    204 inline UBool UVector64::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) {
    205    if ((minimumCapacity >= 0) && (capacity >= minimumCapacity)) {
    206        return true;
    207    } else {
    208        return expandCapacity(minimumCapacity, status);
    209    }
    210 }
    211 
    212 inline int64_t UVector64::elementAti(int32_t index) const {
    213    return (0 <= index && index < count) ? elements[index] : 0;
    214 }
    215 
    216 
    217 inline void UVector64::addElement(int64_t elem, UErrorCode &status) {
    218    if (ensureCapacity(count + 1, status)) {
    219        elements[count] = elem;
    220        count++;
    221    }
    222 }
    223 
    224 inline int64_t *UVector64::reserveBlock(int32_t size, UErrorCode &status) {
    225    if (ensureCapacity(count+size, status) == false) {
    226        return nullptr;
    227    }
    228    int64_t  *rp = elements+count;
    229    count += size;
    230    return rp;
    231 }
    232 
    233 inline int64_t *UVector64::popFrame(int32_t size) {
    234    U_ASSERT(count >= size);
    235    count -= size;
    236    if (count < 0) {
    237        count = 0;
    238    }
    239    return elements+count-size;
    240 }
    241 
    242 
    243 
    244 inline int32_t UVector64::size() const {
    245    return count;
    246 }
    247 
    248 inline int64_t UVector64::lastElementi() const {
    249    return elementAti(count-1);
    250 }
    251 
    252 inline bool UVector64::operator!=(const UVector64& other) {
    253    return !operator==(other);
    254 }
    255 
    256 inline int64_t *UVector64::getBuffer() const {
    257    return elements;
    258 }
    259 
    260 
    261 // UStack inlines
    262 
    263 inline int64_t UVector64::push(int64_t i, UErrorCode &status) {
    264    addElement(i, status);
    265    return i;
    266 }
    267 
    268 inline int64_t UVector64::popi() {
    269    int64_t result = 0;
    270    if (count > 0) {
    271        count--;
    272        result = elements[count];
    273    }
    274    return result;
    275 }
    276 
    277 U_NAMESPACE_END
    278 
    279 #endif