sl@0: /* sl@0: ********************************************************************** sl@0: * Copyright (C) 1999-2005, International Business Machines sl@0: * Corporation and others. All Rights Reserved. sl@0: ********************************************************************** sl@0: */ sl@0: sl@0: // sl@0: // UVector32 is a class implementing a vector of 32 bit integers. sl@0: // It is similar to UVector, but holds int32_t values rather than pointers. sl@0: // Most of the code is unchanged from UVector. sl@0: // sl@0: sl@0: #ifndef UVECTOR32_H sl@0: #define UVECTOR32_H sl@0: sl@0: #include "unicode/utypes.h" sl@0: #include "unicode/uobject.h" sl@0: #include "uhash.h" sl@0: #include "uassert.h" sl@0: sl@0: U_NAMESPACE_BEGIN sl@0: sl@0: sl@0: sl@0: /** sl@0: *
Ultralightweight C++ implementation of a void* vector sl@0: * that is (mostly) compatible with java.util.Vector. sl@0: * sl@0: *
This is a very simple implementation, written to satisfy an sl@0: * immediate porting need. As such, it is not completely fleshed out, sl@0: * and it aims for simplicity and conformity. Nonetheless, it serves sl@0: * its purpose (porting code from java that uses java.util.Vector) sl@0: * well, and it could be easily made into a more robust vector class. sl@0: * sl@0: *
Design notes sl@0: * sl@0: *
There is index bounds checking, but little is done about it. If sl@0: * indices are out of bounds, either nothing happens, or zero is sl@0: * returned. We do avoid indexing off into the weeds. sl@0: * sl@0: *
There is detection of out of memory, but the handling is very sl@0: * coarse-grained -- similar to UnicodeString's protocol, but even sl@0: * coarser. The class contains one static flag that is set sl@0: * when any call to new returns zero. This allows the caller sl@0: * to use several vectors and make just one check at the end to see if sl@0: * a memory failure occurred. This is more efficient than making a sl@0: * check after each call on each vector when doing many operations on sl@0: * multiple vectors. The single static flag works best when memory sl@0: * failures are infrequent, and when recovery options are limited or sl@0: * nonexistent. sl@0: * sl@0: *
To do sl@0: * sl@0: *
Improve the handling of index out of bounds errors. sl@0: * sl@0: * @author Alan Liu sl@0: */ sl@0: class U_COMMON_API UVector32 : public UObject { sl@0: private: sl@0: int32_t count; sl@0: sl@0: int32_t capacity; sl@0: sl@0: int32_t* elements; sl@0: sl@0: public: sl@0: UVector32(UErrorCode &status); sl@0: sl@0: UVector32(int32_t initialCapacity, UErrorCode &status); sl@0: sl@0: virtual ~UVector32(); sl@0: sl@0: /** sl@0: * Assign this object to another (make this a copy of 'other'). sl@0: * Use the 'assign' function to assign each element. sl@0: */ sl@0: void assign(const UVector32& other, UErrorCode &ec); sl@0: sl@0: /** sl@0: * Compare this vector with another. They will be considered sl@0: * equal if they are of the same size and all elements are equal, sl@0: * as compared using this object's comparer. sl@0: */ sl@0: UBool operator==(const UVector32& other); sl@0: sl@0: /** sl@0: * Equivalent to !operator==() sl@0: */ sl@0: inline UBool operator!=(const UVector32& other); sl@0: sl@0: //------------------------------------------------------------ sl@0: // java.util.Vector API sl@0: //------------------------------------------------------------ sl@0: sl@0: void addElement(int32_t elem, UErrorCode &status); sl@0: sl@0: void setElementAt(int32_t elem, int32_t index); sl@0: sl@0: void insertElementAt(int32_t elem, int32_t index, UErrorCode &status); sl@0: sl@0: int32_t elementAti(int32_t index) const; sl@0: sl@0: UBool equals(const UVector32 &other) const; sl@0: sl@0: int32_t lastElementi(void) const; sl@0: sl@0: int32_t indexOf(int32_t elem, int32_t startIndex = 0) const; sl@0: sl@0: UBool contains(int32_t elem) const; sl@0: sl@0: UBool containsAll(const UVector32& other) const; sl@0: sl@0: UBool removeAll(const UVector32& other); sl@0: sl@0: UBool retainAll(const UVector32& other); sl@0: sl@0: void removeElementAt(int32_t index); sl@0: sl@0: void removeAllElements(); sl@0: sl@0: int32_t size(void) const; sl@0: sl@0: UBool isEmpty(void) const; sl@0: sl@0: // Inline. Use this one for speedy size check. sl@0: inline UBool ensureCapacity(int32_t minimumCapacity, UErrorCode &status); sl@0: sl@0: // Out-of-line, handles actual growth. Called by ensureCapacity() when necessary. sl@0: UBool expandCapacity(int32_t minimumCapacity, UErrorCode &status); sl@0: sl@0: /** sl@0: * Change the size of this vector as follows: If newSize is sl@0: * smaller, then truncate the array, possibly deleting held sl@0: * elements for i >= newSize. If newSize is larger, grow the sl@0: * array, filling in new slows with zero. sl@0: */ sl@0: void setSize(int32_t newSize); sl@0: sl@0: //------------------------------------------------------------ sl@0: // New API sl@0: //------------------------------------------------------------ sl@0: sl@0: /** sl@0: * Returns true if this vector contains none of the elements sl@0: * of the given vector. sl@0: * @param other vector to be checked for containment sl@0: * @return true if the test condition is met sl@0: */ sl@0: UBool containsNone(const UVector32& other) const; sl@0: sl@0: sl@0: /** sl@0: * Insert the given integer into this vector at its sorted position. sl@0: * The current elements are assumed to be sorted already. sl@0: */ sl@0: void sortedInsert(int32_t elem, UErrorCode& ec); sl@0: sl@0: /** sl@0: * Returns a pointer to the internal array holding the vector. sl@0: */ sl@0: int32_t *getBuffer() const; sl@0: sl@0: /** sl@0: * ICU "poor man's RTTI", returns a UClassID for this class. sl@0: * sl@0: * @draft ICU 2.2 sl@0: */ sl@0: static UClassID U_EXPORT2 getStaticClassID(); sl@0: sl@0: /** sl@0: * ICU "poor man's RTTI", returns a UClassID for the actual class. sl@0: * sl@0: * @draft ICU 2.2 sl@0: */ sl@0: virtual UClassID getDynamicClassID() const; sl@0: sl@0: private: sl@0: void _init(int32_t initialCapacity, UErrorCode &status); sl@0: sl@0: // Disallow sl@0: UVector32(const UVector32&); sl@0: sl@0: // Disallow sl@0: UVector32& operator=(const UVector32&); sl@0: sl@0: sl@0: // API Functions for Stack operations. sl@0: // In the original UVector, these were in a separate derived class, UStack. sl@0: // Here in UVector32, they are all together. sl@0: public: sl@0: UBool empty(void) const; // TODO: redundant, same as empty(). Remove it? sl@0: sl@0: int32_t peeki(void) const; sl@0: sl@0: int32_t popi(void); sl@0: sl@0: int32_t push(int32_t i, UErrorCode &status); sl@0: sl@0: int32_t *reserveBlock(int32_t size, UErrorCode &status); sl@0: int32_t *popFrame(int32_t size); sl@0: }; sl@0: sl@0: sl@0: // UVector32 inlines sl@0: sl@0: inline UBool UVector32::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { sl@0: if (capacity >= minimumCapacity) { sl@0: return TRUE; sl@0: } else { sl@0: return expandCapacity(minimumCapacity, status); sl@0: } sl@0: } sl@0: sl@0: inline int32_t UVector32::elementAti(int32_t index) const { sl@0: return (0 <= index && index < count) ? elements[index] : 0; sl@0: } sl@0: sl@0: sl@0: inline void UVector32::addElement(int32_t elem, UErrorCode &status) { sl@0: if (ensureCapacity(count + 1, status)) { sl@0: elements[count] = elem; sl@0: count++; sl@0: } sl@0: } sl@0: sl@0: inline int32_t *UVector32::reserveBlock(int32_t size, UErrorCode &status) { sl@0: ensureCapacity(count+size, status); sl@0: int32_t *rp = elements+count; sl@0: count += size; sl@0: return rp; sl@0: } sl@0: sl@0: inline int32_t *UVector32::popFrame(int32_t size) { sl@0: U_ASSERT(count >= size); sl@0: count -= size; sl@0: if (count < 0) { sl@0: count = 0; sl@0: } sl@0: return elements+count-size; sl@0: } sl@0: sl@0: sl@0: sl@0: inline int32_t UVector32::size(void) const { sl@0: return count; sl@0: } sl@0: sl@0: inline UBool UVector32::isEmpty(void) const { sl@0: return count == 0; sl@0: } sl@0: sl@0: inline UBool UVector32::contains(int32_t obj) const { sl@0: return indexOf(obj) >= 0; sl@0: } sl@0: sl@0: inline int32_t UVector32::lastElementi(void) const { sl@0: return elementAti(count-1); sl@0: } sl@0: sl@0: inline UBool UVector32::operator!=(const UVector32& other) { sl@0: return !operator==(other); sl@0: } sl@0: sl@0: inline int32_t *UVector32::getBuffer() const { sl@0: return elements; sl@0: } sl@0: sl@0: sl@0: // UStack inlines sl@0: sl@0: inline UBool UVector32::empty(void) const { sl@0: return isEmpty(); sl@0: } sl@0: sl@0: inline int32_t UVector32::peeki(void) const { sl@0: return lastElementi(); sl@0: } sl@0: sl@0: inline int32_t UVector32::push(int32_t i, UErrorCode &status) { sl@0: addElement(i, status); sl@0: return i; sl@0: } sl@0: sl@0: inline int32_t UVector32::popi(void) { sl@0: int32_t result = 0; sl@0: if (count > 0) { sl@0: count--; sl@0: result = elements[count]; sl@0: } sl@0: return result; sl@0: } sl@0: sl@0: U_NAMESPACE_END sl@0: sl@0: #endif