Home | History | Annotate | Download | only in i18n
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *******************************************************************************
      5 * Copyright (C) 2015, International Business Machines
      6 * Corporation and others.  All Rights Reserved.
      7 *******************************************************************************
      8 * pluralaffix.h
      9 *
     10 * created on: 2015jan06
     11 * created by: Travis Keep
     12 */
     13 
     14 #ifndef __PLURALAFFIX_H__
     15 #define __PLURALAFFIX_H__
     16 
     17 #include "unicode/utypes.h"
     18 
     19 #if !UCONFIG_NO_FORMATTING
     20 
     21 #include "unicode/unum.h"
     22 #include "unicode/uobject.h"
     23 
     24 #include "digitaffix.h"
     25 #include "pluralmap.h"
     26 
     27 U_NAMESPACE_BEGIN
     28 
     29 class FieldPositionHandler;
     30 
     31 // Export an explicit template instantiation.
     32 //
     33 //    MSVC requires this, even though it should not be necessary.
     34 //    No direct access leaks out of the i18n library.
     35 //
     36 //    Macintosh produces duplicate definition linker errors with the explicit template
     37 //    instantiation.
     38 //
     39 #if !U_PLATFORM_IS_DARWIN_BASED
     40 template class U_I18N_API PluralMap<DigitAffix>;
     41 #endif
     42 
     43 
     44 /**
     45  * A plural aware prefix or suffix of a formatted number.
     46  *
     47  * PluralAffix is essentially a map of DigitAffix objects keyed by plural
     48  * category. The 'other' category is the default and always has some
     49  * value. The rest of the categories are optional. Querying for a category that
     50  * is not set always returns the DigitAffix stored in the 'other' category.
     51  *
     52  * To use one of these objects, build it up first using append() and
     53  * setVariant() methods. Once built, leave unchanged and let multiple threads
     54  * safely access.
     55  *
     56  * The following code is sample code for building up:
     57  *   one: US Dollar -
     58  *   other: US Dollars -
     59  *
     60  * and storing it in "negativeCurrencyPrefix"
     61  *
     62  * UErrorCode status = U_ZERO_ERROR;
     63  *
     64  * PluralAffix negativeCurrencyPrefix;
     65  *
     66  * PluralAffix currencyName;
     67  * currencyName.setVariant("one", "US Dollar", status);
     68  * currencyName.setVariant("other", "US Dollars", status);
     69  *
     70  * negativeCurrencyPrefix.append(currencyName, UNUM_CURRENCY_FIELD, status);
     71  * negativeCurrencyPrefix.append(" ");
     72  * negativeCurrencyPrefix.append("-", UNUM_SIGN_FIELD, status);
     73  */
     74 class U_I18N_API PluralAffix : public UMemory {
     75 public:
     76 
     77     /**
     78      * Create empty PluralAffix.
     79      */
     80     PluralAffix() : affixes() { }
     81 
     82     /**
     83      * Create a PluralAffix where the 'other' variant is otherVariant.
     84      */
     85     PluralAffix(const DigitAffix &otherVariant) : affixes(otherVariant) { }
     86 
     87     /**
     88      * Sets a particular variant for a plural category while overwriting
     89      * anything that may have been previously stored for that plural
     90      * category. The set value has no field annotations.
     91      * @param category "one", "two", "few", ...
     92      * @param variant the variant to store under the particular category
     93      * @param status Any error returned here.
     94      */
     95     UBool setVariant(
     96             const char *category,
     97             const UnicodeString &variant,
     98             UErrorCode &status);
     99     /**
    100      * Make the 'other' variant be the empty string with no field annotations
    101      * and remove the variants for the rest of the plural categories.
    102      */
    103     void remove();
    104 
    105     /**
    106      * Append value to all set plural categories. If fieldId present, value
    107      * is that field type.
    108      */
    109     void appendUChar(UChar value, int32_t fieldId=UNUM_FIELD_COUNT);
    110 
    111     /**
    112      * Append value to all set plural categories. If fieldId present, value
    113      * is that field type.
    114      */
    115     void append(const UnicodeString &value, int32_t fieldId=UNUM_FIELD_COUNT);
    116 
    117     /**
    118      * Append value to all set plural categories. If fieldId present, value
    119      * is that field type.
    120      */
    121     void append(const UChar *value, int32_t charCount, int32_t fieldId=UNUM_FIELD_COUNT);
    122 
    123     /**
    124      * Append the value for each plural category in rhs to the corresponding
    125      * plural category in this instance. Each value appended from rhs is
    126      * of type fieldId.
    127      */
    128     UBool append(
    129             const PluralAffix &rhs,
    130             int32_t fieldId,
    131             UErrorCode &status);
    132     /**
    133      * Get the DigitAffix for a paricular category such as "zero", "one", ...
    134      * If the particular category is not set, returns the 'other' category
    135      * which is always set.
    136      */
    137     const DigitAffix &getByCategory(const char *category) const;
    138 
    139     /**
    140      * Get the DigitAffix for a paricular category such as "zero", "one", ...
    141      * If the particular category is not set, returns the 'other' category
    142      * which is always set.
    143      */
    144     const DigitAffix &getByCategory(const UnicodeString &category) const;
    145 
    146     /**
    147      * Get the DigitAffix for the other category which is always set.
    148      */
    149     const DigitAffix &getOtherVariant() const {
    150         return affixes.getOther();
    151     }
    152 
    153     /**
    154      * Returns TRUE if this instance has variants stored besides the "other"
    155      * variant.
    156      */
    157     UBool hasMultipleVariants() const;
    158 
    159     /**
    160      * Returns TRUE if this instance equals rhs.
    161      */
    162     UBool equals(const PluralAffix &rhs) const {
    163         return affixes.equals(rhs.affixes, &eq);
    164     }
    165 
    166 private:
    167     PluralMap<DigitAffix> affixes;
    168 
    169     static UBool eq(const DigitAffix &x, const DigitAffix &y) {
    170         return x.equals(y);
    171     }
    172 };
    173 
    174 
    175 U_NAMESPACE_END
    176 #endif /* #if !UCONFIG_NO_FORMATTING */
    177 #endif  // __PLURALAFFIX_H__
    178