uvectr64.cpp revision 50294ead5e5d23f5bbfed76e00e6b510bd41eee1
1/* 2****************************************************************************** 3* Copyright (C) 1999-2010, International Business Machines Corporation and * 4* others. All Rights Reserved. * 5****************************************************************************** 6*/ 7 8#include "uvectr64.h" 9#include "cmemory.h" 10 11U_NAMESPACE_BEGIN 12 13#define DEFAULT_CAPACITY 8 14 15/* 16 * Constants for hinting whether a key is an integer 17 * or a pointer. If a hint bit is zero, then the associated 18 * token is assumed to be an integer. This is needed for iSeries 19 */ 20 21UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector64) 22 23UVector64::UVector64(UErrorCode &status) : 24 count(0), 25 capacity(0), 26 maxCapacity(0), 27 elements(NULL) 28{ 29 _init(DEFAULT_CAPACITY, status); 30} 31 32UVector64::UVector64(int32_t initialCapacity, UErrorCode &status) : 33 count(0), 34 capacity(0), 35 maxCapacity(0), 36 elements(0) 37{ 38 _init(initialCapacity, status); 39} 40 41 42 43void UVector64::_init(int32_t initialCapacity, UErrorCode &status) { 44 // Fix bogus initialCapacity values; avoid malloc(0) 45 if (initialCapacity < 1) { 46 initialCapacity = DEFAULT_CAPACITY; 47 } 48 if (maxCapacity>0 && maxCapacity<initialCapacity) { 49 initialCapacity = maxCapacity; 50 } 51 elements = (int64_t *)uprv_malloc(sizeof(int64_t)*initialCapacity); 52 if (elements == 0) { 53 status = U_MEMORY_ALLOCATION_ERROR; 54 } else { 55 capacity = initialCapacity; 56 } 57} 58 59UVector64::~UVector64() { 60 uprv_free(elements); 61 elements = 0; 62} 63 64/** 65 * Assign this object to another (make this a copy of 'other'). 66 */ 67void UVector64::assign(const UVector64& other, UErrorCode &ec) { 68 if (ensureCapacity(other.count, ec)) { 69 setSize(other.count); 70 for (int32_t i=0; i<other.count; ++i) { 71 elements[i] = other.elements[i]; 72 } 73 } 74} 75 76 77UBool UVector64::operator==(const UVector64& other) { 78 int32_t i; 79 if (count != other.count) return FALSE; 80 for (i=0; i<count; ++i) { 81 if (elements[i] != other.elements[i]) { 82 return FALSE; 83 } 84 } 85 return TRUE; 86} 87 88 89void UVector64::setElementAt(int64_t elem, int32_t index) { 90 if (0 <= index && index < count) { 91 elements[index] = elem; 92 } 93 /* else index out of range */ 94} 95 96void UVector64::insertElementAt(int64_t elem, int32_t index, UErrorCode &status) { 97 // must have 0 <= index <= count 98 if (0 <= index && index <= count && ensureCapacity(count + 1, status)) { 99 for (int32_t i=count; i>index; --i) { 100 elements[i] = elements[i-1]; 101 } 102 elements[index] = elem; 103 ++count; 104 } 105 /* else index out of range */ 106} 107 108void UVector64::removeAllElements(void) { 109 count = 0; 110} 111 112UBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { 113 if (capacity >= minimumCapacity) { 114 return TRUE; 115 } 116 if (maxCapacity>0 && minimumCapacity>maxCapacity) { 117 status = U_BUFFER_OVERFLOW_ERROR; 118 return FALSE; 119 } 120 int32_t newCap = capacity * 2; 121 if (newCap < minimumCapacity) { 122 newCap = minimumCapacity; 123 } 124 if (maxCapacity > 0 && newCap > maxCapacity) { 125 newCap = maxCapacity; 126 } 127 int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*newCap); 128 if (newElems == NULL) { 129 // We keep the original contents on the memory failure on realloc. 130 status = U_MEMORY_ALLOCATION_ERROR; 131 return FALSE; 132 } 133 elements = newElems; 134 capacity = newCap; 135 return TRUE; 136} 137 138void UVector64::setMaxCapacity(int32_t limit) { 139 U_ASSERT(limit >= 0); 140 maxCapacity = limit; 141 if (maxCapacity < 0) { 142 maxCapacity = 0; 143 } 144 if (capacity <= maxCapacity || maxCapacity == 0) { 145 // Current capacity is within the new limit. 146 return; 147 } 148 149 // New maximum capacity is smaller than the current size. 150 // Realloc the storage to the new, smaller size. 151 int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*maxCapacity); 152 if (newElems == NULL) { 153 // Realloc to smaller failed. 154 // Just keep what we had. No need to call it a failure. 155 return; 156 } 157 elements = newElems; 158 capacity = maxCapacity; 159 if (count > capacity) { 160 count = capacity; 161 } 162} 163 164/** 165 * Change the size of this vector as follows: If newSize is smaller, 166 * then truncate the array, possibly deleting held elements for i >= 167 * newSize. If newSize is larger, grow the array, filling in new 168 * slots with NULL. 169 */ 170void UVector64::setSize(int32_t newSize) { 171 int32_t i; 172 if (newSize < 0) { 173 return; 174 } 175 if (newSize > count) { 176 UErrorCode ec = U_ZERO_ERROR; 177 if (!ensureCapacity(newSize, ec)) { 178 return; 179 } 180 for (i=count; i<newSize; ++i) { 181 elements[i] = 0; 182 } 183 } 184 count = newSize; 185} 186 187U_NAMESPACE_END 188 189