ICU 72.1  72.1
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/formattedvalue.h"
20 #include "unicode/fpositer.h"
21 #include "unicode/measunit.h"
22 #include "unicode/nounit.h"
23 #include "unicode/parseerr.h"
24 #include "unicode/plurrule.h"
25 #include "unicode/ucurr.h"
27 #include "unicode/unum.h"
29 #include "unicode/uobject.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 FormattedNumber;
116 class Notation;
117 class ScientificNotation;
118 class Precision;
119 class FractionPrecision;
120 class CurrencyPrecision;
121 class IncrementPrecision;
122 class IntegerWidth;
123 
124 namespace impl {
125 
126 // can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes
132 typedef int16_t digits_t;
133 
134 // can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization
141 static constexpr int32_t kInternalDefaultThreshold = 3;
142 
143 // Forward declarations:
144 class Padder;
145 struct MacroProps;
146 struct MicroProps;
147 class DecimalQuantity;
148 class UFormattedNumberData;
149 class NumberFormatterImpl;
150 struct ParsedPatternInfo;
151 class ScientificModifier;
152 class MultiplierProducer;
153 class RoundingImpl;
154 class ScientificHandler;
155 class Modifier;
156 class AffixPatternProvider;
157 class NumberPropertyMapper;
158 struct DecimalFormatProperties;
159 class MultiplierFormatHandler;
160 class CurrencySymbols;
161 class GeneratorHelpers;
162 class DecNum;
163 class NumberRangeFormatterImpl;
164 struct RangeMacroProps;
165 struct UFormattedNumberImpl;
166 class MutablePatternModifier;
167 class ImmutablePatternModifier;
168 struct DecimalFormatWarehouse;
169 
176 void touchRangeLocales(impl::RangeMacroProps& macros);
177 
178 } // namespace impl
179 
185 typedef Notation CompactNotation;
186 
192 typedef Notation SimpleNotation;
193 
199 class U_I18N_API Notation : public UMemory {
200  public:
225  static ScientificNotation scientific();
226 
249  static ScientificNotation engineering();
250 
292  static CompactNotation compactShort();
293 
316  static CompactNotation compactLong();
317 
342  static SimpleNotation simple();
343 
344  private:
345  enum NotationType {
346  NTN_SCIENTIFIC, NTN_COMPACT, NTN_SIMPLE, NTN_ERROR
347  } fType;
348 
349  union NotationUnion {
350  // For NTN_SCIENTIFIC
358  impl::digits_t fMinExponentDigits;
361  } scientific;
362 
363  // For NTN_COMPACT
364  UNumberCompactStyle compactStyle;
365 
366  // For NTN_ERROR
367  UErrorCode errorCode;
368  } fUnion;
369 
371 
372  Notation(const NotationType &type, const NotationUnion &union_) : fType(type), fUnion(union_) {}
373 
374  Notation(UErrorCode errorCode) : fType(NTN_ERROR) {
375  fUnion.errorCode = errorCode;
376  }
377 
378  Notation() : fType(NTN_SIMPLE), fUnion() {}
379 
380  UBool copyErrorTo(UErrorCode &status) const {
381  if (fType == NTN_ERROR) {
382  status = fUnion.errorCode;
383  return true;
384  }
385  return false;
386  }
387 
388  // To allow MacroProps to initialize empty instances:
389  friend struct impl::MacroProps;
390  friend class ScientificNotation;
391 
392  // To allow implementation to access internal types:
393  friend class impl::NumberFormatterImpl;
394  friend class impl::ScientificModifier;
395  friend class impl::ScientificHandler;
396 
397  // To allow access to the skeleton generation code:
398  friend class impl::GeneratorHelpers;
399 };
400 
410  public:
424  ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const;
425 
439  ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const;
440 
441  private:
442  // Inherit constructor
443  using Notation::Notation;
444 
445  // Raw constructor for NumberPropertyMapper
446  ScientificNotation(int8_t fEngineeringInterval, bool fRequireMinInt, impl::digits_t fMinExponentDigits,
447  UNumberSignDisplay fExponentSignDisplay);
448 
449  friend class Notation;
450 
451  // So that NumberPropertyMapper can create instances
452  friend class impl::NumberPropertyMapper;
453 };
454 
461 
470 class U_I18N_API Precision : public UMemory {
471 
472  public:
490  static Precision unlimited();
491 
498  static FractionPrecision integer();
499 
527  static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces);
528 
542  static FractionPrecision minFraction(int32_t minFractionPlaces);
543 
554  static FractionPrecision maxFraction(int32_t maxFractionPlaces);
555 
569  static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces);
570 
584  static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits);
585 
598  static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits);
599 
608  static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits);
609 
621  static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits,
622  int32_t maxSignificantDigits);
623 
643  static IncrementPrecision increment(double roundingIncrement);
644 
645 #ifndef U_HIDE_DRAFT_API
646 
669  static IncrementPrecision incrementExact(uint64_t mantissa, int16_t magnitude);
670 #endif // U_HIDE_DRAFT_API
671 
689  static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
690 
698  Precision trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const;
699 
700  private:
701  enum PrecisionType {
702  RND_BOGUS,
703  RND_NONE,
704  RND_FRACTION,
705  RND_SIGNIFICANT,
706  RND_FRACTION_SIGNIFICANT,
707 
708  // Used for strange increments like 3.14.
709  RND_INCREMENT,
710 
711  // Used for increments with 1 as the only digit. This is different than fraction
712  // rounding because it supports having additional trailing zeros. For example, this
713  // class is used to round with the increment 0.010.
714  RND_INCREMENT_ONE,
715 
716  // Used for increments with 5 as the only digit (nickel rounding).
717  RND_INCREMENT_FIVE,
718 
719  RND_CURRENCY,
720  RND_ERROR
721  } fType;
722 
723  union PrecisionUnion {
726  // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT
728  impl::digits_t fMinFrac;
730  impl::digits_t fMaxFrac;
732  impl::digits_t fMinSig;
734  impl::digits_t fMaxSig;
741  bool fRetain;
742  } fracSig;
745  // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE
746  // Note: This is a union, so we shouldn't own memory, since
747  // the default destructor would leak it.
749  uint64_t fIncrement;
751  impl::digits_t fIncrementMagnitude;
753  impl::digits_t fMinFrac;
754  } increment;
755  UCurrencyUsage currencyUsage; // For RND_CURRENCY
756  UErrorCode errorCode; // For RND_ERROR
757  } fUnion;
758 
760 
763 
764  Precision(const PrecisionType& type, const PrecisionUnion& union_)
765  : fType(type), fUnion(union_) {}
766 
767  Precision(UErrorCode errorCode) : fType(RND_ERROR) {
768  fUnion.errorCode = errorCode;
769  }
770 
771  Precision() : fType(RND_BOGUS) {}
772 
773  bool isBogus() const {
774  return fType == RND_BOGUS;
775  }
776 
777  UBool copyErrorTo(UErrorCode &status) const {
778  if (fType == RND_ERROR) {
779  status = fUnion.errorCode;
780  return true;
781  }
782  return false;
783  }
784 
785  // On the parent type so that this method can be called internally on Precision instances.
786  Precision withCurrency(const CurrencyUnit &currency, UErrorCode &status) const;
787 
788  static FractionPrecision constructFraction(int32_t minFrac, int32_t maxFrac);
789 
790  static Precision constructSignificant(int32_t minSig, int32_t maxSig);
791 
792  static Precision constructFractionSignificant(
793  const FractionPrecision &base,
794  int32_t minSig,
795  int32_t maxSig,
796  UNumberRoundingPriority priority,
797  bool retain);
798 
799  static IncrementPrecision constructIncrement(uint64_t increment, impl::digits_t magnitude);
800 
801  static CurrencyPrecision constructCurrency(UCurrencyUsage usage);
802 
803  // To allow MacroProps/MicroProps to initialize bogus instances:
804  friend struct impl::MacroProps;
805  friend struct impl::MicroProps;
806 
807  // To allow NumberFormatterImpl to access isBogus() and other internal methods:
808  friend class impl::NumberFormatterImpl;
809 
810  // To allow NumberPropertyMapper to create instances from DecimalFormatProperties:
811  friend class impl::NumberPropertyMapper;
812 
813  // To allow access to the main implementation class:
814  friend class impl::RoundingImpl;
815 
816  // To allow child classes to call private methods:
817  friend class FractionPrecision;
818  friend class CurrencyPrecision;
819  friend class IncrementPrecision;
820 
821  // To allow access to the skeleton generation code:
822  friend class impl::GeneratorHelpers;
823 
824  // To allow access to isBogus and the default (bogus) constructor:
825  friend class units::UnitsRouter;
826 };
827 
838  public:
853  Precision withSignificantDigits(
854  int32_t minSignificantDigits,
855  int32_t maxSignificantDigits,
856  UNumberRoundingPriority priority) const;
857 
875  Precision withMinDigits(int32_t minSignificantDigits) const;
876 
894  Precision withMaxDigits(int32_t maxSignificantDigits) const;
895 
896  private:
897  // Inherit constructor
898  using Precision::Precision;
899 
900  // To allow parent class to call this class's constructor:
901  friend class Precision;
902 };
903 
914  public:
932  Precision withCurrency(const CurrencyUnit &currency) const;
933 
934  private:
935  // Inherit constructor
936  using Precision::Precision;
937 
938  // To allow parent class to call this class's constructor:
939  friend class Precision;
940 };
941 
952  public:
968  Precision withMinFraction(int32_t minFrac) const;
969 
970  private:
971  // Inherit constructor
972  using Precision::Precision;
973 
974  // To allow parent class to call this class's constructor:
975  friend class Precision;
976 };
977 
988  public:
1000  static IntegerWidth zeroFillTo(int32_t minInt);
1001 
1013  IntegerWidth truncateAt(int32_t maxInt);
1014 
1015  private:
1016  union {
1017  struct {
1018  impl::digits_t fMinInt;
1019  impl::digits_t fMaxInt;
1020  bool fFormatFailIfMoreThanMaxDigits;
1021  } minMaxInt;
1022  UErrorCode errorCode;
1023  } fUnion;
1024  bool fHasError = false;
1025 
1026  IntegerWidth(impl::digits_t minInt, impl::digits_t maxInt, bool formatFailIfMoreThanMaxDigits);
1027 
1028  IntegerWidth(UErrorCode errorCode) { // NOLINT
1029  fUnion.errorCode = errorCode;
1030  fHasError = true;
1031  }
1032 
1033  IntegerWidth() { // NOLINT
1034  fUnion.minMaxInt.fMinInt = -1;
1035  }
1036 
1038  static IntegerWidth standard() {
1039  return IntegerWidth::zeroFillTo(1);
1040  }
1041 
1042  bool isBogus() const {
1043  return !fHasError && fUnion.minMaxInt.fMinInt == -1;
1044  }
1045 
1046  UBool copyErrorTo(UErrorCode &status) const {
1047  if (fHasError) {
1048  status = fUnion.errorCode;
1049  return true;
1050  }
1051  return false;
1052  }
1053 
1054  void apply(impl::DecimalQuantity &quantity, UErrorCode &status) const;
1055 
1056  bool operator==(const IntegerWidth& other) const;
1057 
1058  // To allow MacroProps/MicroProps to initialize empty instances:
1059  friend struct impl::MacroProps;
1060  friend struct impl::MicroProps;
1061 
1062  // To allow NumberFormatterImpl to access isBogus():
1063  friend class impl::NumberFormatterImpl;
1064 
1065  // To allow the use of this class when formatting:
1066  friend class impl::MutablePatternModifier;
1067  friend class impl::ImmutablePatternModifier;
1068 
1069  // So that NumberPropertyMapper can create instances
1070  friend class impl::NumberPropertyMapper;
1071 
1072  // To allow access to the skeleton generation code:
1073  friend class impl::GeneratorHelpers;
1074 };
1075 
1084 class U_I18N_API Scale : public UMemory {
1085  public:
1092  static Scale none();
1093 
1104  static Scale powerOfTen(int32_t power);
1105 
1118  static Scale byDecimal(StringPiece multiplicand);
1119 
1128  static Scale byDouble(double multiplicand);
1129 
1136  static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power);
1137 
1138  // We need a custom destructor for the DecNum, which means we need to declare
1139  // the copy/move constructor/assignment quartet.
1140 
1142  Scale(const Scale& other);
1143 
1145  Scale& operator=(const Scale& other);
1146 
1148  Scale(Scale&& src) U_NOEXCEPT;
1149 
1151  Scale& operator=(Scale&& src) U_NOEXCEPT;
1152 
1154  ~Scale();
1155 
1156 #ifndef U_HIDE_INTERNAL_API
1157 
1158  Scale(int32_t magnitude, impl::DecNum* arbitraryToAdopt);
1159 #endif /* U_HIDE_INTERNAL_API */
1160 
1161  private:
1162  int32_t fMagnitude;
1163  impl::DecNum* fArbitrary;
1164  UErrorCode fError;
1165 
1166  Scale(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {}
1167 
1168  Scale() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {}
1169 
1170  bool isValid() const {
1171  return fMagnitude != 0 || fArbitrary != nullptr;
1172  }
1173 
1174  UBool copyErrorTo(UErrorCode &status) const {
1175  if (U_FAILURE(fError)) {
1176  status = fError;
1177  return true;
1178  }
1179  return false;
1180  }
1181 
1182  void applyTo(impl::DecimalQuantity& quantity) const;
1183 
1184  void applyReciprocalTo(impl::DecimalQuantity& quantity) const;
1185 
1186  // To allow MacroProps/MicroProps to initialize empty instances:
1187  friend struct impl::MacroProps;
1188  friend struct impl::MicroProps;
1189 
1190  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1191  friend class impl::NumberFormatterImpl;
1192 
1193  // To allow the helper class MultiplierFormatHandler access to private fields:
1194  friend class impl::MultiplierFormatHandler;
1195 
1196  // To allow access to the skeleton generation code:
1197  friend class impl::GeneratorHelpers;
1198 
1199  // To allow access to parsing code:
1200  friend class ::icu::numparse::impl::NumberParserImpl;
1201  friend class ::icu::numparse::impl::MultiplierParseHandler;
1202 };
1203 
1204 namespace impl {
1205 
1206 // Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field.
1207 // And do not enclose its class boilerplate within #ifndef U_HIDE_INTERNAL_API.
1213 
1214  public:
1216  ~StringProp();
1217 
1219  StringProp(const StringProp &other);
1220 
1222  StringProp &operator=(const StringProp &other);
1223 
1224 #ifndef U_HIDE_INTERNAL_API
1225 
1228 
1230  StringProp &operator=(StringProp &&src) U_NOEXCEPT;
1231 
1233  int16_t length() const {
1234  return fLength;
1235  }
1236 
1240  void set(StringPiece value);
1241 
1243  bool isSet() const {
1244  return fLength > 0;
1245  }
1246 
1247 #endif // U_HIDE_INTERNAL_API
1248 
1249  private:
1250  char *fValue;
1251  int16_t fLength;
1252  UErrorCode fError;
1253 
1254  StringProp() : fValue(nullptr), fLength(0), fError(U_ZERO_ERROR) {
1255  }
1256 
1258  UBool copyErrorTo(UErrorCode &status) const {
1259  if (U_FAILURE(fError)) {
1260  status = fError;
1261  return true;
1262  }
1263  return false;
1264  }
1265 
1266  // Allow NumberFormatterImpl to access fValue.
1267  friend class impl::NumberFormatterImpl;
1268 
1269  // Allow skeleton generation code to access private members.
1270  friend class impl::GeneratorHelpers;
1271 
1272  // Allow MacroProps/MicroProps to initialize empty instances and to call
1273  // copyErrorTo().
1274  friend struct impl::MacroProps;
1275 };
1276 
1277 // Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1280  public:
1282  SymbolsWrapper() : fType(SYMPTR_NONE), fPtr{nullptr} {}
1283 
1285  SymbolsWrapper(const SymbolsWrapper &other);
1286 
1288  SymbolsWrapper &operator=(const SymbolsWrapper &other);
1289 
1291  SymbolsWrapper(SymbolsWrapper&& src) U_NOEXCEPT;
1292 
1294  SymbolsWrapper &operator=(SymbolsWrapper&& src) U_NOEXCEPT;
1295 
1297  ~SymbolsWrapper();
1298 
1299 #ifndef U_HIDE_INTERNAL_API
1300 
1305  void setTo(const DecimalFormatSymbols &dfs);
1306 
1311  void setTo(const NumberingSystem *ns);
1312 
1317  bool isDecimalFormatSymbols() const;
1318 
1323  bool isNumberingSystem() const;
1324 
1329  const DecimalFormatSymbols *getDecimalFormatSymbols() const;
1330 
1335  const NumberingSystem *getNumberingSystem() const;
1336 
1337 #endif // U_HIDE_INTERNAL_API
1338 
1340  UBool copyErrorTo(UErrorCode &status) const {
1341  if (fType == SYMPTR_DFS && fPtr.dfs == nullptr) {
1342  status = U_MEMORY_ALLOCATION_ERROR;
1343  return true;
1344  } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) {
1345  status = U_MEMORY_ALLOCATION_ERROR;
1346  return true;
1347  }
1348  return false;
1349  }
1350 
1351  private:
1352  enum SymbolsPointerType {
1353  SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS
1354  } fType;
1355 
1356  union {
1357  const DecimalFormatSymbols *dfs;
1358  const NumberingSystem *ns;
1359  } fPtr;
1360 
1361  void doCopyFrom(const SymbolsWrapper &other);
1362 
1363  void doMoveFrom(SymbolsWrapper&& src);
1364 
1365  void doCleanup();
1366 };
1367 
1368 // Do not enclose entire Grouper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1370 class U_I18N_API Grouper : public UMemory {
1371  public:
1372 #ifndef U_HIDE_INTERNAL_API
1373 
1374  static Grouper forStrategy(UNumberGroupingStrategy grouping);
1375 
1380  static Grouper forProperties(const DecimalFormatProperties& properties);
1381 
1382  // Future: static Grouper forProperties(DecimalFormatProperties& properties);
1383 
1385  Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy)
1386  : fGrouping1(grouping1),
1387  fGrouping2(grouping2),
1388  fMinGrouping(minGrouping),
1389  fStrategy(strategy) {}
1390 
1392  int16_t getPrimary() const;
1393 
1395  int16_t getSecondary() const;
1396 #endif // U_HIDE_INTERNAL_API
1397 
1398  private:
1407  int16_t fGrouping1;
1408  int16_t fGrouping2;
1409 
1417  int16_t fMinGrouping;
1418 
1423  UNumberGroupingStrategy fStrategy;
1424 
1425  Grouper() : fGrouping1(-3) {}
1426 
1427  bool isBogus() const {
1428  return fGrouping1 == -3;
1429  }
1430 
1432  void setLocaleData(const impl::ParsedPatternInfo &patternInfo, const Locale& locale);
1433 
1434  bool groupAtPosition(int32_t position, const impl::DecimalQuantity &value) const;
1435 
1436  // To allow MacroProps/MicroProps to initialize empty instances:
1437  friend struct MacroProps;
1438  friend struct MicroProps;
1439 
1440  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1441  friend class NumberFormatterImpl;
1442 
1443  // To allow NumberParserImpl to perform setLocaleData():
1444  friend class ::icu::numparse::impl::NumberParserImpl;
1445 
1446  // To allow access to the skeleton generation code:
1447  friend class impl::GeneratorHelpers;
1448 };
1449 
1450 // Do not enclose entire Padder with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1452 class U_I18N_API Padder : public UMemory {
1453  public:
1454 #ifndef U_HIDE_INTERNAL_API
1455 
1456  static Padder none();
1457 
1459  static Padder codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position);
1460 
1462  static Padder forProperties(const DecimalFormatProperties& properties);
1463 #endif // U_HIDE_INTERNAL_API
1464 
1465  private:
1466  UChar32 fWidth; // -3 = error; -2 = bogus; -1 = no padding
1467  union {
1468  struct {
1469  int32_t fCp;
1470  UNumberFormatPadPosition fPosition;
1471  } padding;
1472  UErrorCode errorCode;
1473  } fUnion;
1474 
1475  Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position);
1476 
1477  Padder(int32_t width);
1478 
1479  Padder(UErrorCode errorCode) : fWidth(-3) { // NOLINT
1480  fUnion.errorCode = errorCode;
1481  }
1482 
1483  Padder() : fWidth(-2) {} // NOLINT
1484 
1485  bool isBogus() const {
1486  return fWidth == -2;
1487  }
1488 
1489  UBool copyErrorTo(UErrorCode &status) const {
1490  if (fWidth == -3) {
1491  status = fUnion.errorCode;
1492  return true;
1493  }
1494  return false;
1495  }
1496 
1497  bool isValid() const {
1498  return fWidth > 0;
1499  }
1500 
1501  int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2,
1502  FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
1503  UErrorCode &status) const;
1504 
1505  // To allow MacroProps/MicroProps to initialize empty instances:
1506  friend struct MacroProps;
1507  friend struct MicroProps;
1508 
1509  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1510  friend class impl::NumberFormatterImpl;
1511 
1512  // To allow access to the skeleton generation code:
1513  friend class impl::GeneratorHelpers;
1514 };
1515 
1516 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1518 struct U_I18N_API MacroProps : public UMemory {
1521 
1523  MeasureUnit unit; // = MeasureUnit(); (the base dimensionless unit)
1524 
1526  MeasureUnit perUnit; // = MeasureUnit(); (the base dimensionless unit)
1527 
1529  Precision precision; // = Precision(); (bogus)
1530 
1533 
1535  Grouper grouper; // = Grouper(); (bogus)
1536 
1538  Padder padder; // = Padder(); (bogus)
1539 
1541  IntegerWidth integerWidth; // = IntegerWidth(); (bogus)
1542 
1545 
1546  // UNUM_XYZ_COUNT denotes null (bogus) values.
1547 
1550 
1553 
1555  bool approximately = false;
1556 
1559 
1561  Scale scale; // = Scale(); (benign value)
1562 
1564  StringProp usage; // = StringProp(); (no usage)
1565 
1567  StringProp unitDisplayCase; // = StringProp(); (nominative)
1568 
1570  const AffixPatternProvider* affixProvider = nullptr; // no ownership
1571 
1573  const PluralRules* rules = nullptr; // no ownership
1574 
1576  int32_t threshold = kInternalDefaultThreshold;
1577 
1580 
1581  // NOTE: Uses default copy and move constructors.
1582 
1587  bool copyErrorTo(UErrorCode &status) const {
1588  return notation.copyErrorTo(status) || precision.copyErrorTo(status) ||
1589  padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) ||
1590  symbols.copyErrorTo(status) || scale.copyErrorTo(status) || usage.copyErrorTo(status) ||
1591  unitDisplayCase.copyErrorTo(status);
1592  }
1593 };
1594 
1595 } // namespace impl
1596 
1597 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER)
1598 // Ignore MSVC warning 4661. This is generated for NumberFormatterSettings<>::toSkeleton() as this method
1599 // is defined elsewhere (in number_skeletons.cpp). The compiler is warning that the explicit template instantiation
1600 // inside this single translation unit (CPP file) is incomplete, and thus it isn't sure if the template class is
1601 // fully defined. However, since each translation unit explicitly instantiates all the necessary template classes,
1602 // they will all be passed to the linker, and the linker will still find and export all the class members.
1603 #pragma warning(push)
1604 #pragma warning(disable: 4661)
1605 #endif
1606 
1612 template<typename Derived>
1614  public:
1643  Derived notation(const Notation &notation) const &;
1644 
1654  Derived notation(const Notation &notation) &&;
1655 
1704  Derived unit(const icu::MeasureUnit &unit) const &;
1705 
1715  Derived unit(const icu::MeasureUnit &unit) &&;
1716 
1730  Derived adoptUnit(icu::MeasureUnit *unit) const &;
1731 
1741  Derived adoptUnit(icu::MeasureUnit *unit) &&;
1742 
1765  Derived perUnit(const icu::MeasureUnit &perUnit) const &;
1766 
1776  Derived perUnit(const icu::MeasureUnit &perUnit) &&;
1777 
1791  Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &;
1792 
1802  Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&;
1803 
1834  Derived precision(const Precision& precision) const &;
1835 
1845  Derived precision(const Precision& precision) &&;
1846 
1865  Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &;
1866 
1875  Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&;
1876 
1904  Derived grouping(UNumberGroupingStrategy strategy) const &;
1905 
1915  Derived grouping(UNumberGroupingStrategy strategy) &&;
1916 
1941  Derived integerWidth(const IntegerWidth &style) const &;
1942 
1952  Derived integerWidth(const IntegerWidth &style) &&;
1953 
1994  Derived symbols(const DecimalFormatSymbols &symbols) const &;
1995 
2005  Derived symbols(const DecimalFormatSymbols &symbols) &&;
2006 
2040  Derived adoptSymbols(NumberingSystem *symbols) const &;
2041 
2051  Derived adoptSymbols(NumberingSystem *symbols) &&;
2052 
2078  Derived unitWidth(UNumberUnitWidth width) const &;
2079 
2089  Derived unitWidth(UNumberUnitWidth width) &&;
2090 
2116  Derived sign(UNumberSignDisplay style) const &;
2117 
2127  Derived sign(UNumberSignDisplay style) &&;
2128 
2154  Derived decimal(UNumberDecimalSeparatorDisplay style) const &;
2155 
2165  Derived decimal(UNumberDecimalSeparatorDisplay style) &&;
2166 
2191  Derived scale(const Scale &scale) const &;
2192 
2202  Derived scale(const Scale &scale) &&;
2203 
2246  Derived usage(StringPiece usage) const &;
2247 
2255  Derived usage(StringPiece usage) &&;
2256 
2257 #ifndef U_HIDE_DRAFT_API
2258 
2266  Derived displayOptions(const DisplayOptions &displayOptions) const &;
2267 
2275  Derived displayOptions(const DisplayOptions &displayOptions) &&;
2276 #endif // U_HIDE_DRAFT_API
2277 
2278 #ifndef U_HIDE_INTERNAL_API
2279 
2289  Derived unitDisplayCase(StringPiece unitDisplayCase) const &;
2290 
2300  Derived unitDisplayCase(StringPiece unitDisplayCase) &&;
2301 #endif // U_HIDE_INTERNAL_API
2302 
2303 #ifndef U_HIDE_INTERNAL_API
2304 
2310  Derived padding(const impl::Padder &padder) const &;
2311 
2313  Derived padding(const impl::Padder &padder) &&;
2314 
2321  Derived threshold(int32_t threshold) const &;
2322 
2324  Derived threshold(int32_t threshold) &&;
2325 
2331  Derived macros(const impl::MacroProps& macros) const &;
2332 
2334  Derived macros(const impl::MacroProps& macros) &&;
2335 
2337  Derived macros(impl::MacroProps&& macros) const &;
2338 
2340  Derived macros(impl::MacroProps&& macros) &&;
2341 
2342 #endif /* U_HIDE_INTERNAL_API */
2343 
2361  UnicodeString toSkeleton(UErrorCode& status) const;
2362 
2374  LocalPointer<Derived> clone() const &;
2375 
2383  LocalPointer<Derived> clone() &&;
2384 
2391  UBool copyErrorTo(UErrorCode &outErrorCode) const {
2392  if (U_FAILURE(outErrorCode)) {
2393  // Do not overwrite the older error code
2394  return true;
2395  }
2396  fMacros.copyErrorTo(outErrorCode);
2397  return U_FAILURE(outErrorCode);
2398  }
2399 
2400  // NOTE: Uses default copy and move constructors.
2401 
2402  private:
2403  impl::MacroProps fMacros;
2404 
2405  // Don't construct me directly! Use (Un)LocalizedNumberFormatter.
2406  NumberFormatterSettings() = default;
2407 
2408  friend class LocalizedNumberFormatter;
2409  friend class UnlocalizedNumberFormatter;
2410 
2411  // Give NumberRangeFormatter access to the MacroProps
2412  friend void impl::touchRangeLocales(impl::RangeMacroProps& macros);
2413  friend class impl::NumberRangeFormatterImpl;
2414 };
2415 
2425  : public NumberFormatterSettings<UnlocalizedNumberFormatter>, public UMemory {
2426 
2427  public:
2437  LocalizedNumberFormatter locale(const icu::Locale &locale) const &;
2438 
2448  LocalizedNumberFormatter locale(const icu::Locale &locale) &&;
2449 
2455  UnlocalizedNumberFormatter() = default;
2456 
2462 
2469 
2474  UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other);
2475 
2482 
2483  private:
2485 
2486  explicit UnlocalizedNumberFormatter(
2488 
2489  // To give the fluent setters access to this class's constructor:
2490  friend class NumberFormatterSettings<UnlocalizedNumberFormatter>;
2491 
2492  // To give NumberFormatter::with() access to this class's constructor:
2493  friend class NumberFormatter;
2494 };
2495 
2505  : public NumberFormatterSettings<LocalizedNumberFormatter>, public UMemory {
2506  public:
2518  FormattedNumber formatInt(int64_t value, UErrorCode &status) const;
2519 
2531  FormattedNumber formatDouble(double value, UErrorCode &status) const;
2532 
2547  FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const;
2548 
2549 #ifndef U_HIDE_INTERNAL_API
2550 
2551 
2555  const DecimalFormatSymbols* getDecimalFormatSymbols() const;
2556 
2560  FormattedNumber formatDecimalQuantity(const impl::DecimalQuantity& dq, UErrorCode& status) const;
2561 
2565  void getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const;
2566 
2571  const impl::NumberFormatterImpl* getCompiled() const;
2572 
2577  int32_t getCallCount() const;
2578 
2579 #endif /* U_HIDE_INTERNAL_API */
2580 
2594  Format* toFormat(UErrorCode& status) const;
2595 
2601  LocalizedNumberFormatter() = default;
2602 
2608 
2615 
2620  LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other);
2621 
2628 
2629 #ifndef U_HIDE_INTERNAL_API
2630 
2643  void formatImpl(impl::UFormattedNumberData *results, UErrorCode &status) const;
2644 
2645 #endif /* U_HIDE_INTERNAL_API */
2646 
2652 
2653  private:
2654  // Note: fCompiled can't be a LocalPointer because impl::NumberFormatterImpl is defined in an internal
2655  // header, and LocalPointer needs the full class definition in order to delete the instance.
2656  const impl::NumberFormatterImpl* fCompiled {nullptr};
2657  char fUnsafeCallCount[8] {}; // internally cast to u_atomic_int32_t
2658 
2659  // Owned pointer to a DecimalFormatWarehouse, used when copying a LocalizedNumberFormatter
2660  // from a DecimalFormat.
2661  const impl::DecimalFormatWarehouse* fWarehouse {nullptr};
2662 
2664 
2666 
2667  LocalizedNumberFormatter(const impl::MacroProps &macros, const Locale &locale);
2668 
2669  LocalizedNumberFormatter(impl::MacroProps &&macros, const Locale &locale);
2670 
2671  void resetCompiled();
2672 
2673  void lnfMoveHelper(LocalizedNumberFormatter&& src);
2674 
2675  void lnfCopyHelper(const LocalizedNumberFormatter& src, UErrorCode& status);
2676 
2680  bool computeCompiled(UErrorCode& status) const;
2681 
2682  // To give the fluent setters access to this class's constructor:
2683  friend class NumberFormatterSettings<UnlocalizedNumberFormatter>;
2684  friend class NumberFormatterSettings<LocalizedNumberFormatter>;
2685 
2686  // To give UnlocalizedNumberFormatter::locale() access to this class's constructor:
2687  friend class UnlocalizedNumberFormatter;
2688 };
2689 
2690 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER)
2691 // Warning 4661.
2692 #pragma warning(pop)
2693 #endif
2694 
2704  public:
2705 
2711  : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
2712 
2718 
2723  virtual ~FormattedNumber() U_OVERRIDE;
2724 
2726  FormattedNumber(const FormattedNumber&) = delete;
2727 
2729  FormattedNumber& operator=(const FormattedNumber&) = delete;
2730 
2735  FormattedNumber& operator=(FormattedNumber&& src) U_NOEXCEPT;
2736 
2737  // Copybrief: this method is older than the parent method
2745  UnicodeString toString(UErrorCode& status) const U_OVERRIDE;
2746 
2747  // Copydoc: this method is new in ICU 64
2749  UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE;
2750 
2751  // Copybrief: this method is older than the parent method
2759  Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE;
2760 
2761  // Copydoc: this method is new in ICU 64
2763  UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
2764 
2783  template<typename StringClass>
2784  inline StringClass toDecimalNumber(UErrorCode& status) const;
2785 
2797  MeasureUnit getOutputUnit(UErrorCode& status) const;
2798 
2799 #ifndef U_HIDE_DRAFT_API
2800 
2808  UDisplayOptionsNounClass getNounClass(UErrorCode &status) const;
2809 
2810 #endif // U_HIDE_DRAFT_API
2811 
2812 #ifndef U_HIDE_INTERNAL_API
2813 
2818  void getDecimalQuantity(impl::DecimalQuantity& output, UErrorCode& status) const;
2819 
2824  void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
2825 
2826 #endif /* U_HIDE_INTERNAL_API */
2827 
2828  private:
2829  // Can't use LocalPointer because UFormattedNumberData is forward-declared
2830  const impl::UFormattedNumberData *fData;
2831 
2832  // Error code for the terminal methods
2833  UErrorCode fErrorCode;
2834 
2839  explicit FormattedNumber(impl::UFormattedNumberData *results)
2840  : fData(results), fErrorCode(U_ZERO_ERROR) {}
2841 
2842  explicit FormattedNumber(UErrorCode errorCode)
2843  : fData(nullptr), fErrorCode(errorCode) {}
2844 
2845  void toDecimalNumber(ByteSink& sink, UErrorCode& status) const;
2846 
2847  // To give LocalizedNumberFormatter format methods access to this class's constructor:
2848  friend class LocalizedNumberFormatter;
2849 
2850  // To give C API access to internals
2851  friend struct impl::UFormattedNumberImpl;
2852 };
2853 
2854 template<typename StringClass>
2855 StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const {
2856  StringClass result;
2857  StringByteSink<StringClass> sink(&result);
2858  toDecimalNumber(sink, status);
2859  return result;
2860 }
2861 
2868  public:
2876  static UnlocalizedNumberFormatter with();
2877 
2887  static LocalizedNumberFormatter withLocale(const Locale &locale);
2888 
2906  static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status);
2907 
2928  static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton,
2929  UParseError& perror, UErrorCode& status);
2930 
2934  NumberFormatter() = delete;
2935 };
2936 
2937 } // namespace number
2938 U_NAMESPACE_END
2939 
2940 #endif /* #if !UCONFIG_NO_FORMATTING */
2941 
2942 #endif /* U_SHOW_CPLUSPLUS_API */
2943 
2944 #endif // __NUMBERFORMATTER_H__
C++ API: Abstract operations for localized strings.
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
#define U_OVERRIDE
Defined to the C++11 &quot;override&quot; keyword if available.
Definition: umachine.h:130
UNumberFormatRoundingMode
The possible number format rounding modes.
Definition: unum.h:282
A unit such as length, mass, volume, currency, etc.
Definition: measunit.h:368
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.
&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: 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...
An abstract formatted value: a string with associated field attributes.
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
An abstract base class for specifying settings related to number formatting.
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside...
Definition: utypes.h:301
Half-even rounding.
Definition: unum.h:291
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...
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).
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:461
C API: Display options (enum types, values, helper functions)
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:326
C++ API: Common ICU base class UObject.
Represents a span of a string containing a given field.
#define U_NOEXCEPT
&quot;noexcept&quot; if supported, otherwise empty.
Definition: platform.h:529
A NumberFormatter that does not yet have a locale.
UNumberCompactStyle
Constants for specifying short or long format.
Definition: unum.h:337
C API: Parse Error Information.
A NumberFormatter that has a locale associated with it; this means .format() methods are available...
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
UDisplayOptionsNounClass
Represents all the grammatical noun classes that are supported by CLDR.
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.
Implementation of ByteSink that writes to a &quot;string&quot;.
Definition: bytestream.h:267
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.
Requested operation can not be completed with ICU in its current state.
Definition: utypes.h:478
Display trailing zeros according to the settings for minimum fraction and significant digits...
One more than the highest UNumberUnitWidth value.
FormattedNumber()
Default constructor; makes an empty FormattedNumber.
int8_t UBool
The ICU boolean type, a signed-byte integer.
Definition: umachine.h:269
Base class for objects to which Unicode characters and strings can be appended.
Definition: appendable.h:54
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