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