|
ICU 73.2
73.2
|
00001 // © 2017 and later: Unicode, Inc. and others. 00002 // License & terms of use: http://www.unicode.org/copyright.html 00003 00004 #ifndef __NUMBERFORMATTER_H__ 00005 #define __NUMBERFORMATTER_H__ 00006 00007 #include "unicode/utypes.h" 00008 00009 #if U_SHOW_CPLUSPLUS_API 00010 00011 #if !UCONFIG_NO_FORMATTING 00012 00013 #include "unicode/appendable.h" 00014 #include "unicode/bytestream.h" 00015 #include "unicode/currunit.h" 00016 #include "unicode/dcfmtsym.h" 00017 #include "unicode/displayoptions.h" 00018 #include "unicode/fieldpos.h" 00019 #include "unicode/fpositer.h" 00020 #include "unicode/measunit.h" 00021 #include "unicode/nounit.h" 00022 #include "unicode/parseerr.h" 00023 #include "unicode/plurrule.h" 00024 #include "unicode/ucurr.h" 00025 #include "unicode/unum.h" 00026 #include "unicode/unumberformatter.h" 00027 #include "unicode/uobject.h" 00028 #include "unicode/unumberoptions.h" 00029 #include "unicode/formattednumber.h" 00030 00086 U_NAMESPACE_BEGIN 00087 00088 // Forward declarations: 00089 class IFixedDecimal; 00090 class FieldPositionIteratorHandler; 00091 class FormattedStringBuilder; 00092 00093 namespace numparse { 00094 namespace impl { 00095 00096 // Forward declarations: 00097 class NumberParserImpl; 00098 class MultiplierParseHandler; 00099 00100 } 00101 } 00102 00103 namespace units { 00104 00105 // Forward declarations: 00106 class UnitsRouter; 00107 00108 } // namespace units 00109 00110 namespace number { // icu::number 00111 00112 // Forward declarations: 00113 class UnlocalizedNumberFormatter; 00114 class LocalizedNumberFormatter; 00115 class SimpleNumberFormatter; 00116 class FormattedNumber; 00117 class Notation; 00118 class ScientificNotation; 00119 class Precision; 00120 class FractionPrecision; 00121 class CurrencyPrecision; 00122 class IncrementPrecision; 00123 class IntegerWidth; 00124 00125 namespace impl { 00126 00127 // can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes 00133 typedef int16_t digits_t; 00134 00135 // can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization 00142 static constexpr int32_t kInternalDefaultThreshold = 3; 00143 00144 // Forward declarations: 00145 class Padder; 00146 struct MacroProps; 00147 struct MicroProps; 00148 class DecimalQuantity; 00149 class UFormattedNumberData; 00150 class NumberFormatterImpl; 00151 struct ParsedPatternInfo; 00152 class ScientificModifier; 00153 class MultiplierProducer; 00154 class RoundingImpl; 00155 class ScientificHandler; 00156 class Modifier; 00157 class AffixPatternProvider; 00158 class NumberPropertyMapper; 00159 struct DecimalFormatProperties; 00160 class MultiplierFormatHandler; 00161 class CurrencySymbols; 00162 class GeneratorHelpers; 00163 class DecNum; 00164 class NumberRangeFormatterImpl; 00165 struct RangeMacroProps; 00166 struct UFormattedNumberImpl; 00167 class MutablePatternModifier; 00168 class ImmutablePatternModifier; 00169 struct DecimalFormatWarehouse; 00170 struct SimpleMicroProps; 00171 class AdoptingSignumModifierStore; 00172 00179 void touchRangeLocales(impl::RangeMacroProps& macros); 00180 00181 } // namespace impl 00182 00188 typedef Notation CompactNotation; 00189 00195 typedef Notation SimpleNotation; 00196 00202 class U_I18N_API Notation : public UMemory { 00203 public: 00228 static ScientificNotation scientific(); 00229 00252 static ScientificNotation engineering(); 00253 00295 static CompactNotation compactShort(); 00296 00319 static CompactNotation compactLong(); 00320 00345 static SimpleNotation simple(); 00346 00347 private: 00348 enum NotationType { 00349 NTN_SCIENTIFIC, NTN_COMPACT, NTN_SIMPLE, NTN_ERROR 00350 } fType; 00351 00352 union NotationUnion { 00353 // For NTN_SCIENTIFIC 00355 struct ScientificSettings { 00357 int8_t fEngineeringInterval; 00359 bool fRequireMinInt; 00361 impl::digits_t fMinExponentDigits; 00363 UNumberSignDisplay fExponentSignDisplay; 00364 } scientific; 00365 00366 // For NTN_COMPACT 00367 UNumberCompactStyle compactStyle; 00368 00369 // For NTN_ERROR 00370 UErrorCode errorCode; 00371 } fUnion; 00372 00373 typedef NotationUnion::ScientificSettings ScientificSettings; 00374 00375 Notation(const NotationType &type, const NotationUnion &union_) : fType(type), fUnion(union_) {} 00376 00377 Notation(UErrorCode errorCode) : fType(NTN_ERROR) { 00378 fUnion.errorCode = errorCode; 00379 } 00380 00381 Notation() : fType(NTN_SIMPLE), fUnion() {} 00382 00383 UBool copyErrorTo(UErrorCode &status) const { 00384 if (fType == NTN_ERROR) { 00385 status = fUnion.errorCode; 00386 return true; 00387 } 00388 return false; 00389 } 00390 00391 // To allow MacroProps to initialize empty instances: 00392 friend struct impl::MacroProps; 00393 friend class ScientificNotation; 00394 00395 // To allow implementation to access internal types: 00396 friend class impl::NumberFormatterImpl; 00397 friend class impl::ScientificModifier; 00398 friend class impl::ScientificHandler; 00399 00400 // To allow access to the skeleton generation code: 00401 friend class impl::GeneratorHelpers; 00402 }; 00403 00412 class U_I18N_API ScientificNotation : public Notation { 00413 public: 00427 ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const; 00428 00442 ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const; 00443 00444 private: 00445 // Inherit constructor 00446 using Notation::Notation; 00447 00448 // Raw constructor for NumberPropertyMapper 00449 ScientificNotation(int8_t fEngineeringInterval, bool fRequireMinInt, impl::digits_t fMinExponentDigits, 00450 UNumberSignDisplay fExponentSignDisplay); 00451 00452 friend class Notation; 00453 00454 // So that NumberPropertyMapper can create instances 00455 friend class impl::NumberPropertyMapper; 00456 }; 00457 00463 typedef Precision SignificantDigitsPrecision; 00464 00473 class U_I18N_API Precision : public UMemory { 00474 00475 public: 00493 static Precision unlimited(); 00494 00501 static FractionPrecision integer(); 00502 00530 static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces); 00531 00545 static FractionPrecision minFraction(int32_t minFractionPlaces); 00546 00557 static FractionPrecision maxFraction(int32_t maxFractionPlaces); 00558 00572 static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces); 00573 00587 static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits); 00588 00601 static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits); 00602 00611 static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits); 00612 00624 static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits, 00625 int32_t maxSignificantDigits); 00626 00646 static IncrementPrecision increment(double roundingIncrement); 00647 00671 static IncrementPrecision incrementExact(uint64_t mantissa, int16_t magnitude); 00672 00690 static CurrencyPrecision currency(UCurrencyUsage currencyUsage); 00691 00699 Precision trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const; 00700 00701 private: 00702 enum PrecisionType { 00703 RND_BOGUS, 00704 RND_NONE, 00705 RND_FRACTION, 00706 RND_SIGNIFICANT, 00707 RND_FRACTION_SIGNIFICANT, 00708 00709 // Used for strange increments like 3.14. 00710 RND_INCREMENT, 00711 00712 // Used for increments with 1 as the only digit. This is different than fraction 00713 // rounding because it supports having additional trailing zeros. For example, this 00714 // class is used to round with the increment 0.010. 00715 RND_INCREMENT_ONE, 00716 00717 // Used for increments with 5 as the only digit (nickel rounding). 00718 RND_INCREMENT_FIVE, 00719 00720 RND_CURRENCY, 00721 RND_ERROR 00722 } fType; 00723 00724 union PrecisionUnion { 00726 struct FractionSignificantSettings { 00727 // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT 00729 impl::digits_t fMinFrac; 00731 impl::digits_t fMaxFrac; 00733 impl::digits_t fMinSig; 00735 impl::digits_t fMaxSig; 00737 UNumberRoundingPriority fPriority; 00742 bool fRetain; 00743 } fracSig; 00745 struct IncrementSettings { 00746 // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE 00747 // Note: This is a union, so we shouldn't own memory, since 00748 // the default destructor would leak it. 00750 uint64_t fIncrement; 00752 impl::digits_t fIncrementMagnitude; 00754 impl::digits_t fMinFrac; 00755 } increment; 00756 UCurrencyUsage currencyUsage; // For RND_CURRENCY 00757 UErrorCode errorCode; // For RND_ERROR 00758 } fUnion; 00759 00760 UNumberTrailingZeroDisplay fTrailingZeroDisplay = UNUM_TRAILING_ZERO_AUTO; 00761 00762 typedef PrecisionUnion::FractionSignificantSettings FractionSignificantSettings; 00763 typedef PrecisionUnion::IncrementSettings IncrementSettings; 00764 00765 Precision(const PrecisionType& type, const PrecisionUnion& union_) 00766 : fType(type), fUnion(union_) {} 00767 00768 Precision(UErrorCode errorCode) : fType(RND_ERROR) { 00769 fUnion.errorCode = errorCode; 00770 } 00771 00772 Precision() : fType(RND_BOGUS) {} 00773 00774 bool isBogus() const { 00775 return fType == RND_BOGUS; 00776 } 00777 00778 UBool copyErrorTo(UErrorCode &status) const { 00779 if (fType == RND_ERROR) { 00780 status = fUnion.errorCode; 00781 return true; 00782 } 00783 return false; 00784 } 00785 00786 // On the parent type so that this method can be called internally on Precision instances. 00787 Precision withCurrency(const CurrencyUnit ¤cy, UErrorCode &status) const; 00788 00789 static FractionPrecision constructFraction(int32_t minFrac, int32_t maxFrac); 00790 00791 static Precision constructSignificant(int32_t minSig, int32_t maxSig); 00792 00793 static Precision constructFractionSignificant( 00794 const FractionPrecision &base, 00795 int32_t minSig, 00796 int32_t maxSig, 00797 UNumberRoundingPriority priority, 00798 bool retain); 00799 00800 static IncrementPrecision constructIncrement(uint64_t increment, impl::digits_t magnitude); 00801 00802 static CurrencyPrecision constructCurrency(UCurrencyUsage usage); 00803 00804 // To allow MacroProps/MicroProps to initialize bogus instances: 00805 friend struct impl::MacroProps; 00806 friend struct impl::MicroProps; 00807 00808 // To allow NumberFormatterImpl to access isBogus() and other internal methods: 00809 friend class impl::NumberFormatterImpl; 00810 00811 // To allow NumberPropertyMapper to create instances from DecimalFormatProperties: 00812 friend class impl::NumberPropertyMapper; 00813 00814 // To allow access to the main implementation class: 00815 friend class impl::RoundingImpl; 00816 00817 // To allow child classes to call private methods: 00818 friend class FractionPrecision; 00819 friend class CurrencyPrecision; 00820 friend class IncrementPrecision; 00821 00822 // To allow access to the skeleton generation code: 00823 friend class impl::GeneratorHelpers; 00824 00825 // To allow access to isBogus and the default (bogus) constructor: 00826 friend class units::UnitsRouter; 00827 }; 00828 00838 class U_I18N_API FractionPrecision : public Precision { 00839 public: 00854 Precision withSignificantDigits( 00855 int32_t minSignificantDigits, 00856 int32_t maxSignificantDigits, 00857 UNumberRoundingPriority priority) const; 00858 00876 Precision withMinDigits(int32_t minSignificantDigits) const; 00877 00895 Precision withMaxDigits(int32_t maxSignificantDigits) const; 00896 00897 private: 00898 // Inherit constructor 00899 using Precision::Precision; 00900 00901 // To allow parent class to call this class's constructor: 00902 friend class Precision; 00903 }; 00904 00914 class U_I18N_API CurrencyPrecision : public Precision { 00915 public: 00933 Precision withCurrency(const CurrencyUnit ¤cy) const; 00934 00935 private: 00936 // Inherit constructor 00937 using Precision::Precision; 00938 00939 // To allow parent class to call this class's constructor: 00940 friend class Precision; 00941 }; 00942 00952 class U_I18N_API IncrementPrecision : public Precision { 00953 public: 00969 Precision withMinFraction(int32_t minFrac) const; 00970 00971 private: 00972 // Inherit constructor 00973 using Precision::Precision; 00974 00975 // To allow parent class to call this class's constructor: 00976 friend class Precision; 00977 }; 00978 00988 class U_I18N_API IntegerWidth : public UMemory { 00989 public: 01001 static IntegerWidth zeroFillTo(int32_t minInt); 01002 01014 IntegerWidth truncateAt(int32_t maxInt); 01015 01016 private: 01017 union { 01018 struct { 01019 impl::digits_t fMinInt; 01020 impl::digits_t fMaxInt; 01021 bool fFormatFailIfMoreThanMaxDigits; 01022 } minMaxInt; 01023 UErrorCode errorCode; 01024 } fUnion; 01025 bool fHasError = false; 01026 01027 IntegerWidth(impl::digits_t minInt, impl::digits_t maxInt, bool formatFailIfMoreThanMaxDigits); 01028 01029 IntegerWidth(UErrorCode errorCode) { // NOLINT 01030 fUnion.errorCode = errorCode; 01031 fHasError = true; 01032 } 01033 01034 IntegerWidth() { // NOLINT 01035 fUnion.minMaxInt.fMinInt = -1; 01036 } 01037 01039 static IntegerWidth standard() { 01040 return IntegerWidth::zeroFillTo(1); 01041 } 01042 01043 bool isBogus() const { 01044 return !fHasError && fUnion.minMaxInt.fMinInt == -1; 01045 } 01046 01047 UBool copyErrorTo(UErrorCode &status) const { 01048 if (fHasError) { 01049 status = fUnion.errorCode; 01050 return true; 01051 } 01052 return false; 01053 } 01054 01055 void apply(impl::DecimalQuantity &quantity, UErrorCode &status) const; 01056 01057 bool operator==(const IntegerWidth& other) const; 01058 01059 // To allow MacroProps/MicroProps to initialize empty instances: 01060 friend struct impl::MacroProps; 01061 friend struct impl::MicroProps; 01062 01063 // To allow NumberFormatterImpl to access isBogus(): 01064 friend class impl::NumberFormatterImpl; 01065 01066 // To allow the use of this class when formatting: 01067 friend class impl::MutablePatternModifier; 01068 friend class impl::ImmutablePatternModifier; 01069 01070 // So that NumberPropertyMapper can create instances 01071 friend class impl::NumberPropertyMapper; 01072 01073 // To allow access to the skeleton generation code: 01074 friend class impl::GeneratorHelpers; 01075 }; 01076 01085 class U_I18N_API Scale : public UMemory { 01086 public: 01093 static Scale none(); 01094 01105 static Scale powerOfTen(int32_t power); 01106 01119 static Scale byDecimal(StringPiece multiplicand); 01120 01129 static Scale byDouble(double multiplicand); 01130 01137 static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power); 01138 01139 // We need a custom destructor for the DecNum, which means we need to declare 01140 // the copy/move constructor/assignment quartet. 01141 01143 Scale(const Scale& other); 01144 01146 Scale& operator=(const Scale& other); 01147 01149 Scale(Scale&& src) noexcept; 01150 01152 Scale& operator=(Scale&& src) noexcept; 01153 01155 ~Scale(); 01156 01157 #ifndef U_HIDE_INTERNAL_API 01158 01159 Scale(int32_t magnitude, impl::DecNum* arbitraryToAdopt); 01160 #endif /* U_HIDE_INTERNAL_API */ 01161 01162 private: 01163 int32_t fMagnitude; 01164 impl::DecNum* fArbitrary; 01165 UErrorCode fError; 01166 01167 Scale(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {} 01168 01169 Scale() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {} 01170 01171 bool isValid() const { 01172 return fMagnitude != 0 || fArbitrary != nullptr; 01173 } 01174 01175 UBool copyErrorTo(UErrorCode &status) const { 01176 if (U_FAILURE(fError)) { 01177 status = fError; 01178 return true; 01179 } 01180 return false; 01181 } 01182 01183 void applyTo(impl::DecimalQuantity& quantity) const; 01184 01185 void applyReciprocalTo(impl::DecimalQuantity& quantity) const; 01186 01187 // To allow MacroProps/MicroProps to initialize empty instances: 01188 friend struct impl::MacroProps; 01189 friend struct impl::MicroProps; 01190 01191 // To allow NumberFormatterImpl to access isBogus() and perform other operations: 01192 friend class impl::NumberFormatterImpl; 01193 01194 // To allow the helper class MultiplierFormatHandler access to private fields: 01195 friend class impl::MultiplierFormatHandler; 01196 01197 // To allow access to the skeleton generation code: 01198 friend class impl::GeneratorHelpers; 01199 01200 // To allow access to parsing code: 01201 friend class ::icu::numparse::impl::NumberParserImpl; 01202 friend class ::icu::numparse::impl::MultiplierParseHandler; 01203 }; 01204 01205 namespace impl { 01206 01207 // Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field. 01208 // And do not enclose its class boilerplate within #ifndef U_HIDE_INTERNAL_API. 01213 class U_I18N_API StringProp : public UMemory { 01214 01215 public: 01217 ~StringProp(); 01218 01220 StringProp(const StringProp &other); 01221 01223 StringProp &operator=(const StringProp &other); 01224 01225 #ifndef U_HIDE_INTERNAL_API 01226 01228 StringProp(StringProp &&src) noexcept; 01229 01231 StringProp &operator=(StringProp &&src) noexcept; 01232 01234 int16_t length() const { 01235 return fLength; 01236 } 01237 01241 void set(StringPiece value); 01242 01244 bool isSet() const { 01245 return fLength > 0; 01246 } 01247 01248 #endif // U_HIDE_INTERNAL_API 01249 01250 private: 01251 char *fValue; 01252 int16_t fLength; 01253 UErrorCode fError; 01254 01255 StringProp() : fValue(nullptr), fLength(0), fError(U_ZERO_ERROR) { 01256 } 01257 01259 UBool copyErrorTo(UErrorCode &status) const { 01260 if (U_FAILURE(fError)) { 01261 status = fError; 01262 return true; 01263 } 01264 return false; 01265 } 01266 01267 // Allow NumberFormatterImpl to access fValue. 01268 friend class impl::NumberFormatterImpl; 01269 01270 // Allow skeleton generation code to access private members. 01271 friend class impl::GeneratorHelpers; 01272 01273 // Allow MacroProps/MicroProps to initialize empty instances and to call 01274 // copyErrorTo(). 01275 friend struct impl::MacroProps; 01276 }; 01277 01278 // Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field 01280 class U_I18N_API SymbolsWrapper : public UMemory { 01281 public: 01283 SymbolsWrapper() : fType(SYMPTR_NONE), fPtr{nullptr} {} 01284 01286 SymbolsWrapper(const SymbolsWrapper &other); 01287 01289 SymbolsWrapper &operator=(const SymbolsWrapper &other); 01290 01292 SymbolsWrapper(SymbolsWrapper&& src) noexcept; 01293 01295 SymbolsWrapper &operator=(SymbolsWrapper&& src) noexcept; 01296 01298 ~SymbolsWrapper(); 01299 01300 #ifndef U_HIDE_INTERNAL_API 01301 01306 void setTo(const DecimalFormatSymbols &dfs); 01307 01312 void setTo(const NumberingSystem *ns); 01313 01318 bool isDecimalFormatSymbols() const; 01319 01324 bool isNumberingSystem() const; 01325 01330 const DecimalFormatSymbols *getDecimalFormatSymbols() const; 01331 01336 const NumberingSystem *getNumberingSystem() const; 01337 01338 #endif // U_HIDE_INTERNAL_API 01339 01341 UBool copyErrorTo(UErrorCode &status) const { 01342 if (fType == SYMPTR_DFS && fPtr.dfs == nullptr) { 01343 status = U_MEMORY_ALLOCATION_ERROR; 01344 return true; 01345 } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) { 01346 status = U_MEMORY_ALLOCATION_ERROR; 01347 return true; 01348 } 01349 return false; 01350 } 01351 01352 private: 01353 enum SymbolsPointerType { 01354 SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS 01355 } fType; 01356 01357 union { 01358 const DecimalFormatSymbols *dfs; 01359 const NumberingSystem *ns; 01360 } fPtr; 01361 01362 void doCopyFrom(const SymbolsWrapper &other); 01363 01364 void doMoveFrom(SymbolsWrapper&& src); 01365 01366 void doCleanup(); 01367 }; 01368 01369 // Do not enclose entire Grouper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field 01371 class U_I18N_API Grouper : public UMemory { 01372 public: 01373 #ifndef U_HIDE_INTERNAL_API 01374 01375 static Grouper forStrategy(UNumberGroupingStrategy grouping); 01376 01381 static Grouper forProperties(const DecimalFormatProperties& properties); 01382 01383 // Future: static Grouper forProperties(DecimalFormatProperties& properties); 01384 01386 Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy) 01387 : fGrouping1(grouping1), 01388 fGrouping2(grouping2), 01389 fMinGrouping(minGrouping), 01390 fStrategy(strategy) {} 01391 01393 int16_t getPrimary() const; 01394 01396 int16_t getSecondary() const; 01397 #endif // U_HIDE_INTERNAL_API 01398 01399 private: 01408 int16_t fGrouping1; 01409 int16_t fGrouping2; 01410 01418 int16_t fMinGrouping; 01419 01424 UNumberGroupingStrategy fStrategy; 01425 01426 Grouper() : fGrouping1(-3) {} 01427 01428 bool isBogus() const { 01429 return fGrouping1 == -3; 01430 } 01431 01433 void setLocaleData(const impl::ParsedPatternInfo &patternInfo, const Locale& locale); 01434 01435 bool groupAtPosition(int32_t position, const impl::DecimalQuantity &value) const; 01436 01437 // To allow MacroProps/MicroProps to initialize empty instances: 01438 friend struct MacroProps; 01439 friend struct MicroProps; 01440 friend struct SimpleMicroProps; 01441 01442 // To allow NumberFormatterImpl to access isBogus() and perform other operations: 01443 friend class NumberFormatterImpl; 01444 friend class ::icu::number::SimpleNumberFormatter; 01445 01446 // To allow NumberParserImpl to perform setLocaleData(): 01447 friend class ::icu::numparse::impl::NumberParserImpl; 01448 01449 // To allow access to the skeleton generation code: 01450 friend class impl::GeneratorHelpers; 01451 }; 01452 01453 // Do not enclose entire Padder with #ifndef U_HIDE_INTERNAL_API, needed for a protected field 01455 class U_I18N_API Padder : public UMemory { 01456 public: 01457 #ifndef U_HIDE_INTERNAL_API 01458 01459 static Padder none(); 01460 01462 static Padder codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position); 01463 01465 static Padder forProperties(const DecimalFormatProperties& properties); 01466 #endif // U_HIDE_INTERNAL_API 01467 01468 private: 01469 UChar32 fWidth; // -3 = error; -2 = bogus; -1 = no padding 01470 union { 01471 struct { 01472 int32_t fCp; 01473 UNumberFormatPadPosition fPosition; 01474 } padding; 01475 UErrorCode errorCode; 01476 } fUnion; 01477 01478 Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position); 01479 01480 Padder(int32_t width); 01481 01482 Padder(UErrorCode errorCode) : fWidth(-3) { // NOLINT 01483 fUnion.errorCode = errorCode; 01484 } 01485 01486 Padder() : fWidth(-2) {} // NOLINT 01487 01488 bool isBogus() const { 01489 return fWidth == -2; 01490 } 01491 01492 UBool copyErrorTo(UErrorCode &status) const { 01493 if (fWidth == -3) { 01494 status = fUnion.errorCode; 01495 return true; 01496 } 01497 return false; 01498 } 01499 01500 bool isValid() const { 01501 return fWidth > 0; 01502 } 01503 01504 int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2, 01505 FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex, 01506 UErrorCode &status) const; 01507 01508 // To allow MacroProps/MicroProps to initialize empty instances: 01509 friend struct MacroProps; 01510 friend struct MicroProps; 01511 01512 // To allow NumberFormatterImpl to access isBogus() and perform other operations: 01513 friend class impl::NumberFormatterImpl; 01514 01515 // To allow access to the skeleton generation code: 01516 friend class impl::GeneratorHelpers; 01517 }; 01518 01519 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field 01521 struct U_I18N_API MacroProps : public UMemory { 01523 Notation notation; 01524 01526 MeasureUnit unit; // = MeasureUnit(); (the base dimensionless unit) 01527 01529 MeasureUnit perUnit; // = MeasureUnit(); (the base dimensionless unit) 01530 01532 Precision precision; // = Precision(); (bogus) 01533 01535 UNumberFormatRoundingMode roundingMode = UNUM_ROUND_HALFEVEN; 01536 01538 Grouper grouper; // = Grouper(); (bogus) 01539 01541 Padder padder; // = Padder(); (bogus) 01542 01544 IntegerWidth integerWidth; // = IntegerWidth(); (bogus) 01545 01547 SymbolsWrapper symbols; 01548 01549 // UNUM_XYZ_COUNT denotes null (bogus) values. 01550 01552 UNumberUnitWidth unitWidth = UNUM_UNIT_WIDTH_COUNT; 01553 01555 UNumberSignDisplay sign = UNUM_SIGN_COUNT; 01556 01558 bool approximately = false; 01559 01561 UNumberDecimalSeparatorDisplay decimal = UNUM_DECIMAL_SEPARATOR_COUNT; 01562 01564 Scale scale; // = Scale(); (benign value) 01565 01567 StringProp usage; // = StringProp(); (no usage) 01568 01570 StringProp unitDisplayCase; // = StringProp(); (nominative) 01571 01573 const AffixPatternProvider* affixProvider = nullptr; // no ownership 01574 01576 const PluralRules* rules = nullptr; // no ownership 01577 01579 int32_t threshold = kInternalDefaultThreshold; 01580 01582 Locale locale; 01583 01584 // NOTE: Uses default copy and move constructors. 01585 01590 bool copyErrorTo(UErrorCode &status) const { 01591 return notation.copyErrorTo(status) || precision.copyErrorTo(status) || 01592 padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) || 01593 symbols.copyErrorTo(status) || scale.copyErrorTo(status) || usage.copyErrorTo(status) || 01594 unitDisplayCase.copyErrorTo(status); 01595 } 01596 }; 01597 01598 } // namespace impl 01599 01600 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER) 01601 // Ignore MSVC warning 4661. This is generated for NumberFormatterSettings<>::toSkeleton() as this method 01602 // is defined elsewhere (in number_skeletons.cpp). The compiler is warning that the explicit template instantiation 01603 // inside this single translation unit (CPP file) is incomplete, and thus it isn't sure if the template class is 01604 // fully defined. However, since each translation unit explicitly instantiates all the necessary template classes, 01605 // they will all be passed to the linker, and the linker will still find and export all the class members. 01606 #pragma warning(push) 01607 #pragma warning(disable: 4661) 01608 #endif 01609 01615 template<typename Derived> 01616 class U_I18N_API NumberFormatterSettings { 01617 public: 01646 Derived notation(const Notation ¬ation) const &; 01647 01657 Derived notation(const Notation ¬ation) &&; 01658 01707 Derived unit(const icu::MeasureUnit &unit) const &; 01708 01718 Derived unit(const icu::MeasureUnit &unit) &&; 01719 01733 Derived adoptUnit(icu::MeasureUnit *unit) const &; 01734 01744 Derived adoptUnit(icu::MeasureUnit *unit) &&; 01745 01768 Derived perUnit(const icu::MeasureUnit &perUnit) const &; 01769 01779 Derived perUnit(const icu::MeasureUnit &perUnit) &&; 01780 01794 Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &; 01795 01805 Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&; 01806 01837 Derived precision(const Precision& precision) const &; 01838 01848 Derived precision(const Precision& precision) &&; 01849 01868 Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &; 01869 01878 Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&; 01879 01907 Derived grouping(UNumberGroupingStrategy strategy) const &; 01908 01918 Derived grouping(UNumberGroupingStrategy strategy) &&; 01919 01944 Derived integerWidth(const IntegerWidth &style) const &; 01945 01955 Derived integerWidth(const IntegerWidth &style) &&; 01956 01997 Derived symbols(const DecimalFormatSymbols &symbols) const &; 01998 02008 Derived symbols(const DecimalFormatSymbols &symbols) &&; 02009 02043 Derived adoptSymbols(NumberingSystem *symbols) const &; 02044 02054 Derived adoptSymbols(NumberingSystem *symbols) &&; 02055 02081 Derived unitWidth(UNumberUnitWidth width) const &; 02082 02092 Derived unitWidth(UNumberUnitWidth width) &&; 02093 02119 Derived sign(UNumberSignDisplay style) const &; 02120 02130 Derived sign(UNumberSignDisplay style) &&; 02131 02157 Derived decimal(UNumberDecimalSeparatorDisplay style) const &; 02158 02168 Derived decimal(UNumberDecimalSeparatorDisplay style) &&; 02169 02194 Derived scale(const Scale &scale) const &; 02195 02205 Derived scale(const Scale &scale) &&; 02206 02249 Derived usage(StringPiece usage) const &; 02250 02258 Derived usage(StringPiece usage) &&; 02259 02260 #ifndef U_HIDE_DRAFT_API 02261 02269 Derived displayOptions(const DisplayOptions &displayOptions) const &; 02270 02278 Derived displayOptions(const DisplayOptions &displayOptions) &&; 02279 #endif // U_HIDE_DRAFT_API 02280 02281 #ifndef U_HIDE_INTERNAL_API 02282 02292 Derived unitDisplayCase(StringPiece unitDisplayCase) const &; 02293 02303 Derived unitDisplayCase(StringPiece unitDisplayCase) &&; 02304 #endif // U_HIDE_INTERNAL_API 02305 02306 #ifndef U_HIDE_INTERNAL_API 02307 02313 Derived padding(const impl::Padder &padder) const &; 02314 02316 Derived padding(const impl::Padder &padder) &&; 02317 02324 Derived threshold(int32_t threshold) const &; 02325 02327 Derived threshold(int32_t threshold) &&; 02328 02334 Derived macros(const impl::MacroProps& macros) const &; 02335 02337 Derived macros(const impl::MacroProps& macros) &&; 02338 02340 Derived macros(impl::MacroProps&& macros) const &; 02341 02343 Derived macros(impl::MacroProps&& macros) &&; 02344 02345 #endif /* U_HIDE_INTERNAL_API */ 02346 02364 UnicodeString toSkeleton(UErrorCode& status) const; 02365 02377 LocalPointer<Derived> clone() const &; 02378 02386 LocalPointer<Derived> clone() &&; 02387 02394 UBool copyErrorTo(UErrorCode &outErrorCode) const { 02395 if (U_FAILURE(outErrorCode)) { 02396 // Do not overwrite the older error code 02397 return true; 02398 } 02399 fMacros.copyErrorTo(outErrorCode); 02400 return U_FAILURE(outErrorCode); 02401 } 02402 02403 // NOTE: Uses default copy and move constructors. 02404 02405 private: 02406 impl::MacroProps fMacros; 02407 02408 // Don't construct me directly! Use (Un)LocalizedNumberFormatter. 02409 NumberFormatterSettings() = default; 02410 02411 friend class LocalizedNumberFormatter; 02412 friend class UnlocalizedNumberFormatter; 02413 02414 // Give NumberRangeFormatter access to the MacroProps 02415 friend void impl::touchRangeLocales(impl::RangeMacroProps& macros); 02416 friend class impl::NumberRangeFormatterImpl; 02417 }; 02418 02419 // Explicit instantiations in source/i18n/number_fluent.cpp. 02420 // (MSVC treats imports/exports of explicit instantiations differently.) 02421 #ifndef _MSC_VER 02422 extern template class NumberFormatterSettings<UnlocalizedNumberFormatter>; 02423 extern template class NumberFormatterSettings<LocalizedNumberFormatter>; 02424 #endif 02425 02434 class U_I18N_API UnlocalizedNumberFormatter 02435 : public NumberFormatterSettings<UnlocalizedNumberFormatter>, public UMemory { 02436 02437 public: 02447 LocalizedNumberFormatter locale(const icu::Locale &locale) const &; 02448 02458 LocalizedNumberFormatter locale(const icu::Locale &locale) &&; 02459 02465 UnlocalizedNumberFormatter() = default; 02466 02471 UnlocalizedNumberFormatter(const UnlocalizedNumberFormatter &other); 02472 02478 UnlocalizedNumberFormatter(UnlocalizedNumberFormatter&& src) noexcept; 02479 02484 UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other); 02485 02491 UnlocalizedNumberFormatter& operator=(UnlocalizedNumberFormatter&& src) noexcept; 02492 02493 private: 02494 explicit UnlocalizedNumberFormatter(const NumberFormatterSettings<UnlocalizedNumberFormatter>& other); 02495 02496 explicit UnlocalizedNumberFormatter( 02497 NumberFormatterSettings<UnlocalizedNumberFormatter>&& src) noexcept; 02498 02499 // To give the fluent setters access to this class's constructor: 02500 friend class NumberFormatterSettings<UnlocalizedNumberFormatter>; 02501 02502 // To give NumberFormatter::with() access to this class's constructor: 02503 friend class NumberFormatter; 02504 }; 02505 02514 class U_I18N_API LocalizedNumberFormatter 02515 : public NumberFormatterSettings<LocalizedNumberFormatter>, public UMemory { 02516 public: 02528 FormattedNumber formatInt(int64_t value, UErrorCode &status) const; 02529 02541 FormattedNumber formatDouble(double value, UErrorCode &status) const; 02542 02557 FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const; 02558 02559 #ifndef U_HIDE_INTERNAL_API 02560 02561 02565 const DecimalFormatSymbols* getDecimalFormatSymbols() const; 02566 02570 FormattedNumber formatDecimalQuantity(const impl::DecimalQuantity& dq, UErrorCode& status) const; 02571 02575 void getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const; 02576 02581 const impl::NumberFormatterImpl* getCompiled() const; 02582 02587 int32_t getCallCount() const; 02588 02589 #endif /* U_HIDE_INTERNAL_API */ 02590 02604 Format* toFormat(UErrorCode& status) const; 02605 02611 LocalizedNumberFormatter() = default; 02612 02617 LocalizedNumberFormatter(const LocalizedNumberFormatter &other); 02618 02624 LocalizedNumberFormatter(LocalizedNumberFormatter&& src) noexcept; 02625 02630 LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other); 02631 02637 LocalizedNumberFormatter& operator=(LocalizedNumberFormatter&& src) noexcept; 02638 02639 #ifndef U_HIDE_INTERNAL_API 02640 02653 void formatImpl(impl::UFormattedNumberData *results, UErrorCode &status) const; 02654 02655 #endif /* U_HIDE_INTERNAL_API */ 02656 02661 ~LocalizedNumberFormatter(); 02662 02663 private: 02664 // Note: fCompiled can't be a LocalPointer because impl::NumberFormatterImpl is defined in an internal 02665 // header, and LocalPointer needs the full class definition in order to delete the instance. 02666 const impl::NumberFormatterImpl* fCompiled {nullptr}; 02667 char fUnsafeCallCount[8] {}; // internally cast to u_atomic_int32_t 02668 02669 // Owned pointer to a DecimalFormatWarehouse, used when copying a LocalizedNumberFormatter 02670 // from a DecimalFormat. 02671 const impl::DecimalFormatWarehouse* fWarehouse {nullptr}; 02672 02673 explicit LocalizedNumberFormatter(const NumberFormatterSettings<LocalizedNumberFormatter>& other); 02674 02675 explicit LocalizedNumberFormatter(NumberFormatterSettings<LocalizedNumberFormatter>&& src) noexcept; 02676 02677 LocalizedNumberFormatter(const impl::MacroProps ¯os, const Locale &locale); 02678 02679 LocalizedNumberFormatter(impl::MacroProps &¯os, const Locale &locale); 02680 02681 void resetCompiled(); 02682 02683 void lnfMoveHelper(LocalizedNumberFormatter&& src); 02684 02685 void lnfCopyHelper(const LocalizedNumberFormatter& src, UErrorCode& status); 02686 02690 bool computeCompiled(UErrorCode& status) const; 02691 02692 // To give the fluent setters access to this class's constructor: 02693 friend class NumberFormatterSettings<UnlocalizedNumberFormatter>; 02694 friend class NumberFormatterSettings<LocalizedNumberFormatter>; 02695 02696 // To give UnlocalizedNumberFormatter::locale() access to this class's constructor: 02697 friend class UnlocalizedNumberFormatter; 02698 }; 02699 02700 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER) 02701 // Warning 4661. 02702 #pragma warning(pop) 02703 #endif 02704 02710 class U_I18N_API NumberFormatter final { 02711 public: 02719 static UnlocalizedNumberFormatter with(); 02720 02730 static LocalizedNumberFormatter withLocale(const Locale &locale); 02731 02749 static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status); 02750 02771 static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, 02772 UParseError& perror, UErrorCode& status); 02773 02777 NumberFormatter() = delete; 02778 }; 02779 02780 } // namespace number 02781 U_NAMESPACE_END 02782 02783 #endif /* #if !UCONFIG_NO_FORMATTING */ 02784 02785 #endif /* U_SHOW_CPLUSPLUS_API */ 02786 02787 #endif // __NUMBERFORMATTER_H__
1.7.6.1