1 /* 2 ********************************************************************** 3 * Copyright (C) 1999-2011, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ********************************************************************** 6 */ 7 8 // 9 // UVector32 is a class implementing a vector of 32 bit integers. 10 // It is similar to UVector, but holds int32_t values rather than pointers. 11 // Most of the code is unchanged from UVector. 12 // 13 14 #ifndef UVECTOR32_H 15 #define UVECTOR32_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 a <tt>void*</tt> vector 28 * that is (mostly) compatible with java.util.Vector. 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 * @author Alan Liu 58 */ 59 class U_COMMON_API UVector32 : public UObject { 60 private: 61 int32_t count; 62 63 int32_t capacity; 64 65 int32_t maxCapacity; // Limit beyond which capacity is not permitted to grow. 66 67 int32_t* elements; 68 69 public: 70 UVector32(UErrorCode &status); 71 72 UVector32(int32_t initialCapacity, UErrorCode &status); 73 74 virtual ~UVector32(); 75 76 /** 77 * Assign this object to another (make this a copy of 'other'). 78 * Use the 'assign' function to assign each element. 79 */ 80 void assign(const UVector32& other, UErrorCode &ec); 81 82 /** 83 * Compare this vector with another. They will be considered 84 * equal if they are of the same size and all elements are equal, 85 * as compared using this object's comparer. 86 */ 87 UBool operator==(const UVector32& other); 88 89 /** 90 * Equivalent to !operator==() 91 */ 92 inline UBool operator!=(const UVector32& other); 93 94 //------------------------------------------------------------ 95 // java.util.Vector API 96 //------------------------------------------------------------ 97 98 void addElement(int32_t elem, UErrorCode &status); 99 100 void setElementAt(int32_t elem, int32_t index); 101 102 void insertElementAt(int32_t elem, int32_t index, UErrorCode &status); 103 104 int32_t elementAti(int32_t index) const; 105 106 UBool equals(const UVector32 &other) const; 107 108 int32_t lastElementi(void) const; 109 110 int32_t indexOf(int32_t elem, int32_t startIndex = 0) const; 111 112 UBool contains(int32_t elem) const; 113 114 UBool containsAll(const UVector32& other) const; 115 116 UBool removeAll(const UVector32& other); 117 118 UBool retainAll(const UVector32& other); 119 120 void removeElementAt(int32_t index); 121 122 void removeAllElements(); 123 124 int32_t size(void) const; 125 126 UBool isEmpty(void) const; 127 128 // Inline. Use this one for speedy size check. 129 inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status); 130 131 // Out-of-line, handles actual growth. Called by ensureCapacity() when necessary. 132 UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status); 133 134 /** 135 * Change the size of this vector as follows: If newSize is 136 * smaller, then truncate the array, possibly deleting held 137 * elements for i >= newSize. If newSize is larger, grow the 138 * array, filling in new slows with zero. 139 */ 140 void setSize(int32_t newSize); 141 142 //------------------------------------------------------------ 143 // New API 144 //------------------------------------------------------------ 145 146 /** 147 * Returns true if this vector contains none of the elements 148 * of the given vector. 149 * @param other vector to be checked for containment 150 * @return true if the test condition is met 151 */ 152 UBool containsNone(const UVector32& other) const; 153 154 155 /** 156 * Insert the given integer into this vector at its sorted position. 157 * The current elements are assumed to be sorted already. 158 */ 159 void sortedInsert(int32_t elem, UErrorCode& ec); 160 161 /** 162 * Returns a pointer to the internal array holding the vector. 163 */ 164 int32_t *getBuffer() const; 165 166 /** 167 * Set the maximum allowed buffer capacity for this vector/stack. 168 * Default with no limit set is unlimited, go until malloc() fails. 169 * A Limit of zero means unlimited capacity. 170 * Units are vector elements (32 bits each), not bytes. 171 */ 172 void setMaxCapacity(int32_t limit); 173 174 /** 175 * ICU "poor man's RTTI", returns a UClassID for this class. 176 */ 177 static UClassID U_EXPORT2 getStaticClassID(); 178 179 /** 180 * ICU "poor man's RTTI", returns a UClassID for the actual class. 181 */ 182 virtual UClassID getDynamicClassID() const; 183 184 private: 185 void _init(int32_t initialCapacity, UErrorCode &status); 186 187 // Disallow 188 UVector32(const UVector32&); 189 190 // Disallow 191 UVector32& operator=(const UVector32&); 192 193 194 // API Functions for Stack operations. 195 // In the original UVector, these were in a separate derived class, UStack. 196 // Here in UVector32, they are all together. 197 public: 198 UBool empty(void) const; // TODO: redundant, same as empty(). Remove it? 199 200 int32_t peeki(void) const; 201 202 int32_t popi(void); 203 204 int32_t push(int32_t i, UErrorCode &status); 205 206 int32_t *reserveBlock(int32_t size, UErrorCode &status); 207 int32_t *popFrame(int32_t size); 208 }; 209 210 211 // UVector32 inlines 212 213 inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { 214 if ((minimumCapacity >= 0) && (capacity >= minimumCapacity)) { 215 return TRUE; 216 } else { 217 return expandCapacity(minimumCapacity, status); 218 } 219 } 220 221 inline int32_t UVector32::elementAti(int32_t index) const { 222 return (index >= 0 && count > 0 && count - index > 0) ? elements[index] : 0; 223 } 224 225 226 inline void UVector32::addElement(int32_t elem, UErrorCode &status) { 227 if (ensureCapacity(count + 1, status)) { 228 elements[count] = elem; 229 count++; 230 } 231 } 232 233 inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) { 234 if (ensureCapacity(count+size, status) == FALSE) { 235 return NULL; 236 } 237 int32_t *rp = elements+count; 238 count += size; 239 return rp; 240 } 241 242 inline int32_t *UVector32::popFrame(int32_t size) { 243 U_ASSERT(count >= size); 244 count -= size; 245 if (count < 0) { 246 count = 0; 247 } 248 return elements+count-size; 249 } 250 251 252 253 inline int32_t UVector32::size(void) const { 254 return count; 255 } 256 257 inline UBool UVector32::isEmpty(void) const { 258 return count == 0; 259 } 260 261 inline UBool UVector32::contains(int32_t obj) const { 262 return indexOf(obj) >= 0; 263 } 264 265 inline int32_t UVector32::lastElementi(void) const { 266 return elementAti(count-1); 267 } 268 269 inline UBool UVector32::operator!=(const UVector32& other) { 270 return !operator==(other); 271 } 272 273 inline int32_t *UVector32::getBuffer() const { 274 return elements; 275 } 276 277 278 // UStack inlines 279 280 inline UBool UVector32::empty(void) const { 281 return isEmpty(); 282 } 283 284 inline int32_t UVector32::peeki(void) const { 285 return lastElementi(); 286 } 287 288 inline int32_t UVector32::push(int32_t i, UErrorCode &status) { 289 addElement(i, status); 290 return i; 291 } 292 293 inline int32_t UVector32::popi(void) { 294 int32_t result = 0; 295 if (count > 0) { 296 count--; 297 result = elements[count]; 298 } 299 return result; 300 } 301 302 U_NAMESPACE_END 303 304 #endif 305