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