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