/*
********************************************************************************
-* Copyright (C) 1997-2009, International Business Machines Corporation and others.
+* Copyright (C) 1997-2014, International Business Machines Corporation and others.
* All Rights Reserved.
********************************************************************************
*
#include "unicode/utypes.h"
/**
- * \file
+ * \file
* \brief C++ API: Abstract base class for all number formats.
*/
-
+
#if !UCONFIG_NO_FORMATTING
#include "unicode/unistr.h"
#include "unicode/format.h"
#include "unicode/unum.h" // UNumberFormatStyle
#include "unicode/locid.h"
+#include "unicode/stringpiece.h"
+#include "unicode/curramt.h"
+#include "unicode/udisplaycontext.h"
+
+class NumberFormatTest;
U_NAMESPACE_BEGIN
+class SharedNumberFormat;
+
#if !UCONFIG_NO_SERVICE
class NumberFormatFactory;
class StringEnumeration;
* cout << " Example 1: " << myString << endl;
* \endcode
* </pre>
+ * Note that there are additional factory methods within subclasses of
+ * NumberFormat.
+ * <P>
* If you are formatting multiple numbers, it is more efficient to get
* the format and use it multiple times so that the system doesn't
* have to fetch the information about the local language and country
* to get a format for displaying percentages. With this format, a
* fraction from 0.53 is displayed as 53%.
* <P>
+ * Starting from ICU 4.2, you can use createInstance() by passing in a 'style'
+ * as parameter to get the correct instance.
+ * For example,
+ * use createInstance(...kNumberStyle...) to get the normal number format,
+ * createInstance(...kPercentStyle...) to get a format for displaying
+ * percentage,
+ * createInstance(...kScientificStyle...) to get a format for displaying
+ * scientific number,
+ * createInstance(...kCurrencyStyle...) to get the currency number format,
+ * in which the currency is represented by its symbol, for example, "$3.00".
+ * createInstance(...kIsoCurrencyStyle...) to get the currency number format,
+ * in which the currency is represented by its ISO code, for example "USD3.00".
+ * createInstance(...kPluralCurrencyStyle...) to get the currency number format,
+ * in which the currency is represented by its full name in plural format,
+ * for example, "3.00 US dollars" or "1.00 US dollar".
+ * <P>
* You can also control the display of numbers with such methods as
* getMinimumFractionDigits. If you want even more control over the
* format or parsing, or want to give your users more control, you can
*/
class U_I18N_API NumberFormat : public Format {
public:
-
/**
* Alignment Field constants used to construct a FieldPosition object.
* Signifies that the position of the integer part or fraction part of
* a formatted number should be returned.
*
+ * Note: as of ICU 4.4, the values in this enum have been extended to
+ * support identification of all number format fields, not just those
+ * pertaining to alignment.
+ *
+ * These constants are provided for backwards compatibility only.
+ * Please use the C style constants defined in the header file unum.h.
+ *
* @see FieldPosition
* @stable ICU 2.0
*/
enum EAlignmentFields {
- kIntegerField,
- kFractionField,
-
+ /** @stable ICU 2.0 */
+ kIntegerField = UNUM_INTEGER_FIELD,
+ /** @stable ICU 2.0 */
+ kFractionField = UNUM_FRACTION_FIELD,
+ /** @stable ICU 2.0 */
+ kDecimalSeparatorField = UNUM_DECIMAL_SEPARATOR_FIELD,
+ /** @stable ICU 2.0 */
+ kExponentSymbolField = UNUM_EXPONENT_SYMBOL_FIELD,
+ /** @stable ICU 2.0 */
+ kExponentSignField = UNUM_EXPONENT_SIGN_FIELD,
+ /** @stable ICU 2.0 */
+ kExponentField = UNUM_EXPONENT_FIELD,
+ /** @stable ICU 2.0 */
+ kGroupingSeparatorField = UNUM_GROUPING_SEPARATOR_FIELD,
+ /** @stable ICU 2.0 */
+ kCurrencyField = UNUM_CURRENCY_FIELD,
+ /** @stable ICU 2.0 */
+ kPercentField = UNUM_PERCENT_FIELD,
+ /** @stable ICU 2.0 */
+ kPermillField = UNUM_PERMILL_FIELD,
+ /** @stable ICU 2.0 */
+ kSignField = UNUM_SIGN_FIELD,
/**
* These constants are provided for backwards compatibility only.
- * Please use the C++ style constants defined above.
- * @stable ICU 2.0
+ * Please use the constants defined in the header file unum.h.
*/
- INTEGER_FIELD = kIntegerField,
- FRACTION_FIELD = kFractionField
+ /** @stable ICU 2.0 */
+ INTEGER_FIELD = UNUM_INTEGER_FIELD,
+ /** @stable ICU 2.0 */
+ FRACTION_FIELD = UNUM_FRACTION_FIELD
};
/**
*/
virtual UBool operator==(const Format& other) const;
+
+ using Format::format;
+
/**
* Format an object to produce a string. This method handles
* Formattable objects with numeric types. If the Formattable
FieldPosition& pos,
UErrorCode& status) const;
+ /**
+ * Format an object to produce a string. This method handles
+ * Formattable objects with numeric types. If the Formattable
+ * object type is not a numeric type, then it returns a failing
+ * UErrorCode.
+ *
+ * @param obj The object to format.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param posIter On return, can be used to iterate over positions
+ * of fields generated by this format call. Can be
+ * NULL.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @stable 4.4
+ */
+ virtual UnicodeString& format(const Formattable& obj,
+ UnicodeString& appendTo,
+ FieldPositionIterator* posIter,
+ UErrorCode& status) const;
+
/**
* Parse a string to produce an object. This methods handles
* parsing of numeric strings into Formattable objects with numeric
virtual UnicodeString& format(double number,
UnicodeString& appendTo,
FieldPosition& pos) const = 0;
+ /**
+ * Format a double number. By default, the parent function simply
+ * calls the base class and does not return an error status.
+ * Therefore, the status may be ignored in some subclasses.
+ *
+ * @param number The value to be formatted.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param pos On input: an alignment field, if desired.
+ * On output: the offsets of the alignment field.
+ * @param status error status
+ * @return Reference to 'appendTo' parameter.
+ * @internal
+ */
+ virtual UnicodeString& format(double number,
+ UnicodeString& appendTo,
+ FieldPosition& pos,
+ UErrorCode &status) const;
+ /**
+ * Format a double number. Subclasses must implement
+ * this method.
+ *
+ * @param number The value to be formatted.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param posIter On return, can be used to iterate over positions
+ * of fields generated by this format call.
+ * Can be NULL.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @stable 4.4
+ */
+ virtual UnicodeString& format(double number,
+ UnicodeString& appendTo,
+ FieldPositionIterator* posIter,
+ UErrorCode& status) const;
/**
* Format a long number. Concrete subclasses must implement
* these pure virtual methods.
UnicodeString& appendTo,
FieldPosition& pos) const = 0;
+ /**
+ * Format a long number. Concrete subclasses may override
+ * this function to provide status return.
+ *
+ * @param number The value to be formatted.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param pos On input: an alignment field, if desired.
+ * On output: the offsets of the alignment field.
+ * @param status the output status.
+ * @return Reference to 'appendTo' parameter.
+ * @internal
+ */
+ virtual UnicodeString& format(int32_t number,
+ UnicodeString& appendTo,
+ FieldPosition& pos,
+ UErrorCode &status) const;
+
+ /**
+ * Format an int32 number. Subclasses must implement
+ * this method.
+ *
+ * @param number The value to be formatted.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param posIter On return, can be used to iterate over positions
+ * of fields generated by this format call.
+ * Can be NULL.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @stable 4.4
+ */
+ virtual UnicodeString& format(int32_t number,
+ UnicodeString& appendTo,
+ FieldPositionIterator* posIter,
+ UErrorCode& status) const;
/**
* Format an int64 number. (Not abstract to retain compatibility
* with earlier releases, however subclasses should override this
virtual UnicodeString& format(int64_t number,
UnicodeString& appendTo,
FieldPosition& pos) const;
+
/**
- * Redeclared Format method.
- * @param obj The object to be formatted.
+ * Format an int64 number. (Not abstract to retain compatibility
+ * with earlier releases, however subclasses should override this
+ * method as it just delegates to format(int32_t number...);
+ *
+ * @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
- * @param status Output parameter set to a failure error code
- * when a failure occurs.
+ * @param pos On input: an alignment field, if desired.
+ * On output: the offsets of the alignment field.
* @return Reference to 'appendTo' parameter.
- * @stable ICU 2.0
+ * @internal
+ */
+ virtual UnicodeString& format(int64_t number,
+ UnicodeString& appendTo,
+ FieldPosition& pos,
+ UErrorCode& status) const;
+ /**
+ * Format an int64 number. Subclasses must implement
+ * this method.
+ *
+ * @param number The value to be formatted.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param posIter On return, can be used to iterate over positions
+ * of fields generated by this format call.
+ * Can be NULL.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @stable 4.4
+ */
+ virtual UnicodeString& format(int64_t number,
+ UnicodeString& appendTo,
+ FieldPositionIterator* posIter,
+ UErrorCode& status) const;
+
+ /**
+ * Format a decimal number. Subclasses must implement
+ * this method. The syntax of the unformatted number is a "numeric string"
+ * as defined in the Decimal Arithmetic Specification, available at
+ * http://speleotrove.com/decimal
+ *
+ * @param number The unformatted number, as a string, to be formatted.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param posIter On return, can be used to iterate over positions
+ * of fields generated by this format call.
+ * Can be NULL.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @stable 4.4
*/
- UnicodeString& format(const Formattable& obj,
- UnicodeString& appendTo,
- UErrorCode& status) const;
+ virtual UnicodeString& format(const StringPiece &number,
+ UnicodeString& appendTo,
+ FieldPositionIterator* posIter,
+ UErrorCode& status) const;
+public:
+ /**
+ * Format a decimal number.
+ * The number is a DigitList wrapper onto a floating point decimal number.
+ * The default implementation in NumberFormat converts the decimal number
+ * to a double and formats that. Subclasses of NumberFormat that want
+ * to specifically handle big decimal numbers must override this method.
+ * class DecimalFormat does so.
+ *
+ * @param number The number, a DigitList format Decimal Floating Point.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param posIter On return, can be used to iterate over positions
+ * of fields generated by this format call.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @internal
+ */
+ virtual UnicodeString& format(const DigitList &number,
+ UnicodeString& appendTo,
+ FieldPositionIterator* posIter,
+ UErrorCode& status) const;
+
+ /**
+ * Format a decimal number.
+ * The number is a DigitList wrapper onto a floating point decimal number.
+ * The default implementation in NumberFormat converts the decimal number
+ * to a double and formats that. Subclasses of NumberFormat that want
+ * to specifically handle big decimal numbers must override this method.
+ * class DecimalFormat does so.
+ *
+ * @param number The number, a DigitList format Decimal Floating Point.
+ * @param appendTo Output parameter to receive result.
+ * Result is appended to existing contents.
+ * @param pos On input: an alignment field, if desired.
+ * On output: the offsets of the alignment field.
+ * @param status Output param filled with success/failure status.
+ * @return Reference to 'appendTo' parameter.
+ * @internal
+ */
+ virtual UnicodeString& format(const DigitList &number,
+ UnicodeString& appendTo,
+ FieldPosition& pos,
+ UErrorCode& status) const;
+
+public:
/**
* Return a long if possible (e.g. within range LONG_MAX,
* @param parsePosition The position to start parsing at on input.
* On output, moved to after the last successfully
* parse character. On parse failure, does not change.
- * @return A Formattable object of numeric type. The caller
- * owns this an must delete it. NULL on failure.
* @stable ICU 2.0
*/
virtual void parse(const UnicodeString& text,
* If parse fails, return contents are undefined.
* @param status Output parameter set to a failure error code
* when a failure occurs.
- * @return A Formattable object of numeric type. The caller
- * owns this an must delete it. NULL on failure.
* @see NumberFormat::isParseIntegerOnly
* @stable ICU 2.0
*/
- virtual void parse( const UnicodeString& text,
- Formattable& result,
- UErrorCode& status) const;
+ virtual void parse(const UnicodeString& text,
+ Formattable& result,
+ UErrorCode& status) const;
/**
* Parses text from the given string as a currency amount. Unlike
* (U+00A4) in its prefix or suffix.
*
* @param text the string to parse
- * @param result output parameter to receive result. This will have
- * its currency set to the parsed ISO currency code.
- * @param pos input-output position; on input, the position within
- * text to match; must have 0 <= pos.getIndex() < text.length();
- * on output, the position after the last matched character. If
- * the parse fails, the position in unchanged upon output.
- * @return a reference to result
- * @internal
+ * @param pos input-output position; on input, the position within text
+ * to match; must have 0 <= pos.getIndex() < text.length();
+ * on output, the position after the last matched character.
+ * If the parse fails, the position in unchanged upon output.
+ * @return if parse succeeds, a pointer to a newly-created CurrencyAmount
+ * object (owned by the caller) containing information about
+ * the parsed currency; if parse fails, this is NULL.
+ * @stable ICU 49
*/
- virtual Formattable& parseCurrency(const UnicodeString& text,
- Formattable& result,
- ParsePosition& pos) const;
+ virtual CurrencyAmount* parseCurrency(const UnicodeString& text,
+ ParsePosition& pos) const;
/**
* Return true if this format will parse numbers as integers
* @stable ICU 2.0
*/
virtual void setParseIntegerOnly(UBool value);
-
+
/**
- * Return whether or not strict parsing is in effect.
+ * Sets whether lenient parsing should be enabled (it is off by default).
*
- * @return <code>TRUE</code> if strict parsing is in effect,
- * <code>FALSE</code> otherwise.
- * @internal
+ * @param enable <code>TRUE</code> if lenient parsing should be used,
+ * <code>FALSE</code> otherwise.
+ * @stable ICU 4.8
*/
- UBool isParseStrict(void) const;
-
+ virtual void setLenient(UBool enable);
+
/**
- * Set whether or not strict parsing should be used.
+ * Returns whether lenient parsing is enabled (it is off by default).
*
- * @param value <code>TRUE</code> if strict parsing should be used,
- * <code>FALSE</code> otherwise.
- * @internal
+ * @return <code>TRUE</code> if lenient parsing is enabled,
+ * <code>FALSE</code> otherwise.
+ * @see #setLenient
+ * @stable ICU 4.8
*/
- virtual void setParseStrict(UBool value);
-
+ virtual UBool isLenient(void) const;
+
/**
* Returns the default number format for the current default
* locale. The default format is one of the styles provided by
static NumberFormat* U_EXPORT2 createInstance(const Locale& inLocale,
UErrorCode&);
+ /**
+ * Creates the specified decimal format style of the desired locale.
+ * @param desiredLocale the given locale.
+ * @param style the given style.
+ * @param errorCode Output param filled with success/failure status.
+ * @return A new NumberFormat instance.
+ * @stable ICU 4.8
+ */
+ static NumberFormat* U_EXPORT2 createInstance(const Locale& desiredLocale,
+ UNumberFormatStyle style,
+ UErrorCode& errorCode);
+
+#ifndef U_HIDE_INTERNAL_API
+
+ /**
+ * ICU use only.
+ * Creates NumberFormat instance without using the cache.
+ * @internal
+ */
+ static NumberFormat* internalCreateInstance(
+ const Locale& desiredLocale,
+ UNumberFormatStyle style,
+ UErrorCode& errorCode);
+
+ /**
+ * ICU use only.
+ * Returns handle to the shared, cached NumberFormat instance for given
+ * locale. On success, caller must call removeRef() on returned value
+ * once it is done with the shared instance.
+ * @internal
+ */
+ static const SharedNumberFormat* U_EXPORT2 createSharedInstance(
+ const Locale& inLocale, UNumberFormatStyle style, UErrorCode& status);
+
+#endif
+
/**
* Returns a currency format for the current default locale.
* @stable ICU 2.0
#if !UCONFIG_NO_SERVICE
/**
* Register a new NumberFormatFactory. The factory will be adopted.
+ * Because ICU may choose to cache NumberFormat objects internally,
+ * this must be called at application startup, prior to any calls to
+ * NumberFormat::createInstance to avoid undefined behavior.
* @param toAdopt the NumberFormatFactory instance to be adopted
* @param status the in/out status code, no special meanings are assigned
* @return a registry key that can be used to unregister this factory
* Unregister a previously-registered NumberFormatFactory using the key returned from the
* register call. Key becomes invalid after a successful call and should not be used again.
* The NumberFormatFactory corresponding to the key will be deleted.
+ * Because ICU may choose to cache NumberFormat objects internally,
+ * this should be called during application shutdown, after all calls to
+ * NumberFormat::createInstance to avoid undefined behavior.
* @param key the registry key returned by a previous call to registerFactory
* @param status the in/out status code, no special meanings are assigned
* @return TRUE if the factory for the key was successfully unregistered
*/
const UChar* getCurrency() const;
+ /* Cannot use #ifndef U_HIDE_DRAFT_API for the following draft method since it is virtual */
+ /**
+ * Set a particular UDisplayContext value in the formatter, such as
+ * UDISPCTX_CAPITALIZATION_FOR_STANDALONE.
+ * @param value The UDisplayContext value to set.
+ * @param status Input/output status. If at entry this indicates a failure
+ * status, the function will do nothing; otherwise this will be
+ * updated with any new status from the function.
+ * @draft ICU 53
+ */
+ virtual void setContext(UDisplayContext value, UErrorCode& status);
+
+ /* Cannot use #ifndef U_HIDE_DRAFT_API for the following draft method since it is virtual */
+ /**
+ * Get the formatter's UDisplayContext value for the specified UDisplayContextType,
+ * such as UDISPCTX_TYPE_CAPITALIZATION.
+ * @param type The UDisplayContextType whose value to return
+ * @param status Input/output status. If at entry this indicates a failure
+ * status, the function will do nothing; otherwise this will be
+ * updated with any new status from the function.
+ * @return The UDisplayContextValue for the specified type.
+ * @draft ICU 53
+ */
+ virtual UDisplayContext getContext(UDisplayContextType type, UErrorCode& status) const;
+
public:
/**
*/
virtual void getEffectiveCurrency(UChar* result, UErrorCode& ec) const;
-private:
-
- enum EStyles {
- kNumberStyle,
- kCurrencyStyle,
- kPercentStyle,
- kScientificStyle,
- kStyleCount // ALWAYS LAST ENUM: number of styles
- };
-
+#ifndef U_HIDE_INTERNAL_API
/**
- * Creates the specified decimal format style of the desired locale.
- * Hook for service registration, uses makeInstance directly if no services
- * registered.
- * @param desiredLocale the given locale.
- * @param choice the given style.
- * @param success Output param filled with success/failure status.
- * @return A new NumberFormat instance.
+ * Creates the specified number format style of the desired locale.
+ * If mustBeDecimalFormat is TRUE, then the returned pointer is
+ * either a DecimalFormat or it is NULL.
+ * @internal
*/
- static NumberFormat* U_EXPORT2 createInstance(const Locale& desiredLocale, EStyles choice, UErrorCode& success);
+ static NumberFormat* makeInstance(const Locale& desiredLocale,
+ UNumberFormatStyle style,
+ UBool mustBeDecimalFormat,
+ UErrorCode& errorCode);
+#endif /* U_HIDE_INTERNAL_API */
+
+private:
+
+ static UBool isStyleSupported(UNumberFormatStyle style);
/**
* Creates the specified decimal format style of the desired locale.
* @param desiredLocale the given locale.
- * @param choice the given style.
- * @param success Output param filled with success/failure status.
+ * @param style the given style.
+ * @param errorCode Output param filled with success/failure status.
* @return A new NumberFormat instance.
*/
- static NumberFormat* makeInstance(const Locale& desiredLocale, EStyles choice, UErrorCode& success);
-
- UBool fGroupingUsed;
- int32_t fMaxIntegerDigits;
- int32_t fMinIntegerDigits;
- int32_t fMaxFractionDigits;
- int32_t fMinFractionDigits;
+ static NumberFormat* makeInstance(const Locale& desiredLocale,
+ UNumberFormatStyle style,
+ UErrorCode& errorCode);
+
+ UBool fGroupingUsed;
+ int32_t fMaxIntegerDigits;
+ int32_t fMinIntegerDigits;
+ int32_t fMaxFractionDigits;
+ int32_t fMinFractionDigits;
+
+ protected:
+ static const int32_t gDefaultMaxIntegerDigits;
+ static const int32_t gDefaultMinIntegerDigits;
+
+ private:
UBool fParseIntegerOnly;
- UBool fParseStrict;
+ UBool fLenient; // TRUE => lenient parse is enabled
// ISO currency code
UChar fCurrency[4];
- friend class ICUNumberFormatFactory; // access to makeInstance, EStyles
+ UDisplayContext fCapitalizationContext;
+
+ friend class ICUNumberFormatFactory; // access to makeInstance
friend class ICUNumberFormatService;
+ friend class ::NumberFormatTest; // access to isStyleSupported()
};
#if !UCONFIG_NO_SERVICE
}
inline UBool
-NumberFormat::isParseStrict() const
+NumberFormat::isLenient() const
{
- return fParseStrict;
-}
-
-inline UnicodeString&
-NumberFormat::format(const Formattable& obj,
- UnicodeString& appendTo,
- UErrorCode& status) const {
- return Format::format(obj, appendTo, status);
+ return fLenient;
}
U_NAMESPACE_END