/* * Copyright (C) {1997-2001}, International Business Machines Corporation and others. All Rights Reserved. ******************************************************************************** * * File NUMFMT.H * * Modification History: * * Date Name Description * 02/19/97 aliu Converted from java. * 03/18/97 clhuang Updated per C++ implementation. * 04/17/97 aliu Changed DigitCount to int per code review. * 07/20/98 stephen JDK 1.2 sync up. Added scientific support. * Changed naming conventions to match C++ guidelines * Derecated Java style constants (eg, INTEGER_FIELD) ******************************************************************************** */ #ifndef NUMFMT_H #define NUMFMT_H #include "unicode/utypes.h" #include "unicode/unistr.h" #include "unicode/format.h" U_NAMESPACE_BEGIN class Locale; /** * Abstract base class for all number formats. Provides interface for * formatting and parsing a number. Also provides methods for * determining which locales have number formats, and what their names * are. *

* NumberFormat helps you to format and parse numbers for any locale. * Your code can be completely independent of the locale conventions * for decimal points, thousands-separators, or even the particular * decimal digits used, or whether the number format is even decimal. *

* To format a number for the current Locale, use one of the static * factory methods: *

 * \code
 *    double myNumber = 7.0;
 *    UnicodeString myString;
 *    UErrorCode success = U_ZERO_ERROR;
 *    NumberFormat* nf = NumberFormat::createInstance(success)
 *    nf->format(myNumber, myString);
 *    cout << " Example 1: " << myString << endl;
 * \endcode
 * 
* 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 * conventions multiple times. *
 * \code
 *     UnicodeString myString;
 *     UErrorCode success = U_ZERO_ERROR;
 *     nf = NumberFormat::createInstance( success );
 *     int32_t a[] = { 123, 3333, -1234567 };
 *     const int32_t a_len = sizeof(a) / sizeof(a[0]);
 *     myString.remove();
 *     for (int32_t i = 0; i < a_len; i++) {
 *         nf->format(a[i], myString);
 *         myString += " ; ";
 *     }
 *     cout << " Example 2: " << myString << endl;
 * \endcide
 * 
* To format a number for a different Locale, specify it in the * call to createInstance(). *
 * \code
 *     nf = NumberFormat::createInstance( Locale::FRENCH, success );
 * \endcode
 * 
* You can use a NumberFormat to parse also. *
 * \code
 *    UErrorCode success;
 *    Formattable result(-999);  // initialized with error code
 *    nf->parse(myString, result, success);
 * \endcode
 * 
* Use createInstance to get the normal number format for that country. * There are other static factory methods available. Use getCurrency * to get the currency number format for that country. Use getPercent * to get a format for displaying percentages. With this format, a * fraction from 0.53 is displayed as 53%. *

* 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 * try casting the NumberFormat you get from the factory methods to a * DecimalNumberFormat. This will work for the vast majority of * countries; just remember to put it in a try block in case you * encounter an unusual one. *

* You can also use forms of the parse and format methods with * ParsePosition and FieldPosition to allow you to: *

* For example, you can align numbers in two ways. *

* If you are using a monospaced font with spacing for alignment, you * can pass the FieldPosition in your format call, with field = * INTEGER_FIELD. On output, getEndIndex will be set to the offset * between the last character of the integer and the decimal. Add * (desiredSpaceCount - getEndIndex) spaces at the front of the * string. *

* If you are using proportional fonts, instead of padding with * spaces, measure the width of the string in pixels from the start to * getEndIndex. Then move the pen by (desiredPixelWidth - * widthToAlignmentPoint) before drawing the text. It also works * where there is no decimal, but possibly additional characters at * the end, e.g. with parentheses in negative numbers: "(12)" for -12. * @stable */ 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. * * @see FieldPosition * @stable */ enum EAlignmentFields { kIntegerField, kFractionField, /** * These constants are provided for backwards compatibility only, * and are deprecated. Please use the C++ style constants defined above. * @stable */ INTEGER_FIELD = kIntegerField, FRACTION_FIELD = kFractionField }; /** * Destructor. * @stable */ virtual ~NumberFormat(); /** * Return true if the given Format objects are semantically equal. * Objects of different subclasses are considered unequal. * @stable */ virtual UBool operator==(const Format& other) 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 toAppendTo Where the text is to be appended. * @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 The value passed in as toAppendTo (this allows chaining, * as with UnicodeString::append()) * @stable */ virtual UnicodeString& format(const Formattable& obj, UnicodeString& toAppendTo, FieldPosition& pos, UErrorCode& status) const; /** * Parse a string to produce an object. This methods handles * parsing of numeric strings into Formattable objects with numeric * types. *

* Before calling, set parse_pos.index to the offset you want to * start parsing at in the source. After calling, parse_pos.index * is the end of the text you parsed. If error occurs, index is * unchanged. *

* When parsing, leading whitespace is discarded (with successful * parse), while trailing whitespace is left as is. *

* See Format::parseObject() for more. * * @param source The string to be parsed into an object. * @param result Formattable to be set to the parse result. * If parse fails, return contents are undefined. * @param parse_pos The position to start parsing at. Upon return * this param is set to the position after the * last character successfully parsed. If the * source is not parsed successfully, this param * will remain unchanged. * @return A newly created Formattable* object, or NULL * on failure. The caller owns this and should * delete it when done. * @stable */ virtual void parseObject(const UnicodeString& source, Formattable& result, ParsePosition& parse_pos) const; /** * Format a double number. These methods call the NumberFormat * pure virtual format() methods with the default FieldPosition. * * @param number The value to be formatted. * @param output Output param with the formatted string. * @return A reference to 'output' param. * @stable */ UnicodeString& format( double number, UnicodeString& output) const; /** * Format a long number. These methods call the NumberFormat * pure virtual format() methods with the default FieldPosition. * * @param number The value to be formatted. * @param output Output param with the formatted string. * @return A reference to 'output' param. * @stable */ UnicodeString& format( int32_t number, UnicodeString& output) const; /** * Format a double number. Concrete subclasses must implement * these pure virtual methods. * * @param number The value to be formatted. * @param toAppendTo The string to append the formatted string to. * This is an output parameter. * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. * @return A reference to 'toAppendTo'. * @stable */ virtual UnicodeString& format(double number, UnicodeString& toAppendTo, FieldPosition& pos) const = 0; /** * Format a long number. Concrete subclasses must implement * these pure virtual methods. * * @param number The value to be formatted. * @param toAppendTo The string to append the formatted string to. * This is an output parameter. * @param pos On input: an alignment field, if desired. * On output: the offsets of the alignment field. * @return A reference to 'toAppendTo'. * @stable */ virtual UnicodeString& format(int32_t number, UnicodeString& toAppendTo, FieldPosition& pos) const = 0; /** * Redeclared Format method. * @stable */ UnicodeString& format(const Formattable& obj, UnicodeString& result, UErrorCode& status) const; /** * Return a long if possible (e.g. within range LONG_MAX, * LONG_MAX], and with no decimals), otherwise a double. If * IntegerOnly is set, will stop at a decimal point (or equivalent; * e.g. for rational numbers "1 2/3", will stop after the 1). *

* If no object can be parsed, index is unchanged, and NULL is * returned. *

* This is a pure virtual which concrete subclasses must implement. * * @param text The text to be parsed. * @param result Formattable to be set to the parse result. * If parse fails, return contents are undefined. * @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 */ virtual void parse(const UnicodeString& text, Formattable& result, ParsePosition& parsePosition) const = 0; /** * Parse a string as a numeric value, and return a Formattable * numeric object. This method parses integers only if IntegerOnly * is set. * * @param text The text to be parsed. * @param result Formattable to be set to the parse result. * If parse fails, return contents are undefined. * @param status Success or failure output parameter. * @return A Formattable object of numeric type. The caller * owns this an must delete it. NULL on failure. * @see NumberFormat::isParseIntegerOnly * @stable */ virtual void parse( const UnicodeString& text, Formattable& result, UErrorCode& status) const; /** * Return true if this format will parse numbers as integers * only. For example in the English locale, with ParseIntegerOnly * true, the string "1234." would be parsed as the integer value * 1234 and parsing would stop at the "." character. Of course, * the exact format accepted by the parse operation is locale * dependant and determined by sub-classes of NumberFormat. * @stable */ UBool isParseIntegerOnly(void) const; /** * Sets whether or not numbers should be parsed as integers only. * @see isParseIntegerOnly * @stable */ virtual void setParseIntegerOnly(UBool value); /** * Returns the default number format for the current default * locale. The default format is one of the styles provided by * the other factory methods: getNumberInstance, * getCurrencyInstance or getPercentInstance. Exactly which one * is locale dependant. * @stable */ static NumberFormat* createInstance(UErrorCode&); /** * Returns the default number format for the specified locale. * The default format is one of the styles provided by the other * factory methods: getNumberInstance, getCurrencyInstance or * getPercentInstance. Exactly which one is locale dependant. * @stable */ static NumberFormat* createInstance(const Locale& inLocale, UErrorCode&); /** * Returns a currency format for the current default locale. * @stable */ static NumberFormat* createCurrencyInstance(UErrorCode&); /** * Returns a currency format for the specified locale. * @stable */ static NumberFormat* createCurrencyInstance(const Locale& inLocale, UErrorCode&); /** * Returns a percentage format for the current default locale. * @stable */ static NumberFormat* createPercentInstance(UErrorCode&); /** * Returns a percentage format for the specified locale. * @stable */ static NumberFormat* createPercentInstance(const Locale& inLocale, UErrorCode&); /** * Returns a scientific format for the current default locale. * @stable */ static NumberFormat* createScientificInstance(UErrorCode&); /** * Returns a scientific format for the specified locale. * @stable */ static NumberFormat* createScientificInstance(const Locale& inLocale, UErrorCode&); /** * Get the set of Locales for which NumberFormats are installed. * @stable */ static const Locale* getAvailableLocales(int32_t& count); /** * Returns true if grouping is used in this format. For example, * in the English locale, with grouping on, the number 1234567 * might be formatted as "1,234,567". The grouping separator as * well as the size of each group is locale dependant and is * determined by sub-classes of NumberFormat. * @see setGroupingUsed * @stable */ UBool isGroupingUsed(void) const; /** * Set whether or not grouping will be used in this format. * @see getGroupingUsed * @stable */ virtual void setGroupingUsed(UBool newValue); /** * Returns the maximum number of digits allowed in the integer portion of a * number. * @see setMaximumIntegerDigits * @stable */ int32_t getMaximumIntegerDigits(void) const; /** * Sets the maximum number of digits allowed in the integer portion of a * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the * new value for maximumIntegerDigits is less than the current value * of minimumIntegerDigits, then minimumIntegerDigits will also be set to * the new value. * * @see getMaximumIntegerDigits * @stable */ virtual void setMaximumIntegerDigits(int32_t newValue); /** * Returns the minimum number of digits allowed in the integer portion of a * number. * @see setMinimumIntegerDigits * @stable */ int32_t getMinimumIntegerDigits(void) const; /** * Sets the minimum number of digits allowed in the integer portion of a * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the * new value for minimumIntegerDigits exceeds the current value * of maximumIntegerDigits, then maximumIntegerDigits will also be set to * the new value. * @see getMinimumIntegerDigits * @stable */ virtual void setMinimumIntegerDigits(int32_t newValue); /** * Returns the maximum number of digits allowed in the fraction portion of a * number. * @see setMaximumFractionDigits * @stable */ int32_t getMaximumFractionDigits(void) const; /** * Sets the maximum number of digits allowed in the fraction portion of a * number. maximumFractionDigits must be >= minimumFractionDigits. If the * new value for maximumFractionDigits is less than the current value * of minimumFractionDigits, then minimumFractionDigits will also be set to * the new value. * @see getMaximumFractionDigits * @stable */ virtual void setMaximumFractionDigits(int32_t newValue); /** * Returns the minimum number of digits allowed in the fraction portion of a * number. * @see setMinimumFractionDigits * @stable */ int32_t getMinimumFractionDigits(void) const; /** * Sets the minimum number of digits allowed in the fraction portion of a * number. minimumFractionDigits must be <= maximumFractionDigits. If the * new value for minimumFractionDigits exceeds the current value * of maximumFractionDigits, then maximumIntegerDigits will also be set to * the new value * @see getMinimumFractionDigits * @stable */ virtual void setMinimumFractionDigits(int32_t newValue); public: /** * Return the class ID for this class. This is useful only for * comparing to a return value from getDynamicClassID(). For example: *

     * .   Base* polymorphic_pointer = createPolymorphicObject();
     * .   if (polymorphic_pointer->getDynamicClassID() ==
     * .       Derived::getStaticClassID()) ...
     * 
* @return The class ID for all objects of this class. * @stable */ static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; } /** * Override Calendar * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. * This method is to implement a simple version of RTTI, since not all * C++ compilers support genuine RTTI. Polymorphic operator==() and * clone() methods call this method. *

* @return The class ID for this object. All objects of a * given class have the same class ID. Objects of * other classes have different class IDs. * @stable */ virtual UClassID getDynamicClassID(void) const { return getStaticClassID(); } protected: /** * Default constructor for subclass use only. * @stable */ NumberFormat(); /** * Copy constructor. * @stable */ NumberFormat(const NumberFormat&); /** * Assignment operator. * @stable */ NumberFormat& operator=(const NumberFormat&); protected: static const int32_t fgMaxIntegerDigits; static const int32_t fgMinIntegerDigits; private: static const char fgClassID; enum EStyles { kNumberStyle, kCurrencyStyle, kPercentStyle, kScientificStyle, kStyleCount // ALWAYS LAST ENUM: number of styles }; static NumberFormat* createInstance(const Locale& desiredLocale, EStyles choice, UErrorCode& success); static const int32_t fgNumberPatternsCount; static const UChar* const fgLastResortNumberPatterns[]; UBool fGroupingUsed; int32_t fMaxIntegerDigits; int32_t fMinIntegerDigits; int32_t fMaxFractionDigits; int32_t fMinFractionDigits; UBool fParseIntegerOnly; }; // ------------------------------------- inline UBool NumberFormat::isParseIntegerOnly() const { return fParseIntegerOnly; } inline UnicodeString& NumberFormat::format(const Formattable& obj, UnicodeString& result, UErrorCode& status) const { return Format::format(obj, result, status); } U_NAMESPACE_END #endif // _NUMFMT //eof