tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

plurrule.h (21128B)


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