/*
********************************************************************************
-* Copyright (C) 1997-2004, International Business Machines
+* Copyright (C) 1997-2010, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************************
*
#include "unicode/utypes.h"
#include "unicode/unistr.h"
+#include "unicode/stringpiece.h"
+
+/**
+ * \file
+ * \brief C++ API: Formattable is a thin wrapper for primitive numeric types.
+ */
#if !UCONFIG_NO_FORMATTING
U_NAMESPACE_BEGIN
+class CharString;
+class DigitList;
+
/**
* Formattable objects can be passed to the Format class or
* its subclasses for formatting. Formattable is a thin wrapper
/**
* Creates a Formattable object with an int64_t number
* @param ll the int64_t number.
- * @draft ICU 2.8
+ * @stable ICU 2.8
*/
Formattable(int64_t ll);
+#if !UCONFIG_NO_CONVERSION
/**
* Creates a Formattable object with a char string pointer.
* Assumes that the char string is null terminated.
* @stable ICU 2.0
*/
Formattable(const char* strToCopy);
+#endif
+
+ /**
+ * Creates a Formattable object of an appropriate numeric type from a
+ * a decimal number in string form. The Formattable will retain the
+ * full precision of the input in decimal format, even when it exceeds
+ * what can be represented by a double of int64_t.
+ *
+ * @param number the unformatted (not localized) string representation
+ * of the Decimal number.
+ * @param status the error code. Possible errors include U_INVALID_FORMAT_ERROR
+ * if the format of the string does not conform to that of a
+ * decimal number.
+ * @stable ICU 4.4
+ */
+ Formattable(const StringPiece &number, UErrorCode &status);
/**
* Creates a Formattable object with a UnicodeString object to copy from.
/**
* Creates a Formattable object that adopts the given UObject.
* @param objectToAdopt the UObject to set this object to
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
Formattable(UObject* objectToAdopt);
* @return a clone of this object
*
* @see getDynamicClassID
- * @draft ICU 2.8
+ * @stable ICU 2.8
*/
Formattable *clone() const;
/**
* Selector indicating a 64-bit integer value. Use getInt64
* to retrieve the value.
- * @draft ICU 2.8
+ * @stable ICU 2.8
*/
kInt64,
/**
* Selector indicating a UObject value. Use getObject to
* retrieve the value.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
kObject
};
/**
* Returns TRUE if the data type of this Formattable object
- * is kDouble, kLong, or kInt64.
+ * is kDouble, kLong, kInt64 or kDecimalNumber.
* @return TRUE if this is a pure numeric object
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
UBool isNumeric() const;
/**
* Gets the double value of this object. If this object is of type
- * long or int64 then a casting conversion is peformed, with
+ * long, int64 or Decimal Number then a conversion is peformed, with
* possible loss of precision. If the type is kObject and the
* object is a Measure, then the result of
* getNumber().getDouble(status) is returned. If this object is
* the status is set to U_INVALID_FORMAT_ERROR.
* @param status the error code
* @return the double value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
double getDouble(UErrorCode& status) const;
* as appropriate, is returned and the status is set to
* U_INVALID_FORMAT_ERROR. If this object is of type kInt64 and
* it fits within a long, then no precision is lost. If it is of
- * type kDouble, then a casting conversion is peformed, with
+ * type kDouble or kDecimalNumber, then a conversion is peformed, with
* truncation of any fractional part. If the type is kObject and
* the object is a Measure, then the result of
* getNumber().getLong(status) is returned. If this object is
* the status is set to U_INVALID_FORMAT_ERROR.
* @param status the error code
* @return the long value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
int32_t getLong(UErrorCode& status) const;
* Gets the int64 value of this object. If this object is not of type
* kInt64 then the result is undefined.
* @return the int64 value of this object.
- * @draft ICU 2.8
+ * @stable ICU 2.8
*/
int64_t getInt64(void) const { return fValue.fInt64; }
/**
- * Gets the int64 value of this object. If this object is of type
- * kDouble and the magnitude is too large to fit in an int64, then
+ * Gets the int64 value of this object. If this object is of a numeric
+ * type and the magnitude is too large to fit in an int64, then
* the maximum or minimum int64 value, as appropriate, is returned
* and the status is set to U_INVALID_FORMAT_ERROR. If the
* magnitude fits in an int64, then a casting conversion is
* the status is set to U_INVALID_FORMAT_ERROR.
* @param status the error code
* @return the int64 value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
int64_t getInt64(UErrorCode& status) const;
* undefined.
* @param status the error code.
* @return the Date value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
UDate getDate(UErrorCode& status) const;
* @param result Output param to receive the Date value of this object.
* @param status the error code.
* @return A reference to 'result'.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
UnicodeString& getString(UnicodeString& result, UErrorCode& status) const;
* U_INVALID_FORMAT_ERROR and the result is a bogus string.
* @param status the error code.
* @return a const reference to the string value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
const UnicodeString& getString(UErrorCode& status) const;
* and the result is a bogus string.
* @param status the error code.
* @return a reference to the string value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
UnicodeString& getString(UErrorCode& status);
* @param count fill-in with the count of this object.
* @param status the error code.
* @return the array value of this object.
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
const Formattable* getArray(int32_t& count, UErrorCode& status) const;
* Returns a pointer to the UObject contained within this
* formattable, or NULL if this object does not contain a UObject.
* @return a UObject pointer, or NULL
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
const UObject* getObject() const;
/**
+ * Returns a numeric string representation of the number contained within this
+ * formattable, or NULL if this object does not contain numeric type.
+ * For values obtained by parsing, the returned decimal number retains
+ * the full precision and range of the original input, unconstrained by
+ * the limits of a double floating point or a 64 bit int.
+ *
+ * This function is not thread safe, and therfore is not declared const,
+ * even though it is logically const.
+ *
+ * Possible errors include U_MEMORY_ALLOCATION_ERROR, and
+ * U_INVALID_STATE if the formattable object has not been set to
+ * a numeric type.
+ *
+ * @param status the error code.
+ * @return the unformatted string representation of a number.
+ * @stable ICU 4.4
+ */
+ StringPiece getDecimalNumber(UErrorCode &status);
+
+ /**
* Sets the double value of this object and changes the type to
* kDouble.
* @param d the new double value to be set.
* Sets the int64 value of this object and changes the type to
* kInt64.
* @param ll the new int64 value to be set.
- * @draft ICU 2.8
+ * @stable ICU 2.8
*/
void setInt64(int64_t ll);
* the type to kObject. After this call, the caller must not
* delete the given object.
* @param objectToAdopt the UObject value to be adopted
- * @draft ICU 3.0
+ * @stable ICU 3.0
*/
void adoptObject(UObject* objectToAdopt);
+ /**
+ * Sets the the numeric value from a decimal number string, and changes
+ * the type to to a numeric type appropriate for the number.
+ * The syntax of the number is a "numeric string"
+ * as defined in the Decimal Arithmetic Specification, available at
+ * http://speleotrove.com/decimal
+ * The full precision and range of the input number will be retained,
+ * even when it exceeds what can be represented by a double or an int64.
+ *
+ * @param numberString a string representation of the unformatted decimal number.
+ * @param status the error code. Set to U_INVALID_FORMAT_ERROR if the
+ * incoming string is not a valid decimal number.
+ * @stable ICU 4.4
+ */
+ void setDecimalNumber(const StringPiece &numberString,
+ UErrorCode &status);
+
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
*/
inline int32_t getLong(UErrorCode* status) const;
+ /**
+ * Internal function, do not use.
+ * TODO: figure out how to make this be non-public.
+ * NumberFormat::format(Formattable, ...
+ * needs to get at the DigitList, if it exists, for
+ * big decimal formatting.
+ * @internal
+ */
+ DigitList *getDigitList() const { return fDecimalNum;};
+
+ /**
+ * Adopt, and set value from, a DigitList
+ * Internal Function, do not use.
+ * @param dl the Digit List to be adopted
+ * @internal
+ */
+ void adoptDigitList(DigitList *dl);
+
private:
/**
* Cleans up the memory for unwanted values. For example, the adopted
void dispose(void);
/**
- * Creates a new Formattable array and copies the values from the specified
- * original.
- * @param array the original array
- * @param count the original array count
- * @return the new Formattable array.
+ * Common initialization, for use by constructors.
*/
- static Formattable* createArrayCopy(const Formattable* array, int32_t count);
+ void init();
UnicodeString* getBogus() const;
} fArrayAndCount;
} fValue;
+ CharString *fDecimalStr;
+ DigitList *fDecimalNum;
+
Type fType;
UnicodeString fBogus; // Bogus string when it's needed.
};
-inline Formattable*
-Formattable::createArrayCopy(const Formattable* array, int32_t count)
-{
- Formattable *result = new Formattable[count];
- for (int32_t i=0; i<count; ++i) result[i] = array[i]; // Don't memcpy!
- return result;
-}
-
inline UDate Formattable::getDate(UErrorCode& status) const {
if (fType != kDate) {
if (U_SUCCESS(status)) {
#endif //_FMTABLE
//eof
-