1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/unicode/plurrule.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,481 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* Copyright (C) 2008-2013, International Business Machines Corporation and 1.7 +* others. All Rights Reserved. 1.8 +******************************************************************************* 1.9 +* 1.10 +* 1.11 +* File PLURRULE.H 1.12 +* 1.13 +* Modification History:* 1.14 +* Date Name Description 1.15 +* 1.16 +******************************************************************************** 1.17 +*/ 1.18 + 1.19 +#ifndef PLURRULE 1.20 +#define PLURRULE 1.21 + 1.22 +#include "unicode/utypes.h" 1.23 + 1.24 +/** 1.25 + * \file 1.26 + * \brief C++ API: PluralRules object 1.27 + */ 1.28 + 1.29 +#if !UCONFIG_NO_FORMATTING 1.30 + 1.31 +#include "unicode/format.h" 1.32 +#include "unicode/upluralrules.h" 1.33 + 1.34 +/** 1.35 + * Value returned by PluralRules::getUniqueKeywordValue() when there is no 1.36 + * unique value to return. 1.37 + * @stable ICU 4.8 1.38 + */ 1.39 +#define UPLRULES_NO_UNIQUE_VALUE ((double)-0.00123456777) 1.40 + 1.41 +U_NAMESPACE_BEGIN 1.42 + 1.43 +class Hashtable; 1.44 +class FixedDecimal; 1.45 +class RuleChain; 1.46 +class PluralRuleParser; 1.47 +class PluralKeywordEnumeration; 1.48 +class AndConstraint; 1.49 + 1.50 +/** 1.51 + * Defines rules for mapping non-negative numeric values onto a small set of 1.52 + * keywords. Rules are constructed from a text description, consisting 1.53 + * of a series of keywords and conditions. The {@link #select} method 1.54 + * examines each condition in order and returns the keyword for the 1.55 + * first condition that matches the number. If none match, 1.56 + * default rule(other) is returned. 1.57 + * 1.58 + * For more information, details, and tips for writing rules, see the 1.59 + * LDML spec, C.11 Language Plural Rules: 1.60 + * http://www.unicode.org/draft/reports/tr35/tr35.html#Language_Plural_Rules 1.61 + * 1.62 + * Examples:<pre> 1.63 + * "one: n is 1; few: n in 2..4"</pre> 1.64 + * This defines two rules, for 'one' and 'few'. The condition for 1.65 + * 'one' is "n is 1" which means that the number must be equal to 1.66 + * 1 for this condition to pass. The condition for 'few' is 1.67 + * "n in 2..4" which means that the number must be between 2 and 1.68 + * 4 inclusive for this condition to pass. All other numbers 1.69 + * are assigned the keyword "other" by the default rule. 1.70 + * </p><pre> 1.71 + * "zero: n is 0; one: n is 1; zero: n mod 100 in 1..19"</pre> 1.72 + * This illustrates that the same keyword can be defined multiple times. 1.73 + * Each rule is examined in order, and the first keyword whose condition 1.74 + * passes is the one returned. Also notes that a modulus is applied 1.75 + * to n in the last rule. Thus its condition holds for 119, 219, 319... 1.76 + * </p><pre> 1.77 + * "one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14"</pre> 1.78 + * This illustrates conjunction and negation. The condition for 'few' 1.79 + * has two parts, both of which must be met: "n mod 10 in 2..4" and 1.80 + * "n mod 100 not in 12..14". The first part applies a modulus to n 1.81 + * before the test as in the previous example. The second part applies 1.82 + * a different modulus and also uses negation, thus it matches all 1.83 + * numbers _not_ in 12, 13, 14, 112, 113, 114, 212, 213, 214... 1.84 + * </p> 1.85 + * <p> 1.86 + * Syntax:<pre> 1.87 + * \code 1.88 + * rules = rule (';' rule)* 1.89 + * rule = keyword ':' condition 1.90 + * keyword = <identifier> 1.91 + * condition = and_condition ('or' and_condition)* 1.92 + * and_condition = relation ('and' relation)* 1.93 + * relation = is_relation | in_relation | within_relation | 'n' <EOL> 1.94 + * is_relation = expr 'is' ('not')? value 1.95 + * in_relation = expr ('not')? 'in' range_list 1.96 + * within_relation = expr ('not')? 'within' range 1.97 + * expr = ('n' | 'i' | 'f' | 'v' | 'j') ('mod' value)? 1.98 + * range_list = (range | value) (',' range_list)* 1.99 + * value = digit+ ('.' digit+)? 1.100 + * digit = 0|1|2|3|4|5|6|7|8|9 1.101 + * range = value'..'value 1.102 + * \endcode 1.103 + * </pre></p> 1.104 + * <p> 1.105 + * <p> 1.106 + * The i, f, and v values are defined as follows: 1.107 + * </p> 1.108 + * <ul> 1.109 + * <li>i to be the integer digits.</li> 1.110 + * <li>f to be the visible fractional digits, as an integer.</li> 1.111 + * <li>v to be the number of visible fraction digits.</li> 1.112 + * <li>j is defined to only match integers. That is j is 3 fails if v != 0 (eg for 3.1 or 3.0).</li> 1.113 + * </ul> 1.114 + * <p> 1.115 + * Examples are in the following table: 1.116 + * </p> 1.117 + * <table border='1' style="border-collapse:collapse"> 1.118 + * <tbody> 1.119 + * <tr> 1.120 + * <th>n</th> 1.121 + * <th>i</th> 1.122 + * <th>f</th> 1.123 + * <th>v</th> 1.124 + * </tr> 1.125 + * <tr> 1.126 + * <td>1.0</td> 1.127 + * <td>1</td> 1.128 + * <td align="right">0</td> 1.129 + * <td>1</td> 1.130 + * </tr> 1.131 + * <tr> 1.132 + * <td>1.00</td> 1.133 + * <td>1</td> 1.134 + * <td align="right">0</td> 1.135 + * <td>2</td> 1.136 + * </tr> 1.137 + * <tr> 1.138 + * <td>1.3</td> 1.139 + * <td>1</td> 1.140 + * <td align="right">3</td> 1.141 + * <td>1</td> 1.142 + * </tr> 1.143 + * <tr> 1.144 + * <td>1.03</td> 1.145 + * <td>1</td> 1.146 + * <td align="right">3</td> 1.147 + * <td>2</td> 1.148 + * </tr> 1.149 + * <tr> 1.150 + * <td>1.23</td> 1.151 + * <td>1</td> 1.152 + * <td align="right">23</td> 1.153 + * <td>2</td> 1.154 + * </tr> 1.155 + * </tbody> 1.156 + * </table> 1.157 + * <p> 1.158 + * The difference between 'in' and 'within' is that 'in' only includes integers in the specified range, while 'within' 1.159 + * includes all values. Using 'within' with a range_list consisting entirely of values is the same as using 'in' (it's 1.160 + * not an error). 1.161 + * </p> 1.162 + 1.163 + * An "identifier" is a sequence of characters that do not have the 1.164 + * Unicode Pattern_Syntax or Pattern_White_Space properties. 1.165 + * <p> 1.166 + * The difference between 'in' and 'within' is that 'in' only includes 1.167 + * integers in the specified range, while 'within' includes all values. 1.168 + * Using 'within' with a range_list consisting entirely of values is the 1.169 + * same as using 'in' (it's not an error). 1.170 + *</p> 1.171 + * <p> 1.172 + * Keywords 1.173 + * could be defined by users or from ICU locale data. There are 6 1.174 + * predefined values in ICU - 'zero', 'one', 'two', 'few', 'many' and 1.175 + * 'other'. Callers need to check the value of keyword returned by 1.176 + * {@link #select} method. 1.177 + * </p> 1.178 + * 1.179 + * Examples:<pre> 1.180 + * UnicodeString keyword = pl->select(number); 1.181 + * if (keyword== UnicodeString("one") { 1.182 + * ... 1.183 + * } 1.184 + * else if ( ... ) 1.185 + * </pre> 1.186 + * <strong>Note:</strong><br> 1.187 + * <p> 1.188 + * ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>. 1.189 + * For these predefined rules, see CLDR page at 1.190 + * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html 1.191 + * </p> 1.192 + */ 1.193 +class U_I18N_API PluralRules : public UObject { 1.194 +public: 1.195 + 1.196 + /** 1.197 + * Constructor. 1.198 + * @param status Output param set to success/failure code on exit, which 1.199 + * must not indicate a failure before the function call. 1.200 + * 1.201 + * @stable ICU 4.0 1.202 + */ 1.203 + PluralRules(UErrorCode& status); 1.204 + 1.205 + /** 1.206 + * Copy constructor. 1.207 + * @stable ICU 4.0 1.208 + */ 1.209 + PluralRules(const PluralRules& other); 1.210 + 1.211 + /** 1.212 + * Destructor. 1.213 + * @stable ICU 4.0 1.214 + */ 1.215 + virtual ~PluralRules(); 1.216 + 1.217 + /** 1.218 + * Clone 1.219 + * @stable ICU 4.0 1.220 + */ 1.221 + PluralRules* clone() const; 1.222 + 1.223 + /** 1.224 + * Assignment operator. 1.225 + * @stable ICU 4.0 1.226 + */ 1.227 + PluralRules& operator=(const PluralRules&); 1.228 + 1.229 + /** 1.230 + * Creates a PluralRules from a description if it is parsable, otherwise 1.231 + * returns NULL. 1.232 + * 1.233 + * @param description rule description 1.234 + * @param status Output param set to success/failure code on exit, which 1.235 + * must not indicate a failure before the function call. 1.236 + * @return new PluralRules pointer. NULL if there is an error. 1.237 + * @stable ICU 4.0 1.238 + */ 1.239 + static PluralRules* U_EXPORT2 createRules(const UnicodeString& description, 1.240 + UErrorCode& status); 1.241 + 1.242 + /** 1.243 + * The default rules that accept any number. 1.244 + * 1.245 + * @param status Output param set to success/failure code on exit, which 1.246 + * must not indicate a failure before the function call. 1.247 + * @return new PluralRules pointer. NULL if there is an error. 1.248 + * @stable ICU 4.0 1.249 + */ 1.250 + static PluralRules* U_EXPORT2 createDefaultRules(UErrorCode& status); 1.251 + 1.252 + /** 1.253 + * Provides access to the predefined cardinal-number <code>PluralRules</code> for a given 1.254 + * locale. 1.255 + * Same as forLocale(locale, UPLURAL_TYPE_CARDINAL, status). 1.256 + * 1.257 + * @param locale The locale for which a <code>PluralRules</code> object is 1.258 + * returned. 1.259 + * @param status Output param set to success/failure code on exit, which 1.260 + * must not indicate a failure before the function call. 1.261 + * @return The predefined <code>PluralRules</code> object pointer for 1.262 + * this locale. If there's no predefined rules for this locale, 1.263 + * the rules for the closest parent in the locale hierarchy 1.264 + * that has one will be returned. The final fallback always 1.265 + * returns the default 'other' rules. 1.266 + * @stable ICU 4.0 1.267 + */ 1.268 + static PluralRules* U_EXPORT2 forLocale(const Locale& locale, UErrorCode& status); 1.269 + 1.270 + /** 1.271 + * Provides access to the predefined <code>PluralRules</code> for a given 1.272 + * locale and the plural type. 1.273 + * 1.274 + * @param locale The locale for which a <code>PluralRules</code> object is 1.275 + * returned. 1.276 + * @param type The plural type (e.g., cardinal or ordinal). 1.277 + * @param status Output param set to success/failure code on exit, which 1.278 + * must not indicate a failure before the function call. 1.279 + * @return The predefined <code>PluralRules</code> object pointer for 1.280 + * this locale. If there's no predefined rules for this locale, 1.281 + * the rules for the closest parent in the locale hierarchy 1.282 + * that has one will be returned. The final fallback always 1.283 + * returns the default 'other' rules. 1.284 + * @stable ICU 50 1.285 + */ 1.286 + static PluralRules* U_EXPORT2 forLocale(const Locale& locale, UPluralType type, UErrorCode& status); 1.287 + 1.288 +#ifndef U_HIDE_INTERNAL_API 1.289 + /** 1.290 + * Return a StringEnumeration over the locales for which there is plurals data. 1.291 + * @return a StringEnumeration over the locales available. 1.292 + * @internal 1.293 + */ 1.294 + static StringEnumeration* U_EXPORT2 getAvailableLocales(UErrorCode &status); 1.295 + 1.296 + /** 1.297 + * Returns whether or not there are overrides. 1.298 + * @param locale the locale to check. 1.299 + * @return 1.300 + * @internal 1.301 + */ 1.302 + static UBool hasOverride(const Locale &locale); 1.303 +#endif /* U_HIDE_INTERNAL_API */ 1.304 + 1.305 + /** 1.306 + * Given a number, returns the keyword of the first rule that applies to 1.307 + * the number. This function can be used with isKeyword* functions to 1.308 + * determine the keyword for default plural rules. 1.309 + * 1.310 + * @param number The number for which the rule has to be determined. 1.311 + * @return The keyword of the selected rule. 1.312 + * @stable ICU 4.0 1.313 + */ 1.314 + UnicodeString select(int32_t number) const; 1.315 + 1.316 + /** 1.317 + * Given a number, returns the keyword of the first rule that applies to 1.318 + * the number. This function can be used with isKeyword* functions to 1.319 + * determine the keyword for default plural rules. 1.320 + * 1.321 + * @param number The number for which the rule has to be determined. 1.322 + * @return The keyword of the selected rule. 1.323 + * @stable ICU 4.0 1.324 + */ 1.325 + UnicodeString select(double number) const; 1.326 + 1.327 +#ifndef U_HIDE_INTERNAL_API 1.328 + /** 1.329 + * @internal 1.330 + */ 1.331 + UnicodeString select(const FixedDecimal &number) const; 1.332 +#endif /* U_HIDE_INTERNAL_API */ 1.333 + 1.334 + /** 1.335 + * Returns a list of all rule keywords used in this <code>PluralRules</code> 1.336 + * object. The rule 'other' is always present by default. 1.337 + * 1.338 + * @param status Output param set to success/failure code on exit, which 1.339 + * must not indicate a failure before the function call. 1.340 + * @return StringEnumeration with the keywords. 1.341 + * The caller must delete the object. 1.342 + * @stable ICU 4.0 1.343 + */ 1.344 + StringEnumeration* getKeywords(UErrorCode& status) const; 1.345 + 1.346 + /** 1.347 + * Returns a unique value for this keyword if it exists, else the constant 1.348 + * UPLRULES_NO_UNIQUE_VALUE. 1.349 + * 1.350 + * @param keyword The keyword. 1.351 + * @return The unique value that generates the keyword, or 1.352 + * UPLRULES_NO_UNIQUE_VALUE if the keyword is undefined or there is no 1.353 + * unique value that generates this keyword. 1.354 + * @stable ICU 4.8 1.355 + */ 1.356 + double getUniqueKeywordValue(const UnicodeString& keyword); 1.357 + 1.358 + /** 1.359 + * Returns all the values for which select() would return the keyword. If 1.360 + * the keyword is unknown, returns no values, but this is not an error. If 1.361 + * the number of values is unlimited, returns no values and -1 as the 1.362 + * count. 1.363 + * 1.364 + * The number of returned values is typically small. 1.365 + * 1.366 + * @param keyword The keyword. 1.367 + * @param dest Array into which to put the returned values. May 1.368 + * be NULL if destCapacity is 0. 1.369 + * @param destCapacity The capacity of the array, must be at least 0. 1.370 + * @param status The error code. 1.371 + * @return The count of values available, or -1. This count 1.372 + * can be larger than destCapacity, but no more than 1.373 + * destCapacity values will be written. 1.374 + * @stable ICU 4.8 1.375 + */ 1.376 + int32_t getAllKeywordValues(const UnicodeString &keyword, 1.377 + double *dest, int32_t destCapacity, 1.378 + UErrorCode& status); 1.379 + 1.380 + /** 1.381 + * Returns sample values for which select() would return the keyword. If 1.382 + * the keyword is unknown, returns no values, but this is not an error. 1.383 + * 1.384 + * The number of returned values is typically small. 1.385 + * 1.386 + * @param keyword The keyword. 1.387 + * @param dest Array into which to put the returned values. May 1.388 + * be NULL if destCapacity is 0. 1.389 + * @param destCapacity The capacity of the array, must be at least 0. 1.390 + * @param status The error code. 1.391 + * @return The count of values written. 1.392 + * If more than destCapacity samples are available, then 1.393 + * only destCapacity are written, and destCapacity is returned as the count, 1.394 + * rather than setting a U_BUFFER_OVERFLOW_ERROR. 1.395 + * (The actual number of keyword values could be unlimited.) 1.396 + * @stable ICU 4.8 1.397 + */ 1.398 + int32_t getSamples(const UnicodeString &keyword, 1.399 + double *dest, int32_t destCapacity, 1.400 + UErrorCode& status); 1.401 + 1.402 + /** 1.403 + * Returns TRUE if the given keyword is defined in this 1.404 + * <code>PluralRules</code> object. 1.405 + * 1.406 + * @param keyword the input keyword. 1.407 + * @return TRUE if the input keyword is defined. 1.408 + * Otherwise, return FALSE. 1.409 + * @stable ICU 4.0 1.410 + */ 1.411 + UBool isKeyword(const UnicodeString& keyword) const; 1.412 + 1.413 + 1.414 + /** 1.415 + * Returns keyword for default plural form. 1.416 + * 1.417 + * @return keyword for default plural form. 1.418 + * @stable ICU 4.0 1.419 + */ 1.420 + UnicodeString getKeywordOther() const; 1.421 + 1.422 +#ifndef U_HIDE_INTERNAL_API 1.423 + /** 1.424 + * 1.425 + * @internal 1.426 + */ 1.427 + UnicodeString getRules() const; 1.428 +#endif /* U_HIDE_INTERNAL_API */ 1.429 + 1.430 + /** 1.431 + * Compares the equality of two PluralRules objects. 1.432 + * 1.433 + * @param other The other PluralRules object to be compared with. 1.434 + * @return True if the given PluralRules is the same as this 1.435 + * PluralRules; false otherwise. 1.436 + * @stable ICU 4.0 1.437 + */ 1.438 + virtual UBool operator==(const PluralRules& other) const; 1.439 + 1.440 + /** 1.441 + * Compares the inequality of two PluralRules objects. 1.442 + * 1.443 + * @param other The PluralRules object to be compared with. 1.444 + * @return True if the given PluralRules is not the same as this 1.445 + * PluralRules; false otherwise. 1.446 + * @stable ICU 4.0 1.447 + */ 1.448 + UBool operator!=(const PluralRules& other) const {return !operator==(other);} 1.449 + 1.450 + 1.451 + /** 1.452 + * ICU "poor man's RTTI", returns a UClassID for this class. 1.453 + * 1.454 + * @stable ICU 4.0 1.455 + * 1.456 + */ 1.457 + static UClassID U_EXPORT2 getStaticClassID(void); 1.458 + 1.459 + /** 1.460 + * ICU "poor man's RTTI", returns a UClassID for the actual class. 1.461 + * 1.462 + * @stable ICU 4.0 1.463 + */ 1.464 + virtual UClassID getDynamicClassID() const; 1.465 + 1.466 + 1.467 +private: 1.468 + RuleChain *mRules; 1.469 + 1.470 + PluralRules(); // default constructor not implemented 1.471 + void parseDescription(const UnicodeString& ruleData, UErrorCode &status); 1.472 + int32_t getNumberValue(const UnicodeString& token) const; 1.473 + UnicodeString getRuleFromResource(const Locale& locale, UPluralType type, UErrorCode& status); 1.474 + RuleChain *rulesForKeyword(const UnicodeString &keyword) const; 1.475 + 1.476 + friend class PluralRuleParser; 1.477 +}; 1.478 + 1.479 +U_NAMESPACE_END 1.480 + 1.481 +#endif /* #if !UCONFIG_NO_FORMATTING */ 1.482 + 1.483 +#endif // _PLURRULE 1.484 +//eof