• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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: Compatibility APIs for measure formatting.
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  * <p><strong>IMPORTANT:</strong> New users are strongly encouraged to see if
91  * numberformatter.h fits their use case.  Although not deprecated, this header
92  * is provided for backwards compatibility only.
93  *
94  * @see Format
95  * @author Alan Liu
96  * @stable ICU 3.0
97  */
98 class U_I18N_API MeasureFormat : public Format {
99  public:
100     using Format::parseObject;
101     using Format::format;
102 
103     /**
104      * Constructor.
105      * <p>
106      * <strong>NOTE:</strong> New users are strongly encouraged to use
107      * {@link icu::number::NumberFormatter} instead of NumberFormat.
108      * @stable ICU 53
109      */
110     MeasureFormat(
111             const Locale &locale, UMeasureFormatWidth width, UErrorCode &status);
112 
113     /**
114      * Constructor.
115      * <p>
116      * <strong>NOTE:</strong> New users are strongly encouraged to use
117      * {@link icu::number::NumberFormatter} instead of NumberFormat.
118      * @stable ICU 53
119      */
120     MeasureFormat(
121             const Locale &locale,
122             UMeasureFormatWidth width,
123             NumberFormat *nfToAdopt,
124             UErrorCode &status);
125 
126     /**
127      * Copy constructor.
128      * @stable ICU 3.0
129      */
130     MeasureFormat(const MeasureFormat &other);
131 
132     /**
133      * Assignment operator.
134      * @stable ICU 3.0
135      */
136     MeasureFormat &operator=(const MeasureFormat &rhs);
137 
138     /**
139      * Destructor.
140      * @stable ICU 3.0
141      */
142     virtual ~MeasureFormat();
143 
144     /**
145      * Return true if given Format objects are semantically equal.
146      * @stable ICU 53
147      */
148     virtual UBool operator==(const Format &other) const;
149 
150     /**
151      * Clones this object polymorphically.
152      * @stable ICU 53
153      */
154     virtual Format *clone() const;
155 
156     /**
157      * Formats object to produce a string.
158      * @stable ICU 53
159      */
160     virtual UnicodeString &format(
161             const Formattable &obj,
162             UnicodeString &appendTo,
163             FieldPosition &pos,
164             UErrorCode &status) const;
165 
166     /**
167      * Parse a string to produce an object. This implementation sets
168      * status to U_UNSUPPORTED_ERROR.
169      *
170      * @draft ICU 53
171      */
172     virtual void parseObject(
173             const UnicodeString &source,
174             Formattable &reslt,
175             ParsePosition &pos) const;
176 
177     /**
178      * Formats measure objects to produce a string. An example of such a
179      * formatted string is 3 meters, 3.5 centimeters. Measure objects appear
180      * in the formatted string in the same order they appear in the "measures"
181      * array. The NumberFormat of this object is used only to format the amount
182      * of the very last measure. The other amounts are formatted with zero
183      * decimal places while rounding toward zero.
184      * @param measures array of measure objects.
185      * @param measureCount the number of measure objects.
186      * @param appendTo formatted string appended here.
187      * @param pos the field position.
188      * @param status the error.
189      * @return appendTo reference
190      *
191      * @stable ICU 53
192      */
193     UnicodeString &formatMeasures(
194             const Measure *measures,
195             int32_t measureCount,
196             UnicodeString &appendTo,
197             FieldPosition &pos,
198             UErrorCode &status) const;
199 
200     /**
201      * Formats a single measure per unit. An example of such a
202      * formatted string is 3.5 meters per second.
203      * @param measure The measure object. In above example, 3.5 meters.
204      * @param perUnit The per unit. In above example, it is
205      *        `*%MeasureUnit::createSecond(status)`.
206      * @param appendTo formatted string appended here.
207      * @param pos the field position.
208      * @param status the error.
209      * @return appendTo reference
210      *
211      * @stable ICU 55
212      */
213     UnicodeString &formatMeasurePerUnit(
214             const Measure &measure,
215             const MeasureUnit &perUnit,
216             UnicodeString &appendTo,
217             FieldPosition &pos,
218             UErrorCode &status) const;
219 
220     /**
221      * Gets the display name of the specified {@link MeasureUnit} corresponding to the current
222      * locale and format width.
223      * @param unit  The unit for which to get a display name.
224      * @param status the error.
225      * @return  The display name in the locale and width specified in
226      *          the MeasureFormat constructor, or null if there is no display name available
227      *          for the specified unit.
228      *
229      * @stable ICU 58
230      */
231     UnicodeString getUnitDisplayName(const MeasureUnit& unit, UErrorCode &status) const;
232 
233 
234     /**
235      * Return a formatter for CurrencyAmount objects in the given
236      * locale.
237      * <p>
238      * <strong>NOTE:</strong> New users are strongly encouraged to use
239      * {@link icu::number::NumberFormatter} instead of NumberFormat.
240      * @param locale desired 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(const Locale& locale,
246                                                UErrorCode& ec);
247 
248     /**
249      * Return a formatter for CurrencyAmount objects in the default
250      * locale.
251      * <p>
252      * <strong>NOTE:</strong> New users are strongly encouraged to use
253      * {@link icu::number::NumberFormatter} instead of NumberFormat.
254      * @param ec input-output error code
255      * @return a formatter object, or NULL upon error
256      * @stable ICU 3.0
257      */
258     static MeasureFormat* U_EXPORT2 createCurrencyFormat(UErrorCode& ec);
259 
260     /**
261      * Return the class ID for this class. This is useful only for comparing to
262      * a return value from getDynamicClassID(). For example:
263      * <pre>
264      * .   Base* polymorphic_pointer = createPolymorphicObject();
265      * .   if (polymorphic_pointer->getDynamicClassID() ==
266      * .       erived::getStaticClassID()) ...
267      * </pre>
268      * @return          The class ID for all objects of this class.
269      * @stable ICU 53
270      */
271     static UClassID U_EXPORT2 getStaticClassID(void);
272 
273     /**
274      * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
275      * method is to implement a simple version of RTTI, since not all C++
276      * compilers support genuine RTTI. Polymorphic operator==() and clone()
277      * methods call this method.
278      *
279      * @return          The class ID for this object. All objects of a
280      *                  given class have the same class ID.  Objects of
281      *                  other classes have different class IDs.
282      * @stable ICU 53
283      */
284     virtual UClassID getDynamicClassID(void) const;
285 
286  protected:
287     /**
288      * Default constructor.
289      * @stable ICU 3.0
290      */
291     MeasureFormat();
292 
293 #ifndef U_HIDE_INTERNAL_API
294 
295     /**
296      * ICU use only.
297      * Initialize or change MeasureFormat class from subclass.
298      * @internal.
299      */
300     void initMeasureFormat(
301             const Locale &locale,
302             UMeasureFormatWidth width,
303             NumberFormat *nfToAdopt,
304             UErrorCode &status);
305     /**
306      * ICU use only.
307      * Allows subclass to change locale. Note that this method also changes
308      * the NumberFormat object. Returns TRUE if locale changed; FALSE if no
309      * change was made.
310      * @internal.
311      */
312     UBool setMeasureFormatLocale(const Locale &locale, UErrorCode &status);
313 
314     /**
315      * ICU use only.
316      * Let subclass change NumberFormat.
317      * @internal.
318      */
319     void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status);
320 
321     /**
322      * ICU use only.
323      * @internal.
324      */
325     const NumberFormat &getNumberFormat() const;
326 
327     /**
328      * ICU use only.
329      * @internal.
330      */
331     const PluralRules &getPluralRules() const;
332 
333     /**
334      * ICU use only.
335      * @internal.
336      */
337     Locale getLocale(UErrorCode &status) const;
338 
339     /**
340      * ICU use only.
341      * @internal.
342      */
343     const char *getLocaleID(UErrorCode &status) const;
344 
345 #endif /* U_HIDE_INTERNAL_API */
346 
347  private:
348     const MeasureFormatCacheData *cache;
349     const SharedNumberFormat *numberFormat;
350     const SharedPluralRules *pluralRules;
351     UMeasureFormatWidth fWidth;
352 
353     // Declared outside of MeasureFormatSharedData because ListFormatter
354     // objects are relatively cheap to copy; therefore, they don't need to be
355     // shared across instances.
356     ListFormatter *listFormatter;
357 
358     const SimpleFormatter *getFormatterOrNull(
359             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index) const;
360 
361     const SimpleFormatter *getFormatter(
362             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
363             UErrorCode &errorCode) const;
364 
365     const SimpleFormatter *getPluralFormatter(
366             const MeasureUnit &unit, UMeasureFormatWidth width, int32_t index,
367             UErrorCode &errorCode) const;
368 
369     const SimpleFormatter *getPerFormatter(
370             UMeasureFormatWidth width,
371             UErrorCode &status) const;
372 
373     int32_t withPerUnitAndAppend(
374         const UnicodeString &formatted,
375         const MeasureUnit &perUnit,
376         UnicodeString &appendTo,
377         UErrorCode &status) const;
378 
379     UnicodeString &formatMeasure(
380         const Measure &measure,
381         const NumberFormat &nf,
382         UnicodeString &appendTo,
383         FieldPosition &pos,
384         UErrorCode &status) const;
385 
386     UnicodeString &formatMeasuresSlowTrack(
387         const Measure *measures,
388         int32_t measureCount,
389         UnicodeString& appendTo,
390         FieldPosition& pos,
391         UErrorCode& status) const;
392 
393     UnicodeString &formatNumeric(
394         const Formattable *hms,  // always length 3: [0] is hour; [1] is
395                                  // minute; [2] is second.
396         int32_t bitMap,   // 1=hour set, 2=minute set, 4=second set
397         UnicodeString &appendTo,
398         UErrorCode &status) const;
399 
400     UnicodeString &formatNumeric(
401         UDate date,
402         const DateFormat &dateFmt,
403         UDateFormatField smallestField,
404         const Formattable &smallestAmount,
405         UnicodeString &appendTo,
406         UErrorCode &status) const;
407 };
408 
409 U_NAMESPACE_END
410 
411 #endif // #if !UCONFIG_NO_FORMATTING
412 #endif // #ifndef MEASUREFORMAT_H
413