2 ******************************************************************************
3 * Copyright (C) 1999-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 ******************************************************************************
6 * Date Name Description
7 * 10/22/99 alan Creation.
8 **********************************************************************
17 #define DEFAULT_CAPACITY 8
20 * Constants for hinting whether a key is an integer
21 * or a pointer. If a hint bit is zero, then the associated
22 * token is assumed to be an integer. This is needed for iSeries
25 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector32
)
27 UVector32::UVector32(UErrorCode
&status
) :
33 _init(DEFAULT_CAPACITY
, status
);
36 UVector32::UVector32(int32_t initialCapacity
, UErrorCode
&status
) :
42 _init(initialCapacity
, status
);
47 void UVector32::_init(int32_t initialCapacity
, UErrorCode
&status
) {
48 // Fix bogus initialCapacity values; avoid malloc(0)
49 if (initialCapacity
< 1) {
50 initialCapacity
= DEFAULT_CAPACITY
;
52 if (maxCapacity
>0 && maxCapacity
<initialCapacity
) {
53 initialCapacity
= maxCapacity
;
55 if (initialCapacity
> (int32_t)(INT32_MAX
/ sizeof(int32_t))) {
56 initialCapacity
= uprv_min(DEFAULT_CAPACITY
, maxCapacity
);
58 elements
= (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity
);
60 status
= U_MEMORY_ALLOCATION_ERROR
;
62 capacity
= initialCapacity
;
66 UVector32::~UVector32() {
72 * Assign this object to another (make this a copy of 'other').
74 void UVector32::assign(const UVector32
& other
, UErrorCode
&ec
) {
75 if (ensureCapacity(other
.count
, ec
)) {
77 for (int32_t i
=0; i
<other
.count
; ++i
) {
78 elements
[i
] = other
.elements
[i
];
84 UBool
UVector32::operator==(const UVector32
& other
) {
86 if (count
!= other
.count
) return FALSE
;
87 for (i
=0; i
<count
; ++i
) {
88 if (elements
[i
] != other
.elements
[i
]) {
96 void UVector32::setElementAt(int32_t elem
, int32_t index
) {
97 if (0 <= index
&& index
< count
) {
98 elements
[index
] = elem
;
100 /* else index out of range */
103 void UVector32::insertElementAt(int32_t elem
, int32_t index
, UErrorCode
&status
) {
104 // must have 0 <= index <= count
105 if (0 <= index
&& index
<= count
&& ensureCapacity(count
+ 1, status
)) {
106 for (int32_t i
=count
; i
>index
; --i
) {
107 elements
[i
] = elements
[i
-1];
109 elements
[index
] = elem
;
112 /* else index out of range */
115 UBool
UVector32::containsAll(const UVector32
& other
) const {
116 for (int32_t i
=0; i
<other
.size(); ++i
) {
117 if (indexOf(other
.elements
[i
]) < 0) {
124 UBool
UVector32::containsNone(const UVector32
& other
) const {
125 for (int32_t i
=0; i
<other
.size(); ++i
) {
126 if (indexOf(other
.elements
[i
]) >= 0) {
133 UBool
UVector32::removeAll(const UVector32
& other
) {
134 UBool changed
= FALSE
;
135 for (int32_t i
=0; i
<other
.size(); ++i
) {
136 int32_t j
= indexOf(other
.elements
[i
]);
145 UBool
UVector32::retainAll(const UVector32
& other
) {
146 UBool changed
= FALSE
;
147 for (int32_t j
=size()-1; j
>=0; --j
) {
148 int32_t i
= other
.indexOf(elements
[j
]);
157 void UVector32::removeElementAt(int32_t index
) {
159 for (int32_t i
=index
; i
<count
-1; ++i
) {
160 elements
[i
] = elements
[i
+1];
166 void UVector32::removeAllElements(void) {
170 UBool
UVector32::equals(const UVector32
&other
) const {
173 if (this->count
!= other
.count
) {
176 for (i
=0; i
<count
; i
++) {
177 if (elements
[i
] != other
.elements
[i
]) {
187 int32_t UVector32::indexOf(int32_t key
, int32_t startIndex
) const {
189 for (i
=startIndex
; i
<count
; ++i
) {
190 if (key
== elements
[i
]) {
198 UBool
UVector32::expandCapacity(int32_t minimumCapacity
, UErrorCode
&status
) {
199 if (minimumCapacity
< 0) {
200 status
= U_ILLEGAL_ARGUMENT_ERROR
;
203 if (capacity
>= minimumCapacity
) {
206 if (maxCapacity
>0 && minimumCapacity
>maxCapacity
) {
207 status
= U_BUFFER_OVERFLOW_ERROR
;
210 if (capacity
> (INT32_MAX
- 1) / 2) { // integer overflow check
211 status
= U_ILLEGAL_ARGUMENT_ERROR
;
214 int32_t newCap
= capacity
* 2;
215 if (newCap
< minimumCapacity
) {
216 newCap
= minimumCapacity
;
218 if (maxCapacity
> 0 && newCap
> maxCapacity
) {
219 newCap
= maxCapacity
;
221 if (newCap
> (int32_t)(INT32_MAX
/ sizeof(int32_t))) { // integer overflow check
222 // We keep the original memory contents on bad minimumCapacity/maxCapacity.
223 status
= U_ILLEGAL_ARGUMENT_ERROR
;
226 int32_t* newElems
= (int32_t *)uprv_realloc(elements
, sizeof(int32_t)*newCap
);
227 if (newElems
== NULL
) {
228 // We keep the original contents on the memory failure on realloc.
229 status
= U_MEMORY_ALLOCATION_ERROR
;
237 void UVector32::setMaxCapacity(int32_t limit
) {
238 U_ASSERT(limit
>= 0);
242 if (limit
> (int32_t)(INT32_MAX
/ sizeof(int32_t))) { // integer overflow check for realloc
243 // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged
247 if (capacity
<= maxCapacity
|| maxCapacity
== 0) {
248 // Current capacity is within the new limit.
252 // New maximum capacity is smaller than the current size.
253 // Realloc the storage to the new, smaller size.
254 int32_t* newElems
= (int32_t *)uprv_realloc(elements
, sizeof(int32_t)*maxCapacity
);
255 if (newElems
== NULL
) {
256 // Realloc to smaller failed.
257 // Just keep what we had. No need to call it a failure.
261 capacity
= maxCapacity
;
262 if (count
> capacity
) {
268 * Change the size of this vector as follows: If newSize is smaller,
269 * then truncate the array, possibly deleting held elements for i >=
270 * newSize. If newSize is larger, grow the array, filling in new
273 void UVector32::setSize(int32_t newSize
) {
278 if (newSize
> count
) {
279 UErrorCode ec
= U_ZERO_ERROR
;
280 if (!ensureCapacity(newSize
, ec
)) {
283 for (i
=count
; i
<newSize
; ++i
) {
294 * Insert the given integer into this vector at its sorted position
295 * as defined by 'compare'. The current elements are assumed to
298 void UVector32::sortedInsert(int32_t tok
, UErrorCode
& ec
) {
299 // Perform a binary search for the location to insert tok at. Tok
300 // will be inserted between two elements a and b such that a <=
301 // tok && tok < b, where there is a 'virtual' elements[-1] always
302 // less than tok and a 'virtual' elements[count] always greater
304 int32_t min
= 0, max
= count
;
306 int32_t probe
= (min
+ max
) / 2;
307 //int8_t c = (*compare)(elements[probe], tok);
309 if (elements
[probe
] > tok
) {
316 if (ensureCapacity(count
+ 1, ec
)) {
317 for (int32_t i
=count
; i
>min
; --i
) {
318 elements
[i
] = elements
[i
-1];