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