Home | History | Annotate | Download | only in unicode
      1 //  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     /**
    214      * Gets the display name of the specified {@link MeasureUnit} corresponding to the current
    215      * locale and format width.
    216      * @param unit  The unit for which to get a display name.
    217      * @param status the error.
    218      * @return  The display name in the locale and width specified in
    219      *          {@link MeasureFormat#getInstance}, or null if there is no display name available
    220      *          for the specified unit.
    221      *
    222      * @stable ICU 58
    223      */
    224     UnicodeString getUnitDisplayName(const MeasureUnit& unit, UErrorCode &status) const;
    225 
    226 
    227     /**
    228      * Return a formatter for CurrencyAmount objects in the given
    229      * locale.
    230      * @param locale desired locale
    231      * @param ec input-output error code
    232      * @return a formatter object, or NULL upon error
    233      * @stable ICU 3.0
    234      */
    235     static MeasureFormat* U_EXPORT2 createCurrencyFormat(const Locale& locale,
    236                                                UErrorCode& ec);
    237 
    238     /**
    239      * Return a formatter for CurrencyAmount objects in the default
    240      * locale.
    241      * @param ec input-output error code
    242      * @return a formatter object, or NULL upon error
    243      * @stable ICU 3.0
    244      */
    245     static MeasureFormat* U_EXPORT2 createCurrencyFormat(UErrorCode& ec);
    246 
    247     /**
    248      * Return the class ID for this class. This is useful only for comparing to
    249      * a return value from getDynamicClassID(). For example:
    250      * <pre>
    251      * .   Base* polymorphic_pointer = createPolymorphicObject();
    252      * .   if (polymorphic_pointer->getDynamicClassID() ==
    253      * .       erived::getStaticClassID()) ...
    254      * </pre>
    255      * @return          The class ID for all objects of this class.
    256      * @stable ICU 53
    257      */
    258     static UClassID U_EXPORT2 getStaticClassID(void);
    259 
    260     /**
    261      * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
    262      * method is to implement a simple version of RTTI, since not all C++
    263      * compilers support genuine RTTI. Polymorphic operator==() and clone()
    264      * methods call this method.
    265      *
    266      * @return          The class ID for this object. All objects of a
    267      *                  given class have the same class ID.  Objects of
    268      *                  other classes have different class IDs.
    269      * @stable ICU 53
    270      */
    271     virtual UClassID getDynamicClassID(void) const;
    272 
    273  protected:
    274     /**
    275      * Default constructor.
    276      * @stable ICU 3.0
    277      */
    278     MeasureFormat();
    279 
    280 #ifndef U_HIDE_INTERNAL_API
    281 
    282     /**
    283      * ICU use only.
    284      * Initialize or change MeasureFormat class from subclass.
    285      * @internal.
    286      */
    287     void initMeasureFormat(
    288             const Locale &locale,
    289             UMeasureFormatWidth width,
    290             NumberFormat *nfToAdopt,
    291             UErrorCode &status);
    292     /**
    293      * ICU use only.
    294      * Allows subclass to change locale. Note that this method also changes
    295      * the NumberFormat object. Returns TRUE if locale changed; FALSE if no
    296      * change was made.
    297      * @internal.
    298      */
    299     UBool setMeasureFormatLocale(const Locale &locale, UErrorCode &status);
    300 
    301     /**
    302      * ICU use only.
    303      * Let subclass change NumberFormat.
    304      * @internal.
    305      */
    306     void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status);
    307 
    308     /**
    309      * ICU use only.
    310      * @internal.
    311      */
    312     const NumberFormat &getNumberFormat() const;
    313 
    314     /**
    315      * ICU use only.
    316      * @internal.
    317      */
    318     const PluralRules &getPluralRules() const;
    319 
    320     /**
    321      * ICU use only.
    322      * @internal.
    323      */
    324     Locale getLocale(UErrorCode &status) const;
    325 
    326     /**
    327      * ICU use only.
    328      * @internal.
    329      */
    330     const char *getLocaleID(UErrorCode &status) const;
    331 
    332 #endif /* U_HIDE_INTERNAL_API */
    333 
    334  private:
    335     const MeasureFormatCacheData *cache;
    336     const SharedNumberFormat *numberFormat;
    337     const SharedPluralRules *pluralRules;
    338     UMeasureFormatWidth width;
    339 
    340     // Declared outside of MeasureFormatSharedData because ListFormatter
    341     // objects are relatively cheap to copy; therefore, they don't need to be
    342     // shared across instances.
    343     ListFormatter *listFormatter;
    344 
    345     const SimpleFormatter *getFormatterOrNull(
    346             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index) const;
    347 
    348     const SimpleFormatter *getFormatter(
    349             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
    350             UErrorCode &errorCode) const;
    351 
    352     const SimpleFormatter *getPluralFormatter(
    353             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
    354             UErrorCode &errorCode) const;
    355 
    356     const SimpleFormatter *getPerFormatter(
    357             UMeasureFormatWidth width,
    358             UErrorCode &status) const;
    359 
    360     int32_t withPerUnitAndAppend(
    361         const UnicodeString &formatted,
    362         const MeasureUnit &perUnit,
    363         UnicodeString &appendTo,
    364         UErrorCode &status) const;
    365 
    366     UnicodeString &formatMeasure(
    367         const Measure &measure,
    368         const NumberFormat &nf,
    369         UnicodeString &appendTo,
    370         FieldPosition &pos,
    371         UErrorCode &status) const;
    372 
    373     UnicodeString &formatMeasuresSlowTrack(
    374         const Measure *measures,
    375         int32_t measureCount,
    376         UnicodeString& appendTo,
    377         FieldPosition& pos,
    378         UErrorCode& status) const;
    379 
    380     UnicodeString &formatNumeric(
    381         const Formattable *hms,  // always length 3: [0] is hour; [1] is
    382                                  // minute; [2] is second.
    383         int32_t bitMap,   // 1=hour set, 2=minute set, 4=second set
    384         UnicodeString &appendTo,
    385         UErrorCode &status) const;
    386 
    387     UnicodeString &formatNumeric(
    388         UDate date,
    389         const DateFormat &dateFmt,
    390         UDateFormatField smallestField,
    391         const Formattable &smallestAmount,
    392         UnicodeString &appendTo,
    393         UErrorCode &status) const;
    394 };
    395 
    396 U_NAMESPACE_END
    397 
    398 #endif // #if !UCONFIG_NO_FORMATTING
    399 #endif // #ifndef MEASUREFORMAT_H
    400