ICU-1023 fix UVector to support int32_t elements properly
X-SVN-Rev: 5398
This commit is contained in:
parent
63e908b597
commit
772c6a5bd5
@ -23,7 +23,7 @@ UVector::UVector(int32_t initialCapacity) :
|
||||
_init(initialCapacity);
|
||||
}
|
||||
|
||||
UVector::UVector(Deleter d, Comparer c, int32_t initialCapacity) :
|
||||
UVector::UVector(UObjectDeleter d, UKeyComparator c, int32_t initialCapacity) :
|
||||
count(0),
|
||||
capacity(0),
|
||||
elements(0),
|
||||
@ -34,7 +34,7 @@ UVector::UVector(Deleter d, Comparer c, int32_t initialCapacity) :
|
||||
}
|
||||
|
||||
void UVector::_init(int32_t initialCapacity) {
|
||||
elements = new void*[initialCapacity];
|
||||
elements = new UHashKey[initialCapacity];
|
||||
if (elements == 0) {
|
||||
outOfMemory = TRUE;
|
||||
} else {
|
||||
@ -50,16 +50,32 @@ UVector::~UVector() {
|
||||
|
||||
void UVector::addElement(void* obj) {
|
||||
if (ensureCapacity(count + 1)) {
|
||||
elements[count++] = obj;
|
||||
elements[count++].pointer = obj;
|
||||
}
|
||||
}
|
||||
|
||||
void UVector::addElement(int32_t elem) {
|
||||
if (ensureCapacity(count + 1)) {
|
||||
elements[count++].integer = elem;
|
||||
}
|
||||
}
|
||||
|
||||
void UVector::setElementAt(void* obj, int32_t index) {
|
||||
if (0 <= index && index < count) {
|
||||
if (elements[index] != 0 && deleter != 0) {
|
||||
(*deleter)(elements[index]);
|
||||
if (elements[index].pointer != 0 && deleter != 0) {
|
||||
(*deleter)(elements[index].pointer);
|
||||
}
|
||||
elements[index] = obj;
|
||||
elements[index].pointer = obj;
|
||||
}
|
||||
/* else index out of range */
|
||||
}
|
||||
|
||||
void UVector::setElementAt(int32_t elem, int32_t index) {
|
||||
if (0 <= index && index < count) {
|
||||
if (elements[index].pointer != 0 && deleter != 0) {
|
||||
(*deleter)(elements[index].pointer);
|
||||
}
|
||||
elements[index].integer = elem;
|
||||
}
|
||||
/* else index out of range */
|
||||
}
|
||||
@ -70,13 +86,17 @@ void UVector::insertElementAt(void* obj, int32_t index) {
|
||||
for (int32_t i=count; i>index; --i) {
|
||||
elements[i] = elements[i-1];
|
||||
}
|
||||
elements[index] = obj;
|
||||
elements[index].pointer = obj;
|
||||
}
|
||||
/* else index out of range */
|
||||
}
|
||||
|
||||
void* UVector::elementAt(int32_t index) const {
|
||||
return (0 <= index && index < count) ? elements[index] : 0;
|
||||
return (0 <= index && index < count) ? elements[index].pointer : 0;
|
||||
}
|
||||
|
||||
int32_t UVector::elementAti(int32_t index) const {
|
||||
return (0 <= index && index < count) ? elements[index].integer : 0;
|
||||
}
|
||||
|
||||
void UVector::removeElementAt(int32_t index) {
|
||||
@ -98,8 +118,8 @@ UBool UVector::removeElement(void* obj) {
|
||||
void UVector::removeAllElements(void) {
|
||||
if (deleter != 0) {
|
||||
for (int32_t i=0; i<count; ++i) {
|
||||
if (elements[i] != 0) {
|
||||
(*deleter)(elements[i]);
|
||||
if (elements[i].pointer != 0) {
|
||||
(*deleter)(elements[i].pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,8 +128,10 @@ void UVector::removeAllElements(void) {
|
||||
|
||||
int32_t UVector::indexOf(void* obj, int32_t startIndex) const {
|
||||
if (comparer != 0) {
|
||||
UHashKey key;
|
||||
key.pointer = obj;
|
||||
for (int32_t i=startIndex; i<count; ++i) {
|
||||
if ((*comparer)(obj, elements[i])) {
|
||||
if ((*comparer)(key, elements[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@ -122,12 +144,12 @@ UBool UVector::ensureCapacity(int32_t minimumCapacity) {
|
||||
return TRUE;
|
||||
} else {
|
||||
int32_t newCap = capacity * 2;
|
||||
void** newElems = new void*[newCap];
|
||||
UHashKey* newElems = new UHashKey[newCap];
|
||||
if (newElems == 0) {
|
||||
outOfMemory = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
uprv_memcpy(newElems, elements, sizeof(void*) * count);
|
||||
uprv_memcpy(newElems, elements, sizeof(elements[0]) * count);
|
||||
delete[] elements;
|
||||
elements = newElems;
|
||||
capacity = newCap;
|
||||
@ -135,14 +157,14 @@ UBool UVector::ensureCapacity(int32_t minimumCapacity) {
|
||||
}
|
||||
}
|
||||
|
||||
UVector::Deleter UVector::setDeleter(Deleter d) {
|
||||
Deleter old = deleter;
|
||||
UObjectDeleter UVector::setDeleter(UObjectDeleter d) {
|
||||
UObjectDeleter old = deleter;
|
||||
deleter = d;
|
||||
return old;
|
||||
}
|
||||
|
||||
UVector::Comparer UVector::setComparer(Comparer d) {
|
||||
Comparer old = comparer;
|
||||
UKeyComparator UVector::setComparer(UKeyComparator d) {
|
||||
UKeyComparator old = comparer;
|
||||
comparer = d;
|
||||
return old;
|
||||
}
|
||||
@ -163,7 +185,7 @@ UBool UVector::isOutOfMemory(void) {
|
||||
void* UVector::orphanElementAt(int32_t index) {
|
||||
void* e = 0;
|
||||
if (0 <= index && index < count) {
|
||||
e = elements[index];
|
||||
e = elements[index].pointer;
|
||||
for (int32_t i=index; i<count-1; ++i) {
|
||||
elements[i] = elements[i+1];
|
||||
}
|
||||
@ -177,16 +199,28 @@ UStack::UStack(int32_t initialCapacity) :
|
||||
UVector(initialCapacity) {
|
||||
}
|
||||
|
||||
UStack::UStack(Deleter d, Comparer c, int32_t initialCapacity) :
|
||||
UStack::UStack(UObjectDeleter d, UKeyComparator c, int32_t initialCapacity) :
|
||||
UVector(d, c, initialCapacity) {
|
||||
}
|
||||
|
||||
void* UStack::pop(void) {
|
||||
void* obj = lastElement();
|
||||
if (obj != 0) {
|
||||
removeElementAt(size() - 1);
|
||||
int32_t n = size() - 1;
|
||||
void* result = 0;
|
||||
if (n >= 0) {
|
||||
result = elementAt(n);
|
||||
removeElementAt(n);
|
||||
}
|
||||
return obj;
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t UStack::popi(void) {
|
||||
int32_t n = size() - 1;
|
||||
int32_t result = 0;
|
||||
if (n >= 0) {
|
||||
result = elementAti(n);
|
||||
removeElementAt(n);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t UStack::search(void* obj) const {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define UVECTOR_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "uhash.h"
|
||||
|
||||
/**
|
||||
* <p>Ultralightweight C++ implementation of a <tt>void*</tt> vector
|
||||
@ -65,27 +66,30 @@
|
||||
* @author Alan Liu
|
||||
*/
|
||||
class U_COMMON_API UVector {
|
||||
public:
|
||||
typedef void (* U_CALLCONV Deleter)(void*);
|
||||
typedef UBool (* U_CALLCONV Comparer)(const void*, const void*);
|
||||
// NOTE: UVector uses the UHashKey (union of void* and int32_t) as
|
||||
// its basic storage type. It uses UKeyComparator as its
|
||||
// comparison function. It uses UObjectDeleter as its deleter
|
||||
// function. These are named for hashtables, but used here as-is
|
||||
// rather than duplicating the type. This allows sharing of
|
||||
// support functions.
|
||||
|
||||
private:
|
||||
int32_t count;
|
||||
|
||||
int32_t capacity;
|
||||
|
||||
void** elements;
|
||||
UHashKey* elements;
|
||||
|
||||
Deleter deleter;
|
||||
UObjectDeleter deleter;
|
||||
|
||||
Comparer comparer;
|
||||
UKeyComparator comparer;
|
||||
|
||||
static UBool outOfMemory;
|
||||
|
||||
public:
|
||||
UVector(int32_t initialCapacity = 8);
|
||||
|
||||
UVector(Deleter d, Comparer c, int32_t initialCapacity = 8);
|
||||
UVector(UObjectDeleter d, UKeyComparator c, int32_t initialCapacity = 8);
|
||||
|
||||
~UVector();
|
||||
|
||||
@ -95,12 +99,18 @@ public:
|
||||
|
||||
void addElement(void* obj);
|
||||
|
||||
void addElement(int32_t elem);
|
||||
|
||||
void setElementAt(void* obj, int32_t index);
|
||||
|
||||
void setElementAt(int32_t elem, int32_t index);
|
||||
|
||||
void insertElementAt(void* obj, int32_t index);
|
||||
|
||||
void* elementAt(int32_t index) const;
|
||||
|
||||
int32_t elementAti(int32_t index) const;
|
||||
|
||||
void* firstElement(void) const;
|
||||
|
||||
void* lastElement(void) const;
|
||||
@ -125,9 +135,9 @@ public:
|
||||
// New API
|
||||
//------------------------------------------------------------
|
||||
|
||||
Deleter setDeleter(Deleter d);
|
||||
UObjectDeleter setDeleter(UObjectDeleter d);
|
||||
|
||||
Comparer setComparer(Comparer c);
|
||||
UKeyComparator setComparer(UKeyComparator c);
|
||||
|
||||
static UBool isOutOfMemory(void);
|
||||
|
||||
@ -175,7 +185,7 @@ class U_COMMON_API UStack : public UVector {
|
||||
public:
|
||||
UStack(int32_t initialCapacity = 8);
|
||||
|
||||
UStack(Deleter d, Comparer c, int32_t initialCapacity = 8);
|
||||
UStack(UObjectDeleter d, UKeyComparator c, int32_t initialCapacity = 8);
|
||||
|
||||
// It's okay not to have a virtual destructor (in UVector)
|
||||
// because UStack has no special cleanup to do.
|
||||
@ -186,8 +196,12 @@ public:
|
||||
|
||||
void* pop(void);
|
||||
|
||||
int32_t popi(void);
|
||||
|
||||
void* push(void* obj);
|
||||
|
||||
int32_t push(int32_t i);
|
||||
|
||||
int32_t search(void* obj) const;
|
||||
|
||||
private:
|
||||
@ -240,4 +254,9 @@ inline void* UStack::push(void* obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
inline int32_t UStack::push(int32_t i) {
|
||||
addElement(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -160,24 +160,12 @@ private:
|
||||
int32_t size() const; // size of the UVectors
|
||||
};
|
||||
|
||||
// Store int32_t as a void* in a UVector. DO NOT ASSUME sizeof(void*)
|
||||
// is 32. Assume sizeof(void*) >= 32.
|
||||
inline void* _int32_to_voidPtr(int32_t x) {
|
||||
void* a = 0; // May be > 32 bits
|
||||
*(int32_t*)&a = x; // Careful here...
|
||||
return a;
|
||||
}
|
||||
inline int32_t _voidPtr_to_int32(void* x) {
|
||||
void* a = x; // Copy to stack (portability)
|
||||
return *(int32_t*)&a; // Careful here...
|
||||
}
|
||||
|
||||
int32_t Segments::offset(int32_t i) const {
|
||||
return _voidPtr_to_int32(offsets.elementAt(i));
|
||||
return offsets.elementAti(i);
|
||||
}
|
||||
|
||||
UBool Segments::isOpen(int32_t i) const {
|
||||
return _voidPtr_to_int32(isOpenParen.elementAt(i)) != 0;
|
||||
return isOpenParen.elementAti(i) != 0;
|
||||
}
|
||||
|
||||
int32_t Segments::size() const {
|
||||
@ -189,8 +177,8 @@ Segments::Segments() {}
|
||||
Segments::~Segments() {}
|
||||
|
||||
void Segments::addParenthesisAt(int32_t offset, UBool isOpen) {
|
||||
offsets.addElement(_int32_to_voidPtr(offset));
|
||||
isOpenParen.addElement(_int32_to_voidPtr(isOpen ? 1 : 0));
|
||||
offsets.addElement(offset);
|
||||
isOpenParen.addElement(isOpen ? 1 : 0);
|
||||
}
|
||||
|
||||
int32_t Segments::getLastParenOffset(UBool& isOpenParen) const {
|
||||
@ -226,7 +214,7 @@ UBool Segments::extractLastParenSubstring(int32_t& start, int32_t& limit) {
|
||||
// Reset all segment pairs from i to size() - 1 to [start, start+1).
|
||||
while (i<size()) {
|
||||
int32_t o = isOpen(i) ? start : (start+1);
|
||||
offsets.setElementAt(_int32_to_voidPtr(o), i);
|
||||
offsets.setElementAt(o, i);
|
||||
++i;
|
||||
}
|
||||
return TRUE;
|
||||
@ -301,10 +289,10 @@ int32_t* Segments::createArray() const {
|
||||
// Close parens are at 2*seg+1 in array 2.
|
||||
if (open) {
|
||||
array[a2offset + 2*nextOpen] = 2+i;
|
||||
stack.push(_int32_to_voidPtr(nextOpen));
|
||||
stack.push(nextOpen);
|
||||
++nextOpen;
|
||||
} else {
|
||||
int32_t nextClose = _voidPtr_to_int32(stack.pop());
|
||||
int32_t nextClose = stack.popi();
|
||||
array[a2offset + 2*nextClose+1] = 2+i;
|
||||
}
|
||||
}
|
||||
|
@ -1475,22 +1475,6 @@ UChar Transliterator::filteredCharAt(const Replaceable& text, int32_t i) const {
|
||||
(localFilter->contains(c = text.charAt(i)) ? c : (UChar)0xFFFE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison function for UVector.
|
||||
*
|
||||
* Do not make this a class static: This should remain a C function
|
||||
* for os/390 and Solaris Workshop [grhoten]
|
||||
*/
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV
|
||||
_compareCaselessUnicodeString(const void* a, const void* b) {
|
||||
UHashKey s, t;
|
||||
s.pointer = (void*) a;
|
||||
t.pointer = (void*) b;
|
||||
return uhash_compareCaselessUnicodeString(s, t);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
void Transliterator::initializeCache(void) {
|
||||
// Lock first, check init boolean second
|
||||
Mutex lock(&cacheMutex);
|
||||
@ -1504,7 +1488,7 @@ void Transliterator::initializeCache(void) {
|
||||
// That way if the resource is absent, we will at least
|
||||
// have a valid cache object.
|
||||
cacheIDs.setDeleter(uhash_deleteUnicodeString);
|
||||
cacheIDs.setComparer(_compareCaselessUnicodeString);
|
||||
cacheIDs.setComparer(uhash_compareCaselessUnicodeString);
|
||||
|
||||
/* The following code parses the index table located in
|
||||
* icu/data/translit_index.txt. The index is an n x 4 table
|
||||
|
Loading…
Reference in New Issue
Block a user