// © 2017 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html #ifndef __NUMBERFORMATTER_H__ #define __NUMBERFORMATTER_H__ #include "unicode/utypes.h" #if U_SHOW_CPLUSPLUS_API #if !UCONFIG_NO_FORMATTING #include "unicode/appendable.h" #include "unicode/bytestream.h" #include "unicode/currunit.h" #include "unicode/dcfmtsym.h" #include "unicode/displayoptions.h" #include "unicode/fieldpos.h" #include "unicode/fpositer.h" #include "unicode/measunit.h" #include "unicode/nounit.h" #include "unicode/parseerr.h" #include "unicode/plurrule.h" #include "unicode/ucurr.h" #include "unicode/unum.h" #include "unicode/unumberformatter.h" #include "unicode/uobject.h" #include "unicode/unumberoptions.h" #include "unicode/formattednumber.h" /** * \file * \brief C++ API: All-in-one formatter for localized numbers, currencies, and units. * * For a full list of options, see icu::number::NumberFormatterSettings. * * <pre> * // Most basic usage: * NumberFormatter::withLocale(...).format(123).toString(); // 1,234 in en-US * * // Custom notation, unit, and rounding precision: * NumberFormatter::with() * .notation(Notation::compactShort()) * .unit(CurrencyUnit("EUR", status)) * .precision(Precision::maxDigits(2)) * .locale(...) * .format(1234) * .toString(); // €1.2K in en-US * * // Create a formatter in a singleton by value for use later: * static const LocalizedNumberFormatter formatter = NumberFormatter::withLocale(...) * .unit(NoUnit::percent()) * .precision(Precision::fixedFraction(3)); * formatter.format(5.9831).toString(); // 5.983% in en-US * * // Create a "template" in a singleton unique_ptr but without setting a locale until the call site: * std::unique_ptr<UnlocalizedNumberFormatter> template = NumberFormatter::with() * .sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS) * .unit(MeasureUnit::getMeter()) * .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME) * .clone(); * template->locale(...).format(1234).toString(); // +1,234 meters in en-US * </pre> * * <p> * This API offers more features than DecimalFormat and is geared toward new users of ICU. * * <p> * NumberFormatter instances (i.e., LocalizedNumberFormatter and UnlocalizedNumberFormatter) * are immutable and thread safe. This means that invoking a configuration method has no * effect on the receiving instance; you must store and use the new number formatter instance it returns instead. * * <pre> * UnlocalizedNumberFormatter formatter = UnlocalizedNumberFormatter::with().notation(Notation::scientific()); * formatter.precision(Precision.maxFraction(2)); // does nothing! * formatter.locale(Locale.getEnglish()).format(9.8765).toString(); // prints "9.8765E0", not "9.88E0" * </pre> * * <p> * This API is based on the <em>fluent</em> design pattern popularized by libraries such as Google's Guava. For * extensive details on the design of this API, read <a href="https://goo.gl/szi5VB">the design doc</a>. * * <p> * Note: To format monetary/currency values, specify the currency in the `.unit()` function. * * @author Shane Carr */ U_NAMESPACE_BEGIN // Forward declarations: class IFixedDecimal; class FieldPositionIteratorHandler; class FormattedStringBuilder; namespace numparse { namespace impl { // Forward declarations: class NumberParserImpl; class MultiplierParseHandler; } } namespace units { // Forward declarations: class UnitsRouter; } // namespace units namespace number { // icu::number // Forward declarations: class UnlocalizedNumberFormatter; class LocalizedNumberFormatter; class SimpleNumberFormatter; class FormattedNumber; class Notation; class ScientificNotation; class Precision; class FractionPrecision; class CurrencyPrecision; class IncrementPrecision; class IntegerWidth; namespace impl { // can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes /** * Datatype for minimum/maximum fraction digits. Must be able to hold kMaxIntFracSig. * * @internal */ digits_t; // can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization /** * Use a default threshold of 3. This means that the third time .format() is called, the data structures get built * using the "safe" code path. The first two calls to .format() will trigger the unsafe code path. * * @internal */ static constexpr int32_t kInternalDefaultThreshold = …; // Forward declarations: class Padder; struct MacroProps; struct MicroProps; class DecimalQuantity; class UFormattedNumberData; class NumberFormatterImpl; struct ParsedPatternInfo; class ScientificModifier; class MultiplierProducer; class RoundingImpl; class ScientificHandler; class Modifier; class AffixPatternProvider; class NumberPropertyMapper; struct DecimalFormatProperties; class MultiplierFormatHandler; class CurrencySymbols; class GeneratorHelpers; class DecNum; class NumberRangeFormatterImpl; struct RangeMacroProps; struct UFormattedNumberImpl; class MutablePatternModifier; class ImmutablePatternModifier; struct DecimalFormatWarehouse; struct SimpleMicroProps; class AdoptingSignumModifierStore; /** * Used for NumberRangeFormatter and implemented in numrange_fluent.cpp. * Declared here so it can be friended. * * @internal */ void touchRangeLocales(impl::RangeMacroProps& macros); } // namespace impl /** * Extra name reserved in case it is needed in the future. * * @stable ICU 63 */ CompactNotation; /** * Extra name reserved in case it is needed in the future. * * @stable ICU 63 */ SimpleNotation; /** * A class that defines the notation style to be used when formatting numbers in NumberFormatter. * * @stable ICU 60 */ class U_I18N_API Notation : public UMemory { … }; /** * A class that defines the scientific notation style to be used when formatting numbers in NumberFormatter. * * <p> * To create a ScientificNotation, use one of the factory methods in {@link Notation}. * * @stable ICU 60 */ class U_I18N_API ScientificNotation : public Notation { … }; /** * Extra name reserved in case it is needed in the future. * * @stable ICU 63 */ SignificantDigitsPrecision; /** * A class that defines the rounding precision to be used when formatting numbers in NumberFormatter. * * <p> * To create a Precision, use one of the factory methods. * * @stable ICU 60 */ class U_I18N_API Precision : public UMemory { … }; /** * A class that defines a rounding precision based on a number of fraction places and optionally significant digits to be * used when formatting numbers in NumberFormatter. * * <p> * To create a FractionPrecision, use one of the factory methods on Precision. * * @stable ICU 60 */ class U_I18N_API FractionPrecision : public Precision { … }; /** * A class that defines a rounding precision parameterized by a currency to be used when formatting numbers in * NumberFormatter. * * <p> * To create a CurrencyPrecision, use one of the factory methods on Precision. * * @stable ICU 60 */ class U_I18N_API CurrencyPrecision : public Precision { … }; /** * A class that defines a rounding precision parameterized by a rounding increment to be used when formatting numbers in * NumberFormatter. * * <p> * To create an IncrementPrecision, use one of the factory methods on Precision. * * @stable ICU 60 */ class U_I18N_API IncrementPrecision : public Precision { … }; /** * A class that defines the strategy for padding and truncating integers before the decimal separator. * * <p> * To create an IntegerWidth, use one of the factory methods. * * @stable ICU 60 * @see NumberFormatter */ class U_I18N_API IntegerWidth : public UMemory { … }; /** * A class that defines a quantity by which a number should be multiplied when formatting. * * <p> * To create a Scale, use one of the factory methods. * * @stable ICU 62 */ class U_I18N_API Scale : public UMemory { … }; namespace impl { // Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field. // And do not enclose its class boilerplate within #ifndef U_HIDE_INTERNAL_API. /** * Manages NumberFormatterSettings::usage()'s char* instance on the heap. * @internal */ class U_I18N_API StringProp : public UMemory { … }; // Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field /** @internal */ class U_I18N_API SymbolsWrapper : public UMemory { … }; // Do not enclose entire Grouper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field /** @internal */ class U_I18N_API Grouper : public UMemory { … }; // Do not enclose entire Padder with #ifndef U_HIDE_INTERNAL_API, needed for a protected field /** @internal */ class U_I18N_API Padder : public UMemory { … }; // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field /** @internal */ struct U_I18N_API MacroProps : public UMemory { … }; } // namespace impl #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER) // Ignore MSVC warning 4661. This is generated for NumberFormatterSettings<>::toSkeleton() as this method // is defined elsewhere (in number_skeletons.cpp). The compiler is warning that the explicit template instantiation // inside this single translation unit (CPP file) is incomplete, and thus it isn't sure if the template class is // fully defined. However, since each translation unit explicitly instantiates all the necessary template classes, // they will all be passed to the linker, and the linker will still find and export all the class members. #pragma warning(push) #pragma warning(disable: 4661) #endif /** * An abstract base class for specifying settings related to number formatting. This class is implemented by * {@link UnlocalizedNumberFormatter} and {@link LocalizedNumberFormatter}. This class is not intended for * public subclassing. */ template<typename Derived> class U_I18N_API NumberFormatterSettings { … }; // Explicit instantiations in source/i18n/number_fluent.cpp. // (MSVC treats imports/exports of explicit instantiations differently.) #ifndef _MSC_VER extern template class NumberFormatterSettings<UnlocalizedNumberFormatter>; extern template class NumberFormatterSettings<LocalizedNumberFormatter>; #endif /** * A NumberFormatter that does not yet have a locale. In order to format numbers, a locale must be specified. * * Instances of this class are immutable and thread-safe. * * @see NumberFormatter * @stable ICU 60 */ class U_I18N_API UnlocalizedNumberFormatter : public NumberFormatterSettings<UnlocalizedNumberFormatter>, public UMemory { … }; /** * A NumberFormatter that has a locale associated with it; this means .format() methods are available. * * Instances of this class are immutable and thread-safe. * * @see NumberFormatter * @stable ICU 60 */ class U_I18N_API LocalizedNumberFormatter : public NumberFormatterSettings<LocalizedNumberFormatter>, public UMemory { … }; #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER) // Warning 4661. #pragma warning(pop) #endif /** * See the main description in numberformatter.h for documentation and examples. * * @stable ICU 60 */ class U_I18N_API NumberFormatter final { … }; } // namespace number U_NAMESPACE_END #endif /* #if !UCONFIG_NO_FORMATTING */ #endif /* U_SHOW_CPLUSPLUS_API */ #endif // __NUMBERFORMATTER_H__