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