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