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