intl/icu/source/i18n/unicode/plurrule.h

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 *******************************************************************************
michael@0 3 * Copyright (C) 2008-2013, International Business Machines Corporation and
michael@0 4 * others. All Rights Reserved.
michael@0 5 *******************************************************************************
michael@0 6 *
michael@0 7 *
michael@0 8 * File PLURRULE.H
michael@0 9 *
michael@0 10 * Modification History:*
michael@0 11 * Date Name Description
michael@0 12 *
michael@0 13 ********************************************************************************
michael@0 14 */
michael@0 15
michael@0 16 #ifndef PLURRULE
michael@0 17 #define PLURRULE
michael@0 18
michael@0 19 #include "unicode/utypes.h"
michael@0 20
michael@0 21 /**
michael@0 22 * \file
michael@0 23 * \brief C++ API: PluralRules object
michael@0 24 */
michael@0 25
michael@0 26 #if !UCONFIG_NO_FORMATTING
michael@0 27
michael@0 28 #include "unicode/format.h"
michael@0 29 #include "unicode/upluralrules.h"
michael@0 30
michael@0 31 /**
michael@0 32 * Value returned by PluralRules::getUniqueKeywordValue() when there is no
michael@0 33 * unique value to return.
michael@0 34 * @stable ICU 4.8
michael@0 35 */
michael@0 36 #define UPLRULES_NO_UNIQUE_VALUE ((double)-0.00123456777)
michael@0 37
michael@0 38 U_NAMESPACE_BEGIN
michael@0 39
michael@0 40 class Hashtable;
michael@0 41 class FixedDecimal;
michael@0 42 class RuleChain;
michael@0 43 class PluralRuleParser;
michael@0 44 class PluralKeywordEnumeration;
michael@0 45 class AndConstraint;
michael@0 46
michael@0 47 /**
michael@0 48 * Defines rules for mapping non-negative numeric values onto a small set of
michael@0 49 * keywords. Rules are constructed from a text description, consisting
michael@0 50 * of a series of keywords and conditions. The {@link #select} method
michael@0 51 * examines each condition in order and returns the keyword for the
michael@0 52 * first condition that matches the number. If none match,
michael@0 53 * default rule(other) is returned.
michael@0 54 *
michael@0 55 * For more information, details, and tips for writing rules, see the
michael@0 56 * LDML spec, C.11 Language Plural Rules:
michael@0 57 * http://www.unicode.org/draft/reports/tr35/tr35.html#Language_Plural_Rules
michael@0 58 *
michael@0 59 * Examples:<pre>
michael@0 60 * "one: n is 1; few: n in 2..4"</pre>
michael@0 61 * This defines two rules, for 'one' and 'few'. The condition for
michael@0 62 * 'one' is "n is 1" which means that the number must be equal to
michael@0 63 * 1 for this condition to pass. The condition for 'few' is
michael@0 64 * "n in 2..4" which means that the number must be between 2 and
michael@0 65 * 4 inclusive for this condition to pass. All other numbers
michael@0 66 * are assigned the keyword "other" by the default rule.
michael@0 67 * </p><pre>
michael@0 68 * "zero: n is 0; one: n is 1; zero: n mod 100 in 1..19"</pre>
michael@0 69 * This illustrates that the same keyword can be defined multiple times.
michael@0 70 * Each rule is examined in order, and the first keyword whose condition
michael@0 71 * passes is the one returned. Also notes that a modulus is applied
michael@0 72 * to n in the last rule. Thus its condition holds for 119, 219, 319...
michael@0 73 * </p><pre>
michael@0 74 * "one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14"</pre>
michael@0 75 * This illustrates conjunction and negation. The condition for 'few'
michael@0 76 * has two parts, both of which must be met: "n mod 10 in 2..4" and
michael@0 77 * "n mod 100 not in 12..14". The first part applies a modulus to n
michael@0 78 * before the test as in the previous example. The second part applies
michael@0 79 * a different modulus and also uses negation, thus it matches all
michael@0 80 * numbers _not_ in 12, 13, 14, 112, 113, 114, 212, 213, 214...
michael@0 81 * </p>
michael@0 82 * <p>
michael@0 83 * Syntax:<pre>
michael@0 84 * \code
michael@0 85 * rules = rule (';' rule)*
michael@0 86 * rule = keyword ':' condition
michael@0 87 * keyword = <identifier>
michael@0 88 * condition = and_condition ('or' and_condition)*
michael@0 89 * and_condition = relation ('and' relation)*
michael@0 90 * relation = is_relation | in_relation | within_relation | 'n' <EOL>
michael@0 91 * is_relation = expr 'is' ('not')? value
michael@0 92 * in_relation = expr ('not')? 'in' range_list
michael@0 93 * within_relation = expr ('not')? 'within' range
michael@0 94 * expr = ('n' | 'i' | 'f' | 'v' | 'j') ('mod' value)?
michael@0 95 * range_list = (range | value) (',' range_list)*
michael@0 96 * value = digit+ ('.' digit+)?
michael@0 97 * digit = 0|1|2|3|4|5|6|7|8|9
michael@0 98 * range = value'..'value
michael@0 99 * \endcode
michael@0 100 * </pre></p>
michael@0 101 * <p>
michael@0 102 * <p>
michael@0 103 * The i, f, and v values are defined as follows:
michael@0 104 * </p>
michael@0 105 * <ul>
michael@0 106 * <li>i to be the integer digits.</li>
michael@0 107 * <li>f to be the visible fractional digits, as an integer.</li>
michael@0 108 * <li>v to be the number of visible fraction digits.</li>
michael@0 109 * <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>
michael@0 110 * </ul>
michael@0 111 * <p>
michael@0 112 * Examples are in the following table:
michael@0 113 * </p>
michael@0 114 * <table border='1' style="border-collapse:collapse">
michael@0 115 * <tbody>
michael@0 116 * <tr>
michael@0 117 * <th>n</th>
michael@0 118 * <th>i</th>
michael@0 119 * <th>f</th>
michael@0 120 * <th>v</th>
michael@0 121 * </tr>
michael@0 122 * <tr>
michael@0 123 * <td>1.0</td>
michael@0 124 * <td>1</td>
michael@0 125 * <td align="right">0</td>
michael@0 126 * <td>1</td>
michael@0 127 * </tr>
michael@0 128 * <tr>
michael@0 129 * <td>1.00</td>
michael@0 130 * <td>1</td>
michael@0 131 * <td align="right">0</td>
michael@0 132 * <td>2</td>
michael@0 133 * </tr>
michael@0 134 * <tr>
michael@0 135 * <td>1.3</td>
michael@0 136 * <td>1</td>
michael@0 137 * <td align="right">3</td>
michael@0 138 * <td>1</td>
michael@0 139 * </tr>
michael@0 140 * <tr>
michael@0 141 * <td>1.03</td>
michael@0 142 * <td>1</td>
michael@0 143 * <td align="right">3</td>
michael@0 144 * <td>2</td>
michael@0 145 * </tr>
michael@0 146 * <tr>
michael@0 147 * <td>1.23</td>
michael@0 148 * <td>1</td>
michael@0 149 * <td align="right">23</td>
michael@0 150 * <td>2</td>
michael@0 151 * </tr>
michael@0 152 * </tbody>
michael@0 153 * </table>
michael@0 154 * <p>
michael@0 155 * The difference between 'in' and 'within' is that 'in' only includes integers in the specified range, while 'within'
michael@0 156 * includes all values. Using 'within' with a range_list consisting entirely of values is the same as using 'in' (it's
michael@0 157 * not an error).
michael@0 158 * </p>
michael@0 159
michael@0 160 * An "identifier" is a sequence of characters that do not have the
michael@0 161 * Unicode Pattern_Syntax or Pattern_White_Space properties.
michael@0 162 * <p>
michael@0 163 * The difference between 'in' and 'within' is that 'in' only includes
michael@0 164 * integers in the specified range, while 'within' includes all values.
michael@0 165 * Using 'within' with a range_list consisting entirely of values is the
michael@0 166 * same as using 'in' (it's not an error).
michael@0 167 *</p>
michael@0 168 * <p>
michael@0 169 * Keywords
michael@0 170 * could be defined by users or from ICU locale data. There are 6
michael@0 171 * predefined values in ICU - 'zero', 'one', 'two', 'few', 'many' and
michael@0 172 * 'other'. Callers need to check the value of keyword returned by
michael@0 173 * {@link #select} method.
michael@0 174 * </p>
michael@0 175 *
michael@0 176 * Examples:<pre>
michael@0 177 * UnicodeString keyword = pl->select(number);
michael@0 178 * if (keyword== UnicodeString("one") {
michael@0 179 * ...
michael@0 180 * }
michael@0 181 * else if ( ... )
michael@0 182 * </pre>
michael@0 183 * <strong>Note:</strong><br>
michael@0 184 * <p>
michael@0 185 * ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>.
michael@0 186 * For these predefined rules, see CLDR page at
michael@0 187 * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
michael@0 188 * </p>
michael@0 189 */
michael@0 190 class U_I18N_API PluralRules : public UObject {
michael@0 191 public:
michael@0 192
michael@0 193 /**
michael@0 194 * Constructor.
michael@0 195 * @param status Output param set to success/failure code on exit, which
michael@0 196 * must not indicate a failure before the function call.
michael@0 197 *
michael@0 198 * @stable ICU 4.0
michael@0 199 */
michael@0 200 PluralRules(UErrorCode& status);
michael@0 201
michael@0 202 /**
michael@0 203 * Copy constructor.
michael@0 204 * @stable ICU 4.0
michael@0 205 */
michael@0 206 PluralRules(const PluralRules& other);
michael@0 207
michael@0 208 /**
michael@0 209 * Destructor.
michael@0 210 * @stable ICU 4.0
michael@0 211 */
michael@0 212 virtual ~PluralRules();
michael@0 213
michael@0 214 /**
michael@0 215 * Clone
michael@0 216 * @stable ICU 4.0
michael@0 217 */
michael@0 218 PluralRules* clone() const;
michael@0 219
michael@0 220 /**
michael@0 221 * Assignment operator.
michael@0 222 * @stable ICU 4.0
michael@0 223 */
michael@0 224 PluralRules& operator=(const PluralRules&);
michael@0 225
michael@0 226 /**
michael@0 227 * Creates a PluralRules from a description if it is parsable, otherwise
michael@0 228 * returns NULL.
michael@0 229 *
michael@0 230 * @param description rule description
michael@0 231 * @param status Output param set to success/failure code on exit, which
michael@0 232 * must not indicate a failure before the function call.
michael@0 233 * @return new PluralRules pointer. NULL if there is an error.
michael@0 234 * @stable ICU 4.0
michael@0 235 */
michael@0 236 static PluralRules* U_EXPORT2 createRules(const UnicodeString& description,
michael@0 237 UErrorCode& status);
michael@0 238
michael@0 239 /**
michael@0 240 * The default rules that accept any number.
michael@0 241 *
michael@0 242 * @param status Output param set to success/failure code on exit, which
michael@0 243 * must not indicate a failure before the function call.
michael@0 244 * @return new PluralRules pointer. NULL if there is an error.
michael@0 245 * @stable ICU 4.0
michael@0 246 */
michael@0 247 static PluralRules* U_EXPORT2 createDefaultRules(UErrorCode& status);
michael@0 248
michael@0 249 /**
michael@0 250 * Provides access to the predefined cardinal-number <code>PluralRules</code> for a given
michael@0 251 * locale.
michael@0 252 * Same as forLocale(locale, UPLURAL_TYPE_CARDINAL, status).
michael@0 253 *
michael@0 254 * @param locale The locale for which a <code>PluralRules</code> object is
michael@0 255 * returned.
michael@0 256 * @param status Output param set to success/failure code on exit, which
michael@0 257 * must not indicate a failure before the function call.
michael@0 258 * @return The predefined <code>PluralRules</code> object pointer for
michael@0 259 * this locale. If there's no predefined rules for this locale,
michael@0 260 * the rules for the closest parent in the locale hierarchy
michael@0 261 * that has one will be returned. The final fallback always
michael@0 262 * returns the default 'other' rules.
michael@0 263 * @stable ICU 4.0
michael@0 264 */
michael@0 265 static PluralRules* U_EXPORT2 forLocale(const Locale& locale, UErrorCode& status);
michael@0 266
michael@0 267 /**
michael@0 268 * Provides access to the predefined <code>PluralRules</code> for a given
michael@0 269 * locale and the plural type.
michael@0 270 *
michael@0 271 * @param locale The locale for which a <code>PluralRules</code> object is
michael@0 272 * returned.
michael@0 273 * @param type The plural type (e.g., cardinal or ordinal).
michael@0 274 * @param status Output param set to success/failure code on exit, which
michael@0 275 * must not indicate a failure before the function call.
michael@0 276 * @return The predefined <code>PluralRules</code> object pointer for
michael@0 277 * this locale. If there's no predefined rules for this locale,
michael@0 278 * the rules for the closest parent in the locale hierarchy
michael@0 279 * that has one will be returned. The final fallback always
michael@0 280 * returns the default 'other' rules.
michael@0 281 * @stable ICU 50
michael@0 282 */
michael@0 283 static PluralRules* U_EXPORT2 forLocale(const Locale& locale, UPluralType type, UErrorCode& status);
michael@0 284
michael@0 285 #ifndef U_HIDE_INTERNAL_API
michael@0 286 /**
michael@0 287 * Return a StringEnumeration over the locales for which there is plurals data.
michael@0 288 * @return a StringEnumeration over the locales available.
michael@0 289 * @internal
michael@0 290 */
michael@0 291 static StringEnumeration* U_EXPORT2 getAvailableLocales(UErrorCode &status);
michael@0 292
michael@0 293 /**
michael@0 294 * Returns whether or not there are overrides.
michael@0 295 * @param locale the locale to check.
michael@0 296 * @return
michael@0 297 * @internal
michael@0 298 */
michael@0 299 static UBool hasOverride(const Locale &locale);
michael@0 300 #endif /* U_HIDE_INTERNAL_API */
michael@0 301
michael@0 302 /**
michael@0 303 * Given a number, returns the keyword of the first rule that applies to
michael@0 304 * the number. This function can be used with isKeyword* functions to
michael@0 305 * determine the keyword for default plural rules.
michael@0 306 *
michael@0 307 * @param number The number for which the rule has to be determined.
michael@0 308 * @return The keyword of the selected rule.
michael@0 309 * @stable ICU 4.0
michael@0 310 */
michael@0 311 UnicodeString select(int32_t number) const;
michael@0 312
michael@0 313 /**
michael@0 314 * Given a number, returns the keyword of the first rule that applies to
michael@0 315 * the number. This function can be used with isKeyword* functions to
michael@0 316 * determine the keyword for default plural rules.
michael@0 317 *
michael@0 318 * @param number The number for which the rule has to be determined.
michael@0 319 * @return The keyword of the selected rule.
michael@0 320 * @stable ICU 4.0
michael@0 321 */
michael@0 322 UnicodeString select(double number) const;
michael@0 323
michael@0 324 #ifndef U_HIDE_INTERNAL_API
michael@0 325 /**
michael@0 326 * @internal
michael@0 327 */
michael@0 328 UnicodeString select(const FixedDecimal &number) const;
michael@0 329 #endif /* U_HIDE_INTERNAL_API */
michael@0 330
michael@0 331 /**
michael@0 332 * Returns a list of all rule keywords used in this <code>PluralRules</code>
michael@0 333 * object. The rule 'other' is always present by default.
michael@0 334 *
michael@0 335 * @param status Output param set to success/failure code on exit, which
michael@0 336 * must not indicate a failure before the function call.
michael@0 337 * @return StringEnumeration with the keywords.
michael@0 338 * The caller must delete the object.
michael@0 339 * @stable ICU 4.0
michael@0 340 */
michael@0 341 StringEnumeration* getKeywords(UErrorCode& status) const;
michael@0 342
michael@0 343 /**
michael@0 344 * Returns a unique value for this keyword if it exists, else the constant
michael@0 345 * UPLRULES_NO_UNIQUE_VALUE.
michael@0 346 *
michael@0 347 * @param keyword The keyword.
michael@0 348 * @return The unique value that generates the keyword, or
michael@0 349 * UPLRULES_NO_UNIQUE_VALUE if the keyword is undefined or there is no
michael@0 350 * unique value that generates this keyword.
michael@0 351 * @stable ICU 4.8
michael@0 352 */
michael@0 353 double getUniqueKeywordValue(const UnicodeString& keyword);
michael@0 354
michael@0 355 /**
michael@0 356 * Returns all the values for which select() would return the keyword. If
michael@0 357 * the keyword is unknown, returns no values, but this is not an error. If
michael@0 358 * the number of values is unlimited, returns no values and -1 as the
michael@0 359 * count.
michael@0 360 *
michael@0 361 * The number of returned values is typically small.
michael@0 362 *
michael@0 363 * @param keyword The keyword.
michael@0 364 * @param dest Array into which to put the returned values. May
michael@0 365 * be NULL if destCapacity is 0.
michael@0 366 * @param destCapacity The capacity of the array, must be at least 0.
michael@0 367 * @param status The error code.
michael@0 368 * @return The count of values available, or -1. This count
michael@0 369 * can be larger than destCapacity, but no more than
michael@0 370 * destCapacity values will be written.
michael@0 371 * @stable ICU 4.8
michael@0 372 */
michael@0 373 int32_t getAllKeywordValues(const UnicodeString &keyword,
michael@0 374 double *dest, int32_t destCapacity,
michael@0 375 UErrorCode& status);
michael@0 376
michael@0 377 /**
michael@0 378 * Returns sample values for which select() would return the keyword. If
michael@0 379 * the keyword is unknown, returns no values, but this is not an error.
michael@0 380 *
michael@0 381 * The number of returned values is typically small.
michael@0 382 *
michael@0 383 * @param keyword The keyword.
michael@0 384 * @param dest Array into which to put the returned values. May
michael@0 385 * be NULL if destCapacity is 0.
michael@0 386 * @param destCapacity The capacity of the array, must be at least 0.
michael@0 387 * @param status The error code.
michael@0 388 * @return The count of values written.
michael@0 389 * If more than destCapacity samples are available, then
michael@0 390 * only destCapacity are written, and destCapacity is returned as the count,
michael@0 391 * rather than setting a U_BUFFER_OVERFLOW_ERROR.
michael@0 392 * (The actual number of keyword values could be unlimited.)
michael@0 393 * @stable ICU 4.8
michael@0 394 */
michael@0 395 int32_t getSamples(const UnicodeString &keyword,
michael@0 396 double *dest, int32_t destCapacity,
michael@0 397 UErrorCode& status);
michael@0 398
michael@0 399 /**
michael@0 400 * Returns TRUE if the given keyword is defined in this
michael@0 401 * <code>PluralRules</code> object.
michael@0 402 *
michael@0 403 * @param keyword the input keyword.
michael@0 404 * @return TRUE if the input keyword is defined.
michael@0 405 * Otherwise, return FALSE.
michael@0 406 * @stable ICU 4.0
michael@0 407 */
michael@0 408 UBool isKeyword(const UnicodeString& keyword) const;
michael@0 409
michael@0 410
michael@0 411 /**
michael@0 412 * Returns keyword for default plural form.
michael@0 413 *
michael@0 414 * @return keyword for default plural form.
michael@0 415 * @stable ICU 4.0
michael@0 416 */
michael@0 417 UnicodeString getKeywordOther() const;
michael@0 418
michael@0 419 #ifndef U_HIDE_INTERNAL_API
michael@0 420 /**
michael@0 421 *
michael@0 422 * @internal
michael@0 423 */
michael@0 424 UnicodeString getRules() const;
michael@0 425 #endif /* U_HIDE_INTERNAL_API */
michael@0 426
michael@0 427 /**
michael@0 428 * Compares the equality of two PluralRules objects.
michael@0 429 *
michael@0 430 * @param other The other PluralRules object to be compared with.
michael@0 431 * @return True if the given PluralRules is the same as this
michael@0 432 * PluralRules; false otherwise.
michael@0 433 * @stable ICU 4.0
michael@0 434 */
michael@0 435 virtual UBool operator==(const PluralRules& other) const;
michael@0 436
michael@0 437 /**
michael@0 438 * Compares the inequality of two PluralRules objects.
michael@0 439 *
michael@0 440 * @param other The PluralRules object to be compared with.
michael@0 441 * @return True if the given PluralRules is not the same as this
michael@0 442 * PluralRules; false otherwise.
michael@0 443 * @stable ICU 4.0
michael@0 444 */
michael@0 445 UBool operator!=(const PluralRules& other) const {return !operator==(other);}
michael@0 446
michael@0 447
michael@0 448 /**
michael@0 449 * ICU "poor man's RTTI", returns a UClassID for this class.
michael@0 450 *
michael@0 451 * @stable ICU 4.0
michael@0 452 *
michael@0 453 */
michael@0 454 static UClassID U_EXPORT2 getStaticClassID(void);
michael@0 455
michael@0 456 /**
michael@0 457 * ICU "poor man's RTTI", returns a UClassID for the actual class.
michael@0 458 *
michael@0 459 * @stable ICU 4.0
michael@0 460 */
michael@0 461 virtual UClassID getDynamicClassID() const;
michael@0 462
michael@0 463
michael@0 464 private:
michael@0 465 RuleChain *mRules;
michael@0 466
michael@0 467 PluralRules(); // default constructor not implemented
michael@0 468 void parseDescription(const UnicodeString& ruleData, UErrorCode &status);
michael@0 469 int32_t getNumberValue(const UnicodeString& token) const;
michael@0 470 UnicodeString getRuleFromResource(const Locale& locale, UPluralType type, UErrorCode& status);
michael@0 471 RuleChain *rulesForKeyword(const UnicodeString &keyword) const;
michael@0 472
michael@0 473 friend class PluralRuleParser;
michael@0 474 };
michael@0 475
michael@0 476 U_NAMESPACE_END
michael@0 477
michael@0 478 #endif /* #if !UCONFIG_NO_FORMATTING */
michael@0 479
michael@0 480 #endif // _PLURRULE
michael@0 481 //eof

mercurial