2 ****************************************************************************** 
   3 * Copyright (C) 1999-2001, International Business Machines Corporation and   * 
   4 * others. All Rights Reserved.                                               * 
   5 ****************************************************************************** 
   6 *   Date        Name        Description 
   7 *   10/22/99    alan        Creation. 
   8 ********************************************************************** 
  16 #define DEFUALT_CAPACITY 8 
  19  * Constants for hinting whether a key is an integer 
  20  * or a pointer.  If a hint bit is zero, then the associated 
  21  * token is assumed to be an integer. This is needed for iSeries 
  23 #define HINT_KEY_POINTER   (1) 
  24 #define HINT_KEY_INTEGER   (0) 
  26 const char UVector::fgClassID
=0; 
  28 UVector::UVector(UErrorCode 
&status
) : 
  35     _init(DEFUALT_CAPACITY
, status
); 
  38 UVector::UVector(int32_t initialCapacity
, UErrorCode 
&status
) : 
  45     _init(initialCapacity
, status
); 
  48 UVector::UVector(UObjectDeleter 
*d
, UKeyComparator 
*c
, UErrorCode 
&status
) : 
  55     _init(DEFUALT_CAPACITY
, status
); 
  58 UVector::UVector(UObjectDeleter 
*d
, UKeyComparator 
*c
, int32_t initialCapacity
, UErrorCode 
&status
) : 
  65     _init(initialCapacity
, status
); 
  68 void UVector::_init(int32_t initialCapacity
, UErrorCode 
&status
) { 
  69     // Fix bogus initialCapacity values; avoid malloc(0) 
  70     if (initialCapacity 
< 1) { 
  71         initialCapacity 
= DEFUALT_CAPACITY
; 
  73     elements 
= (UHashTok 
*)uprv_malloc(sizeof(UHashTok
)*initialCapacity
); 
  75         status 
= U_MEMORY_ALLOCATION_ERROR
; 
  77         capacity 
= initialCapacity
; 
  88  * Assign this object to another (make this a copy of 'other'). 
  89  * Use the 'assign' function to assign each element. 
  91 void UVector::assign(const UVector
& other
, UTokenAssigner 
*assign
, UErrorCode 
&ec
) { 
  92     if (ensureCapacity(other
.count
, ec
)) { 
  94         for (int32_t i
=0; i
<other
.count
; ++i
) { 
  95             if (elements
[i
].pointer 
!= 0 && deleter 
!= 0) { 
  96                 (*deleter
)(elements
[i
].pointer
); 
  98             (*assign
)(&elements
[i
], &other
.elements
[i
]); 
 103 // This only does something sensible if this object has a non-null comparer 
 104 UBool 
UVector::operator==(const UVector
& other
) { 
 106     if (count 
!= other
.count
) return FALSE
; 
 107     if (comparer 
!= NULL
) { 
 108         // Compare using this object's comparer 
 109         for (i
=0; i
<count
; ++i
) { 
 110             if (!(*comparer
)(elements
[i
], other
.elements
[i
])) { 
 118 void UVector::addElement(void* obj
, UErrorCode 
&status
) { 
 119     if (ensureCapacity(count 
+ 1, status
)) { 
 120         elements
[count
++].pointer 
= obj
; 
 124 void UVector::addElement(int32_t elem
, UErrorCode 
&status
) { 
 125     if (ensureCapacity(count 
+ 1, status
)) { 
 126         elements
[count
].pointer 
= NULL
;     // Pointers may be bigger than ints. 
 127         elements
[count
].integer 
= elem
; 
 132 void UVector::setElementAt(void* obj
, int32_t index
) { 
 133     if (0 <= index 
&& index 
< count
) { 
 134         if (elements
[index
].pointer 
!= 0 && deleter 
!= 0) { 
 135             (*deleter
)(elements
[index
].pointer
); 
 137         elements
[index
].pointer 
= obj
; 
 139     /* else index out of range */ 
 142 void UVector::setElementAt(int32_t elem
, int32_t index
) { 
 143     if (0 <= index 
&& index 
< count
) { 
 144         if (elements
[index
].pointer 
!= 0 && deleter 
!= 0) { 
 145             // TODO:  this should be an error.  mixing up ints and pointers. 
 146             (*deleter
)(elements
[index
].pointer
); 
 148         elements
[index
].pointer 
= NULL
; 
 149         elements
[index
].integer 
= elem
; 
 151     /* else index out of range */ 
 154 void UVector::insertElementAt(void* obj
, int32_t index
, UErrorCode 
&status
) { 
 155     // must have 0 <= index <= count 
 156     if (0 <= index 
&& index 
<= count 
&& ensureCapacity(count 
+ 1, status
)) { 
 157         for (int32_t i
=count
; i
>index
; --i
) { 
 158             elements
[i
] = elements
[i
-1]; 
 160         elements
[index
].pointer 
= obj
; 
 163     /* else index out of range */ 
 166 void UVector::insertElementAt(int32_t elem
, int32_t index
, UErrorCode 
&status
) { 
 167     // must have 0 <= index <= count 
 168     if (0 <= index 
&& index 
<= count 
&& ensureCapacity(count 
+ 1, status
)) { 
 169         for (int32_t i
=count
; i
>index
; --i
) { 
 170             elements
[i
] = elements
[i
-1]; 
 172         elements
[index
].pointer 
= NULL
; 
 173         elements
[index
].integer 
= elem
; 
 176     /* else index out of range */ 
 179 void* UVector::elementAt(int32_t index
) const { 
 180     return (0 <= index 
&& index 
< count
) ? elements
[index
].pointer 
: 0; 
 183 int32_t UVector::elementAti(int32_t index
) const { 
 184     return (0 <= index 
&& index 
< count
) ? elements
[index
].integer 
: 0; 
 187 UBool 
UVector::containsAll(const UVector
& other
) const { 
 188     for (int32_t i
=0; i
<other
.size(); ++i
) { 
 189         if (indexOf(other
.elements
[i
]) < 0) { 
 196 UBool 
UVector::containsNone(const UVector
& other
) const { 
 197     for (int32_t i
=0; i
<other
.size(); ++i
) { 
 198         if (indexOf(other
.elements
[i
]) >= 0) { 
 205 UBool 
UVector::removeAll(const UVector
& other
) { 
 206     UBool changed 
= FALSE
; 
 207     for (int32_t i
=0; i
<other
.size(); ++i
) { 
 208         int32_t j 
= indexOf(other
.elements
[i
]); 
 217 UBool 
UVector::retainAll(const UVector
& other
) { 
 218     UBool changed 
= FALSE
; 
 219     for (int32_t j
=size()-1; j
>=0; --j
) { 
 220         int32_t i 
= other
.indexOf(elements
[j
]); 
 229 void UVector::removeElementAt(int32_t index
) { 
 230     void* e 
= orphanElementAt(index
); 
 231     if (e 
!= 0 && deleter 
!= 0) { 
 236 UBool 
UVector::removeElement(void* obj
) { 
 237     int32_t i 
= indexOf(obj
); 
 245 void UVector::removeAllElements(void) { 
 247         for (int32_t i
=0; i
<count
; ++i
) { 
 248             if (elements
[i
].pointer 
!= 0) { 
 249                 (*deleter
)(elements
[i
].pointer
); 
 256 UBool   
UVector::equals(const UVector 
&other
) const { 
 259     if (this->count 
!= other
.count
) { 
 263         for (i
=0; i
<count
; i
++) { 
 264             if (elements
[i
].pointer 
!= other
.elements
[i
].pointer
) { 
 270         for (i
=0; i
<count
; i
++) { 
 271             key
.pointer 
= &other
.elements
[i
]; 
 272             if (!(*comparer
)(key
, elements
[i
])) { 
 282 int32_t UVector::indexOf(void* obj
, int32_t startIndex
) const { 
 285     return indexOf(key
, startIndex
, HINT_KEY_POINTER
); 
 288 int32_t UVector::indexOf(int32_t obj
, int32_t startIndex
) const { 
 291     return indexOf(key
, startIndex
, HINT_KEY_INTEGER
); 
 294 // This only works if this object has a non-null comparer 
 295 int32_t UVector::indexOf(UHashTok key
, int32_t startIndex
, int8_t hint
) const { 
 298         for (i
=startIndex
; i
<count
; ++i
) { 
 299             if ((*comparer
)(key
, elements
[i
])) { 
 304         for (i
=startIndex
; i
<count
; ++i
) { 
 305             /* Pointers are not always the same size as ints so to perform 
 306              * a valid comparision we need to know whether we are being 
 307              * provided an int or a pointer. */ 
 308             if (hint 
& HINT_KEY_POINTER
) { 
 309                 if (key
.pointer 
== elements
[i
].pointer
) { 
 313                 if (key
.integer 
== elements
[i
].integer
) { 
 322 UBool 
UVector::ensureCapacity(int32_t minimumCapacity
, UErrorCode 
&status
) { 
 323     if (capacity 
>= minimumCapacity
) { 
 326         int32_t newCap 
= capacity 
* 2; 
 327         if (newCap 
< minimumCapacity
) { 
 328             newCap 
= minimumCapacity
; 
 330         UHashTok
* newElems 
= (UHashTok 
*)uprv_malloc(sizeof(UHashTok
)*newCap
); 
 332             status 
= U_MEMORY_ALLOCATION_ERROR
; 
 335         uprv_memcpy(newElems
, elements
, sizeof(elements
[0]) * count
); 
 344  * Change the size of this vector as follows: If newSize is smaller, 
 345  * then truncate the array, possibly deleting held elements for i >= 
 346  * newSize.  If newSize is larger, grow the array, filling in new 
 349 void UVector::setSize(int32_t newSize
) { 
 354     if (newSize 
> count
) { 
 355         UErrorCode ec 
= U_ZERO_ERROR
; 
 356         if (!ensureCapacity(newSize
, ec
)) { 
 360         empty
.pointer 
= NULL
; 
 362         for (i
=count
; i
<newSize
; ++i
) { 
 366         /* Most efficient to count down */ 
 367         for (i
=count
-1; i
>=newSize
; --i
) { 
 375  * Fill in the given array with all elements of this vector. 
 377 void** UVector::toArray(void** result
) const { 
 379     for (int i
=0; i
<count
; ++i
) { 
 380         *a
++ = elements
[i
].pointer
; 
 385 UObjectDeleter 
*UVector::setDeleter(UObjectDeleter 
*d
) { 
 386     UObjectDeleter 
*old 
= deleter
; 
 391 UKeyComparator 
*UVector::setComparer(UKeyComparator 
*d
) { 
 392     UKeyComparator 
*old 
= comparer
; 
 398  * Removes the element at the given index from this vector and 
 399  * transfer ownership of it to the caller.  After this call, the 
 400  * caller owns the result and must delete it and the vector entry 
 401  * at 'index' is removed, shifting all subsequent entries back by 
 402  * one index and shortening the size of the vector by one.  If the 
 403  * index is out of range or if there is no item at the given index 
 404  * then 0 is returned and the vector is unchanged. 
 406 void* UVector::orphanElementAt(int32_t index
) { 
 408     if (0 <= index 
&& index 
< count
) { 
 409         e 
= elements
[index
].pointer
; 
 410         for (int32_t i
=index
; i
<count
-1; ++i
) { 
 411             elements
[i
] = elements
[i
+1]; 
 415     /* else index out of range */ 
 420  * Insert the given object into this vector at its sorted position 
 421  * as defined by 'compare'.  The current elements are assumed to 
 424 void UVector::sortedInsert(void* obj
, USortComparator 
*compare
, UErrorCode
& ec
) { 
 427     sortedInsert(tok
, compare
, ec
); 
 431  * Insert the given integer into this vector at its sorted position 
 432  * as defined by 'compare'.  The current elements are assumed to 
 435 void UVector::sortedInsert(int32_t obj
, USortComparator 
*compare
, UErrorCode
& ec
) { 
 438     sortedInsert(tok
, compare
, ec
); 
 441 // ASSUME elements[] IS CURRENTLY SORTED 
 442 void UVector::sortedInsert(UHashTok tok
, USortComparator 
*compare
, UErrorCode
& ec
) { 
 443     // Perform a binary search for the location to insert tok at.  Tok 
 444     // will be inserted between two elements a and b such that a <= 
 445     // tok && tok < b, where there is a 'virtual' elements[-1] always 
 446     // less than tok and a 'virtual' elements[count] always greater 
 448     int32_t min 
= 0, max 
= count
; 
 450         int32_t probe 
= (min 
+ max
) / 2; 
 451         int8_t c 
= (*compare
)(elements
[probe
], tok
); 
 459     if (ensureCapacity(count 
+ 1, ec
)) { 
 460         for (int32_t i
=count
; i
>min
; --i
) { 
 461             elements
[i
] = elements
[i
-1]; 
 468 const char UStack::fgClassID
=0; 
 470 UStack::UStack(UErrorCode 
&status
) : 
 475 UStack::UStack(int32_t initialCapacity
, UErrorCode 
&status
) : 
 476     UVector(initialCapacity
, status
) 
 480 UStack::UStack(UObjectDeleter 
*d
, UKeyComparator 
*c
, UErrorCode 
&status
) : 
 481     UVector(d
, c
, status
) 
 485 UStack::UStack(UObjectDeleter 
*d
, UKeyComparator 
*c
, int32_t initialCapacity
, UErrorCode 
&status
) : 
 486     UVector(d
, c
, initialCapacity
, status
) 
 490 void* UStack::pop(void) { 
 491     int32_t n 
= size() - 1; 
 494         result 
= elementAt(n
); 
 500 int32_t UStack::popi(void) { 
 501     int32_t n 
= size() - 1; 
 504         result 
= elementAti(n
); 
 510 int32_t UStack::search(void* obj
) const { 
 511     int32_t i 
= indexOf(obj
); 
 512     return (i 
>= 0) ? size() - i 
: i
;