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