ICU-1749 API additions to support UnicodeSet

X-SVN-Rev: 8526
This commit is contained in:
Alan Liu 2002-04-26 06:30:37 +00:00
parent 2edd9a085e
commit 37b4739783
2 changed files with 208 additions and 13 deletions

View file

@ -74,6 +74,37 @@ UVector::~UVector() {
elements = 0;
}
/**
* Assign this object to another (make this a copy of 'other').
* Use the 'assign' function to assign each element.
*/
void UVector::assign(const UVector& other, UTokenAssigner assign, UErrorCode &ec) {
if (ensureCapacity(other.count, ec)) {
setSize(other.count);
for (int32_t i=0; i<other.count; ++i) {
if (elements[i].pointer != 0 && deleter != 0) {
(*deleter)(elements[i].pointer);
}
(*assign)(elements[i], other.elements[i]);
}
}
}
// This only does something sensible if this object has a non-null comparer
UBool UVector::operator==(const UVector& other) {
int32_t i;
if (count != other.count) return FALSE;
if (comparer != NULL) {
// Compare using this object's comparer
for (i=0; i<count; ++i) {
if (!(*comparer)(elements[i], other.elements[i])) {
return FALSE;
}
}
}
return TRUE;
}
void UVector::addElement(void* obj, UErrorCode &status) {
if (ensureCapacity(count + 1, status)) {
elements[count++].pointer = obj;
@ -126,6 +157,48 @@ int32_t UVector::elementAti(int32_t index) const {
return (0 <= index && index < count) ? elements[index].integer : 0;
}
UBool UVector::containsAll(const UVector& other) const {
for (int32_t i=0; i<other.size(); ++i) {
if (indexOf(other.elements[i]) < 0) {
return FALSE;
}
}
return TRUE;
}
UBool UVector::containsNone(const UVector& other) const {
for (int32_t i=0; i<other.size(); ++i) {
if (indexOf(other.elements[i]) >= 0) {
return FALSE;
}
}
return TRUE;
}
UBool UVector::removeAll(const UVector& other) {
UBool changed = FALSE;
for (int32_t i=0; i<other.size(); ++i) {
int32_t j = indexOf(other.elements[i]);
if (j >= 0) {
removeElementAt(j);
changed = TRUE;
}
}
return changed;
}
UBool UVector::retainAll(const UVector& other) {
UBool changed = FALSE;
for (int32_t j=size()-1; j>=0; --j) {
int32_t i = other.indexOf(elements[j]);
if (i < 0) {
removeElementAt(j);
changed = TRUE;
}
}
return changed;
}
void UVector::removeElementAt(int32_t index) {
void* e = orphanElementAt(index);
if (e != 0 && deleter != 0) {
@ -154,23 +227,22 @@ void UVector::removeAllElements(void) {
}
int32_t UVector::indexOf(void* obj, int32_t startIndex) const {
if (comparer != 0) {
UHashTok key;
key.pointer = obj;
for (int32_t i=startIndex; i<count; ++i) {
if ((*comparer)(key, elements[i])) {
return i;
}
}
}
return -1;
UHashTok key;
key.pointer = obj;
return indexOf(key, startIndex);
}
int32_t UVector::indexOf(int32_t obj, int32_t startIndex) const {
UHashTok key;
key.integer = obj;
return indexOf(key, startIndex);
}
// This only works if this object has a non-null comparer
int32_t UVector::indexOf(UHashTok key, int32_t startIndex) const {
int32_t i;
if (comparer != 0) {
UHashTok key;
key.integer = obj;
for (int32_t i=startIndex; i<count; ++i) {
for (i=startIndex; i<count; ++i) {
if ((*comparer)(key, elements[i])) {
return i;
}
@ -276,6 +348,55 @@ void* UVector::orphanElementAt(int32_t index) {
return e;
}
/**
* Insert the given object into this vector at its sorted position
* as defined by 'compare'. The current elements are assumed to
* be sorted already.
*/
void UVector::sortedInsert(void* obj, USortComparator compare, UErrorCode& ec) {
UHashTok tok;
tok.pointer = obj;
sortedInsert(tok, compare, ec);
}
/**
* Insert the given integer into this vector at its sorted position
* as defined by 'compare'. The current elements are assumed to
* be sorted already.
*/
void UVector::sortedInsert(int32_t obj, USortComparator compare, UErrorCode& ec) {
UHashTok tok;
tok.integer = obj;
sortedInsert(tok, compare, ec);
}
// ASSUME elements[] IS CURRENTLY SORTED
void UVector::sortedInsert(UHashTok tok, USortComparator compare, UErrorCode& ec) {
// Perform a binary search for the location to insert tok at. Tok
// will be inserted between two elements a and b such that a <=
// tok && tok < b, where there is a 'virtual' elements[-1] always
// less than tok and a 'virtual' elements[count] always greater
// than tok.
int32_t min = 0, max = count;
while (min != max) {
int32_t probe = (min + max) / 2;
int8_t c = (*compare)(elements[probe], tok);
if (c > 0) {
max = probe;
} else {
// assert(c <= 0);
min = probe + 1;
}
}
if (ensureCapacity(count + 1, ec)) {
for (int32_t i=count; i>min; --i) {
elements[i] = elements[i-1];
}
elements[min] = tok;
++count;
}
}
UStack::UStack(UErrorCode &status) :
UVector(status)
{

View file

@ -17,6 +17,25 @@
U_NAMESPACE_BEGIN
/**
* A token comparison function.
* @param tok1 A token (object or integer)
* @param tok2 A token (object or integer)
* @return 0 if the two tokens are equal, -1 if tok1 is < tok2, or
* +1 if tok1 is > tok2.
*/
typedef int8_t (U_EXPORT2 * U_CALLCONV USortComparator)(UHashTok tok1,
UHashTok tok2);
/**
* A token assignment function. It may copy an integer, copy
* a pointer, or clone a pointer, as appropriate.
* @param dst The token to be assigned to
* @param src The token to assign from
*/
typedef void (U_EXPORT2 * U_CALLCONV UTokenAssigner)(UHashTok dst,
UHashTok src);
/**
* <p>Ultralightweight C++ implementation of a <tt>void*</tt> vector
* that is (mostly) compatible with java.util.Vector.
@ -94,8 +113,27 @@ public:
UVector(UObjectDeleter d, UKeyComparator c, UErrorCode &status);
UVector(UObjectDeleter d, UKeyComparator c, int32_t initialCapacity, UErrorCode &status);
~UVector();
/**
* Assign this object to another (make this a copy of 'other').
* Use the 'assign' function to assign each element.
*/
void assign(const UVector& other, UTokenAssigner assign, UErrorCode &ec);
/**
* Compare this vector with another. They will be considered
* equal if they are of the same size and all elements are equal,
* as compared using this object's comparer.
*/
UBool operator==(const UVector& other);
/**
* Equivalent to !operator==()
*/
inline UBool operator!=(const UVector& other);
//------------------------------------------------------------
// java.util.Vector API
//------------------------------------------------------------
@ -128,6 +166,12 @@ public:
UBool contains(int32_t obj) const;
UBool containsAll(const UVector& other) const;
UBool removeAll(const UVector& other);
UBool retainAll(const UVector& other);
void removeElementAt(int32_t index);
UBool removeElement(void* obj);
@ -174,9 +218,35 @@ public:
*/
void* orphanElementAt(int32_t index);
/**
* Returns true if this vector contains none of the elements
* of the given vector.
* @param other vector to be checked for containment
* @return true if the test condition is met
*/
UBool containsNone(const UVector& other) const;
/**
* Insert the given object into this vector at its sorted position
* as defined by 'compare'. The current elements are assumed to
* be sorted already.
*/
void sortedInsert(void* obj, USortComparator compare, UErrorCode& ec);
/**
* Insert the given integer into this vector at its sorted position
* as defined by 'compare'. The current elements are assumed to
* be sorted already.
*/
void sortedInsert(int32_t obj, USortComparator compare, UErrorCode& ec);
private:
void _init(int32_t initialCapacity, UErrorCode &status);
int32_t indexOf(UHashTok key, int32_t startIndex = 0) const;
void sortedInsert(UHashTok tok, USortComparator compare, UErrorCode& ec);
// Disallow
UVector(const UVector&);
@ -273,6 +343,10 @@ inline void* UVector::operator[](int32_t index) const {
return elementAt(index);
}
inline UBool UVector::operator!=(const UVector& other) {
return !operator==(other);
}
// UStack inlines
inline UBool UStack::empty(void) const {