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