X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..0f5d89e82340278ed3d7d50029f37cab2c41a57e:/icuSources/i18n/unicode/decimfmt.h diff --git a/icuSources/i18n/unicode/decimfmt.h b/icuSources/i18n/unicode/decimfmt.h index 03313804..a331051d 100644 --- a/icuSources/i18n/unicode/decimfmt.h +++ b/icuSources/i18n/unicode/decimfmt.h @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************** -* Copyright (C) 1997-2003, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************** * @@ -17,63 +19,95 @@ * 07/10/97 helena Made ParsePosition a class and get rid of the function * hiding problems. * 09/09/97 aliu Ported over support for exponential formats. -* 07/20/98 stephen Changed documentation +* 07/20/98 stephen Changed documentation +* 01/30/13 emmons Added Scaling methods ******************************************************************************** */ - + #ifndef DECIMFMT_H #define DECIMFMT_H - + #include "unicode/utypes.h" +/** + * \file + * \brief C++ API: Compatibility APIs for decimal formatting. + */ #if !UCONFIG_NO_FORMATTING #include "unicode/dcfmtsym.h" #include "unicode/numfmt.h" #include "unicode/locid.h" +#include "unicode/fpositer.h" +#include "unicode/stringpiece.h" +#include "unicode/curramt.h" +#include "unicode/enumset.h" +#ifndef U_HIDE_INTERNAL_API +/** + * \def UNUM_DECIMALFORMAT_INTERNAL_SIZE + * @internal + */ +#if UCONFIG_FORMAT_FASTPATHS_49 +#define UNUM_DECIMALFORMAT_INTERNAL_SIZE 16 +#endif +#endif /* U_HIDE_INTERNAL_API */ + +#if U_SHOW_CPLUSPLUS_API U_NAMESPACE_BEGIN class DigitList; -class ChoiceFormat; +class CurrencyPluralInfo; +class Hashtable; +class UnicodeSet; +class FieldPositionHandler; +class DecimalFormatStaticSets; +class FixedDecimal; +class DecimalFormatImpl; +class PluralRules; +class VisibleDigitsWithExponent; + +// explicit template instantiation. see digitlst.h +// (When building DLLs for Windows this is required.) +#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN +template class U_I18N_API EnumSet; +#endif /** - * Concrete class for formatting decimal numbers, allowing a variety - * of parameters, and localization to Western, Arabic, or Indic numbers. - *

- * Normally, you get the proper NumberFormat for a specific locale - * (including the default locale) using the NumberFormat factory methods, - * rather than constructing a DecimalNumberFormat directly. - *

- * Either the prefixes or the suffixes must be different for the parse - * to distinguish positive from negative. Parsing will be unreliable - * if the digits, thousands or decimal separators are the same, or if - * any of them occur in the prefixes or suffixes. - *

- * [Special cases:] - *

- * NaN is formatted as a single character, typically \\uFFFD. - *

- * +/-Infinity is formatted as a single character, typically \\u221E, - * plus the positive and negative pre/suffixes. - *

- * Note: this class is designed for common users; for very large or small - * numbers, use a format that can express exponential values. - *

- * [Example:] - *

+ * 

IMPORTANT: New users are strongly encouraged to see if + * numberformatter.h fits their use case. Although not deprecated, this header + * is provided for backwards compatibility only. + *


+ * + * DecimalFormat is a concrete subclass of NumberFormat that formats decimal + * numbers. It has a variety of features designed to make it possible to parse + * and format numbers in any locale, including support for Western, Arabic, or + * Indic digits. It also supports different flavors of numbers, including + * integers ("123"), fixed-point numbers ("123.4"), scientific notation + * ("1.23E4"), percentages ("12%"), and currency amounts ("$123", "USD123", + * "123 US dollars"). All of these flavors can be easily localized. + * + *

To obtain a NumberFormat for a specific locale (including the default + * locale) call one of NumberFormat's factory methods such as + * createInstance(). Do not call the DecimalFormat constructors directly, unless + * you know what you are doing, since the NumberFormat factory methods may + * return subclasses other than DecimalFormat. + * + *

Example Usage + * * \code - * // normally we would have a GUI with a menu for this + * // Normally we would have a GUI with a menu for this * int32_t locCount; * const Locale* locales = NumberFormat::getAvailableLocales(locCount); - * if (locCount > 12) locCount = 12; //limit output - * + * * double myNumber = -1234.56; * UErrorCode success = U_ZERO_ERROR; - * NumberFormat* form; //= NumberFormat::createInstance(success); - * - * // just for fun, we print out a number with the locale number, currency - * // and percent format for each locale we can. + * NumberFormat* form; + * + * // Print out a number with the localized number, currency and percent + * // format for each locale. * UnicodeString countryName; * UnicodeString displayName; * UnicodeString str; @@ -87,11 +121,11 @@ class ChoiceFormat; * continue; * } * switch (j) { - * default: + * case 0: * form = NumberFormat::createInstance(locales[i], success ); break; * case 1: * form = NumberFormat::createCurrencyInstance(locales[i], success ); break; - * case 0: + * default: * form = NumberFormat::createPercentInstance(locales[i], success ); break; * } * if (form) { @@ -100,106 +134,550 @@ class ChoiceFormat; * cout << locales[i].getDisplayName(displayName) << ": " << pattern; * cout << " -> " << form->format(myNumber,str) << endl; * form->parse(form->format(myNumber,str), fmtable, success); - * //cout << " parsed: " << fmtable << endl; - * delete form; + * delete form; * } * } * } * \endcode - *

- * [The following shows the structure of the pattern.] - *
- * \code
- *     pattern    := subpattern{;subpattern}
- *     subpattern := {prefix}integer{.fraction}{suffix}
- *     
- *     prefix     := '\\u0000'..'\\uFFFD' - specialCharacters
- *     suffix     := '\\u0000'..'\\uFFFD' - specialCharacters
- *     integer    := '#'* '0'* '0'
- *     fraction   := '0'* '#'*
- *   
- *  Notation:
- *     X*       0 or more instances of X
- *     (X | Y)  either X or Y.
- *     X..Y     any character from X up to Y, inclusive.
- *     S - T    characters in S, except those in T
- * \code
- * /pre>
- * The first subpattern is for positive numbers. The second (optional)
- * subpattern is used for negative numbers. (In both cases, ',' can
- * occur inside the integer portion--it is just too messy to indicate
- * in BNF.)  For the second subpattern, only the PREFIX and SUFFIX are
- * noted; other attributes are taken only from the first subpattern.
  * 

- * Here are the special characters used in the parts of the - * subpattern, with notes on their usage. + * Another example use createInstance(style) + *

*

- * \code
- *     Symbol   Meaning
- *       0      a digit, showing up a zero if it is zero
- *       #      a digit, supressed if zero
- *       .      placeholder for decimal separator
- *       ,      placeholder for grouping separator.
- *       E      separates mantissa and exponent for exponential formats.
- *       ;      separates formats.
- *       -      default negative prefix.
- *       %      multiply by 100 and show as percentage
- *       \u2030 multiply by 1000 and show as per mille
- *       \u00A4 currency sign; replaced by currency symbol; if
- *              doubled, replaced by international currency symbol.
- *              If present in a pattern, the monetary decimal separator
- *              is used instead of the decimal separator.
- *       X      any other characters can be used in the prefix or suffix
- *       '      used to quote special characters in a prefix or suffix.
- * \endcode
+ * // Print out a number using the localized number, currency,
+ * // percent, scientific, integer, iso currency, and plural currency
+ * // format for each locale
+ * Locale* locale = new Locale("en", "US");
+ * double myNumber = 1234.56;
+ * UErrorCode success = U_ZERO_ERROR;
+ * UnicodeString str;
+ * Formattable fmtable;
+ * for (int j=NumberFormat::kNumberStyle;
+ *      j<=NumberFormat::kPluralCurrencyStyle;
+ *      ++j) {
+ *     NumberFormat* format = NumberFormat::createInstance(locale, j, success);
+ *     str.remove();
+ *     cout << "format result " << form->format(myNumber, str) << endl;
+ *     format->parse(form->format(myNumber, str), fmtable, success);
+ * }
+ * + * + *

Patterns + * + *

A DecimalFormat consists of a pattern and a set of + * symbols. The pattern may be set directly using + * applyPattern(), or indirectly using other API methods which + * manipulate aspects of the pattern, such as the minimum number of integer + * digits. The symbols are stored in a DecimalFormatSymbols + * object. When using the NumberFormat factory methods, the + * pattern and symbols are read from ICU's locale data. + * + *

Special Pattern Characters + * + *

Many characters in a pattern are taken literally; they are matched during + * parsing and output unchanged during formatting. Special characters, on the + * other hand, stand for other characters, strings, or classes of characters. + * For example, the '#' character is replaced by a localized digit. Often the + * replacement character is the same as the pattern character; in the U.S. locale, + * the ',' grouping character is replaced by ','. However, the replacement is + * still happening, and if the symbols are modified, the grouping character + * changes. Some special characters affect the behavior of the formatter by + * their presence; for example, if the percent character is seen, then the + * value is multiplied by 100 before being displayed. + * + *

To insert a special character in a pattern as a literal, that is, without + * any special meaning, the character must be quoted. There are some exceptions to + * this which are noted below. + * + *

The characters listed here are used in non-localized patterns. Localized + * patterns use the corresponding characters taken from this formatter's + * DecimalFormatSymbols object instead, and these characters lose + * their special status. Two exceptions are the currency sign and quote, which + * are not localized. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Symbol + * Location + * Localized? + * Meaning + *
0 + * Number + * Yes + * Digit + *
1-9 + * Number + * Yes + * '1' through '9' indicate rounding. + *
\htmlonly@\endhtmlonly + * Number + * No + * Significant digit + *
# + * Number + * Yes + * Digit, zero shows as absent + *
. + * Number + * Yes + * Decimal separator or monetary decimal separator + *
- + * Number + * Yes + * Minus sign + *
, + * Number + * Yes + * Grouping separator + *
E + * Number + * Yes + * Separates mantissa and exponent in scientific notation. + * Need not be quoted in prefix or suffix. + *
+ + * Exponent + * Yes + * Prefix positive exponents with localized plus sign. + * Need not be quoted in prefix or suffix. + *
; + * Subpattern boundary + * Yes + * Separates positive and negative subpatterns + *
\% + * Prefix or suffix + * Yes + * Multiply by 100 and show as percentage + *
\\u2030 + * Prefix or suffix + * Yes + * Multiply by 1000 and show as per mille + *
\htmlonly¤\endhtmlonly (\\u00A4) + * Prefix or suffix + * No + * Currency sign, replaced by currency symbol. If + * doubled, replaced by international currency symbol. + * If tripled, replaced by currency plural names, for example, + * "US dollar" or "US dollars" for America. + * If present in a pattern, the monetary decimal separator + * is used instead of the decimal separator. + *
' + * Prefix or suffix + * No + * Used to quote special characters in a prefix or suffix, + * for example, "'#'#" formats 123 to + * "#123". To create a single quote + * itself, use two in a row: "# o''clock". + *
* + * Prefix or suffix boundary + * Yes + * Pad escape, precedes pad character + *
+ * + *

A DecimalFormat pattern contains a postive and negative + * subpattern, for example, "#,##0.00;(#,##0.00)". Each subpattern has a + * prefix, a numeric part, and a suffix. If there is no explicit negative + * subpattern, the negative subpattern is the localized minus sign prefixed to the + * positive subpattern. That is, "0.00" alone is equivalent to "0.00;-0.00". If there + * is an explicit negative subpattern, it serves only to specify the negative + * prefix and suffix; the number of digits, minimal digits, and other + * characteristics are ignored in the negative subpattern. That means that + * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)". + * + *

The prefixes, suffixes, and various symbols used for infinity, digits, + * thousands separators, decimal separators, etc. may be set to arbitrary + * values, and they will appear properly during formatting. However, care must + * be taken that the symbols and strings do not conflict, or parsing will be + * unreliable. For example, either the positive and negative prefixes or the + * suffixes must be distinct for parse() to be able + * to distinguish positive from negative values. Another example is that the + * decimal separator and thousands separator should be distinct characters, or + * parsing will be impossible. + * + *

The grouping separator is a character that separates clusters of + * integer digits to make large numbers more legible. It commonly used for + * thousands, but in some locales it separates ten-thousands. The grouping + * size is the number of digits between the grouping separators, such as 3 + * for "100,000,000" or 4 for "1 0000 0000". There are actually two different + * grouping sizes: One used for the least significant integer digits, the + * primary grouping size, and one used for all others, the + * secondary grouping size. In most locales these are the same, but + * sometimes they are different. For example, if the primary grouping interval + * is 3, and the secondary is 2, then this corresponds to the pattern + * "#,##,##0", and the number 123456789 is formatted as "12,34,56,789". If a + * pattern contains multiple grouping separators, the interval between the last + * one and the end of the integer defines the primary grouping size, and the + * interval between the last two defines the secondary grouping size. All others + * are ignored, so "#,##,###,####" == "###,###,####" == "##,#,###,####". + * + *

Illegal patterns, such as "#.#.#" or "#.###,###", will cause + * DecimalFormat to set a failing UErrorCode. + * + *

Pattern BNF + * + *

+ * pattern    := subpattern (';' subpattern)?
+ * subpattern := prefix? number exponent? suffix?
+ * number     := (integer ('.' fraction)?) | sigDigits
+ * prefix     := '\\u0000'..'\\uFFFD' - specialCharacters
+ * suffix     := '\\u0000'..'\\uFFFD' - specialCharacters
+ * integer    := '#'* '0'* '0'
+ * fraction   := '0'* '#'*
+ * sigDigits  := '#'* '@' '@'* '#'*
+ * exponent   := 'E' '+'? '0'* '0'
+ * padSpec    := '*' padChar
+ * padChar    := '\\u0000'..'\\uFFFD' - quote
+ *  
+ * Notation:
+ *   X*       0 or more instances of X
+ *   X?       0 or 1 instances of X
+ *   X|Y      either X or Y
+ *   C..D     any character from C up to D, inclusive
+ *   S-T      characters in S, except those in T
  * 
- * [Notes] - *

- * If there is no explicit negative subpattern, - is prefixed to the - * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00". - *

- * Illegal formats, such as "#.#.#" in the same format, will cause a - * failing UErrorCode to be returned. - *

- * The grouping separator is commonly used for thousands, but in some - * countries for ten-thousands. The interval is a constant number of - * digits between the grouping characters, such as 100,000,000 or 1,0000,0000. - * If you supply a pattern with multiple grouping characters, the interval - * between the last one and the end of the integer determines the primary - * grouping size, and the interval between the last two determines - * the secondary grouping size (see below); all others are ignored. - * So "#,##,###,####" == "###,###,####" == "##,#,###,####". - *

- * Some locales have two different grouping intervals: One used for the - * least significant integer digits (the primary grouping size), and - * one used for all others (the secondary grouping size). For example, - * if the primary grouping interval is 3, and the secondary is 2, then - * this corresponds to the pattern "#,##,##0", and the number 123456789 - * is formatted as "12,34,56,789". - *

- * This class only handles localized digits where the 10 digits are - * contiguous in Unicode, from 0 to 9. Other digits sets (such as - * superscripts) would need a different subclass. + * The first subpattern is for positive numbers. The second (optional) + * subpattern is for negative numbers. + * + *

Not indicated in the BNF syntax above: + * + *

+ * + *

Parsing + * + *

DecimalFormat parses all Unicode characters that represent + * decimal digits, as defined by u_charDigitValue(). In addition, + * DecimalFormat also recognizes as digits the ten consecutive + * characters starting with the localized zero digit defined in the + * DecimalFormatSymbols object. During formatting, the + * DecimalFormatSymbols-based digits are output. + * + *

During parsing, grouping separators are ignored. + * + *

For currency parsing, the formatter is able to parse every currency + * style formats no matter which style the formatter is constructed with. + * For example, a formatter instance gotten from + * NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can parse + * formats such as "USD1.00" and "3.00 US dollars". + * + *

If parse(UnicodeString&,Formattable&,ParsePosition&) + * fails to parse a string, it leaves the parse position unchanged. + * The convenience method parse(UnicodeString&,Formattable&,UErrorCode&) + * indicates parse failure by setting a failing + * UErrorCode. + * + *

Formatting + * + *

Formatting is guided by several parameters, all of which can be + * specified either using a pattern or using the API. The following + * description applies to formats that do not use scientific + * notation or significant digits. + * + *

+ * + *

Special Values + * + *

NaN is represented as a single character, typically + * \\uFFFD. This character is determined by the + * DecimalFormatSymbols object. This is the only value for which + * the prefixes and suffixes are not used. + * + *

Infinity is represented as a single character, typically + * \\u221E, with the positive or negative prefixes and suffixes + * applied. The infinity character is determined by the + * DecimalFormatSymbols object. + * + * Scientific Notation + * + *

Numbers in scientific notation are expressed as the product of a mantissa + * and a power of ten, for example, 1234 can be expressed as 1.234 x 103. The + * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0), + * but it need not be. DecimalFormat supports arbitrary mantissas. + * DecimalFormat can be instructed to use scientific + * notation through the API or through the pattern. In a pattern, the exponent + * character immediately followed by one or more digit characters indicates + * scientific notation. Example: "0.###E0" formats the number 1234 as + * "1.234E3". + * + *

+ * + * Significant Digits + * + * DecimalFormat has two ways of controlling how many + * digits are shows: (a) significant digits counts, or (b) integer and + * fraction digit counts. Integer and fraction digit counts are + * described above. When a formatter is using significant digits + * counts, the number of integer and fraction digits is not specified + * directly, and the formatter settings for these counts are ignored. + * Instead, the formatter uses however many integer and fraction + * digits are required to display the specified number of significant + * digits. Examples: + * + * + * + * + * + * + * + *
Pattern + * Minimum significant digits + * Maximum significant digits + * Number + * Output of format() + *
\@\@\@ + * 3 + * 3 + * 12345 + * 12300 + *
\@\@\@ + * 3 + * 3 + * 0.12345 + * 0.123 + *
\@\@## + * 2 + * 4 + * 3.14159 + * 3.142 + *
\@\@## + * 2 + * 4 + * 1.23004 + * 1.23 + *
+ * + * + * + *

Padding + * + *

DecimalFormat supports padding the result of + * format() to a specific width. Padding may be specified either + * through the API or through the pattern syntax. In a pattern the pad escape + * character, followed by a single pad character, causes padding to be parsed + * and formatted. The pad escape character is '*' in unlocalized patterns, and + * can be localized using DecimalFormatSymbols::setSymbol() with a + * DecimalFormatSymbols::kPadEscapeSymbol + * selector. For example, "$*x#,##0.00" formats 123 to + * "$xx123.00", and 1234 to "$1,234.00". + * + *

+ * + *

Rounding + * + *

DecimalFormat supports rounding to a specific increment. For + * example, 1230 rounded to the nearest 50 is 1250. 1.234 rounded to the + * nearest 0.65 is 1.3. The rounding increment may be specified through the API + * or in a pattern. To specify a rounding increment in a pattern, include the + * increment in the pattern itself. "#,#50" specifies a rounding increment of + * 50. "#,##0.05" specifies a rounding increment of 0.05. + * + *

In the absense of an explicit rounding increment numbers are + * rounded to their formatted width. + * + *

+ * + *

Synchronization + * + *

DecimalFormat objects are not synchronized. Multiple + * threads should not access one formatter concurrently. + * + *

Subclassing + * + *

User subclasses are not supported. While clients may write + * subclasses, such code will not necessarily work and will not be + * guaranteed to work stably from release to release. */ class U_I18N_API DecimalFormat: public NumberFormat { public: - /** Rounding mode - * @draft ICU 2.4 - */ - enum ERoundingMode { - kRoundCeiling, - kRoundFloor, - kRoundDown, - kRoundUp, - kRoundHalfEven, - kRoundHalfDown, - kRoundHalfUp - // We don't support ROUND_UNNECESSARY - }; - - /** Pad position - * @draft ICU 2.4 - */ + /** + * Pad position. + * @stable ICU 2.4 + */ enum EPadPosition { kPadBeforePrefix, kPadAfterPrefix, @@ -216,6 +694,9 @@ public: * on NumberFormat such as createInstance. These factories will * return the most appropriate sub-class of NumberFormat for a given * locale. + *

+ * NOTE: New users are strongly encouraged to use + * {@link NumberFormatter} instead of DecimalFormat. * @param status Output param set to success/failure code. If the * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 @@ -231,6 +712,9 @@ public: * on NumberFormat such as createInstance. These factories will * return the most appropriate sub-class of NumberFormat for a given * locale. + *

+ * NOTE: New users are strongly encouraged to use + * {@link NumberFormatter} instead of DecimalFormat. * @param pattern A non-localized pattern string. * @param status Output param set to success/failure code. If the * pattern is invalid this will be set to a failure code. @@ -249,6 +733,9 @@ public: * createInstance or createCurrencyInstance. If you need only minor adjustments * to a standard format, you can modify the format returned by * a NumberFormat factory method. + *

+ * NOTE: New users are strongly encouraged to use + * {@link NumberFormatter} instead of DecimalFormat. * * @param pattern a non-localized pattern string * @param symbolsToAdopt the set of symbols to be used. The caller should not @@ -261,6 +748,89 @@ public: DecimalFormatSymbols* symbolsToAdopt, UErrorCode& status); +#ifndef U_HIDE_INTERNAL_API + /** + * This API is for ICU use only. + * Create a DecimalFormat from the given pattern, symbols, and style. + * + * @param pattern a non-localized pattern string + * @param symbolsToAdopt the set of symbols to be used. The caller should not + * delete this object after making this call. + * @param style style of decimal format + * @param status Output param set to success/failure code. If the + * pattern is invalid this will be set to a failure code. + * @internal + */ + DecimalFormat( const UnicodeString& pattern, + DecimalFormatSymbols* symbolsToAdopt, + UNumberFormatStyle style, + UErrorCode& status); + +#if UCONFIG_HAVE_PARSEALLINPUT + /** + * @internal + */ + void setParseAllInput(UNumberFormatAttributeValue value); +#endif + +#endif /* U_HIDE_INTERNAL_API */ + + + /** + * Set an integer attribute on this DecimalFormat. + * May return U_UNSUPPORTED_ERROR if this instance does not support + * the specified attribute. + * @param attr the attribute to set + * @param newvalue new value + * @param status the error type + * @return *this - for chaining (example: format.setAttribute(...).setAttribute(...) ) + * @stable ICU 51 + */ + virtual DecimalFormat& setAttribute( UNumberFormatAttribute attr, + int32_t newvalue, + UErrorCode &status); + + /** + * Get an integer + * May return U_UNSUPPORTED_ERROR if this instance does not support + * the specified attribute. + * @param attr the attribute to set + * @param status the error type + * @return the attribute value. Undefined if there is an error. + * @stable ICU 51 + */ + virtual int32_t getAttribute( UNumberFormatAttribute attr, + UErrorCode &status) const; + + + /** + * Set whether or not grouping will be used in this format. + * @param newValue True, grouping will be used in this format. + * @see getGroupingUsed + * @stable ICU 53 + */ + virtual void setGroupingUsed(UBool newValue); + + /** + * Sets whether or not numbers should be parsed as integers only. + * @param value set True, this format will parse numbers as integers + * only. + * @see isParseIntegerOnly + * @stable ICU 53 + */ + virtual void setParseIntegerOnly(UBool value); + + /** + * 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. + * @stable ICU 53 + */ + virtual void setContext(UDisplayContext value, UErrorCode& status); + /** * Create a DecimalFormat from the given pattern and symbols. * Use this constructor when you need to completely customize the @@ -271,11 +841,14 @@ public: * createInstance or createCurrencyInstance. If you need only minor adjustments * to a standard format, you can modify the format returned by * a NumberFormat factory method. + *

+ * NOTE: New users are strongly encouraged to use + * {@link NumberFormatter} instead of DecimalFormat. * * @param pattern a non-localized pattern string * @param symbolsToAdopt the set of symbols to be used. The caller should not * delete this object after making this call. - * @param parseError Output param to receive errors occured during parsing + * @param parseError Output param to receive errors occured during parsing * @param status Output param set to success/failure code. If the * pattern is invalid this will be set to a failure code. * @stable ICU 2.0 @@ -294,6 +867,9 @@ public: * createInstance or createCurrencyInstance. If you need only minor adjustments * to a standard format, you can modify the format returned by * a NumberFormat factory method. + *

+ * NOTE: New users are strongly encouraged to use + * {@link NumberFormatter} instead of DecimalFormat. * * @param pattern a non-localized pattern string * @param symbols the set of symbols to be used @@ -307,7 +883,7 @@ public: /** * Copy constructor. - * + * * @param source the DecimalFormat object to be copied from. * @stable ICU 2.0 */ @@ -346,6 +922,9 @@ public: */ virtual UBool operator==(const Format& other) const; + + using NumberFormat::format; + /** * Format a double or long number using base-10 representation. * @@ -356,10 +935,47 @@ public: * On output: the offsets of the alignment field. * @return Reference to 'appendTo' parameter. * @stable ICU 2.0 - */ + */ virtual UnicodeString& format(double number, UnicodeString& appendTo, FieldPosition& pos) const; + + + /** + * Format a double or long number using base-10 representation. + * + * @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 + * @return Reference to 'appendTo' parameter. + * @internal + */ + virtual UnicodeString& format(double number, + UnicodeString& appendTo, + FieldPosition& pos, + UErrorCode &status) const; + + /** + * Format a double or long number using base-10 representation. + * + * @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 ICU 4.4 + */ + virtual UnicodeString& format(double number, + UnicodeString& appendTo, + FieldPositionIterator* posIter, + UErrorCode& status) const; + /** * Format a long number using base-10 representation. * @@ -374,71 +990,194 @@ public: virtual UnicodeString& format(int32_t number, UnicodeString& appendTo, FieldPosition& pos) const; + /** - * Format a Formattable using base-10 representation. + * Format a long number using base-10 representation. * - * @param obj The value to be formatted. + * @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 code indicating success or failure. * @return Reference to 'appendTo' parameter. - * @stable ICU 2.0 + * @internal */ - virtual UnicodeString& format(const Formattable& obj, + virtual UnicodeString& format(int32_t number, UnicodeString& appendTo, FieldPosition& pos, + UErrorCode &status) const; + + /** + * Format a long number using base-10 representation. + * + * @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 ICU 4.4 + */ + virtual UnicodeString& format(int32_t number, + UnicodeString& appendTo, + FieldPositionIterator* posIter, UErrorCode& status) const; /** - * Redeclared NumberFormat method. - * Formats an object to produce a string. + * Format an int64 number using base-10 representation. * - * @param obj The object to format. + * @param number The value to be formatted. * @param appendTo Output parameter to receive result. * Result is appended to existing contents. - * @param status Output parameter filled in with success or failure status. + * @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 + * @stable ICU 2.8 */ - UnicodeString& format(const Formattable& obj, - UnicodeString& appendTo, - UErrorCode& status) const; + virtual UnicodeString& format(int64_t number, + UnicodeString& appendTo, + FieldPosition& pos) const; /** - * Redeclared NumberFormat method. - * Format a double number. + * Format an int64 number using base-10 representation. * * @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. * @return Reference to 'appendTo' parameter. - * @stable ICU 2.0 + * @internal */ - UnicodeString& format(double number, - UnicodeString& appendTo) const; + virtual UnicodeString& format(int64_t number, + UnicodeString& appendTo, + FieldPosition& pos, + UErrorCode &status) const; /** - * Redeclared NumberFormat method. - * Format a long number. These methods call the NumberFormat - * pure virtual format() methods with the default FieldPosition. + * Format an int64 number using base-10 representation. * * @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 ICU 2.0 + * @stable ICU 4.4 + */ + virtual UnicodeString& format(int64_t number, + UnicodeString& appendTo, + FieldPositionIterator* posIter, + UErrorCode& status) const; + + /** + * Format a decimal number. + * 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. + * @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 ICU 4.4 */ - UnicodeString& format(int32_t number, - UnicodeString& appendTo) const; + virtual UnicodeString& format(StringPiece 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. + * + * @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. + * @param number The number + * @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 VisibleDigitsWithExponent &number, + UnicodeString& appendTo, + FieldPosition& pos, + UErrorCode& status) const; + + /** + * Format a decimal number. + * @param number The number + * @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 VisibleDigitsWithExponent &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. + * + * @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; + + using NumberFormat::parse; /** * Parse the given string using this object's choices. The method * does string comparisons to try to find an optimal match. * If no object can be parsed, index is unchanged, and NULL is * returned. The result is returned as the most parsimonious - * type of Formattable that will accomodate all of the + * type of Formattable that will accomodate all of the * necessary precision. For example, if the result is exactly 12, * it will be returned as a long. However, if it is 1.5, it will * be returned as a double. @@ -456,18 +1195,27 @@ public: Formattable& result, ParsePosition& parsePosition) const; - // Declare here again to get rid of function hiding problems. - /** - * Parse the given string using this object's choices. + /** + * Parses text from the given string as a currency amount. Unlike + * the parse() method, this method will attempt to parse a generic + * currency name, searching for a match of this object's locale's + * currency display names, or for a 3-letter ISO currency code. + * This method will fail if this format is not a currency format, + * that is, if it does not contain the currency pattern symbol + * (U+00A4) in its prefix or suffix. * - * @param text The text to be parsed. - * @param result Formattable to be set to the parse result. - * @param status Output parameter filled in with success or failure status. - * @stable ICU 2.0 + * @param text the string to parse + * @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 void parse(const UnicodeString& text, - Formattable& result, - UErrorCode& status) const; + virtual CurrencyAmount* parseCurrency(const UnicodeString& text, + ParsePosition& pos) const; /** * Returns the decimal format symbols, which is generally not changed @@ -495,6 +1243,31 @@ public: virtual void setDecimalFormatSymbols(const DecimalFormatSymbols& symbols); + /** + * Returns the currency plural format information, + * which is generally not changed by the programmer or user. + * @return desired CurrencyPluralInfo + * @stable ICU 4.2 + */ + virtual const CurrencyPluralInfo* getCurrencyPluralInfo(void) const; + + /** + * Sets the currency plural format information, + * which is generally not changed by the programmer or user. + * @param toAdopt CurrencyPluralInfo to be adopted. + * @stable ICU 4.2 + */ + virtual void adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt); + + /** + * Sets the currency plural format information, + * which is generally not changed by the programmer or user. + * @param info Currency Plural Info. + * @stable ICU 4.2 + */ + virtual void setCurrencyPluralInfo(const CurrencyPluralInfo& info); + + /** * Get the positive prefix. * @@ -575,7 +1348,7 @@ public: * Get the multiplier for use in percent, permill, etc. * For a percentage, set the suffixes to have "%" and the multiplier to be 100. * (For Arabic, use arabic percent symbol). - * For a permill, set the suffixes to have "\u2031" and the multiplier to be 1000. + * For a permill, set the suffixes to have "\\u2031" and the multiplier to be 1000. * * @return the multiplier for use in percent, permill, etc. * Examples: with 100, 1.23 -> "123", and "123" -> 1.23 @@ -587,7 +1360,7 @@ public: * Set the multiplier for use in percent, permill, etc. * For a percentage, set the suffixes to have "%" and the multiplier to be 100. * (For Arabic, use arabic percent symbol). - * For a permill, set the suffixes to have "\u2031" and the multiplier to be 1000. + * For a permill, set the suffixes to have "\\u2031" and the multiplier to be 1000. * * @param newValue the new value of the multiplier for use in percent, permill, etc. * Examples: with 100, 1.23 -> "123", and "123" -> 1.23 @@ -597,19 +1370,20 @@ public: /** * Get the rounding increment. - * @return A positive rounding increment, or 0.0 if rounding - * is not in effect. + * @return A positive rounding increment, or 0.0 if a custom rounding + * increment is not in effect. * @see #setRoundingIncrement * @see #getRoundingMode * @see #setRoundingMode * @stable ICU 2.0 */ - virtual double getRoundingIncrement(void); + virtual double getRoundingIncrement(void) const; /** - * Set the rounding increment. This method also controls whether - * rounding is enabled. - * @param newValue A positive rounding increment, or 0.0 to disable rounding. + * Set the rounding increment. In the absence of a rounding increment, + * numbers will be rounded to the number of digits displayed. + * @param newValue A positive rounding increment, or 0.0 to + * use the default rounding increment. * Negative increments are equivalent to 0.0. * @see #getRoundingIncrement * @see #getRoundingMode @@ -626,11 +1400,10 @@ public: * @see #setRoundingMode * @stable ICU 2.0 */ - virtual ERoundingMode getRoundingMode(void); + virtual ERoundingMode getRoundingMode(void) const; /** - * Set the rounding mode. This has no effect unless the rounding - * increment is greater than zero. + * Set the rounding mode. * @param roundingMode A rounding mode * @see #setRoundingIncrement * @see #getRoundingIncrement @@ -640,25 +1413,27 @@ public: virtual void setRoundingMode(ERoundingMode roundingMode); /** - * Get the width to which the output of format() is padded. + * Get the width to which the output of format() is padded. + * The width is counted in 16-bit code units. * @return the format width, or zero if no padding is in effect * @see #setFormatWidth - * @see #getPadCharacter + * @see #getPadCharacterString * @see #setPadCharacter * @see #getPadPosition * @see #setPadPosition * @stable ICU 2.0 */ - virtual int32_t getFormatWidth(void); + virtual int32_t getFormatWidth(void) const; /** - * Set the width to which the output of format() is padded. + * Set the width to which the output of format() is padded. + * The width is counted in 16-bit code units. * This method also controls whether padding is enabled. * @param width the width to which to pad the result of - * format(), or zero to disable padding. A negative + * format(), or zero to disable padding. A negative * width is equivalent to 0. * @see #getFormatWidth - * @see #getPadCharacter + * @see #getPadCharacterString * @see #setPadCharacter * @see #getPadPosition * @see #setPadPosition @@ -667,11 +1442,10 @@ public: virtual void setFormatWidth(int32_t width); /** - * Get the grapheme string (a character, possibly with modifier letters) - * used to pad to the format width. The default is " ". - * Note: The current implementation only stores the first code unit of the - * pad string. - * @return the pad grapheme string + * Get the pad character used to pad to the format width. The + * default is ' '. + * @return a string containing the pad character. This will always + * have a length of one 32-bit code point. * @see #setFormatWidth * @see #getFormatWidth * @see #setPadCharacter @@ -679,18 +1453,18 @@ public: * @see #setPadPosition * @stable ICU 2.0 */ - virtual UnicodeString getPadCharacterString(); + virtual UnicodeString getPadCharacterString() const; /** - * Set the grapheme string (a character, possibly with modifier letters) - * used to pad to the format width. This has no effect - * unless padding is enabled. - * Note: The current implementation only stores the first code unit of the - * pad string. - * @param padChar the pad grapheme + * Set the character used to pad to the format width. If padding + * is not enabled, then this will take effect if padding is later + * enabled. + * @param padChar a string containing the pad charcter. If the string + * has length 0, then the pad characer is set to ' '. Otherwise + * padChar.char32At(0) will be used as the pad character. * @see #setFormatWidth * @see #getFormatWidth - * @see #getPadCharacter + * @see #getPadCharacterString * @see #getPadPosition * @see #setPadPosition * @stable ICU 2.0 @@ -699,42 +1473,35 @@ public: /** * Get the position at which padding will take place. This is the location - * at which padding will be inserted if the result of format() + * at which padding will be inserted if the result of format() * is shorter than the format width. - * @return the pad position, one of kPadBeforePrefix, - * kPadAfterPrefix, kPadBeforeSuffix, or - * kPadAfterSuffix. + * @return the pad position, one of kPadBeforePrefix, + * kPadAfterPrefix, kPadBeforeSuffix, or + * kPadAfterSuffix. * @see #setFormatWidth * @see #getFormatWidth * @see #setPadCharacter - * @see #getPadCharacter + * @see #getPadCharacterString * @see #setPadPosition - * @see #kPadBeforePrefix - * @see #kPadAfterPrefix - * @see #kPadBeforeSuffix - * @see #kPadAfterSuffix + * @see #EPadPosition * @stable ICU 2.0 */ - virtual EPadPosition getPadPosition(void); + virtual EPadPosition getPadPosition(void) const; /** - * NEW * Set the position at which padding will take place. This is the location - * at which padding will be inserted if the result of format() + * at which padding will be inserted if the result of format() * is shorter than the format width. This has no effect unless padding is * enabled. - * @param padPos the pad position, one of kPadBeforePrefix, - * kPadAfterPrefix, kPadBeforeSuffix, or - * kPadAfterSuffix. + * @param padPos the pad position, one of kPadBeforePrefix, + * kPadAfterPrefix, kPadBeforeSuffix, or + * kPadAfterSuffix. * @see #setFormatWidth * @see #getFormatWidth * @see #setPadCharacter - * @see #getPadCharacter + * @see #getPadCharacterString * @see #getPadPosition - * @see #kPadBeforePrefix - * @see #kPadAfterPrefix - * @see #kPadBeforeSuffix - * @see #kPadAfterSuffix + * @see #EPadPosition * @stable ICU 2.0 */ virtual void setPadPosition(EPadPosition padPos); @@ -749,10 +1516,14 @@ public: * @see #setExponentSignAlwaysShown * @stable ICU 2.0 */ - virtual UBool isScientificNotation(void); + virtual UBool isScientificNotation(void) const; /** - * Set whether or not scientific notation is used. + * Set whether or not scientific notation is used. When scientific notation + * is used, the effective maximum number of integer digits is <= 8. If the + * maximum number of integer digits is set to more than 8, the effective + * maximum will be 1. This allows this call to generate a 'default' scientific + * number format without additional changes. * @param useScientific TRUE if this object formats and parses scientific * notation * @see #isScientificNotation @@ -774,7 +1545,7 @@ public: * @see #setExponentSignAlwaysShown * @stable ICU 2.0 */ - virtual int8_t getMinimumExponentDigits(void); + virtual int8_t getMinimumExponentDigits(void) const; /** * Set the minimum exponent digits that will be shown. This has no @@ -802,7 +1573,7 @@ public: * @see #setExponentSignAlwaysShown * @stable ICU 2.0 */ - virtual UBool isExponentSignAlwaysShown(void); + virtual UBool isExponentSignAlwaysShown(void) const; /** * Set whether the exponent sign is always shown. This has no effect @@ -852,7 +1623,7 @@ public: * others (the secondary grouping size). A formatter supporting a * secondary grouping size will return a positive integer unequal * to the primary grouping size returned by - * getGroupingSize(). For example, if the primary + * getGroupingSize(). For example, if the primary * grouping size is 4, and the secondary grouping size is 2, then * the number 123456789 formats as "1,23,45,6789", and the pattern * appears as "#,##,###0". @@ -861,7 +1632,7 @@ public: * @see setSecondaryGroupingSize * @see NumberFormat::isGroupingUsed * @see DecimalFormatSymbols::getGroupingSeparator - * @draft ICU 2.4 + * @stable ICU 2.4 */ int32_t getSecondaryGroupingSize(void) const; @@ -874,10 +1645,49 @@ public: * @see getSecondaryGroupingSize * @see NumberFormat#setGroupingUsed * @see DecimalFormatSymbols::setGroupingSeparator - * @draft ICU 2.4 + * @stable ICU 2.4 */ virtual void setSecondaryGroupingSize(int32_t newValue); +#ifndef U_HIDE_INTERNAL_API + + /** + * Returns the minimum number of grouping digits. + * Grouping separators are output if there are at least this many + * digits to the left of the first (rightmost) grouping separator, + * that is, there are at least (minimum grouping + grouping size) integer digits. + * (Subject to isGroupingUsed().) + * + * For example, if this value is 2, and the grouping size is 3, then + * 9999 -> "9999" and 10000 -> "10,000" + * + * This is a technology preview. This API may change behavior or may be removed. + * + * The default value for this attribute is 0. + * A value of 1, 0, or lower, means that the use of grouping separators + * only depends on the grouping size (and on isGroupingUsed()). + * Currently, the corresponding CLDR data is not used; this is likely to change. + * + * @see setMinimumGroupingDigits + * @see getGroupingSize + * @internal technology preview + */ + int32_t getMinimumGroupingDigits() const; + +#endif /* U_HIDE_INTERNAL_API */ + + /* Cannot use #ifndef U_HIDE_INTERNAL_API for the following draft method since it is virtual. */ + /** + * Sets the minimum grouping digits. Setting to a value less than or + * equal to 1 turns off minimum grouping digits. + * + * @param newValue the new value of minimum grouping digits. + * @see getMinimumGroupingDigits + * @internal technology preview + */ + virtual void setMinimumGroupingDigits(int32_t newValue); + + /** * Allows you to get the behavior of the decimal separator with integers. * (The decimal separator will always appear with decimals.) @@ -898,6 +1708,26 @@ public: */ virtual void setDecimalSeparatorAlwaysShown(UBool newValue); + /** + * Allows you to get the parse behavior of the pattern decimal mark. + * + * @return TRUE if input must contain a match to decimal mark in pattern + * @stable ICU 54 + */ + UBool isDecimalPatternMatchRequired(void) const; + + /** + * Allows you to set the behavior of the pattern decimal mark. + * + * if TRUE, the input must have a decimal mark if one was specified in the pattern. When + * FALSE the decimal mark may be omitted from the input. + * + * @param newValue set TRUE if input must contain a match to decimal mark in pattern + * @stable ICU 54 + */ + virtual void setDecimalPatternMatchRequired(UBool newValue); + + /** * Synthesizes a pattern string that represents the current state * of this Format object. @@ -921,7 +1751,7 @@ public: * @stable ICU 2.0 */ virtual UnicodeString& toLocalizedPattern(UnicodeString& result) const; - + /** * Apply the given pattern to this Format object. A pattern is a * short-hand specification for the various formatting properties. @@ -944,7 +1774,7 @@ public: * these are presumed to be set in the positive pattern. * * @param pattern The pattern to be applied. - * @param parseError Struct to recieve information on position + * @param parseError Struct to recieve information on position * of error if an error is encountered * @param status Output param set to success/failure code on * exit. If the pattern is invalid, this will be @@ -961,7 +1791,7 @@ public: * exit. If the pattern is invalid, this will be * set to a failure result. * @stable ICU 2.0 - */ + */ virtual void applyPattern(const UnicodeString& pattern, UErrorCode& status); @@ -988,7 +1818,7 @@ public: * these are presumed to be set in the positive pattern. * * @param pattern The localized pattern to be applied. - * @param parseError Struct to recieve information on position + * @param parseError Struct to recieve information on position * of error if an error is encountered * @param status Output param set to success/failure code on * exit. If the pattern is invalid, this will be @@ -1016,7 +1846,7 @@ public: * Sets the maximum number of digits allowed in the integer portion of a * number. This override limits the integer digit count to 309. * - * @param newValue the new value of the maximum number of digits + * @param newValue the new value of the maximum number of digits * allowed in the integer portion of a number. * @see NumberFormat#setMaximumIntegerDigits * @stable ICU 2.0 @@ -1026,8 +1856,8 @@ public: /** * Sets the minimum number of digits allowed in the integer portion of a * number. This override limits the integer digit count to 309. - * - * @param newValue the new value of the minimum number of digits + * + * @param newValue the new value of the minimum number of digits * allowed in the integer portion of a number. * @see NumberFormat#setMinimumIntegerDigits * @stable ICU 2.0 @@ -1038,7 +1868,7 @@ public: * Sets the maximum number of digits allowed in the fraction portion of a * number. This override limits the fraction digit count to 340. * - * @param newValue the new value of the maximum number of digits + * @param newValue the new value of the maximum number of digits * allowed in the fraction portion of a number. * @see NumberFormat#setMaximumFractionDigits * @stable ICU 2.0 @@ -1049,13 +1879,75 @@ public: * Sets the minimum number of digits allowed in the fraction portion of a * number. This override limits the fraction digit count to 340. * - * @param newValue the new value of the minimum number of digits + * @param newValue the new value of the minimum number of digits * allowed in the fraction portion of a number. * @see NumberFormat#setMinimumFractionDigits * @stable ICU 2.0 */ virtual void setMinimumFractionDigits(int32_t newValue); + /** + * Returns the minimum number of significant digits that will be + * displayed. This value has no effect unless areSignificantDigitsUsed() + * returns true. + * @return the fewest significant digits that will be shown + * @stable ICU 3.0 + */ + int32_t getMinimumSignificantDigits() const; + + /** + * Returns the maximum number of significant digits that will be + * displayed. This value has no effect unless areSignificantDigitsUsed() + * returns true. + * @return the most significant digits that will be shown + * @stable ICU 3.0 + */ + int32_t getMaximumSignificantDigits() const; + + /** + * Sets the minimum number of significant digits that will be + * displayed. If min is less than one then it is set + * to one. If the maximum significant digits count is less than + * min, then it is set to min. + * This function also enables the use of significant digits + * by this formatter - areSignificantDigitsUsed() will return TRUE. + * @see #areSignificantDigitsUsed + * @param min the fewest significant digits to be shown + * @stable ICU 3.0 + */ + void setMinimumSignificantDigits(int32_t min); + + /** + * Sets the maximum number of significant digits that will be + * displayed. If max is less than one then it is set + * to one. If the minimum significant digits count is greater + * than max, then it is set to max. + * This function also enables the use of significant digits + * by this formatter - areSignificantDigitsUsed() will return TRUE. + * @see #areSignificantDigitsUsed + * @param max the most significant digits to be shown + * @stable ICU 3.0 + */ + void setMaximumSignificantDigits(int32_t max); + + /** + * Returns true if significant digits are in use, or false if + * integer and fraction digit counts are in use. + * @return true if significant digits are in use + * @stable ICU 3.0 + */ + UBool areSignificantDigitsUsed() const; + + /** + * Sets whether significant digits are in use, or integer and + * fraction digit counts are in use. + * @param useSignificantDigits true to use significant digits, or + * false to use integer and fraction digit counts + * @stable ICU 3.0 + */ + void setSignificantDigitsUsed(UBool useSignificantDigits); + + public: /** * Sets the currency used to display currency * amounts. This takes effect immediately, if this format is a @@ -1063,17 +1955,105 @@ public: * the currency is used if and when this object becomes a * currency format through the application of a new pattern. * @param theCurrency a 3-letter ISO code indicating new currency - * to use. It need not be null-terminated. - * @draft ICU 2.2 + * to use. It need not be null-terminated. May be the empty + * string or NULL to indicate no currency. + * @param ec input-output error code + * @stable ICU 3.0 */ - virtual void setCurrency(const UChar* theCurrency); + virtual void setCurrency(const char16_t* theCurrency, UErrorCode& ec); + /** + * Sets the currency used to display currency amounts. See + * setCurrency(const char16_t*, UErrorCode&). + * @deprecated ICU 3.0. Use setCurrency(const char16_t*, UErrorCode&). + */ + virtual void setCurrency(const char16_t* theCurrency); + + /** + * Sets the Currency Context object used to display currency. + * This takes effect immediately, if this format is a + * currency format. + * @param currencyContext new currency context object to use. + * @stable ICU 54 + */ + void setCurrencyUsage(UCurrencyUsage newUsage, UErrorCode* ec); + + /** + * Returns the Currency Context object used to display currency + * @stable ICU 54 + */ + UCurrencyUsage getCurrencyUsage() const; + + +#ifndef U_HIDE_DEPRECATED_API /** * The resource tags we use to retrieve decimal format data from * locale resource bundles. - * @stable ICU 2.0 + * @deprecated ICU 3.4. This string has no public purpose. Please don't use it. */ static const char fgNumberPatterns[]; +#endif // U_HIDE_DEPRECATED_API + +#ifndef U_HIDE_INTERNAL_API + /** + * Get a FixedDecimal corresponding to a double as it would be + * formatted by this DecimalFormat. + * Internal, not intended for public use. + * @internal + */ + FixedDecimal getFixedDecimal(double number, UErrorCode &status) const; + + /** + * Get a FixedDecimal corresponding to a formattable as it would be + * formatted by this DecimalFormat. + * Internal, not intended for public use. + * @internal + */ + FixedDecimal getFixedDecimal(const Formattable &number, UErrorCode &status) const; + + /** + * Get a FixedDecimal corresponding to a DigitList as it would be + * formatted by this DecimalFormat. Note: the DigitList may be modified. + * Internal, not intended for public use. + * @internal + */ + FixedDecimal getFixedDecimal(DigitList &number, UErrorCode &status) const; + + /** + * Get a VisibleDigitsWithExponent corresponding to a double + * as it would be formatted by this DecimalFormat. + * Internal, not intended for public use. + * @internal + */ + VisibleDigitsWithExponent &initVisibleDigitsWithExponent( + double number, + VisibleDigitsWithExponent &digits, + UErrorCode &status) const; + + /** + * Get a VisibleDigitsWithExponent corresponding to a formattable + * as it would be formatted by this DecimalFormat. + * Internal, not intended for public use. + * @internal + */ + VisibleDigitsWithExponent &initVisibleDigitsWithExponent( + const Formattable &number, + VisibleDigitsWithExponent &digits, + UErrorCode &status) const; + + /** + * Get a VisibleDigitsWithExponent corresponding to a DigitList + * as it would be formatted by this DecimalFormat. + * Note: the DigitList may be modified. + * Internal, not intended for public use. + * @internal + */ + VisibleDigitsWithExponent &initVisibleDigitsWithExponent( + DigitList &number, + VisibleDigitsWithExponent &digits, + UErrorCode &status) const; + +#endif /* U_HIDE_INTERNAL_API */ public: @@ -1088,7 +2068,7 @@ public: * @return The class ID for all objects of this class. * @stable ICU 2.0 */ - static inline UClassID getStaticClassID(void); + static UClassID U_EXPORT2 getStaticClassID(void); /** * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. @@ -1104,260 +2084,219 @@ public: virtual UClassID getDynamicClassID(void) const; private: - static const char fgClassID; DecimalFormat(); // default constructor not implemented + /** + * Initialize all fields of a new DecimalFormatter to a safe default value. + * Common code for use by constructors. + */ + void init(); + /** * Do real work of constructing a new DecimalFormat. */ - void construct(UErrorCode& status, + void construct(UErrorCode& status, UParseError& parseErr, const UnicodeString* pattern = 0, DecimalFormatSymbols* symbolsToAdopt = 0 ); - /** - * Does the real work of generating a pattern. - * - * @param result Output param which will receive the pattern. - * Previous contents are deleted. - * @param localized TRUE return localized pattern. - * @return A reference to 'result'. - */ - UnicodeString& toPattern(UnicodeString& result, UBool localized) const; + void handleCurrencySignInPattern(UErrorCode& status); - /** - * Does the real work of applying a pattern. - * @param pattern The pattern to be applied. - * @param localized If true, the pattern is localized; else false. - * @param parseError Struct to recieve information on position - * of error if an error is encountered - * @param status Output param set to success/failure code on - * exit. If the pattern is invalid, this will be - * set to a failure result. - */ - void applyPattern(const UnicodeString& pattern, - UBool localized, - UParseError& parseError, - UErrorCode& status); - /** - * Do the work of formatting a number, either a double or a long. - * - * @param appendTo Output parameter to receive result. - * Result is appended to existing contents. - * @param fieldPosition On input: an alignment field, if desired. - * On output: the offsets of the alignment field. - * @param digits the digits to be formatted. - * @param isInteger if TRUE format the digits as Integer. - * @return Reference to 'appendTo' parameter. - */ - UnicodeString& subformat(UnicodeString& appendTo, - FieldPosition& fieldPosition, - DigitList& digits, - UBool isInteger) const; + void parse(const UnicodeString& text, + Formattable& result, + ParsePosition& pos, + char16_t* currency) const; enum { fgStatusInfinite, fgStatusLength // Leave last in list. } StatusFlags; - /** - * Parse the given text into a number. The text is parsed beginning at - * parsePosition, until an unparseable character is seen. - * @param text The string to parse. - * @param parsePosition The position at which to being parsing. Upon - * return, the first unparseable character. - * @param digits The DigitList to set to the parsed value. - * @param isExponent If true, parse an exponent. This means no - * infinite values and integer only. - * @param status Upon return contains boolean status flags indicating - * whether the value was infinite and whether it was positive. - */ - UBool subparse(const UnicodeString& text, ParsePosition& parsePosition, - DigitList& digits, UBool* status) const; + UBool subparse(const UnicodeString& text, + const UnicodeString* negPrefix, + const UnicodeString* negSuffix, + const UnicodeString* posPrefix, + const UnicodeString* posSuffix, + UBool complexCurrencyParsing, + int8_t type, + ParsePosition& parsePosition, + DigitList& digits, UBool* status, + char16_t* currency) const; + + // Mixed style parsing for currency. + // It parses against the current currency pattern + // using complex affix comparison + // parses against the currency plural patterns using complex affix comparison, + // and parses against the current pattern using simple affix comparison. + UBool parseForCurrency(const UnicodeString& text, + ParsePosition& parsePosition, + DigitList& digits, + UBool* status, + char16_t* currency) const; int32_t skipPadding(const UnicodeString& text, int32_t position) const; int32_t compareAffix(const UnicodeString& input, int32_t pos, UBool isNegative, - UBool isPrefix) const; - - static int32_t compareSimpleAffix(const UnicodeString& affix, + UBool isPrefix, + const UnicodeString* affixPat, + UBool complexCurrencyParsing, + int8_t type, + char16_t* currency) const; + + static UnicodeString& trimMarksFromAffix(const UnicodeString& affix, UnicodeString& trimmedAffix); + + UBool equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) const; + + int32_t compareSimpleAffix(const UnicodeString& affix, const UnicodeString& input, - int32_t pos); - - static int32_t skipRuleWhiteSpace(const UnicodeString& text, int32_t pos); - + int32_t pos, + UBool lenient) const; + + static int32_t skipPatternWhiteSpace(const UnicodeString& text, int32_t pos); + static int32_t skipUWhiteSpace(const UnicodeString& text, int32_t pos); - + + static int32_t skipUWhiteSpaceAndMarks(const UnicodeString& text, int32_t pos); + + static int32_t skipBidiMarks(const UnicodeString& text, int32_t pos); + int32_t compareComplexAffix(const UnicodeString& affixPat, const UnicodeString& input, - int32_t pos) const; + int32_t pos, + int8_t type, + char16_t* currency) const; static int32_t match(const UnicodeString& text, int32_t pos, UChar32 ch); static int32_t match(const UnicodeString& text, int32_t pos, const UnicodeString& str); - /** - * Get a decimal format symbol. - * Returns a const reference to the symbol string. - * @internal - */ - inline const UnicodeString &getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const; + static UBool matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol, + UnicodeSet *sset, UChar32 schar); - int32_t appendAffix(UnicodeString& buf, double number, - UBool isNegative, UBool isPrefix) const; + static UBool matchDecimal(UChar32 symbolChar, + UBool sawDecimal, UChar32 sawDecimalChar, + const UnicodeSet *sset, UChar32 schar); - /** - * Append an affix to the given UnicodeString, using quotes if - * there are special characters. Single quotes themselves must be - * escaped in either case. - */ - void appendAffixPattern(UnicodeString& appendTo, const UnicodeString& affix, - UBool localized) const; + static UBool matchGrouping(UChar32 groupingChar, + UBool sawGrouping, UChar32 sawGroupingChar, + const UnicodeSet *sset, + UChar32 decimalChar, const UnicodeSet *decimalSet, + UChar32 schar); - void appendAffixPattern(UnicodeString& appendTo, - const UnicodeString* affixPattern, - const UnicodeString& expAffix, UBool localized) const; + // set up currency affix patterns for mix parsing. + // The patterns saved here are the affix patterns of default currency + // pattern and the unique affix patterns of the plural currency patterns. + // Those patterns are used by parseForCurrency(). + void setupCurrencyAffixPatterns(UErrorCode& status); - void expandAffix(const UnicodeString& pattern, - UnicodeString& affix, - double number, - UBool doFormat) const; + // get the currency rounding with respect to currency usage + double getCurrencyRounding(const char16_t* currency, + UErrorCode* ec) const; - void expandAffixes(); - - static double round(double a, ERoundingMode mode, UBool isNegative); + // get the currency fraction with respect to currency usage + int getCurrencyFractionDigits(const char16_t* currency, + UErrorCode* ec) const; - void addPadding(UnicodeString& appendTo, - FieldPosition& fieldPosition, - int32_t prefixLen, int32_t suffixLen) const; + // hashtable operations + Hashtable* initHashForAffixPattern(UErrorCode& status); - UBool isGroupingPosition(int32_t pos) const; + void deleteHashForAffixPattern(); - void setCurrencyForSymbols(); + void copyHashForAffixPattern(const Hashtable* source, + Hashtable* target, UErrorCode& status); - void setCurrencyForLocale(const char* locale, UErrorCode& ec); + DecimalFormatImpl *fImpl; /** * Constants. */ - //static const int8_t fgMaxDigit; // The largest digit, in this case 9 - - /*transient*/ //DigitList* fDigitList; - - UnicodeString fPositivePrefix; - UnicodeString fPositiveSuffix; - UnicodeString fNegativePrefix; - UnicodeString fNegativeSuffix; - UnicodeString* fPosPrefixPattern; - UnicodeString* fPosSuffixPattern; - UnicodeString* fNegPrefixPattern; - UnicodeString* fNegSuffixPattern; - - /** - * Formatter for ChoiceFormat-based currency names. If this field - * is not null, then delegate to it to format currency symbols. - * @since ICU 2.6 - */ - ChoiceFormat* fCurrencyChoice; - - int32_t fMultiplier; - int32_t fGroupingSize; - int32_t fGroupingSize2; - UBool fDecimalSeparatorAlwaysShown; - /*transient*/ UBool fIsCurrencyFormat; - DecimalFormatSymbols* fSymbols; - - UBool fUseExponentialNotation; - int8_t fMinExponentDigits; - UBool fExponentSignAlwaysShown; - - /* If fRoundingIncrement is NULL, there is no rounding. Otherwise, round to - * fRoundingIncrement.getDouble(). Since this operation may be expensive, - * we cache the result in fRoundingDouble. All methods that update - * fRoundingIncrement also update fRoundingDouble. */ - DigitList* fRoundingIncrement; - /*transient*/ double fRoundingDouble; - ERoundingMode fRoundingMode; - - UChar32 fPad; - int32_t fFormatWidth; - EPadPosition fPadPosition; - - // Constants for characters used in programmatic (unlocalized) patterns. - static const UChar kPatternZeroDigit; - static const UChar kPatternGroupingSeparator; - static const UChar kPatternDecimalSeparator; - static const UChar kPatternPerMill; - static const UChar kPatternPercent; - static const UChar kPatternDigit; - static const UChar kPatternSeparator; - static const UChar kPatternExponent; - static const UChar kPatternPlus; - static const UChar kPatternMinus; - static const UChar kPatternPadEscape; - - /** - * The CURRENCY_SIGN is the standard Unicode symbol for currency. It - * is used in patterns and substitued with either the currency symbol, - * or if it is doubled, with the international currency symbol. If the - * CURRENCY_SIGN is seen in a pattern, then the decimal separator is - * replaced with the monetary decimal separator. - */ - static const UChar kCurrencySign; - static const UChar kQuote; + + + EnumSet + fBoolFlags; + + + // style is only valid when decimal formatter is constructed by + // DecimalFormat(pattern, decimalFormatSymbol, style) + int fStyle; + + + // Affix pattern set for currency. + // It is a set of AffixPatternsForCurrency, + // each element of the set saves the negative prefix pattern, + // negative suffix pattern, positive prefix pattern, + // and positive suffix pattern of a pattern. + // It is used for currency mixed style parsing. + // It is actually is a set. + // The set contains the default currency pattern from the locale, + // and the currency plural patterns. + // Since it is a set, it does not contain duplicated items. + // For example, if 2 currency plural patterns are the same, only one pattern + // is included in the set. When parsing, we do not check whether the plural + // count match or not. + Hashtable* fAffixPatternsForCurrency; + + // Information needed for DecimalFormat to format/parse currency plural. + CurrencyPluralInfo* fCurrencyPluralInfo; + +#if UCONFIG_HAVE_PARSEALLINPUT + UNumberFormatAttributeValue fParseAllInput; +#endif + + // Decimal Format Static Sets singleton. + const DecimalFormatStaticSets *fStaticSets; protected: - /** number of integer digits - * @draft ICU 2.4 - */ + +#ifndef U_HIDE_INTERNAL_API + /** + * Rounds a value according to the rules of this object. + * @internal + */ + DigitList& _round(const DigitList& number, DigitList& adjustedNum, UBool& isNegative, UErrorCode& status) const; +#endif /* U_HIDE_INTERNAL_API */ + + /** + * Returns the currency in effect for this formatter. Subclasses + * should override this method as needed. Unlike getCurrency(), + * this method should never return "". + * @result output parameter for null-terminated result, which must + * have a capacity of at least 4 + * @internal + */ + virtual void getEffectiveCurrency(char16_t* result, UErrorCode& ec) const; + + /** number of integer digits + * @stable ICU 2.4 + */ static const int32_t kDoubleIntegerDigits; - /** number of fraction digits - * @draft ICU 2.4 - */ + /** number of fraction digits + * @stable ICU 2.4 + */ static const int32_t kDoubleFractionDigits; -}; -inline UClassID -DecimalFormat::getStaticClassID(void) -{ return (UClassID)&fgClassID; } - -inline UClassID -DecimalFormat::getDynamicClassID(void) const -{ return DecimalFormat::getStaticClassID(); } - -inline UnicodeString& -DecimalFormat::format(const Formattable& obj, - UnicodeString& appendTo, - UErrorCode& status) const { - // Don't use Format:: - use immediate base class only, - // in case immediate base modifies behavior later. - return NumberFormat::format(obj, appendTo, status); -} - -inline UnicodeString& -DecimalFormat::format(double number, - UnicodeString& appendTo) const { - FieldPosition pos(0); - return format(number, appendTo, pos); -} - -inline UnicodeString& -DecimalFormat::format(int32_t number, - UnicodeString& appendTo) const { - FieldPosition pos(0); - return format(number, appendTo, pos); -} - -inline const UnicodeString & -DecimalFormat::getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const { - return fSymbols->getConstSymbol(symbol); -} + /** + * When someone turns on scientific mode, we assume that more than this + * number of digits is due to flipping from some other mode that didn't + * restrict the maximum, and so we force 1 integer digit. We don't bother + * to track and see if someone is using exponential notation with more than + * this number, it wouldn't make sense anyway, and this is just to make sure + * that someone turning on scientific mode with default settings doesn't + * end up with lots of zeroes. + * @stable ICU 2.8 + */ + static const int32_t kMaxScientificIntegerDigits; + +}; U_NAMESPACE_END +#endif // U_SHOW_CPLUSPLUS_API #endif /* #if !UCONFIG_NO_FORMATTING */