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.

     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 */
    16 #ifndef PLURRULE
    17 #define PLURRULE
    19 #include "unicode/utypes.h"
    21 /**
    22  * \file
    23  * \brief C++ API: PluralRules object
    24  */
    26 #if !UCONFIG_NO_FORMATTING
    28 #include "unicode/format.h"
    29 #include "unicode/upluralrules.h"
    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)
    38 U_NAMESPACE_BEGIN
    40 class Hashtable;
    41 class FixedDecimal;
    42 class RuleChain;
    43 class PluralRuleParser;
    44 class PluralKeywordEnumeration;
    45 class AndConstraint;
    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>
   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:
   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);
   202     /**
   203      * Copy constructor.
   204      * @stable ICU 4.0
   205      */
   206     PluralRules(const PluralRules& other);
   208     /**
   209      * Destructor.
   210      * @stable ICU 4.0
   211      */
   212     virtual ~PluralRules();
   214     /**
   215      * Clone
   216      * @stable ICU 4.0
   217      */
   218     PluralRules* clone() const;
   220     /**
   221       * Assignment operator.
   222       * @stable ICU 4.0
   223       */
   224     PluralRules& operator=(const PluralRules&);
   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);
   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);
   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);
   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);
   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);
   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 */
   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;
   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;
   324 #ifndef U_HIDE_INTERNAL_API
   325     /**
   326       * @internal
   327       */
   328     UnicodeString select(const FixedDecimal &number) const;
   329 #endif  /* U_HIDE_INTERNAL_API */
   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;
   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);
   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);
   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);
   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;
   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;
   419 #ifndef U_HIDE_INTERNAL_API
   420     /**
   421      *
   422      * @internal
   423      */
   424      UnicodeString getRules() const;
   425 #endif  /* U_HIDE_INTERNAL_API */
   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;
   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);}
   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);
   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;
   464 private:
   465     RuleChain  *mRules;
   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;
   473     friend class PluralRuleParser;
   474 };
   476 U_NAMESPACE_END
   478 #endif /* #if !UCONFIG_NO_FORMATTING */
   480 #endif // _PLURRULE
   481 //eof

mercurial