Home | History | Annotate | Download | only in unicode
      1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 **********************************************************************
      5 * Copyright (c) 2004-2016, International Business Machines
      6 * Corporation and others.  All Rights Reserved.
      7 **********************************************************************
      8 * Author: Alan Liu
      9 * Created: April 20, 2004
     10 * Since: ICU 3.0
     11 **********************************************************************
     12 */
     13 #ifndef MEASUREFORMAT_H
     14 #define MEASUREFORMAT_H
     15 
     16 #include "unicode/utypes.h"
     17 
     18 #if !UCONFIG_NO_FORMATTING
     19 
     20 #include "unicode/format.h"
     21 #include "unicode/udat.h"
     22 
     23 /**
     24  * \file
     25  * \brief C++ API: Formatter for measure objects.
     26  */
     27 
     28 /**
     29  * Constants for various widths.
     30  * There are 4 widths: Wide, Short, Narrow, Numeric.
     31  * For example, for English, when formatting "3 hours"
     32  * Wide is "3 hours"; short is "3 hrs"; narrow is "3h";
     33  * formatting "3 hours 17 minutes" as numeric give "3:17"
     34  * @stable ICU 53
     35  */
     36 enum UMeasureFormatWidth {
     37 
     38     // Wide, short, and narrow must be first and in this order.
     39     /**
     40      * Spell out measure units.
     41      * @stable ICU 53
     42      */
     43     UMEASFMT_WIDTH_WIDE,
     44 
     45     /**
     46      * Abbreviate measure units.
     47      * @stable ICU 53
     48      */
     49     UMEASFMT_WIDTH_SHORT,
     50 
     51     /**
     52      * Use symbols for measure units when possible.
     53      * @stable ICU 53
     54      */
     55     UMEASFMT_WIDTH_NARROW,
     56 
     57     /**
     58      * Completely omit measure units when possible. For example, format
     59      * '5 hours, 37 minutes' as '5:37'
     60      * @stable ICU 53
     61      */
     62     UMEASFMT_WIDTH_NUMERIC,
     63 
     64 #ifndef U_HIDE_DEPRECATED_API
     65     /**
     66      * One more than the highest normal UMeasureFormatWidth value.
     67      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
     68      */
     69     UMEASFMT_WIDTH_COUNT = 4
     70 #endif  // U_HIDE_DEPRECATED_API
     71 };
     72 /** @stable ICU 53 */
     73 typedef enum UMeasureFormatWidth UMeasureFormatWidth;
     74 
     75 U_NAMESPACE_BEGIN
     76 
     77 class Measure;
     78 class MeasureUnit;
     79 class NumberFormat;
     80 class PluralRules;
     81 class MeasureFormatCacheData;
     82 class SharedNumberFormat;
     83 class SharedPluralRules;
     84 class QuantityFormatter;
     85 class SimpleFormatter;
     86 class ListFormatter;
     87 class DateFormat;
     88 
     89 /**
     90  *
     91  * A formatter for measure objects.
     92  *
     93  * @see Format
     94  * @author Alan Liu
     95  * @stable ICU 3.0
     96  */
     97 class U_I18N_API MeasureFormat : public Format {
     98  public:
     99     using Format::parseObject;
    100     using Format::format;
    101 
    102     /**
    103      * Constructor.
    104      * @stable ICU 53
    105      */
    106     MeasureFormat(
    107             const Locale &locale, UMeasureFormatWidth width, UErrorCode &status);
    108 
    109     /**
    110      * Constructor.
    111      * @stable ICU 53
    112      */
    113     MeasureFormat(
    114             const Locale &locale,
    115             UMeasureFormatWidth width,
    116             NumberFormat *nfToAdopt,
    117             UErrorCode &status);
    118 
    119     /**
    120      * Copy constructor.
    121      * @stable ICU 3.0
    122      */
    123     MeasureFormat(const MeasureFormat &other);
    124 
    125     /**
    126      * Assignment operator.
    127      * @stable ICU 3.0
    128      */
    129     MeasureFormat &operator=(const MeasureFormat &rhs);
    130 
    131     /**
    132      * Destructor.
    133      * @stable ICU 3.0
    134      */
    135     virtual ~MeasureFormat();
    136 
    137     /**
    138      * Return true if given Format objects are semantically equal.
    139      * @stable ICU 53
    140      */
    141     virtual UBool operator==(const Format &other) const;
    142 
    143     /**
    144      * Clones this object polymorphically.
    145      * @stable ICU 53
    146      */
    147     virtual Format *clone() const;
    148 
    149     /**
    150      * Formats object to produce a string.
    151      * @stable ICU 53
    152      */
    153     virtual UnicodeString &format(
    154             const Formattable &obj,
    155             UnicodeString &appendTo,
    156             FieldPosition &pos,
    157             UErrorCode &status) const;
    158 
    159     /**
    160      * Parse a string to produce an object. This implementation sets
    161      * status to U_UNSUPPORTED_ERROR.
    162      *
    163      * @draft ICU 53
    164      */
    165     virtual void parseObject(
    166             const UnicodeString &source,
    167             Formattable &reslt,
    168             ParsePosition &pos) const;
    169 
    170     /**
    171      * Formats measure objects to produce a string. An example of such a
    172      * formatted string is 3 meters, 3.5 centimeters. Measure objects appear
    173      * in the formatted string in the same order they appear in the "measures"
    174      * array. The NumberFormat of this object is used only to format the amount
    175      * of the very last measure. The other amounts are formatted with zero
    176      * decimal places while rounding toward zero.
    177      * @param measures array of measure objects.
    178      * @param measureCount the number of measure objects.
    179      * @param appendTo formatted string appended here.
    180      * @param pos the field position.
    181      * @param status the error.
    182      * @return appendTo reference
    183      *
    184      * @stable ICU 53
    185      */
    186     UnicodeString &formatMeasures(
    187             const Measure *measures,
    188             int32_t measureCount,
    189             UnicodeString &appendTo,
    190             FieldPosition &pos,
    191             UErrorCode &status) const;
    192 
    193     /**
    194      * Formats a single measure per unit. An example of such a
    195      * formatted string is 3.5 meters per second.
    196      * @param measure The measure object. In above example, 3.5 meters.
    197      * @param perUnit The per unit. In above example, it is
    198      *        *MeasureUnit::createSecond(status).
    199      * @param appendTo formatted string appended here.
    200      * @param pos the field position.
    201      * @param status the error.
    202      * @return appendTo reference
    203      *
    204      * @stable ICU 55
    205      */
    206     UnicodeString &formatMeasurePerUnit(
    207             const Measure &measure,
    208             const MeasureUnit &perUnit,
    209             UnicodeString &appendTo,
    210             FieldPosition &pos,
    211             UErrorCode &status) const;
    212 
    213 #ifndef U_HIDE_DRAFT_API
    214     /**
    215      * Gets the display name of the specified {@link MeasureUnit} corresponding to the current
    216      * locale and format width.
    217      * @param unit  The unit for which to get a display name.
    218      * @param status the error.
    219      * @return  The display name in the locale and width specified in
    220      *          {@link MeasureFormat#getInstance}, or null if there is no display name available
    221      *          for the specified unit.
    222      *
    223      * @draft ICU 58
    224      */
    225     UnicodeString getUnitDisplayName(const MeasureUnit& unit, UErrorCode &status) const;
    226 #endif /* U_HIDE_DRAFT_API */
    227 
    228 
    229     /**
    230      * Return a formatter for CurrencyAmount objects in the given
    231      * locale.
    232      * @param locale desired locale
    233      * @param ec input-output error code
    234      * @return a formatter object, or NULL upon error
    235      * @stable ICU 3.0
    236      */
    237     static MeasureFormat* U_EXPORT2 createCurrencyFormat(const Locale& locale,
    238                                                UErrorCode& ec);
    239 
    240     /**
    241      * Return a formatter for CurrencyAmount objects in the default
    242      * locale.
    243      * @param ec input-output error code
    244      * @return a formatter object, or NULL upon error
    245      * @stable ICU 3.0
    246      */
    247     static MeasureFormat* U_EXPORT2 createCurrencyFormat(UErrorCode& ec);
    248 
    249     /**
    250      * Return the class ID for this class. This is useful only for comparing to
    251      * a return value from getDynamicClassID(). For example:
    252      * <pre>
    253      * .   Base* polymorphic_pointer = createPolymorphicObject();
    254      * .   if (polymorphic_pointer->getDynamicClassID() ==
    255      * .       erived::getStaticClassID()) ...
    256      * </pre>
    257      * @return          The class ID for all objects of this class.
    258      * @stable ICU 53
    259      */
    260     static UClassID U_EXPORT2 getStaticClassID(void);
    261 
    262     /**
    263      * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
    264      * method is to implement a simple version of RTTI, since not all C++
    265      * compilers support genuine RTTI. Polymorphic operator==() and clone()
    266      * methods call this method.
    267      *
    268      * @return          The class ID for this object. All objects of a
    269      *                  given class have the same class ID.  Objects of
    270      *                  other classes have different class IDs.
    271      * @stable ICU 53
    272      */
    273     virtual UClassID getDynamicClassID(void) const;
    274 
    275  protected:
    276     /**
    277      * Default constructor.
    278      * @stable ICU 3.0
    279      */
    280     MeasureFormat();
    281 
    282 #ifndef U_HIDE_INTERNAL_API
    283 
    284     /**
    285      * ICU use only.
    286      * Initialize or change MeasureFormat class from subclass.
    287      * @internal.
    288      */
    289     void initMeasureFormat(
    290             const Locale &locale,
    291             UMeasureFormatWidth width,
    292             NumberFormat *nfToAdopt,
    293             UErrorCode &status);
    294     /**
    295      * ICU use only.
    296      * Allows subclass to change locale. Note that this method also changes
    297      * the NumberFormat object. Returns TRUE if locale changed; FALSE if no
    298      * change was made.
    299      * @internal.
    300      */
    301     UBool setMeasureFormatLocale(const Locale &locale, UErrorCode &status);
    302 
    303     /**
    304      * ICU use only.
    305      * Let subclass change NumberFormat.
    306      * @internal.
    307      */
    308     void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status);
    309 
    310     /**
    311      * ICU use only.
    312      * @internal.
    313      */
    314     const NumberFormat &getNumberFormat() const;
    315 
    316     /**
    317      * ICU use only.
    318      * @internal.
    319      */
    320     const PluralRules &getPluralRules() const;
    321 
    322     /**
    323      * ICU use only.
    324      * @internal.
    325      */
    326     Locale getLocale(UErrorCode &status) const;
    327 
    328     /**
    329      * ICU use only.
    330      * @internal.
    331      */
    332     const char *getLocaleID(UErrorCode &status) const;
    333 
    334 #endif /* U_HIDE_INTERNAL_API */
    335 
    336  private:
    337     const MeasureFormatCacheData *cache;
    338     const SharedNumberFormat *numberFormat;
    339     const SharedPluralRules *pluralRules;
    340     UMeasureFormatWidth width;
    341 
    342     // Declared outside of MeasureFormatSharedData because ListFormatter
    343     // objects are relatively cheap to copy; therefore, they don't need to be
    344     // shared across instances.
    345     ListFormatter *listFormatter;
    346 
    347     const SimpleFormatter *getFormatterOrNull(
    348             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index) const;
    349 
    350     const SimpleFormatter *getFormatter(
    351             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
    352             UErrorCode &errorCode) const;
    353 
    354     const SimpleFormatter *getPluralFormatter(
    355             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
    356             UErrorCode &errorCode) const;
    357 
    358     const SimpleFormatter *getPerFormatter(
    359             UMeasureFormatWidth width,
    360             UErrorCode &status) const;
    361 
    362     int32_t withPerUnitAndAppend(
    363         const UnicodeString &formatted,
    364         const MeasureUnit &perUnit,
    365         UnicodeString &appendTo,
    366         UErrorCode &status) const;
    367 
    368     UnicodeString &formatMeasure(
    369         const Measure &measure,
    370         const NumberFormat &nf,
    371         UnicodeString &appendTo,
    372         FieldPosition &pos,
    373         UErrorCode &status) const;
    374 
    375     UnicodeString &formatMeasuresSlowTrack(
    376         const Measure *measures,
    377         int32_t measureCount,
    378         UnicodeString& appendTo,
    379         FieldPosition& pos,
    380         UErrorCode& status) const;
    381 
    382     UnicodeString &formatNumeric(
    383         const Formattable *hms,  // always length 3: [0] is hour; [1] is
    384                                  // minute; [2] is second.
    385         int32_t bitMap,   // 1=hour set, 2=minute set, 4=second set
    386         UnicodeString &appendTo,
    387         UErrorCode &status) const;
    388 
    389     UnicodeString &formatNumeric(
    390         UDate date,
    391         const DateFormat &dateFmt,
    392         UDateFormatField smallestField,
    393         const Formattable &smallestAmount,
    394         UnicodeString &appendTo,
    395         UErrorCode &status) const;
    396 };
    397 
    398 U_NAMESPACE_END
    399 
    400 #endif // #if !UCONFIG_NO_FORMATTING
    401 #endif // #ifndef MEASUREFORMAT_H
    402