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