From: Markus Scherer
Last updated: 2012-Jun-25
+
Last updated: 2012-Aug-03
Copyright © 1997-2012 International Business Machines Corporation and
others. All Rights Reserved.
u_setMutexFunctions()
and u_setAtomicIncDecFunctions()
with empty implementation functions.
+ We have made some changes to the C++ Collator API for ICU 50 + that will make it easier to use and implement the Collator but + which are incompatible for subclasses. + If there are subclasses, they will have to be modified as well. + It will be easy to adapt subclass source code, if there is any. + We think it is unlikely (or at least rare) that users write subclasses of the C++ Collator, + given the number of virtual methods and the complexities of a collation implementation.
+ +For details see the email "ICU4C C++ Collator subclassing-API breaking changes" + sent on 2012-jul-25 to the icu-design and icu-support + mailing lists, + and ICU ticket #9346, + including the changes for that ticket.
+ +In particular, the class TestCollator
in
+ source/test/intltest/apicoll.cpp
+ illustrates how a subclass needs to be changed.
+ However, note that the TestCollator was also simplified slightly;
+ not all changes made there were strictly required for the API signature changes.
typeid(*this) == typeid(other)
.
+ *
+ * Subclass implementations should do something like the following:
+ * + * if (this == &other) { return TRUE; } + * if (!Collator::operator==(other)) { return FALSE; } // not the same class + * + * const MyCollator &o = (const MyCollator&)other; + * (compare this vs. o's subclass fields) + ** @param other Collator object to be compared - * @return true if other is the same as this. + * @return TRUE if other is the same as this. * @stable ICU 2.0 */ virtual UBool operator==(const Collator& other) const; /** * Returns true if "other" is not the same as "this". + * Calls !Collator::operator==(other) which works for all subclasses. * @param other Collator object to be compared - * @return true if other is not the same as this. + * @return TRUE if other is not the same as this. * @stable ICU 2.0 */ virtual UBool operator!=(const Collator& other) const; @@ -404,6 +417,24 @@ public: * The comparison function compares the character data stored in two * different string arrays. Returns information about whether a string array * is less than, greater than or equal to another string array. + *
Example of use: + *
+ * . UChar ABC[] = {0x41, 0x42, 0x43, 0}; // = "ABC" + * . UChar abc[] = {0x61, 0x62, 0x63, 0}; // = "abc" + * . UErrorCode status = U_ZERO_ERROR; + * . Collator *myCollation = + * . Collator::createInstance(Locale::US, status); + * . if (U_FAILURE(status)) return; + * . myCollation->setStrength(Collator::PRIMARY); + * . // result would be Collator::EQUAL ("abc" == "ABC") + * . // (no primary difference between "abc" and "ABC") + * . Collator::EComparisonResult result = + * . myCollation->compare(abc, 3, ABC, 3); + * . myCollation->setStrength(Collator::TERTIARY); + * . // result would be Collator::LESS ("abc" <<< "ABC") + * . // (with tertiary difference between "abc" and "ABC") + * . result = myCollation->compare(abc, 3, ABC, 3); + ** @param source the source string array to be compared with. * @param sourceLength the length of the source string array. If this value * is equal to -1, the string array is null-terminated. @@ -528,7 +559,7 @@ public: * @deprecated ICU 2.8 This API is under consideration for revision * in ICU 3.0. */ - virtual const Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const = 0; + virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const = 0; /** * Convenience method for comparing two strings based on the collation rules. @@ -566,7 +597,7 @@ public: UBool equals(const UnicodeString& source, const UnicodeString& target) const; /** - * Determines the minimum strength that will be use in comparison or + * Determines the minimum strength that will be used in comparison or * transformation. *
E.g. with strength == SECONDARY, the tertiary difference is ignored *
E.g. with strength == PRIMARY, the secondary and tertiary difference @@ -575,7 +606,7 @@ public: * @see Collator#setStrength * @deprecated ICU 2.6 Use getAttribute(UCOL_STRENGTH...) instead */ - virtual ECollationStrength getStrength(void) const = 0; + virtual ECollationStrength getStrength(void) const; /** * Sets the minimum strength to be used in comparison or transformation. @@ -595,7 +626,7 @@ public: * @param newStrength the new comparison level. * @deprecated ICU 2.6 Use setAttribute(UCOL_STRENGTH...) instead */ - virtual void setStrength(ECollationStrength newStrength) = 0; + virtual void setStrength(ECollationStrength newStrength); /** * Retrieves the reordering codes for this collator. @@ -612,9 +643,9 @@ public: * @see UColReorderCode * @stable ICU 4.8 */ - virtual int32_t U_EXPORT2 getReorderCodes(int32_t *dest, - int32_t destCapacity, - UErrorCode& status) const; + virtual int32_t getReorderCodes(int32_t *dest, + int32_t destCapacity, + UErrorCode& status) const; /** * Sets the ordering of scripts for this collator. @@ -630,9 +661,9 @@ public: * @see UColReorderCode * @stable ICU 4.8 */ - virtual void U_EXPORT2 setReorderCodes(const int32_t* reorderCodes, - int32_t reorderCodesLength, - UErrorCode& status) ; + virtual void setReorderCodes(const int32_t* reorderCodes, + int32_t reorderCodesLength, + UErrorCode& status) ; /** * Retrieves the reorder codes that are grouped with the given reorder code. Some reorder @@ -849,7 +880,7 @@ public: * @stable ICU 2.2 */ virtual UColAttributeValue getAttribute(UColAttribute attr, - UErrorCode &status) = 0; + UErrorCode &status) const = 0; /** * Sets the variable top to a collation element value of a string supplied. @@ -872,7 +903,7 @@ public: * @return a 32 bit value containing the value of the variable top in upper 16 bits. Lower 16 bits are undefined * @stable ICU 2.0 */ - virtual uint32_t setVariableTop(const UnicodeString varTop, UErrorCode &status) = 0; + virtual uint32_t setVariableTop(const UnicodeString &varTop, UErrorCode &status) = 0; /** * Sets the variable top to a collation element value supplied. Variable top is set to the upper 16 bits. @@ -881,7 +912,7 @@ public: * @param status error code (not changed by function) * @stable ICU 2.0 */ - virtual void setVariableTop(const uint32_t varTop, UErrorCode &status) = 0; + virtual void setVariableTop(uint32_t varTop, UErrorCode &status) = 0; /** * Gets the variable top value of a Collator. @@ -908,7 +939,7 @@ public: * @return pointer to the new clone, user should remove it. * @stable ICU 2.2 */ - virtual Collator* safeClone(void) = 0; + virtual Collator* safeClone(void) const = 0; /** * Get the sort key as an array of bytes from an UnicodeString. diff --git a/icu4c/source/i18n/unicode/tblcoll.h b/icu4c/source/i18n/unicode/tblcoll.h index e4dcee9fe91..f08ee599ecf 100644 --- a/icu4c/source/i18n/unicode/tblcoll.h +++ b/icu4c/source/i18n/unicode/tblcoll.h @@ -223,14 +223,6 @@ public: */ virtual UBool operator==(const Collator& other) const; - /** - * Returns true if argument is not the same as this object. - * @param other Collator object to be compared - * @return returns true if argument is not the same as this object. - * @stable ICU 2.0 - */ - virtual UBool operator!=(const Collator& other) const; - /** * Makes a deep copy of the object. * The caller owns the returned object. @@ -264,21 +256,8 @@ public: virtual CollationElementIterator* createCollationElementIterator( const CharacterIterator& source) const; - /** - * Compares a range of character data stored in two different strings based - * on the collation rules. Returns information about whether a string is - * less than, greater than or equal to another string in a language. - * This can be overriden in a subclass. - * @param source the source string. - * @param target the target string to be compared with the source string. - * @return the comparison result. GREATER if the source string is greater - * than the target string, LESS if the source is less than the - * target. Otherwise, returns EQUAL. - * @deprecated ICU 2.6 Use overload with UErrorCode& - */ - virtual EComparisonResult compare(const UnicodeString& source, - const UnicodeString& target) const; - + // Make deprecated versions of Collator::compare() visible. + using Collator::compare; /** * The comparison function compares the character data stored in two @@ -296,23 +275,6 @@ public: const UnicodeString& target, UErrorCode &status) const; - /** - * Compares a range of character data stored in two different strings based - * on the collation rules up to the specified length. Returns information - * about whether a string is less than, greater than or equal to another - * string in a language. This can be overriden in a subclass. - * @param source the source string. - * @param target the target string to be compared with the source string. - * @param length compares up to the specified length - * @return the comparison result. GREATER if the source string is greater - * than the target string, LESS if the source is less than the - * target. Otherwise, returns EQUAL. - * @deprecated ICU 2.6 Use overload with UErrorCode& - */ - virtual EComparisonResult compare(const UnicodeString& source, - const UnicodeString& target, - int32_t length) const; - /** * Does the same thing as compare but limits the comparison to a specified * length @@ -331,43 +293,6 @@ public: int32_t length, UErrorCode &status) const; - /** - * The comparison function compares the character data stored in two - * different string arrays. Returns information about whether a string array - * is less than, greater than or equal to another string array. - *
Example of use: - *
- * . UChar ABC[] = {0x41, 0x42, 0x43, 0}; // = "ABC" - * . UChar abc[] = {0x61, 0x62, 0x63, 0}; // = "abc" - * . UErrorCode status = U_ZERO_ERROR; - * . Collator *myCollation = - * . Collator::createInstance(Locale::US, status); - * . if (U_FAILURE(status)) return; - * . myCollation->setStrength(Collator::PRIMARY); - * . // result would be Collator::EQUAL ("abc" == "ABC") - * . // (no primary difference between "abc" and "ABC") - * . Collator::EComparisonResult result = - * . myCollation->compare(abc, 3, ABC, 3); - * . myCollation->setStrength(Collator::TERTIARY); - * . // result would be Collator::LESS ("abc" <<< "ABC") - * . // (with tertiary difference between "abc" and "ABC") - * . result = myCollation->compare(abc, 3, ABC, 3); - *- * @param source the source string array to be compared with. - * @param sourceLength the length of the source string array. If this value - * is equal to -1, the string array is null-terminated. - * @param target the string that is to be compared with the source string. - * @param targetLength the length of the target string array. If this value - * is equal to -1, the string array is null-terminated. - * @return Returns a byte value. GREATER if source is greater than target; - * EQUAL if source is equal to target; LESS if source is less than - * target - * @deprecated ICU 2.6 Use overload with UErrorCode& - */ - virtual EComparisonResult compare(const UChar* source, int32_t sourceLength, - const UChar* target, int32_t targetLength) - const; - /** * The comparison function compares the character data stored in two * different string arrays. Returns information about whether a string array @@ -454,7 +379,7 @@ public: * was instantiated from rules, locale is empty. * @deprecated ICU 2.8 likely to change in ICU 3.0, based on feedback */ - virtual const Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; + virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; /** * Gets the table-based rules for the collation object. @@ -558,7 +483,7 @@ public: * @stable ICU 2.2 */ virtual UColAttributeValue getAttribute(UColAttribute attr, - UErrorCode &status); + UErrorCode &status) const; /** * Sets the variable top to a collation element value of a string supplied. @@ -581,7 +506,7 @@ public: * @return a 32 bit value containing the value of the variable top in upper 16 bits. Lower 16 bits are undefined * @stable ICU 2.0 */ - virtual uint32_t setVariableTop(const UnicodeString varTop, UErrorCode &status); + virtual uint32_t setVariableTop(const UnicodeString &varTop, UErrorCode &status); /** * Sets the variable top to a collation element value supplied. Variable top is set to the upper 16 bits. @@ -590,7 +515,7 @@ public: * @param status error code (not changed by function) * @stable ICU 2.0 */ - virtual void setVariableTop(const uint32_t varTop, UErrorCode &status); + virtual void setVariableTop(uint32_t varTop, UErrorCode &status); /** * Gets the variable top value of a Collator. @@ -616,7 +541,7 @@ public: * @return pointer to the new clone, user should remove it. * @stable ICU 2.2 */ - virtual Collator* safeClone(void); + virtual Collator* safeClone(void) const; /** * Get the sort key as an array of bytes from an UnicodeString. @@ -646,26 +571,6 @@ public: virtual int32_t getSortKey(const UChar *source, int32_t sourceLength, uint8_t *result, int32_t resultLength) const; - /** - * Determines the minimum strength that will be use in comparison or - * transformation. - *
E.g. with strength == SECONDARY, the tertiary difference is ignored - *
E.g. with strength == PRIMARY, the secondary and tertiary difference - * are ignored. - * @return the current comparison level. - * @see RuleBasedCollator#setStrength - * @deprecated ICU 2.6 Use getAttribute(UCOL_STRENGTH...) instead - */ - virtual ECollationStrength getStrength(void) const; - - /** - * Sets the minimum strength to be used in comparison or transformation. - * @see RuleBasedCollator#getStrength - * @param newStrength the new comparison level. - * @deprecated ICU 2.6 Use setAttribute(UCOL_STRENGTH...) instead - */ - virtual void setStrength(ECollationStrength newStrength); - /** * Retrieves the reordering codes for this collator. * @param dest The array to fill with the script ordering. @@ -679,9 +584,9 @@ public: * @see Collator#setReorderCodes * @stable ICU 4.8 */ - virtual int32_t U_EXPORT2 getReorderCodes(int32_t *dest, - int32_t destCapacity, - UErrorCode& status) const; + virtual int32_t getReorderCodes(int32_t *dest, + int32_t destCapacity, + UErrorCode& status) const; /** * Sets the ordering of scripts for this collator. @@ -693,9 +598,9 @@ public: * @see Collator#getEquivalentReorderCodes * @stable ICU 4.8 */ - virtual void U_EXPORT2 setReorderCodes(const int32_t* reorderCodes, - int32_t reorderCodesLength, - UErrorCode& status) ; + virtual void setReorderCodes(const int32_t* reorderCodes, + int32_t reorderCodesLength, + UErrorCode& status) ; /** * Retrieves the reorder codes that are grouped with the given reorder code. Some reorder @@ -878,38 +783,13 @@ protected: virtual void setLocales(const Locale& requestedLocale, const Locale& validLocale, const Locale& actualLocale); private: - // if not owned and not a write through alias, copy the ucollator void checkOwned(void); // utility to init rule string used by checkOwned and construct void setRuleStringFromCollator(); - /** - * Converts C's UCollationResult to EComparisonResult - * @param result member of the enum UComparisonResult - * @return EComparisonResult equivalent of UCollationResult - * @deprecated ICU 2.6. We will not need it. - */ - Collator::EComparisonResult getEComparisonResult( - const UCollationResult &result) const; - - /** - * Converts C's UCollationStrength to ECollationStrength - * @param strength member of the enum UCollationStrength - * @return ECollationStrength equivalent of UCollationStrength - */ - Collator::ECollationStrength getECollationStrength( - const UCollationStrength &strength) const; - - /** - * Converts C++'s ECollationStrength to UCollationStrength - * @param strength member of the enum ECollationStrength - * @return UCollationStrength equivalent of ECollationStrength - */ - UCollationStrength getUCollationStrength( - const Collator::ECollationStrength &strength) const; - public: +public: /** Get the short definition string for a collator. This internal API harvests the collator's * locale and the attribute set and produces a string that can be used for opening * a collator with the same properties using the ucol_openFromShortString API. @@ -967,56 +847,6 @@ inline const UCollator * RuleBasedCollator::getUCollator() } #endif -inline Collator::EComparisonResult RuleBasedCollator::getEComparisonResult( - const UCollationResult &result) const -{ - switch (result) - { - case UCOL_LESS : - return Collator::LESS; - case UCOL_EQUAL : - return Collator::EQUAL; - default : - return Collator::GREATER; - } -} - -inline Collator::ECollationStrength RuleBasedCollator::getECollationStrength( - const UCollationStrength &strength) const -{ - switch (strength) - { - case UCOL_PRIMARY : - return Collator::PRIMARY; - case UCOL_SECONDARY : - return Collator::SECONDARY; - case UCOL_TERTIARY : - return Collator::TERTIARY; - case UCOL_QUATERNARY : - return Collator::QUATERNARY; - default : - return Collator::IDENTICAL; - } -} - -inline UCollationStrength RuleBasedCollator::getUCollationStrength( - const Collator::ECollationStrength &strength) const -{ - switch (strength) - { - case Collator::PRIMARY : - return UCOL_PRIMARY; - case Collator::SECONDARY : - return UCOL_SECONDARY; - case Collator::TERTIARY : - return UCOL_TERTIARY; - case Collator::QUATERNARY : - return UCOL_QUATERNARY; - default : - return UCOL_IDENTICAL; - } -} - U_NAMESPACE_END #endif /* #if !UCONFIG_NO_COLLATION */ diff --git a/icu4c/source/test/intltest/apicoll.cpp b/icu4c/source/test/intltest/apicoll.cpp index 7c998e5db5a..3f31a4d971c 100644 --- a/icu4c/source/test/intltest/apicoll.cpp +++ b/icu4c/source/test/intltest/apicoll.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2011, International Business Machines Corporation and + * Copyright (c) 1997-2012, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ //=============================================================================== @@ -1902,32 +1902,7 @@ class TestCollator : public Collator public: virtual Collator* clone(void) const; - // dang, markus says we can't use 'using' in ICU. I hate doing this for - // deprecated methods... - - // using Collator::compare; - - virtual EComparisonResult compare(const UnicodeString& source, - const UnicodeString& target) const - { - return Collator::compare(source, target); - } - - virtual EComparisonResult compare(const UnicodeString& source, - const UnicodeString& target, - int32_t length) const - { - return Collator::compare(source, target, length); - } - - virtual EComparisonResult compare(const UChar* source, - int32_t sourceLength, - const UChar* target, - int32_t targetLength) const - { - return Collator::compare(source, sourceLength, target, targetLength); - } - + using Collator::compare; virtual UCollationResult compare(const UnicodeString& source, const UnicodeString& target, @@ -1949,8 +1924,7 @@ public: CollationKey& key, UErrorCode& status) const; virtual int32_t hashCode(void) const; - virtual const Locale getLocale(ULocDataLocaleType type, - UErrorCode& status) const; + virtual Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; virtual ECollationStrength getStrength(void) const; virtual void setStrength(ECollationStrength newStrength); virtual UClassID getDynamicClassID(void) const; @@ -1958,35 +1932,39 @@ public: virtual void setAttribute(UColAttribute attr, UColAttributeValue value, UErrorCode &status); virtual UColAttributeValue getAttribute(UColAttribute attr, - UErrorCode &status); + UErrorCode &status) const; virtual uint32_t setVariableTop(const UChar *varTop, int32_t len, UErrorCode &status); - virtual uint32_t setVariableTop(const UnicodeString varTop, + virtual uint32_t setVariableTop(const UnicodeString &varTop, UErrorCode &status); - virtual void setVariableTop(const uint32_t varTop, UErrorCode &status); + virtual void setVariableTop(uint32_t varTop, UErrorCode &status); virtual uint32_t getVariableTop(UErrorCode &status) const; - virtual Collator* safeClone(void); + virtual Collator* safeClone(void) const; virtual int32_t getSortKey(const UnicodeString& source, uint8_t* result, int32_t resultLength) const; virtual int32_t getSortKey(const UChar*source, int32_t sourceLength, uint8_t*result, int32_t resultLength) const; virtual UnicodeSet *getTailoredSet(UErrorCode &status) const; - virtual UBool operator!=(const Collator& other) const; + virtual UBool operator==(const Collator& other) const; + // Collator::operator!= calls !Collator::operator== which works for all subclasses. virtual void setLocales(const Locale& requestedLocale, const Locale& validLocale, const Locale& actualLocale); TestCollator() : Collator() {}; TestCollator(UCollationStrength collationStrength, UNormalizationMode decompositionMode) : Collator(collationStrength, decompositionMode) {}; }; -inline UBool TestCollator::operator!=(const Collator& other) const { - return Collator::operator!=(other); -} +inline UBool TestCollator::operator==(const Collator& other) const { + // TestCollator has no fields, so we test for identity. + return this == &other; -#define returnEComparisonResult(data) \ - if (data < 0) return Collator::LESS;\ - if (data > 0) return Collator::GREATER;\ - return Collator::EQUAL; + // Normally, subclasses should do something like the following: + // if (this == &other) { return TRUE; } + // if (!Collator::operator==(other)) { return FALSE; } // not the same class + // + // const TestCollator &o = (const TestCollator&)other; + // (compare this vs. o's subclass fields) +} Collator* TestCollator::clone() const { @@ -2072,8 +2050,7 @@ int32_t TestCollator::hashCode() const return 0; } -const Locale TestCollator::getLocale(ULocDataLocaleType type, - UErrorCode& status) const +Locale TestCollator::getLocale(ULocDataLocaleType type, UErrorCode& status) const { // api not used, this is to make the compiler happy if (U_FAILURE(status)) { @@ -2115,7 +2092,7 @@ void TestCollator::setAttribute(UColAttribute attr, UColAttributeValue value, } UColAttributeValue TestCollator::getAttribute(UColAttribute attr, - UErrorCode &status) + UErrorCode &status) const { // api not used, this is to make the compiler happy if (U_FAILURE(status) || attr == UCOL_ATTRIBUTE_COUNT) { @@ -2134,7 +2111,7 @@ uint32_t TestCollator::setVariableTop(const UChar *varTop, int32_t len, return 0; } -uint32_t TestCollator::setVariableTop(const UnicodeString varTop, +uint32_t TestCollator::setVariableTop(const UnicodeString &varTop, UErrorCode &status) { // api not used, this is to make the compiler happy @@ -2144,7 +2121,7 @@ uint32_t TestCollator::setVariableTop(const UnicodeString varTop, return 0; } -void TestCollator::setVariableTop(const uint32_t varTop, UErrorCode &status) +void TestCollator::setVariableTop(uint32_t varTop, UErrorCode &status) { // api not used, this is to make the compiler happy if (U_SUCCESS(status) && varTop == 0) { @@ -2162,7 +2139,7 @@ uint32_t TestCollator::getVariableTop(UErrorCode &status) const return (uint32_t)(0xFFFFFFFFu); } -Collator* TestCollator::safeClone(void) +Collator* TestCollator::safeClone(void) const { return new TestCollator(); } @@ -2182,7 +2159,7 @@ void CollationAPITest::TestSubclass() { TestCollator col1; TestCollator col2; - doAssert(col1 != col2, "2 instance of TestCollator should be different"); + doAssert(col1 != col2, "2 instances of TestCollator should be different"); if (col1.hashCode() != col2.hashCode()) { errln("Every TestCollator has the same hashcode"); }