1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ******************************************************************************
5 * Copyright (C) 1999-2015, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ******************************************************************************
8 * Date Name Description
9 * 10/22/99 alan Creation.
10 **********************************************************************
19 #define DEFAULT_CAPACITY 8
22 * Constants for hinting whether a key is an integer
23 * or a pointer. If a hint bit is zero, then the associated
24 * token is assumed to be an integer. This is needed for iSeries
27 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UVector32
)
29 UVector32::UVector32(UErrorCode
&status
) :
35 _init(DEFAULT_CAPACITY
, status
);
38 UVector32::UVector32(int32_t initialCapacity
, UErrorCode
&status
) :
44 _init(initialCapacity
, status
);
49 void UVector32::_init(int32_t initialCapacity
, UErrorCode
&status
) {
50 // Fix bogus initialCapacity values; avoid malloc(0)
51 if (initialCapacity
< 1) {
52 initialCapacity
= DEFAULT_CAPACITY
;
54 if (maxCapacity
>0 && maxCapacity
<initialCapacity
) {
55 initialCapacity
= maxCapacity
;
57 if (initialCapacity
> (int32_t)(INT32_MAX
/ sizeof(int32_t))) {
58 initialCapacity
= uprv_min(DEFAULT_CAPACITY
, maxCapacity
);
60 elements
= (int32_t *)uprv_malloc(sizeof(int32_t)*initialCapacity
);
62 status
= U_MEMORY_ALLOCATION_ERROR
;
64 capacity
= initialCapacity
;
68 UVector32::~UVector32() {
74 * Assign this object to another (make this a copy of 'other').
76 void UVector32::assign(const UVector32
& other
, UErrorCode
&ec
) {
77 if (ensureCapacity(other
.count
, ec
)) {
79 for (int32_t i
=0; i
<other
.count
; ++i
) {
80 elements
[i
] = other
.elements
[i
];
86 UBool
UVector32::operator==(const UVector32
& other
) {
88 if (count
!= other
.count
) return FALSE
;
89 for (i
=0; i
<count
; ++i
) {
90 if (elements
[i
] != other
.elements
[i
]) {
98 void UVector32::setElementAt(int32_t elem
, int32_t index
) {
99 if (0 <= index
&& index
< count
) {
100 elements
[index
] = elem
;
102 /* else index out of range */
105 void UVector32::insertElementAt(int32_t elem
, int32_t index
, UErrorCode
&status
) {
106 // must have 0 <= index <= count
107 if (0 <= index
&& index
<= count
&& ensureCapacity(count
+ 1, status
)) {
108 for (int32_t i
=count
; i
>index
; --i
) {
109 elements
[i
] = elements
[i
-1];
111 elements
[index
] = elem
;
114 /* else index out of range */
117 UBool
UVector32::containsAll(const UVector32
& other
) const {
118 for (int32_t i
=0; i
<other
.size(); ++i
) {
119 if (indexOf(other
.elements
[i
]) < 0) {
126 UBool
UVector32::containsNone(const UVector32
& other
) const {
127 for (int32_t i
=0; i
<other
.size(); ++i
) {
128 if (indexOf(other
.elements
[i
]) >= 0) {
135 UBool
UVector32::removeAll(const UVector32
& other
) {
136 UBool changed
= FALSE
;
137 for (int32_t i
=0; i
<other
.size(); ++i
) {
138 int32_t j
= indexOf(other
.elements
[i
]);
147 UBool
UVector32::retainAll(const UVector32
& other
) {
148 UBool changed
= FALSE
;
149 for (int32_t j
=size()-1; j
>=0; --j
) {
150 int32_t i
= other
.indexOf(elements
[j
]);
159 void UVector32::removeElementAt(int32_t index
) {
161 for (int32_t i
=index
; i
<count
-1; ++i
) {
162 elements
[i
] = elements
[i
+1];
168 void UVector32::removeAllElements(void) {
172 UBool
UVector32::equals(const UVector32
&other
) const {
175 if (this->count
!= other
.count
) {
178 for (i
=0; i
<count
; i
++) {
179 if (elements
[i
] != other
.elements
[i
]) {
189 int32_t UVector32::indexOf(int32_t key
, int32_t startIndex
) const {
191 for (i
=startIndex
; i
<count
; ++i
) {
192 if (key
== elements
[i
]) {
200 UBool
UVector32::expandCapacity(int32_t minimumCapacity
, UErrorCode
&status
) {
201 if (U_FAILURE(status
)) {
204 if (minimumCapacity
< 0) {
205 status
= U_ILLEGAL_ARGUMENT_ERROR
;
208 if (capacity
>= minimumCapacity
) {
211 if (maxCapacity
>0 && minimumCapacity
>maxCapacity
) {
212 status
= U_BUFFER_OVERFLOW_ERROR
;
215 if (capacity
> (INT32_MAX
- 1) / 2) { // integer overflow check
216 status
= U_ILLEGAL_ARGUMENT_ERROR
;
219 int32_t newCap
= capacity
* 2;
220 if (newCap
< minimumCapacity
) {
221 newCap
= minimumCapacity
;
223 if (maxCapacity
> 0 && newCap
> maxCapacity
) {
224 newCap
= maxCapacity
;
226 if (newCap
> (int32_t)(INT32_MAX
/ sizeof(int32_t))) { // integer overflow check
227 // We keep the original memory contents on bad minimumCapacity/maxCapacity.
228 status
= U_ILLEGAL_ARGUMENT_ERROR
;
231 int32_t* newElems
= (int32_t *)uprv_realloc(elements
, sizeof(int32_t)*newCap
);
232 if (newElems
== NULL
) {
233 // We keep the original contents on the memory failure on realloc.
234 status
= U_MEMORY_ALLOCATION_ERROR
;
242 void UVector32::setMaxCapacity(int32_t limit
) {
243 U_ASSERT(limit
>= 0);
247 if (limit
> (int32_t)(INT32_MAX
/ sizeof(int32_t))) { // integer overflow check for realloc
248 // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged
252 if (capacity
<= maxCapacity
|| maxCapacity
== 0) {
253 // Current capacity is within the new limit.
257 // New maximum capacity is smaller than the current size.
258 // Realloc the storage to the new, smaller size.
259 int32_t* newElems
= (int32_t *)uprv_realloc(elements
, sizeof(int32_t)*maxCapacity
);
260 if (newElems
== NULL
) {
261 // Realloc to smaller failed.
262 // Just keep what we had. No need to call it a failure.
266 capacity
= maxCapacity
;
267 if (count
> capacity
) {
273 * Change the size of this vector as follows: If newSize is smaller,
274 * then truncate the array, possibly deleting held elements for i >=
275 * newSize. If newSize is larger, grow the array, filling in new
278 void UVector32::setSize(int32_t newSize
) {
283 if (newSize
> count
) {
284 UErrorCode ec
= U_ZERO_ERROR
;
285 if (!ensureCapacity(newSize
, ec
)) {
288 for (i
=count
; i
<newSize
; ++i
) {
299 * Insert the given integer into this vector at its sorted position
300 * as defined by 'compare'. The current elements are assumed to
303 void UVector32::sortedInsert(int32_t tok
, UErrorCode
& ec
) {
304 // Perform a binary search for the location to insert tok at. Tok
305 // will be inserted between two elements a and b such that a <=
306 // tok && tok < b, where there is a 'virtual' elements[-1] always
307 // less than tok and a 'virtual' elements[count] always greater
309 int32_t min
= 0, max
= count
;
311 int32_t probe
= (min
+ max
) / 2;
312 //int8_t c = (*compare)(elements[probe], tok);
314 if (elements
[probe
] > tok
) {
321 if (ensureCapacity(count
+ 1, ec
)) {
322 for (int32_t i
=count
; i
>min
; --i
) {
323 elements
[i
] = elements
[i
-1];