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) 1997-2014, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ******************************************************************************** 8 * 9 * File FMTABLE.H 10 * 11 * Modification History: 12 * 13 * Date Name Description 14 * 02/29/97 aliu Creation. 15 ******************************************************************************** 16 */ 17 #ifndef FMTABLE_H 18 #define FMTABLE_H 19 20 #include "unicode/utypes.h" 21 22 /** 23 * \file 24 * \brief C++ API: Formattable is a thin wrapper for primitive types used for formatting and parsing 25 */ 26 27 #if !UCONFIG_NO_FORMATTING 28 29 #include "unicode/unistr.h" 30 #include "unicode/stringpiece.h" 31 #include "unicode/uformattable.h" 32 33 U_NAMESPACE_BEGIN 34 35 class CharString; 36 class DigitList; 37 38 /** 39 * \def UNUM_INTERNAL_STACKARRAY_SIZE 40 * @internal 41 */ 42 #if U_PLATFORM == U_PF_OS400 43 #define UNUM_INTERNAL_STACKARRAY_SIZE 144 44 #else 45 #define UNUM_INTERNAL_STACKARRAY_SIZE 128 46 #endif 47 48 /** 49 * Formattable objects can be passed to the Format class or 50 * its subclasses for formatting. Formattable is a thin wrapper 51 * class which interconverts between the primitive numeric types 52 * (double, long, etc.) as well as UDate and UnicodeString. 53 * 54 * <p>Internally, a Formattable object is a union of primitive types. 55 * As such, it can only store one flavor of data at a time. To 56 * determine what flavor of data it contains, use the getType method. 57 * 58 * <p>As of ICU 3.0, Formattable may also wrap a UObject pointer, 59 * which it owns. This allows an instance of any ICU class to be 60 * encapsulated in a Formattable. For legacy reasons and for 61 * efficiency, primitive numeric types are still stored directly 62 * within a Formattable. 63 * 64 * <p>The Formattable class is not suitable for subclassing. 65 * 66 * <p>See UFormattable for a C wrapper. 67 */ 68 class U_I18N_API Formattable : public UObject { 69 public: 70 /** 71 * This enum is only used to let callers distinguish between 72 * the Formattable(UDate) constructor and the Formattable(double) 73 * constructor; the compiler cannot distinguish the signatures, 74 * since UDate is currently typedefed to be either double or long. 75 * If UDate is changed later to be a bonafide class 76 * or struct, then we no longer need this enum. 77 * @stable ICU 2.4 78 */ 79 enum ISDATE { kIsDate }; 80 81 /** 82 * Default constructor 83 * @stable ICU 2.4 84 */ 85 Formattable(); // Type kLong, value 0 86 87 /** 88 * Creates a Formattable object with a UDate instance. 89 * @param d the UDate instance. 90 * @param flag the flag to indicate this is a date. Always set it to kIsDate 91 * @stable ICU 2.0 92 */ 93 Formattable(UDate d, ISDATE flag); 94 95 /** 96 * Creates a Formattable object with a double number. 97 * @param d the double number. 98 * @stable ICU 2.0 99 */ 100 Formattable(double d); 101 102 /** 103 * Creates a Formattable object with a long number. 104 * @param l the long number. 105 * @stable ICU 2.0 106 */ 107 Formattable(int32_t l); 108 109 /** 110 * Creates a Formattable object with an int64_t number 111 * @param ll the int64_t number. 112 * @stable ICU 2.8 113 */ 114 Formattable(int64_t ll); 115 116 #if !UCONFIG_NO_CONVERSION 117 /** 118 * Creates a Formattable object with a char string pointer. 119 * Assumes that the char string is null terminated. 120 * @param strToCopy the char string. 121 * @stable ICU 2.0 122 */ 123 Formattable(const char* strToCopy); 124 #endif 125 126 /** 127 * Creates a Formattable object of an appropriate numeric type from a 128 * a decimal number in string form. The Formattable will retain the 129 * full precision of the input in decimal format, even when it exceeds 130 * what can be represented by a double or int64_t. 131 * 132 * @param number the unformatted (not localized) string representation 133 * of the Decimal number. 134 * @param status the error code. Possible errors include U_INVALID_FORMAT_ERROR 135 * if the format of the string does not conform to that of a 136 * decimal number. 137 * @stable ICU 4.4 138 */ 139 Formattable(StringPiece number, UErrorCode &status); 140 141 /** 142 * Creates a Formattable object with a UnicodeString object to copy from. 143 * @param strToCopy the UnicodeString string. 144 * @stable ICU 2.0 145 */ 146 Formattable(const UnicodeString& strToCopy); 147 148 /** 149 * Creates a Formattable object with a UnicodeString object to adopt from. 150 * @param strToAdopt the UnicodeString string. 151 * @stable ICU 2.0 152 */ 153 Formattable(UnicodeString* strToAdopt); 154 155 /** 156 * Creates a Formattable object with an array of Formattable objects. 157 * @param arrayToCopy the Formattable object array. 158 * @param count the array count. 159 * @stable ICU 2.0 160 */ 161 Formattable(const Formattable* arrayToCopy, int32_t count); 162 163 /** 164 * Creates a Formattable object that adopts the given UObject. 165 * @param objectToAdopt the UObject to set this object to 166 * @stable ICU 3.0 167 */ 168 Formattable(UObject* objectToAdopt); 169 170 /** 171 * Copy constructor. 172 * @stable ICU 2.0 173 */ 174 Formattable(const Formattable&); 175 176 /** 177 * Assignment operator. 178 * @param rhs The Formattable object to copy into this object. 179 * @stable ICU 2.0 180 */ 181 Formattable& operator=(const Formattable &rhs); 182 183 /** 184 * Equality comparison. 185 * @param other the object to be compared with. 186 * @return TRUE if other are equal to this, FALSE otherwise. 187 * @stable ICU 2.0 188 */ 189 UBool operator==(const Formattable &other) const; 190 191 /** 192 * Equality operator. 193 * @param other the object to be compared with. 194 * @return TRUE if other are unequal to this, FALSE otherwise. 195 * @stable ICU 2.0 196 */ 197 UBool operator!=(const Formattable& other) const 198 { return !operator==(other); } 199 200 /** 201 * Destructor. 202 * @stable ICU 2.0 203 */ 204 virtual ~Formattable(); 205 206 /** 207 * Clone this object. 208 * Clones can be used concurrently in multiple threads. 209 * If an error occurs, then NULL is returned. 210 * The caller must delete the clone. 211 * 212 * @return a clone of this object 213 * 214 * @see getDynamicClassID 215 * @stable ICU 2.8 216 */ 217 Formattable *clone() const; 218 219 /** 220 * Selector for flavor of data type contained within a 221 * Formattable object. Formattable is a union of several 222 * different types, and at any time contains exactly one type. 223 * @stable ICU 2.4 224 */ 225 enum Type { 226 /** 227 * Selector indicating a UDate value. Use getDate to retrieve 228 * the value. 229 * @stable ICU 2.4 230 */ 231 kDate, 232 233 /** 234 * Selector indicating a double value. Use getDouble to 235 * retrieve the value. 236 * @stable ICU 2.4 237 */ 238 kDouble, 239 240 /** 241 * Selector indicating a 32-bit integer value. Use getLong to 242 * retrieve the value. 243 * @stable ICU 2.4 244 */ 245 kLong, 246 247 /** 248 * Selector indicating a UnicodeString value. Use getString 249 * to retrieve the value. 250 * @stable ICU 2.4 251 */ 252 kString, 253 254 /** 255 * Selector indicating an array of Formattables. Use getArray 256 * to retrieve the value. 257 * @stable ICU 2.4 258 */ 259 kArray, 260 261 /** 262 * Selector indicating a 64-bit integer value. Use getInt64 263 * to retrieve the value. 264 * @stable ICU 2.8 265 */ 266 kInt64, 267 268 /** 269 * Selector indicating a UObject value. Use getObject to 270 * retrieve the value. 271 * @stable ICU 3.0 272 */ 273 kObject 274 }; 275 276 /** 277 * Gets the data type of this Formattable object. 278 * @return the data type of this Formattable object. 279 * @stable ICU 2.0 280 */ 281 Type getType(void) const; 282 283 /** 284 * Returns TRUE if the data type of this Formattable object 285 * is kDouble, kLong, or kInt64 286 * @return TRUE if this is a pure numeric object 287 * @stable ICU 3.0 288 */ 289 UBool isNumeric() const; 290 291 /** 292 * Gets the double value of this object. If this object is not of type 293 * kDouble then the result is undefined. 294 * @return the double value of this object. 295 * @stable ICU 2.0 296 */ 297 double getDouble(void) const { return fValue.fDouble; } 298 299 /** 300 * Gets the double value of this object. If this object is of type 301 * long, int64 or Decimal Number then a conversion is peformed, with 302 * possible loss of precision. If the type is kObject and the 303 * object is a Measure, then the result of 304 * getNumber().getDouble(status) is returned. If this object is 305 * neither a numeric type nor a Measure, then 0 is returned and 306 * the status is set to U_INVALID_FORMAT_ERROR. 307 * @param status the error code 308 * @return the double value of this object. 309 * @stable ICU 3.0 310 */ 311 double getDouble(UErrorCode& status) const; 312 313 /** 314 * Gets the long value of this object. If this object is not of type 315 * kLong then the result is undefined. 316 * @return the long value of this object. 317 * @stable ICU 2.0 318 */ 319 int32_t getLong(void) const { return (int32_t)fValue.fInt64; } 320 321 /** 322 * Gets the long value of this object. If the magnitude is too 323 * large to fit in a long, then the maximum or minimum long value, 324 * as appropriate, is returned and the status is set to 325 * U_INVALID_FORMAT_ERROR. If this object is of type kInt64 and 326 * it fits within a long, then no precision is lost. If it is of 327 * type kDouble, then a conversion is peformed, with 328 * truncation of any fractional part. If the type is kObject and 329 * the object is a Measure, then the result of 330 * getNumber().getLong(status) is returned. If this object is 331 * neither a numeric type nor a Measure, then 0 is returned and 332 * the status is set to U_INVALID_FORMAT_ERROR. 333 * @param status the error code 334 * @return the long value of this object. 335 * @stable ICU 3.0 336 */ 337 int32_t getLong(UErrorCode& status) const; 338 339 /** 340 * Gets the int64 value of this object. If this object is not of type 341 * kInt64 then the result is undefined. 342 * @return the int64 value of this object. 343 * @stable ICU 2.8 344 */ 345 int64_t getInt64(void) const { return fValue.fInt64; } 346 347 /** 348 * Gets the int64 value of this object. If this object is of a numeric 349 * type and the magnitude is too large to fit in an int64, then 350 * the maximum or minimum int64 value, as appropriate, is returned 351 * and the status is set to U_INVALID_FORMAT_ERROR. If the 352 * magnitude fits in an int64, then a casting conversion is 353 * peformed, with truncation of any fractional part. If the type 354 * is kObject and the object is a Measure, then the result of 355 * getNumber().getDouble(status) is returned. If this object is 356 * neither a numeric type nor a Measure, then 0 is returned and 357 * the status is set to U_INVALID_FORMAT_ERROR. 358 * @param status the error code 359 * @return the int64 value of this object. 360 * @stable ICU 3.0 361 */ 362 int64_t getInt64(UErrorCode& status) const; 363 364 /** 365 * Gets the Date value of this object. If this object is not of type 366 * kDate then the result is undefined. 367 * @return the Date value of this object. 368 * @stable ICU 2.0 369 */ 370 UDate getDate() const { return fValue.fDate; } 371 372 /** 373 * Gets the Date value of this object. If the type is not a date, 374 * status is set to U_INVALID_FORMAT_ERROR and the return value is 375 * undefined. 376 * @param status the error code. 377 * @return the Date value of this object. 378 * @stable ICU 3.0 379 */ 380 UDate getDate(UErrorCode& status) const; 381 382 /** 383 * Gets the string value of this object. If this object is not of type 384 * kString then the result is undefined. 385 * @param result Output param to receive the Date value of this object. 386 * @return A reference to 'result'. 387 * @stable ICU 2.0 388 */ 389 UnicodeString& getString(UnicodeString& result) const 390 { result=*fValue.fString; return result; } 391 392 /** 393 * Gets the string value of this object. If the type is not a 394 * string, status is set to U_INVALID_FORMAT_ERROR and a bogus 395 * string is returned. 396 * @param result Output param to receive the Date value of this object. 397 * @param status the error code. 398 * @return A reference to 'result'. 399 * @stable ICU 3.0 400 */ 401 UnicodeString& getString(UnicodeString& result, UErrorCode& status) const; 402 403 /** 404 * Gets a const reference to the string value of this object. If 405 * this object is not of type kString then the result is 406 * undefined. 407 * @return a const reference to the string value of this object. 408 * @stable ICU 2.0 409 */ 410 inline const UnicodeString& getString(void) const; 411 412 /** 413 * Gets a const reference to the string value of this object. If 414 * the type is not a string, status is set to 415 * U_INVALID_FORMAT_ERROR and the result is a bogus string. 416 * @param status the error code. 417 * @return a const reference to the string value of this object. 418 * @stable ICU 3.0 419 */ 420 const UnicodeString& getString(UErrorCode& status) const; 421 422 /** 423 * Gets a reference to the string value of this object. If this 424 * object is not of type kString then the result is undefined. 425 * @return a reference to the string value of this object. 426 * @stable ICU 2.0 427 */ 428 inline UnicodeString& getString(void); 429 430 /** 431 * Gets a reference to the string value of this object. If the 432 * type is not a string, status is set to U_INVALID_FORMAT_ERROR 433 * and the result is a bogus string. 434 * @param status the error code. 435 * @return a reference to the string value of this object. 436 * @stable ICU 3.0 437 */ 438 UnicodeString& getString(UErrorCode& status); 439 440 /** 441 * Gets the array value and count of this object. If this object 442 * is not of type kArray then the result is undefined. 443 * @param count fill-in with the count of this object. 444 * @return the array value of this object. 445 * @stable ICU 2.0 446 */ 447 const Formattable* getArray(int32_t& count) const 448 { count=fValue.fArrayAndCount.fCount; return fValue.fArrayAndCount.fArray; } 449 450 /** 451 * Gets the array value and count of this object. If the type is 452 * not an array, status is set to U_INVALID_FORMAT_ERROR, count is 453 * set to 0, and the result is NULL. 454 * @param count fill-in with the count of this object. 455 * @param status the error code. 456 * @return the array value of this object. 457 * @stable ICU 3.0 458 */ 459 const Formattable* getArray(int32_t& count, UErrorCode& status) const; 460 461 /** 462 * Accesses the specified element in the array value of this 463 * Formattable object. If this object is not of type kArray then 464 * the result is undefined. 465 * @param index the specified index. 466 * @return the accessed element in the array. 467 * @stable ICU 2.0 468 */ 469 Formattable& operator[](int32_t index) { return fValue.fArrayAndCount.fArray[index]; } 470 471 /** 472 * Returns a pointer to the UObject contained within this 473 * formattable, or NULL if this object does not contain a UObject. 474 * @return a UObject pointer, or NULL 475 * @stable ICU 3.0 476 */ 477 const UObject* getObject() const; 478 479 /** 480 * Returns a numeric string representation of the number contained within this 481 * formattable, or NULL if this object does not contain numeric type. 482 * For values obtained by parsing, the returned decimal number retains 483 * the full precision and range of the original input, unconstrained by 484 * the limits of a double floating point or a 64 bit int. 485 * 486 * This function is not thread safe, and therfore is not declared const, 487 * even though it is logically const. 488 * 489 * Possible errors include U_MEMORY_ALLOCATION_ERROR, and 490 * U_INVALID_STATE if the formattable object has not been set to 491 * a numeric type. 492 * 493 * @param status the error code. 494 * @return the unformatted string representation of a number. 495 * @stable ICU 4.4 496 */ 497 StringPiece getDecimalNumber(UErrorCode &status); 498 499 /** 500 * Sets the double value of this object and changes the type to 501 * kDouble. 502 * @param d the new double value to be set. 503 * @stable ICU 2.0 504 */ 505 void setDouble(double d); 506 507 /** 508 * Sets the long value of this object and changes the type to 509 * kLong. 510 * @param l the new long value to be set. 511 * @stable ICU 2.0 512 */ 513 void setLong(int32_t l); 514 515 /** 516 * Sets the int64 value of this object and changes the type to 517 * kInt64. 518 * @param ll the new int64 value to be set. 519 * @stable ICU 2.8 520 */ 521 void setInt64(int64_t ll); 522 523 /** 524 * Sets the Date value of this object and changes the type to 525 * kDate. 526 * @param d the new Date value to be set. 527 * @stable ICU 2.0 528 */ 529 void setDate(UDate d); 530 531 /** 532 * Sets the string value of this object and changes the type to 533 * kString. 534 * @param stringToCopy the new string value to be set. 535 * @stable ICU 2.0 536 */ 537 void setString(const UnicodeString& stringToCopy); 538 539 /** 540 * Sets the array value and count of this object and changes the 541 * type to kArray. 542 * @param array the array value. 543 * @param count the number of array elements to be copied. 544 * @stable ICU 2.0 545 */ 546 void setArray(const Formattable* array, int32_t count); 547 548 /** 549 * Sets and adopts the string value and count of this object and 550 * changes the type to kArray. 551 * @param stringToAdopt the new string value to be adopted. 552 * @stable ICU 2.0 553 */ 554 void adoptString(UnicodeString* stringToAdopt); 555 556 /** 557 * Sets and adopts the array value and count of this object and 558 * changes the type to kArray. 559 * @stable ICU 2.0 560 */ 561 void adoptArray(Formattable* array, int32_t count); 562 563 /** 564 * Sets and adopts the UObject value of this object and changes 565 * the type to kObject. After this call, the caller must not 566 * delete the given object. 567 * @param objectToAdopt the UObject value to be adopted 568 * @stable ICU 3.0 569 */ 570 void adoptObject(UObject* objectToAdopt); 571 572 /** 573 * Sets the the numeric value from a decimal number string, and changes 574 * the type to to a numeric type appropriate for the number. 575 * The syntax of the number is a "numeric string" 576 * as defined in the Decimal Arithmetic Specification, available at 577 * http://speleotrove.com/decimal 578 * The full precision and range of the input number will be retained, 579 * even when it exceeds what can be represented by a double or an int64. 580 * 581 * @param numberString a string representation of the unformatted decimal number. 582 * @param status the error code. Set to U_INVALID_FORMAT_ERROR if the 583 * incoming string is not a valid decimal number. 584 * @stable ICU 4.4 585 */ 586 void setDecimalNumber(StringPiece numberString, 587 UErrorCode &status); 588 589 /** 590 * ICU "poor man's RTTI", returns a UClassID for the actual class. 591 * 592 * @stable ICU 2.2 593 */ 594 virtual UClassID getDynamicClassID() const; 595 596 /** 597 * ICU "poor man's RTTI", returns a UClassID for this class. 598 * 599 * @stable ICU 2.2 600 */ 601 static UClassID U_EXPORT2 getStaticClassID(); 602 603 /** 604 * Convert the UFormattable to a Formattable. Internally, this is a reinterpret_cast. 605 * @param fmt a valid UFormattable 606 * @return the UFormattable as a Formattable object pointer. This is an alias to the original 607 * UFormattable, and so is only valid while the original argument remains in scope. 608 * @stable ICU 52 609 */ 610 static inline Formattable *fromUFormattable(UFormattable *fmt); 611 612 /** 613 * Convert the const UFormattable to a const Formattable. Internally, this is a reinterpret_cast. 614 * @param fmt a valid UFormattable 615 * @return the UFormattable as a Formattable object pointer. This is an alias to the original 616 * UFormattable, and so is only valid while the original argument remains in scope. 617 * @stable ICU 52 618 */ 619 static inline const Formattable *fromUFormattable(const UFormattable *fmt); 620 621 /** 622 * Convert this object pointer to a UFormattable. 623 * @return this object as a UFormattable pointer. This is an alias to this object, 624 * and so is only valid while this object remains in scope. 625 * @stable ICU 52 626 */ 627 inline UFormattable *toUFormattable(); 628 629 /** 630 * Convert this object pointer to a UFormattable. 631 * @return this object as a UFormattable pointer. This is an alias to this object, 632 * and so is only valid while this object remains in scope. 633 * @stable ICU 52 634 */ 635 inline const UFormattable *toUFormattable() const; 636 637 #ifndef U_HIDE_DEPRECATED_API 638 /** 639 * Deprecated variant of getLong(UErrorCode&). 640 * @param status the error code 641 * @return the long value of this object. 642 * @deprecated ICU 3.0 use getLong(UErrorCode&) instead 643 */ 644 inline int32_t getLong(UErrorCode* status) const; 645 #endif /* U_HIDE_DEPRECATED_API */ 646 647 #ifndef U_HIDE_INTERNAL_API 648 /** 649 * Internal function, do not use. 650 * TODO: figure out how to make this be non-public. 651 * NumberFormat::format(Formattable, ... 652 * needs to get at the DigitList, if it exists, for 653 * big decimal formatting. 654 * @internal 655 */ 656 DigitList *getDigitList() const { return fDecimalNum;} 657 658 /** 659 * @internal 660 */ 661 DigitList *getInternalDigitList(); 662 663 /** 664 * Adopt, and set value from, a DigitList 665 * Internal Function, do not use. 666 * @param dl the Digit List to be adopted 667 * @internal 668 */ 669 void adoptDigitList(DigitList *dl); 670 671 /** 672 * Internal function to return the CharString pointer. 673 * @param status error code 674 * @return pointer to the CharString - may become invalid if the object is modified 675 * @internal 676 */ 677 CharString *internalGetCharString(UErrorCode &status); 678 679 #endif /* U_HIDE_INTERNAL_API */ 680 681 private: 682 /** 683 * Cleans up the memory for unwanted values. For example, the adopted 684 * string or array objects. 685 */ 686 void dispose(void); 687 688 /** 689 * Common initialization, for use by constructors. 690 */ 691 void init(); 692 693 UnicodeString* getBogus() const; 694 695 union { 696 UObject* fObject; 697 UnicodeString* fString; 698 double fDouble; 699 int64_t fInt64; 700 UDate fDate; 701 struct { 702 Formattable* fArray; 703 int32_t fCount; 704 } fArrayAndCount; 705 } fValue; 706 707 CharString *fDecimalStr; 708 709 DigitList *fDecimalNum; 710 711 char fStackData[UNUM_INTERNAL_STACKARRAY_SIZE]; // must be big enough for DigitList 712 713 Type fType; 714 UnicodeString fBogus; // Bogus string when it's needed. 715 }; 716 717 inline UDate Formattable::getDate(UErrorCode& status) const { 718 if (fType != kDate) { 719 if (U_SUCCESS(status)) { 720 status = U_INVALID_FORMAT_ERROR; 721 } 722 return 0; 723 } 724 return fValue.fDate; 725 } 726 727 inline const UnicodeString& Formattable::getString(void) const { 728 return *fValue.fString; 729 } 730 731 inline UnicodeString& Formattable::getString(void) { 732 return *fValue.fString; 733 } 734 735 #ifndef U_HIDE_DEPRECATED_API 736 inline int32_t Formattable::getLong(UErrorCode* status) const { 737 return getLong(*status); 738 } 739 #endif /* U_HIDE_DEPRECATED_API */ 740 741 inline UFormattable* Formattable::toUFormattable() { 742 return reinterpret_cast<UFormattable*>(this); 743 } 744 745 inline const UFormattable* Formattable::toUFormattable() const { 746 return reinterpret_cast<const UFormattable*>(this); 747 } 748 749 inline Formattable* Formattable::fromUFormattable(UFormattable *fmt) { 750 return reinterpret_cast<Formattable *>(fmt); 751 } 752 753 inline const Formattable* Formattable::fromUFormattable(const UFormattable *fmt) { 754 return reinterpret_cast<const Formattable *>(fmt); 755 } 756 757 U_NAMESPACE_END 758 759 #endif /* #if !UCONFIG_NO_FORMATTING */ 760 761 #endif //_FMTABLE 762 //eof 763