ICU 73.2  73.2
numberformatter.h
Go to the documentation of this file.
1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #ifndef __NUMBERFORMATTER_H__
5 #define __NUMBERFORMATTER_H__
6 
7 #include "unicode/utypes.h"
8 
9 #if U_SHOW_CPLUSPLUS_API
10 
11 #if !UCONFIG_NO_FORMATTING
12 
13 #include "unicode/appendable.h"
14 #include "unicode/bytestream.h"
15 #include "unicode/currunit.h"
16 #include "unicode/dcfmtsym.h"
17 #include "unicode/displayoptions.h"
18 #include "unicode/fieldpos.h"
19 #include "unicode/fpositer.h"
20 #include "unicode/measunit.h"
21 #include "unicode/nounit.h"
22 #include "unicode/parseerr.h"
23 #include "unicode/plurrule.h"
24 #include "unicode/ucurr.h"
25 #include "unicode/unum.h"
27 #include "unicode/uobject.h"
28 #include "unicode/unumberoptions.h"
30 
86 U_NAMESPACE_BEGIN
87 
88 // Forward declarations:
89 class IFixedDecimal;
90 class FieldPositionIteratorHandler;
91 class FormattedStringBuilder;
92 
93 namespace numparse {
94 namespace impl {
95 
96 // Forward declarations:
97 class NumberParserImpl;
98 class MultiplierParseHandler;
99 
100 }
101 }
102 
103 namespace units {
104 
105 // Forward declarations:
106 class UnitsRouter;
107 
108 } // namespace units
109 
110 namespace number { // icu::number
111 
112 // Forward declarations:
113 class UnlocalizedNumberFormatter;
114 class LocalizedNumberFormatter;
115 class SimpleNumberFormatter;
116 class FormattedNumber;
117 class Notation;
118 class ScientificNotation;
119 class Precision;
120 class FractionPrecision;
121 class CurrencyPrecision;
122 class IncrementPrecision;
123 class IntegerWidth;
124 
125 namespace impl {
126 
127 // can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes
133 typedef int16_t digits_t;
134 
135 // can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization
142 static constexpr int32_t kInternalDefaultThreshold = 3;
143 
144 // Forward declarations:
145 class Padder;
146 struct MacroProps;
147 struct MicroProps;
148 class DecimalQuantity;
149 class UFormattedNumberData;
150 class NumberFormatterImpl;
151 struct ParsedPatternInfo;
152 class ScientificModifier;
153 class MultiplierProducer;
154 class RoundingImpl;
155 class ScientificHandler;
156 class Modifier;
157 class AffixPatternProvider;
158 class NumberPropertyMapper;
159 struct DecimalFormatProperties;
160 class MultiplierFormatHandler;
161 class CurrencySymbols;
162 class GeneratorHelpers;
163 class DecNum;
164 class NumberRangeFormatterImpl;
165 struct RangeMacroProps;
166 struct UFormattedNumberImpl;
167 class MutablePatternModifier;
168 class ImmutablePatternModifier;
169 struct DecimalFormatWarehouse;
170 struct SimpleMicroProps;
171 class AdoptingSignumModifierStore;
172 
179 void touchRangeLocales(impl::RangeMacroProps& macros);
180 
181 } // namespace impl
182 
188 typedef Notation CompactNotation;
189 
195 typedef Notation SimpleNotation;
196 
202 class U_I18N_API Notation : public UMemory {
203  public:
228  static ScientificNotation scientific();
229 
252  static ScientificNotation engineering();
253 
295  static CompactNotation compactShort();
296 
319  static CompactNotation compactLong();
320 
345  static SimpleNotation simple();
346 
347  private:
348  enum NotationType {
349  NTN_SCIENTIFIC, NTN_COMPACT, NTN_SIMPLE, NTN_ERROR
350  } fType;
351 
352  union NotationUnion {
353  // For NTN_SCIENTIFIC
361  impl::digits_t fMinExponentDigits;
364  } scientific;
365 
366  // For NTN_COMPACT
367  UNumberCompactStyle compactStyle;
368 
369  // For NTN_ERROR
370  UErrorCode errorCode;
371  } fUnion;
372 
374 
375  Notation(const NotationType &type, const NotationUnion &union_) : fType(type), fUnion(union_) {}
376 
377  Notation(UErrorCode errorCode) : fType(NTN_ERROR) {
378  fUnion.errorCode = errorCode;
379  }
380 
381  Notation() : fType(NTN_SIMPLE), fUnion() {}
382 
383  UBool copyErrorTo(UErrorCode &status) const {
384  if (fType == NTN_ERROR) {
385  status = fUnion.errorCode;
386  return true;
387  }
388  return false;
389  }
390 
391  // To allow MacroProps to initialize empty instances:
392  friend struct impl::MacroProps;
393  friend class ScientificNotation;
394 
395  // To allow implementation to access internal types:
396  friend class impl::NumberFormatterImpl;
397  friend class impl::ScientificModifier;
398  friend class impl::ScientificHandler;
399 
400  // To allow access to the skeleton generation code:
401  friend class impl::GeneratorHelpers;
402 };
403 
413  public:
427  ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const;
428 
442  ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const;
443 
444  private:
445  // Inherit constructor
446  using Notation::Notation;
447 
448  // Raw constructor for NumberPropertyMapper
449  ScientificNotation(int8_t fEngineeringInterval, bool fRequireMinInt, impl::digits_t fMinExponentDigits,
450  UNumberSignDisplay fExponentSignDisplay);
451 
452  friend class Notation;
453 
454  // So that NumberPropertyMapper can create instances
455  friend class impl::NumberPropertyMapper;
456 };
457 
464 
473 class U_I18N_API Precision : public UMemory {
474 
475  public:
493  static Precision unlimited();
494 
501  static FractionPrecision integer();
502 
530  static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces);
531 
545  static FractionPrecision minFraction(int32_t minFractionPlaces);
546 
557  static FractionPrecision maxFraction(int32_t maxFractionPlaces);
558 
572  static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces);
573 
587  static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits);
588 
601  static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits);
602 
611  static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits);
612 
624  static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits,
625  int32_t maxSignificantDigits);
626 
646  static IncrementPrecision increment(double roundingIncrement);
647 
671  static IncrementPrecision incrementExact(uint64_t mantissa, int16_t magnitude);
672 
690  static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
691 
699  Precision trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const;
700 
701  private:
702  enum PrecisionType {
703  RND_BOGUS,
704  RND_NONE,
705  RND_FRACTION,
706  RND_SIGNIFICANT,
707  RND_FRACTION_SIGNIFICANT,
708 
709  // Used for strange increments like 3.14.
710  RND_INCREMENT,
711 
712  // Used for increments with 1 as the only digit. This is different than fraction
713  // rounding because it supports having additional trailing zeros. For example, this
714  // class is used to round with the increment 0.010.
715  RND_INCREMENT_ONE,
716 
717  // Used for increments with 5 as the only digit (nickel rounding).
718  RND_INCREMENT_FIVE,
719 
720  RND_CURRENCY,
721  RND_ERROR
722  } fType;
723 
724  union PrecisionUnion {
727  // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT
729  impl::digits_t fMinFrac;
731  impl::digits_t fMaxFrac;
733  impl::digits_t fMinSig;
735  impl::digits_t fMaxSig;
742  bool fRetain;
743  } fracSig;
746  // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE
747  // Note: This is a union, so we shouldn't own memory, since
748  // the default destructor would leak it.
750  uint64_t fIncrement;
752  impl::digits_t fIncrementMagnitude;
754  impl::digits_t fMinFrac;
755  } increment;
756  UCurrencyUsage currencyUsage; // For RND_CURRENCY
757  UErrorCode errorCode; // For RND_ERROR
758  } fUnion;
759 
761 
764 
765  Precision(const PrecisionType& type, const PrecisionUnion& union_)
766  : fType(type), fUnion(union_) {}
767 
768  Precision(UErrorCode errorCode) : fType(RND_ERROR) {
769  fUnion.errorCode = errorCode;
770  }
771 
772  Precision() : fType(RND_BOGUS) {}
773 
774  bool isBogus() const {
775  return fType == RND_BOGUS;
776  }
777 
778  UBool copyErrorTo(UErrorCode &status) const {
779  if (fType == RND_ERROR) {
780  status = fUnion.errorCode;
781  return true;
782  }
783  return false;
784  }
785 
786  // On the parent type so that this method can be called internally on Precision instances.
787  Precision withCurrency(const CurrencyUnit &currency, UErrorCode &status) const;
788 
789  static FractionPrecision constructFraction(int32_t minFrac, int32_t maxFrac);
790 
791  static Precision constructSignificant(int32_t minSig, int32_t maxSig);
792 
793  static Precision constructFractionSignificant(
794  const FractionPrecision &base,
795  int32_t minSig,
796  int32_t maxSig,
797  UNumberRoundingPriority priority,
798  bool retain);
799 
800  static IncrementPrecision constructIncrement(uint64_t increment, impl::digits_t magnitude);
801 
802  static CurrencyPrecision constructCurrency(UCurrencyUsage usage);
803 
804  // To allow MacroProps/MicroProps to initialize bogus instances:
805  friend struct impl::MacroProps;
806  friend struct impl::MicroProps;
807 
808  // To allow NumberFormatterImpl to access isBogus() and other internal methods:
809  friend class impl::NumberFormatterImpl;
810 
811  // To allow NumberPropertyMapper to create instances from DecimalFormatProperties:
812  friend class impl::NumberPropertyMapper;
813 
814  // To allow access to the main implementation class:
815  friend class impl::RoundingImpl;
816 
817  // To allow child classes to call private methods:
818  friend class FractionPrecision;
819  friend class CurrencyPrecision;
820  friend class IncrementPrecision;
821 
822  // To allow access to the skeleton generation code:
823  friend class impl::GeneratorHelpers;
824 
825  // To allow access to isBogus and the default (bogus) constructor:
826  friend class units::UnitsRouter;
827 };
828 
839  public:
854  Precision withSignificantDigits(
855  int32_t minSignificantDigits,
856  int32_t maxSignificantDigits,
857  UNumberRoundingPriority priority) const;
858 
876  Precision withMinDigits(int32_t minSignificantDigits) const;
877 
895  Precision withMaxDigits(int32_t maxSignificantDigits) const;
896 
897  private:
898  // Inherit constructor
899  using Precision::Precision;
900 
901  // To allow parent class to call this class's constructor:
902  friend class Precision;
903 };
904 
915  public:
933  Precision withCurrency(const CurrencyUnit &currency) const;
934 
935  private:
936  // Inherit constructor
937  using Precision::Precision;
938 
939  // To allow parent class to call this class's constructor:
940  friend class Precision;
941 };
942 
953  public:
969  Precision withMinFraction(int32_t minFrac) const;
970 
971  private:
972  // Inherit constructor
973  using Precision::Precision;
974 
975  // To allow parent class to call this class's constructor:
976  friend class Precision;
977 };
978 
989  public:
1001  static IntegerWidth zeroFillTo(int32_t minInt);
1002 
1014  IntegerWidth truncateAt(int32_t maxInt);
1015 
1016  private:
1017  union {
1018  struct {
1019  impl::digits_t fMinInt;
1020  impl::digits_t fMaxInt;
1021  bool fFormatFailIfMoreThanMaxDigits;
1022  } minMaxInt;
1023  UErrorCode errorCode;
1024  } fUnion;
1025  bool fHasError = false;
1026 
1027  IntegerWidth(impl::digits_t minInt, impl::digits_t maxInt, bool formatFailIfMoreThanMaxDigits);
1028 
1029  IntegerWidth(UErrorCode errorCode) { // NOLINT
1030  fUnion.errorCode = errorCode;
1031  fHasError = true;
1032  }
1033 
1034  IntegerWidth() { // NOLINT
1035  fUnion.minMaxInt.fMinInt = -1;
1036  }
1037 
1039  static IntegerWidth standard() {
1040  return IntegerWidth::zeroFillTo(1);
1041  }
1042 
1043  bool isBogus() const {
1044  return !fHasError && fUnion.minMaxInt.fMinInt == -1;
1045  }
1046 
1047  UBool copyErrorTo(UErrorCode &status) const {
1048  if (fHasError) {
1049  status = fUnion.errorCode;
1050  return true;
1051  }
1052  return false;
1053  }
1054 
1055  void apply(impl::DecimalQuantity &quantity, UErrorCode &status) const;
1056 
1057  bool operator==(const IntegerWidth& other) const;
1058 
1059  // To allow MacroProps/MicroProps to initialize empty instances:
1060  friend struct impl::MacroProps;
1061  friend struct impl::MicroProps;
1062 
1063  // To allow NumberFormatterImpl to access isBogus():
1064  friend class impl::NumberFormatterImpl;
1065 
1066  // To allow the use of this class when formatting:
1067  friend class impl::MutablePatternModifier;
1068  friend class impl::ImmutablePatternModifier;
1069 
1070  // So that NumberPropertyMapper can create instances
1071  friend class impl::NumberPropertyMapper;
1072 
1073  // To allow access to the skeleton generation code:
1074  friend class impl::GeneratorHelpers;
1075 };
1076 
1085 class U_I18N_API Scale : public UMemory {
1086  public:
1093  static Scale none();
1094 
1105  static Scale powerOfTen(int32_t power);
1106 
1119  static Scale byDecimal(StringPiece multiplicand);
1120 
1129  static Scale byDouble(double multiplicand);
1130 
1137  static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power);
1138 
1139  // We need a custom destructor for the DecNum, which means we need to declare
1140  // the copy/move constructor/assignment quartet.
1141 
1143  Scale(const Scale& other);
1144 
1146  Scale& operator=(const Scale& other);
1147 
1149  Scale(Scale&& src) noexcept;
1150 
1152  Scale& operator=(Scale&& src) noexcept;
1153 
1155  ~Scale();
1156 
1157 #ifndef U_HIDE_INTERNAL_API
1158 
1159  Scale(int32_t magnitude, impl::DecNum* arbitraryToAdopt);
1160 #endif /* U_HIDE_INTERNAL_API */
1161 
1162  private:
1163  int32_t fMagnitude;
1164  impl::DecNum* fArbitrary;
1165  UErrorCode fError;
1166 
1167  Scale(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {}
1168 
1169  Scale() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {}
1170 
1171  bool isValid() const {
1172  return fMagnitude != 0 || fArbitrary != nullptr;
1173  }
1174 
1175  UBool copyErrorTo(UErrorCode &status) const {
1176  if (U_FAILURE(fError)) {
1177  status = fError;
1178  return true;
1179  }
1180  return false;
1181  }
1182 
1183  void applyTo(impl::DecimalQuantity& quantity) const;
1184 
1185  void applyReciprocalTo(impl::DecimalQuantity& quantity) const;
1186 
1187  // To allow MacroProps/MicroProps to initialize empty instances:
1188  friend struct impl::MacroProps;
1189  friend struct impl::MicroProps;
1190 
1191  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1192  friend class impl::NumberFormatterImpl;
1193 
1194  // To allow the helper class MultiplierFormatHandler access to private fields:
1195  friend class impl::MultiplierFormatHandler;
1196 
1197  // To allow access to the skeleton generation code:
1198  friend class impl::GeneratorHelpers;
1199 
1200  // To allow access to parsing code:
1201  friend class ::icu::numparse::impl::NumberParserImpl;
1202  friend class ::icu::numparse::impl::MultiplierParseHandler;
1203 };
1204 
1205 namespace impl {
1206 
1207 // Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field.
1208 // And do not enclose its class boilerplate within #ifndef U_HIDE_INTERNAL_API.
1214 
1215  public:
1217  ~StringProp();
1218 
1220  StringProp(const StringProp &other);
1221 
1223  StringProp &operator=(const StringProp &other);
1224 
1225 #ifndef U_HIDE_INTERNAL_API
1226 
1228  StringProp(StringProp &&src) noexcept;
1229 
1231  StringProp &operator=(StringProp &&src) noexcept;
1232 
1234  int16_t length() const {
1235  return fLength;
1236  }
1237 
1241  void set(StringPiece value);
1242 
1244  bool isSet() const {
1245  return fLength > 0;
1246  }
1247 
1248 #endif // U_HIDE_INTERNAL_API
1249 
1250  private:
1251  char *fValue;
1252  int16_t fLength;
1253  UErrorCode fError;
1254 
1255  StringProp() : fValue(nullptr), fLength(0), fError(U_ZERO_ERROR) {
1256  }
1257 
1259  UBool copyErrorTo(UErrorCode &status) const {
1260  if (U_FAILURE(fError)) {
1261  status = fError;
1262  return true;
1263  }
1264  return false;
1265  }
1266 
1267  // Allow NumberFormatterImpl to access fValue.
1268  friend class impl::NumberFormatterImpl;
1269 
1270  // Allow skeleton generation code to access private members.
1271  friend class impl::GeneratorHelpers;
1272 
1273  // Allow MacroProps/MicroProps to initialize empty instances and to call
1274  // copyErrorTo().
1275  friend struct impl::MacroProps;
1276 };
1277 
1278 // Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1281  public:
1283  SymbolsWrapper() : fType(SYMPTR_NONE), fPtr{nullptr} {}
1284 
1286  SymbolsWrapper(const SymbolsWrapper &other);
1287 
1289  SymbolsWrapper &operator=(const SymbolsWrapper &other);
1290 
1292  SymbolsWrapper(SymbolsWrapper&& src) noexcept;
1293 
1295  SymbolsWrapper &operator=(SymbolsWrapper&& src) noexcept;
1296 
1298  ~SymbolsWrapper();
1299 
1300 #ifndef U_HIDE_INTERNAL_API
1301 
1306  void setTo(const DecimalFormatSymbols &dfs);
1307 
1312  void setTo(const NumberingSystem *ns);
1313 
1318  bool isDecimalFormatSymbols() const;
1319 
1324  bool isNumberingSystem() const;
1325 
1330  const DecimalFormatSymbols *getDecimalFormatSymbols() const;
1331 
1336  const NumberingSystem *getNumberingSystem() const;
1337 
1338 #endif // U_HIDE_INTERNAL_API
1339 
1341  UBool copyErrorTo(UErrorCode &status) const {
1342  if (fType == SYMPTR_DFS && fPtr.dfs == nullptr) {
1343  status = U_MEMORY_ALLOCATION_ERROR;
1344  return true;
1345  } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) {
1346  status = U_MEMORY_ALLOCATION_ERROR;
1347  return true;
1348  }
1349  return false;
1350  }
1351 
1352  private:
1353  enum SymbolsPointerType {
1354  SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS
1355  } fType;
1356 
1357  union {
1358  const DecimalFormatSymbols *dfs;
1359  const NumberingSystem *ns;
1360  } fPtr;
1361 
1362  void doCopyFrom(const SymbolsWrapper &other);
1363 
1364  void doMoveFrom(SymbolsWrapper&& src);
1365 
1366  void doCleanup();
1367 };
1368 
1369 // Do not enclose entire Grouper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1371 class U_I18N_API Grouper : public UMemory {
1372  public:
1373 #ifndef U_HIDE_INTERNAL_API
1374 
1375  static Grouper forStrategy(UNumberGroupingStrategy grouping);
1376 
1381  static Grouper forProperties(const DecimalFormatProperties& properties);
1382 
1383  // Future: static Grouper forProperties(DecimalFormatProperties& properties);
1384 
1386  Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy)
1387  : fGrouping1(grouping1),
1388  fGrouping2(grouping2),
1389  fMinGrouping(minGrouping),
1390  fStrategy(strategy) {}
1391 
1393  int16_t getPrimary() const;
1394 
1396  int16_t getSecondary() const;
1397 #endif // U_HIDE_INTERNAL_API
1398 
1399  private:
1408  int16_t fGrouping1;
1409  int16_t fGrouping2;
1410 
1418  int16_t fMinGrouping;
1419 
1424  UNumberGroupingStrategy fStrategy;
1425 
1426  Grouper() : fGrouping1(-3) {}
1427 
1428  bool isBogus() const {
1429  return fGrouping1 == -3;
1430  }
1431 
1433  void setLocaleData(const impl::ParsedPatternInfo &patternInfo, const Locale& locale);
1434 
1435  bool groupAtPosition(int32_t position, const impl::DecimalQuantity &value) const;
1436 
1437  // To allow MacroProps/MicroProps to initialize empty instances:
1438  friend struct MacroProps;
1439  friend struct MicroProps;
1440  friend struct SimpleMicroProps;
1441 
1442  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1443  friend class NumberFormatterImpl;
1444  friend class ::icu::number::SimpleNumberFormatter;
1445 
1446  // To allow NumberParserImpl to perform setLocaleData():
1447  friend class ::icu::numparse::impl::NumberParserImpl;
1448 
1449  // To allow access to the skeleton generation code:
1450  friend class impl::GeneratorHelpers;
1451 };
1452 
1453 // Do not enclose entire Padder with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1455 class U_I18N_API Padder : public UMemory {
1456  public:
1457 #ifndef U_HIDE_INTERNAL_API
1458 
1459  static Padder none();
1460 
1462  static Padder codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position);
1463 
1465  static Padder forProperties(const DecimalFormatProperties& properties);
1466 #endif // U_HIDE_INTERNAL_API
1467 
1468  private:
1469  UChar32 fWidth; // -3 = error; -2 = bogus; -1 = no padding
1470  union {
1471  struct {
1472  int32_t fCp;
1473  UNumberFormatPadPosition fPosition;
1474  } padding;
1475  UErrorCode errorCode;
1476  } fUnion;
1477 
1478  Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position);
1479 
1480  Padder(int32_t width);
1481 
1482  Padder(UErrorCode errorCode) : fWidth(-3) { // NOLINT
1483  fUnion.errorCode = errorCode;
1484  }
1485 
1486  Padder() : fWidth(-2) {} // NOLINT
1487 
1488  bool isBogus() const {
1489  return fWidth == -2;
1490  }
1491 
1492  UBool copyErrorTo(UErrorCode &status) const {
1493  if (fWidth == -3) {
1494  status = fUnion.errorCode;
1495  return true;
1496  }
1497  return false;
1498  }
1499 
1500  bool isValid() const {
1501  return fWidth > 0;
1502  }
1503 
1504  int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2,
1505  FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
1506  UErrorCode &status) const;
1507 
1508  // To allow MacroProps/MicroProps to initialize empty instances:
1509  friend struct MacroProps;
1510  friend struct MicroProps;
1511 
1512  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1513  friend class impl::NumberFormatterImpl;
1514 
1515  // To allow access to the skeleton generation code:
1516  friend class impl::GeneratorHelpers;
1517 };
1518 
1519 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1521 struct U_I18N_API MacroProps : public UMemory {
1524 
1526  MeasureUnit unit; // = MeasureUnit(); (the base dimensionless unit)
1527 
1529  MeasureUnit perUnit; // = MeasureUnit(); (the base dimensionless unit)
1530 
1532  Precision precision; // = Precision(); (bogus)
1533 
1536 
1538  Grouper grouper; // = Grouper(); (bogus)
1539 
1541  Padder padder; // = Padder(); (bogus)
1542 
1544  IntegerWidth integerWidth; // = IntegerWidth(); (bogus)
1545 
1548 
1549  // UNUM_XYZ_COUNT denotes null (bogus) values.
1550 
1553 
1556 
1558  bool approximately = false;
1559 
1562 
1564  Scale scale; // = Scale(); (benign value)
1565 
1567  StringProp usage; // = StringProp(); (no usage)
1568 
1570  StringProp unitDisplayCase; // = StringProp(); (nominative)
1571 
1573  const AffixPatternProvider* affixProvider = nullptr; // no ownership
1574 
1576  const PluralRules* rules = nullptr; // no ownership
1577 
1579  int32_t threshold = kInternalDefaultThreshold;
1580 
1583 
1584  // NOTE: Uses default copy and move constructors.
1585 
1590  bool copyErrorTo(UErrorCode &status) const {
1591  return notation.copyErrorTo(status) || precision.copyErrorTo(status) ||
1592  padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) ||
1593  symbols.copyErrorTo(status) || scale.copyErrorTo(status) || usage.copyErrorTo(status) ||
1594  unitDisplayCase.copyErrorTo(status);
1595  }
1596 };
1597 
1598 } // namespace impl
1599 
1600 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER)
1601 // Ignore MSVC warning 4661. This is generated for NumberFormatterSettings<>::toSkeleton() as this method
1602 // is defined elsewhere (in number_skeletons.cpp). The compiler is warning that the explicit template instantiation
1603 // inside this single translation unit (CPP file) is incomplete, and thus it isn't sure if the template class is
1604 // fully defined. However, since each translation unit explicitly instantiates all the necessary template classes,
1605 // they will all be passed to the linker, and the linker will still find and export all the class members.
1606 #pragma warning(push)
1607 #pragma warning(disable: 4661)
1608 #endif
1609 
1615 template<typename Derived>
1617  public:
1646  Derived notation(const Notation &notation) const &;
1647 
1657  Derived notation(const Notation &notation) &&;
1658 
1707  Derived unit(const icu::MeasureUnit &unit) const &;
1708 
1718  Derived unit(const icu::MeasureUnit &unit) &&;
1719 
1733  Derived adoptUnit(icu::MeasureUnit *unit) const &;
1734 
1744  Derived adoptUnit(icu::MeasureUnit *unit) &&;
1745 
1768  Derived perUnit(const icu::MeasureUnit &perUnit) const &;
1769 
1779  Derived perUnit(const icu::MeasureUnit &perUnit) &&;
1780 
1794  Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &;
1795 
1805  Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&;
1806 
1837  Derived precision(const Precision& precision) const &;
1838 
1848  Derived precision(const Precision& precision) &&;
1849 
1868  Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &;
1869 
1878  Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&;
1879 
1907  Derived grouping(UNumberGroupingStrategy strategy) const &;
1908 
1918  Derived grouping(UNumberGroupingStrategy strategy) &&;
1919 
1944  Derived integerWidth(const IntegerWidth &style) const &;
1945 
1955  Derived integerWidth(const IntegerWidth &style) &&;
1956 
1997  Derived symbols(const DecimalFormatSymbols &symbols) const &;
1998 
2008  Derived symbols(const DecimalFormatSymbols &symbols) &&;
2009 
2043  Derived adoptSymbols(NumberingSystem *symbols) const &;
2044 
2054  Derived adoptSymbols(NumberingSystem *symbols) &&;
2055 
2081  Derived unitWidth(UNumberUnitWidth width) const &;
2082 
2092  Derived unitWidth(UNumberUnitWidth width) &&;
2093 
2119  Derived sign(UNumberSignDisplay style) const &;
2120 
2130  Derived sign(UNumberSignDisplay style) &&;
2131 
2157  Derived decimal(UNumberDecimalSeparatorDisplay style) const &;
2158 
2168  Derived decimal(UNumberDecimalSeparatorDisplay style) &&;
2169 
2194  Derived scale(const Scale &scale) const &;
2195 
2205  Derived scale(const Scale &scale) &&;
2206 
2249  Derived usage(StringPiece usage) const &;
2250 
2258  Derived usage(StringPiece usage) &&;
2259 
2260 #ifndef U_HIDE_DRAFT_API
2261 
2269  Derived displayOptions(const DisplayOptions &displayOptions) const &;
2270 
2278  Derived displayOptions(const DisplayOptions &displayOptions) &&;
2279 #endif // U_HIDE_DRAFT_API
2280 
2281 #ifndef U_HIDE_INTERNAL_API
2282 
2292  Derived unitDisplayCase(StringPiece unitDisplayCase) const &;
2293 
2303  Derived unitDisplayCase(StringPiece unitDisplayCase) &&;
2304 #endif // U_HIDE_INTERNAL_API
2305 
2306 #ifndef U_HIDE_INTERNAL_API
2307 
2313  Derived padding(const impl::Padder &padder) const &;
2314 
2316  Derived padding(const impl::Padder &padder) &&;
2317 
2324  Derived threshold(int32_t threshold) const &;
2325 
2327  Derived threshold(int32_t threshold) &&;
2328 
2334  Derived macros(const impl::MacroProps& macros) const &;
2335 
2337  Derived macros(const impl::MacroProps& macros) &&;
2338 
2340  Derived macros(impl::MacroProps&& macros) const &;
2341 
2343  Derived macros(impl::MacroProps&& macros) &&;
2344 
2345 #endif /* U_HIDE_INTERNAL_API */
2346 
2364  UnicodeString toSkeleton(UErrorCode& status) const;
2365 
2377  LocalPointer<Derived> clone() const &;
2378 
2386  LocalPointer<Derived> clone() &&;
2387 
2394  UBool copyErrorTo(UErrorCode &outErrorCode) const {
2395  if (U_FAILURE(outErrorCode)) {
2396  // Do not overwrite the older error code
2397  return true;
2398  }
2399  fMacros.copyErrorTo(outErrorCode);
2400  return U_FAILURE(outErrorCode);
2401  }
2402 
2403  // NOTE: Uses default copy and move constructors.
2404 
2405  private:
2406  impl::MacroProps fMacros;
2407 
2408  // Don't construct me directly! Use (Un)LocalizedNumberFormatter.
2409  NumberFormatterSettings() = default;
2410 
2411  friend class LocalizedNumberFormatter;
2412  friend class UnlocalizedNumberFormatter;
2413 
2414  // Give NumberRangeFormatter access to the MacroProps
2415  friend void impl::touchRangeLocales(impl::RangeMacroProps& macros);
2416  friend class impl::NumberRangeFormatterImpl;
2417 };
2418 
2419 // Explicit instantiations in source/i18n/number_fluent.cpp.
2420 // (MSVC treats imports/exports of explicit instantiations differently.)
2421 #ifndef _MSC_VER
2422 extern template class NumberFormatterSettings<UnlocalizedNumberFormatter>;
2423 extern template class NumberFormatterSettings<LocalizedNumberFormatter>;
2424 #endif
2425 
2436 
2437  public:
2447  LocalizedNumberFormatter locale(const icu::Locale &locale) const &;
2448 
2458  LocalizedNumberFormatter locale(const icu::Locale &locale) &&;
2459 
2465  UnlocalizedNumberFormatter() = default;
2466 
2472 
2479 
2484  UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other);
2485 
2491  UnlocalizedNumberFormatter& operator=(UnlocalizedNumberFormatter&& src) noexcept;
2492 
2493  private:
2495 
2496  explicit UnlocalizedNumberFormatter(
2498 
2499  // To give the fluent setters access to this class's constructor:
2501 
2502  // To give NumberFormatter::with() access to this class's constructor:
2503  friend class NumberFormatter;
2504 };
2505 
2516  public:
2528  FormattedNumber formatInt(int64_t value, UErrorCode &status) const;
2529 
2541  FormattedNumber formatDouble(double value, UErrorCode &status) const;
2542 
2557  FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const;
2558 
2559 #ifndef U_HIDE_INTERNAL_API
2560 
2561 
2565  const DecimalFormatSymbols* getDecimalFormatSymbols() const;
2566 
2570  FormattedNumber formatDecimalQuantity(const impl::DecimalQuantity& dq, UErrorCode& status) const;
2571 
2575  void getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const;
2576 
2581  const impl::NumberFormatterImpl* getCompiled() const;
2582 
2587  int32_t getCallCount() const;
2588 
2589 #endif /* U_HIDE_INTERNAL_API */
2590 
2604  Format* toFormat(UErrorCode& status) const;
2605 
2611  LocalizedNumberFormatter() = default;
2612 
2618 
2625 
2630  LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other);
2631 
2637  LocalizedNumberFormatter& operator=(LocalizedNumberFormatter&& src) noexcept;
2638 
2639 #ifndef U_HIDE_INTERNAL_API
2640 
2653  void formatImpl(impl::UFormattedNumberData *results, UErrorCode &status) const;
2654 
2655 #endif /* U_HIDE_INTERNAL_API */
2656 
2662 
2663  private:
2664  // Note: fCompiled can't be a LocalPointer because impl::NumberFormatterImpl is defined in an internal
2665  // header, and LocalPointer needs the full class definition in order to delete the instance.
2666  const impl::NumberFormatterImpl* fCompiled {nullptr};
2667  char fUnsafeCallCount[8] {}; // internally cast to u_atomic_int32_t
2668 
2669  // Owned pointer to a DecimalFormatWarehouse, used when copying a LocalizedNumberFormatter
2670  // from a DecimalFormat.
2671  const impl::DecimalFormatWarehouse* fWarehouse {nullptr};
2672 
2674 
2676 
2677  LocalizedNumberFormatter(const impl::MacroProps &macros, const Locale &locale);
2678 
2679  LocalizedNumberFormatter(impl::MacroProps &&macros, const Locale &locale);
2680 
2681  void resetCompiled();
2682 
2683  void lnfMoveHelper(LocalizedNumberFormatter&& src);
2684 
2685  void lnfCopyHelper(const LocalizedNumberFormatter& src, UErrorCode& status);
2686 
2690  bool computeCompiled(UErrorCode& status) const;
2691 
2692  // To give the fluent setters access to this class's constructor:
2695 
2696  // To give UnlocalizedNumberFormatter::locale() access to this class's constructor:
2697  friend class UnlocalizedNumberFormatter;
2698 };
2699 
2700 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER)
2701 // Warning 4661.
2702 #pragma warning(pop)
2703 #endif
2704 
2711  public:
2719  static UnlocalizedNumberFormatter with();
2720 
2730  static LocalizedNumberFormatter withLocale(const Locale &locale);
2731 
2749  static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status);
2750 
2771  static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton,
2772  UParseError& perror, UErrorCode& status);
2773 
2777  NumberFormatter() = delete;
2778 };
2779 
2780 } // namespace number
2781 U_NAMESPACE_END
2782 
2783 #endif /* #if !UCONFIG_NO_FORMATTING */
2784 
2785 #endif /* U_SHOW_CPLUSPLUS_API */
2786 
2787 #endif // __NUMBERFORMATTER_H__
One more than the highest UNumberSignDisplay value.
Base class for all formats.
Definition: format.h:98
C++ API: Display options class.
This class represents the set of symbols needed by DecimalFormat to format numbers.
Definition: dcfmtsym.h:86
A unit such as length, mass, volume, currency, etc.
Definition: measunit.h:369
C++ API: Currency Unit Information.
C API: Localized number formatting; not recommended for C++.
bool copyErrorTo(UErrorCode &status) const
Check all members for errors.
See the main description in numberformatter.h for documentation and examples.
#define U_FAILURE(x)
Does the error code indicate a failure?
Definition: utypes.h:717
A class that defines the strategy for padding and truncating integers before the decimal separator...
C++ API: FieldPosition Iterator.
UNumberGroupingStrategy
An enum declaring the strategy for when and how to display grouping separators (i.e., the separator, often a comma or period, after every 2-3 powers of ten).
&quot;Smart pointer&quot; class, deletes objects via the standard C++ delete operator.
Definition: localpointer.h:191
U_EXPORT UBool operator==(const StringPiece &x, const StringPiece &y)
Global operator == for StringPiece.
Defines numbering systems.
Definition: numsys.h:60
C API: Formatted number result from various number formatting functions.
C++ API: Appendable class: Sink for Unicode code points and 16-bit code units (char16_ts).
C++ API: units for percent and permille.
No error, no warning.
Definition: utypes.h:449
C++ API: PluralRules object.
A class that defines a rounding precision parameterized by a rounding increment to be used when forma...
UNumberDecimalSeparatorDisplay
An enum declaring how to render the decimal separator.
Defines rules for mapping non-negative numeric values onto a small set of keywords.
Definition: plurrule.h:212
bool fRetain
Whether to retain trailing zeros based on the looser strategy.
Memory allocation error.
Definition: utypes.h:457
C API: Header-only input options for various number formatting APIs.
An abstract base class for specifying settings related to number formatting.
Half-even rounding.
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside...
Definition: utypes.h:301
C++ API: FieldPosition identifies the fields in a formatted output.
A class that defines the notation style to be used when formatting numbers in NumberFormatter.
C++ API: Interface for writing bytes, and implementation classes.
UNumberTrailingZeroDisplay
An enum declaring how to render trailing zeros.
C++ API: A unit for measuring a quantity.
C API: Encapsulates information about a currency.
UNumberSignDisplay
An enum declaring how to denote positive and negative numbers.
Represents all the display options that are supported by CLDR such as grammatical case...
A class that defines a rounding precision based on a number of fraction places and optionally signifi...
UCurrencyUsage
Currency Usage used for Decimal Format.
Definition: ucurr.h:41
Manages NumberFormatterSettings::usage()&#39;s char* instance on the heap.
int32_t UChar32
Define UChar32 as a type for single Unicode code points.
Definition: umachine.h:435
A class that defines a rounding precision parameterized by a currency to be used when formatting numb...
A unit of currency, such as USD (U.S.
Definition: currunit.h:39
UNumberFormatPadPosition
The possible number format pad positions.
Definition: unum.h:278
C++ API: Common ICU base class UObject.
A NumberFormatter that does not yet have a locale.
UNumberCompactStyle
Constants for specifying short or long format.
Definition: unum.h:289
C API: Parse Error Information.
A NumberFormatter that has a locale associated with it; this means .format() methods are available...
UNumberFormatRoundingMode
The possible number format rounding modes.
UBool copyErrorTo(UErrorCode &outErrorCode) const
Sets the UErrorCode if an error occurred in the fluent chain.
UBool copyErrorTo(UErrorCode &status) const
A class that defines a quantity by which a number should be multiplied when formatting.
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition: utypes.h:415
C++ API: Symbols for formatting numbers.
A class that defines the scientific notation style to be used when formatting numbers in NumberFormat...
UNumberUnitWidth
An enum declaring how to render units, including currencies.
A UParseError struct is used to returned detailed information about parsing errors.
Definition: parseerr.h:58
Basic definitions for ICU, for both C and C++ APIs.
UnicodeString is a string class that stores Unicode characters directly and provides similar function...
Definition: unistr.h:295
The result of a number formatting operation.
Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy)
A string-like object that points to a sized piece of memory.
Definition: stringpiece.h:60
UMemory is the common ICU base class.
Definition: uobject.h:115
A class that defines the rounding precision to be used when formatting numbers in NumberFormatter...
One more than the highest UNumberDecimalSeparatorDisplay value.
Display trailing zeros according to the settings for minimum fraction and significant digits...
One more than the highest UNumberUnitWidth value.
int8_t UBool
The ICU boolean type, a signed-byte integer.
Definition: umachine.h:247
UNumberRoundingPriority
An enum declaring how to resolve conflicts between maximum fraction digits and maximum significant di...
C API: Compatibility APIs for number formatting.
A Locale object represents a specific geographical, political, or cultural region.
Definition: locid.h:195