1 /* 2 ******************************************************************************* 3 * Copyright (C) 2008-2010, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ******************************************************************************* 6 * 7 * 8 * File PLURRULE.H 9 * 10 * Modification History:* 11 * Date Name Description 12 * 13 ******************************************************************************** 14 */ 15 16 #ifndef PLURRULE 17 #define PLURRULE 18 19 #include "unicode/utypes.h" 20 21 /** 22 * \file 23 * \brief C++ API: PluralRules object 24 */ 25 26 #if !UCONFIG_NO_FORMATTING 27 28 #include "unicode/format.h" 29 30 U_NAMESPACE_BEGIN 31 32 class Hashtable; 33 class RuleChain; 34 class RuleParser; 35 36 /** 37 * Defines rules for mapping positive long values onto a small set of 38 * keywords. Rules are constructed from a text description, consisting 39 * of a series of keywords and conditions. The {@link #select} method 40 * examines each condition in order and returns the keyword for the 41 * first condition that matches the number. If none match, 42 * default rule(other) is returned. 43 * 44 * Examples:<pre> 45 * "one: n is 1; few: n in 2..4"</pre> 46 * This defines two rules, for 'one' and 'few'. The condition for 47 * 'one' is "n is 1" which means that the number must be equal to 48 * 1 for this condition to pass. The condition for 'few' is 49 * "n in 2..4" which means that the number must be between 2 and 50 * 4 inclusive for this condition to pass. All other numbers 51 * are assigned the keyword "other" by the default rule. 52 * </p><pre> 53 * "zero: n is 0; one: n is 1; zero: n mod 100 in 1..19"</pre> 54 * This illustrates that the same keyword can be defined multiple times. 55 * Each rule is examined in order, and the first keyword whose condition 56 * passes is the one returned. Also notes that a modulus is applied 57 * to n in the last rule. Thus its condition holds for 119, 219, 319... 58 * </p><pre> 59 * "one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14"</pre> 60 * This illustrates conjunction and negation. The condition for 'few' 61 * has two parts, both of which must be met: "n mod 10 in 2..4" and 62 * "n mod 100 not in 12..14". The first part applies a modulus to n 63 * before the test as in the previous example. The second part applies 64 * a different modulus and also uses negation, thus it matches all 65 * numbers _not_ in 12, 13, 14, 112, 113, 114, 212, 213, 214... 66 * </p> 67 * <p> 68 * Syntax:<pre> 69 * \code 70 * rules = rule (';' rule)* 71 * rule = keyword ':' condition 72 * keyword = <identifier> 73 * condition = and_condition ('or' and_condition)* 74 * and_condition = relation ('and' relation)* 75 * relation = is_relation | in_relation | within_relation | 'n' <EOL> 76 * is_relation = expr 'is' ('not')? value 77 * in_relation = expr ('not')? 'in' range 78 * within_relation = expr ('not')? 'within' range 79 * expr = 'n' ('mod' value)? 80 * value = digit+ 81 * digit = 0|1|2|3|4|5|6|7|8|9 82 * range = value'..'value 83 * \endcode 84 * </pre></p> 85 * <p> 86 * The difference between 'in' and 'within' is that 'in' only includes 87 * integers in the specified range, while 'within' includes all values.</p> 88 * <p> 89 * Keywords 90 * could be defined by users or from ICU locale data. There are 6 91 * predefined values in ICU - 'zero', 'one', 'two', 'few', 'many' and 92 * 'other'. Callers need to check the value of keyword returned by 93 * {@link #select} method. 94 * </p> 95 * 96 * Examples:<pre> 97 * UnicodeString keyword = pl->select(number); 98 * if (keyword== UnicodeString("one") { 99 * ... 100 * } 101 * else if ( ... ) 102 * </pre> 103 * <strong>Note:</strong><br> 104 * <p> 105 * ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>. 106 * For these predefined rules, see CLDR page at 107 * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html 108 * </p> 109 */ 110 class U_I18N_API PluralRules : public UObject { 111 public: 112 113 /** 114 * Constructor. 115 * @param status Output param set to success/failure code on exit, which 116 * must not indicate a failure before the function call. 117 * 118 * @stable ICU 4.0 119 */ 120 PluralRules(UErrorCode& status); 121 122 /** 123 * Copy constructor. 124 * @stable ICU 4.0 125 */ 126 PluralRules(const PluralRules& other); 127 128 /** 129 * Destructor. 130 * @stable ICU 4.0 131 */ 132 virtual ~PluralRules(); 133 134 /** 135 * Clone 136 * @stable ICU 4.0 137 */ 138 PluralRules* clone() const; 139 140 /** 141 * Assignment operator. 142 * @stable ICU 4.0 143 */ 144 PluralRules& operator=(const PluralRules&); 145 146 /** 147 * Creates a PluralRules from a description if it is parsable, otherwise 148 * returns null. 149 * 150 * @param description rule description 151 * @param status Output param set to success/failure code on exit, which 152 * must not indicate a failure before the function call. 153 * @return new PluralRules pointer. NULL if there is an error. 154 * @stable ICU 4.0 155 */ 156 static PluralRules* U_EXPORT2 createRules(const UnicodeString& description, 157 UErrorCode& status); 158 159 /** 160 * The default rules that accept any number. 161 * 162 * @param status Output param set to success/failure code on exit, which 163 * must not indicate a failure before the function call. 164 * @return new PluralRules pointer. NULL if there is an error. 165 * @stable ICU 4.0 166 */ 167 static PluralRules* U_EXPORT2 createDefaultRules(UErrorCode& status); 168 169 /** 170 * Provides access to the predefined <code>PluralRules</code> for a given 171 * locale. 172 * 173 * @param locale The locale for which a <code>PluralRules</code> object is 174 * returned. 175 * @param status Output param set to success/failure code on exit, which 176 * must not indicate a failure before the function call. 177 * @return The predefined <code>PluralRules</code> object pointer for 178 * this locale. If there's no predefined rules for this locale, 179 * the rules for the closest parent in the locale hierarchy 180 * that has one will be returned. The final fallback always 181 * returns the default 'other' rules. 182 * @stable ICU 4.0 183 */ 184 static PluralRules* U_EXPORT2 forLocale(const Locale& locale, UErrorCode& status); 185 186 /** 187 * Given a number, returns the keyword of the first rule that applies to 188 * the number. This function can be used with isKeyword* functions to 189 * determine the keyword for default plural rules. 190 * 191 * @param number The number for which the rule has to be determined. 192 * @return The keyword of the selected rule. 193 * @stable ICU 4.0 194 */ 195 UnicodeString select(int32_t number) const; 196 197 /** 198 * Given a number, returns the keyword of the first rule that applies to 199 * the number. This function can be used with isKeyword* functions to 200 * determine the keyword for default plural rules. 201 * 202 * @param number The number for which the rule has to be determined. 203 * @return The keyword of the selected rule. 204 * @stable ICU 4.0 205 */ 206 UnicodeString select(double number) const; 207 208 /** 209 * Returns a list of all rule keywords used in this <code>PluralRules</code> 210 * object. The rule 'other' is always present by default. 211 * 212 * @param status Output param set to success/failure code on exit, which 213 * must not indicate a failure before the function call. 214 * @return StringEnumeration with the keywords. 215 * The caller must delete the object. 216 * @stable ICU 4.0 217 */ 218 StringEnumeration* getKeywords(UErrorCode& status) const; 219 220 /** 221 * Returns TRUE if the given keyword is defined in this 222 * <code>PluralRules</code> object. 223 * 224 * @param keyword the input keyword. 225 * @return TRUE if the input keyword is defined. 226 * Otherwise, return FALSE. 227 * @stable ICU 4.0 228 */ 229 UBool isKeyword(const UnicodeString& keyword) const; 230 231 232 /** 233 * Returns keyword for default plural form. 234 * 235 * @return keyword for default plural form. 236 * @internal 4.0 237 * @stable ICU 4.0 238 */ 239 UnicodeString getKeywordOther() const; 240 241 /** 242 * Compares the equality of two PluralRules objects. 243 * 244 * @param other The other PluralRules object to be compared with. 245 * @return True if the given PluralRules is the same as this 246 * PluralRules; false otherwise. 247 * @stable ICU 4.0 248 */ 249 virtual UBool operator==(const PluralRules& other) const; 250 251 /** 252 * Compares the inequality of two PluralRules objects. 253 * 254 * @param other The PluralRules object to be compared with. 255 * @return True if the given PluralRules is not the same as this 256 * PluralRules; false otherwise. 257 * @stable ICU 4.0 258 */ 259 UBool operator!=(const PluralRules& other) const {return !operator==(other);} 260 261 262 /** 263 * ICU "poor man's RTTI", returns a UClassID for this class. 264 * 265 * @stable ICU 4.0 266 * 267 */ 268 static UClassID U_EXPORT2 getStaticClassID(void); 269 270 /** 271 * ICU "poor man's RTTI", returns a UClassID for the actual class. 272 * 273 * @stable ICU 4.0 274 */ 275 virtual UClassID getDynamicClassID() const; 276 277 278 private: 279 Hashtable *fLocaleStringsHash; 280 UnicodeString mLocaleName; 281 RuleChain *mRules; 282 RuleParser *mParser; 283 284 PluralRules(); // default constructor not implemented 285 int32_t getRepeatLimit() const; 286 void parseDescription(UnicodeString& ruleData, RuleChain& rules, UErrorCode &status); 287 void getNextLocale(const UnicodeString& localeData, int32_t* curIndex, UnicodeString& localeName); 288 void addRules(RuleChain& rules); 289 int32_t getNumberValue(const UnicodeString& token) const; 290 UnicodeString getRuleFromResource(const Locale& locale, UErrorCode& status); 291 292 }; 293 294 U_NAMESPACE_END 295 296 #endif /* #if !UCONFIG_NO_FORMATTING */ 297 298 #endif // _PLURRULE 299 //eof 300