1 // Copyright (C) 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * Copyright (C) 2015, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ******************************************************************************* 8 * pluralaffix.h 9 * 10 * created on: 2015jan06 11 * created by: Travis Keep 12 */ 13 14 #ifndef __PLURALAFFIX_H__ 15 #define __PLURALAFFIX_H__ 16 17 #include "unicode/utypes.h" 18 19 #if !UCONFIG_NO_FORMATTING 20 21 #include "unicode/unum.h" 22 #include "unicode/uobject.h" 23 24 #include "digitaffix.h" 25 #include "pluralmap.h" 26 27 U_NAMESPACE_BEGIN 28 29 class FieldPositionHandler; 30 31 // Export an explicit template instantiation. 32 // 33 // MSVC requires this, even though it should not be necessary. 34 // No direct access leaks out of the i18n library. 35 // 36 // Macintosh produces duplicate definition linker errors with the explicit template 37 // instantiation. 38 // 39 #if !U_PLATFORM_IS_DARWIN_BASED 40 template class U_I18N_API PluralMap<DigitAffix>; 41 #endif 42 43 44 /** 45 * A plural aware prefix or suffix of a formatted number. 46 * 47 * PluralAffix is essentially a map of DigitAffix objects keyed by plural 48 * category. The 'other' category is the default and always has some 49 * value. The rest of the categories are optional. Querying for a category that 50 * is not set always returns the DigitAffix stored in the 'other' category. 51 * 52 * To use one of these objects, build it up first using append() and 53 * setVariant() methods. Once built, leave unchanged and let multiple threads 54 * safely access. 55 * 56 * The following code is sample code for building up: 57 * one: US Dollar - 58 * other: US Dollars - 59 * 60 * and storing it in "negativeCurrencyPrefix" 61 * 62 * UErrorCode status = U_ZERO_ERROR; 63 * 64 * PluralAffix negativeCurrencyPrefix; 65 * 66 * PluralAffix currencyName; 67 * currencyName.setVariant("one", "US Dollar", status); 68 * currencyName.setVariant("other", "US Dollars", status); 69 * 70 * negativeCurrencyPrefix.append(currencyName, UNUM_CURRENCY_FIELD, status); 71 * negativeCurrencyPrefix.append(" "); 72 * negativeCurrencyPrefix.append("-", UNUM_SIGN_FIELD, status); 73 */ 74 class U_I18N_API PluralAffix : public UMemory { 75 public: 76 77 /** 78 * Create empty PluralAffix. 79 */ PluralAffix()80 PluralAffix() : affixes() { } 81 82 /** 83 * Create a PluralAffix where the 'other' variant is otherVariant. 84 */ PluralAffix(const DigitAffix & otherVariant)85 PluralAffix(const DigitAffix &otherVariant) : affixes(otherVariant) { } 86 87 /** 88 * Sets a particular variant for a plural category while overwriting 89 * anything that may have been previously stored for that plural 90 * category. The set value has no field annotations. 91 * @param category "one", "two", "few", ... 92 * @param variant the variant to store under the particular category 93 * @param status Any error returned here. 94 */ 95 UBool setVariant( 96 const char *category, 97 const UnicodeString &variant, 98 UErrorCode &status); 99 /** 100 * Make the 'other' variant be the empty string with no field annotations 101 * and remove the variants for the rest of the plural categories. 102 */ 103 void remove(); 104 105 /** 106 * Append value to all set plural categories. If fieldId present, value 107 * is that field type. 108 */ 109 void appendUChar(UChar value, int32_t fieldId=UNUM_FIELD_COUNT); 110 111 /** 112 * Append value to all set plural categories. If fieldId present, value 113 * is that field type. 114 */ 115 void append(const UnicodeString &value, int32_t fieldId=UNUM_FIELD_COUNT); 116 117 /** 118 * Append value to all set plural categories. If fieldId present, value 119 * is that field type. 120 */ 121 void append(const UChar *value, int32_t charCount, int32_t fieldId=UNUM_FIELD_COUNT); 122 123 /** 124 * Append the value for each plural category in rhs to the corresponding 125 * plural category in this instance. Each value appended from rhs is 126 * of type fieldId. 127 */ 128 UBool append( 129 const PluralAffix &rhs, 130 int32_t fieldId, 131 UErrorCode &status); 132 /** 133 * Get the DigitAffix for a paricular category such as "zero", "one", ... 134 * If the particular category is not set, returns the 'other' category 135 * which is always set. 136 */ 137 const DigitAffix &getByCategory(const char *category) const; 138 139 /** 140 * Get the DigitAffix for a paricular category such as "zero", "one", ... 141 * If the particular category is not set, returns the 'other' category 142 * which is always set. 143 */ 144 const DigitAffix &getByCategory(const UnicodeString &category) const; 145 146 /** 147 * Get the DigitAffix for the other category which is always set. 148 */ getOtherVariant()149 const DigitAffix &getOtherVariant() const { 150 return affixes.getOther(); 151 } 152 153 /** 154 * Returns TRUE if this instance has variants stored besides the "other" 155 * variant. 156 */ 157 UBool hasMultipleVariants() const; 158 159 /** 160 * Returns TRUE if this instance equals rhs. 161 */ equals(const PluralAffix & rhs)162 UBool equals(const PluralAffix &rhs) const { 163 return affixes.equals(rhs.affixes, &eq); 164 } 165 166 private: 167 PluralMap<DigitAffix> affixes; 168 eq(const DigitAffix & x,const DigitAffix & y)169 static UBool eq(const DigitAffix &x, const DigitAffix &y) { 170 return x.equals(y); 171 } 172 }; 173 174 175 U_NAMESPACE_END 176 #endif /* #if !UCONFIG_NO_FORMATTING */ 177 #endif // __PLURALAFFIX_H__ 178