ICU 76.1  76.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/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 
89 U_NAMESPACE_BEGIN
90 
91 // Forward declarations:
92 class IFixedDecimal;
93 class FieldPositionIteratorHandler;
94 class FormattedStringBuilder;
95 
96 namespace numparse::impl {
97 
98 // Forward declarations:
99 class NumberParserImpl;
100 class MultiplierParseHandler;
101 
102 } // namespace numparse::impl
103 
104 namespace units {
105 
106 // Forward declarations:
107 class UnitsRouter;
108 
109 } // namespace units
110 
111 namespace number { // icu::number
112 
113 // Forward declarations:
114 class UnlocalizedNumberFormatter;
115 class LocalizedNumberFormatter;
116 class SimpleNumberFormatter;
117 class FormattedNumber;
118 class Notation;
119 class ScientificNotation;
120 class Precision;
121 class FractionPrecision;
122 class CurrencyPrecision;
123 class IncrementPrecision;
124 class IntegerWidth;
125 
126 namespace impl {
127 
128 // can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes
134 typedef int16_t digits_t;
135 
136 // can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization
143 static constexpr int32_t kInternalDefaultThreshold = 3;
144 
145 // Forward declarations:
146 class Padder;
147 struct MacroProps;
148 struct MicroProps;
149 class DecimalQuantity;
150 class UFormattedNumberData;
151 class NumberFormatterImpl;
152 struct ParsedPatternInfo;
153 class ScientificModifier;
154 class MultiplierProducer;
155 class RoundingImpl;
156 class ScientificHandler;
157 class Modifier;
158 class AffixPatternProvider;
159 class NumberPropertyMapper;
160 struct DecimalFormatProperties;
161 class MultiplierFormatHandler;
162 class CurrencySymbols;
163 class GeneratorHelpers;
164 class DecNum;
165 class NumberRangeFormatterImpl;
166 struct RangeMacroProps;
167 struct UFormattedNumberImpl;
168 class MutablePatternModifier;
169 class ImmutablePatternModifier;
170 struct DecimalFormatWarehouse;
171 struct SimpleMicroProps;
172 class AdoptingSignumModifierStore;
173 
181 
182 } // namespace impl
183 
190 
197 
203 class U_I18N_API Notation : public UMemory {
204  public:
229  static ScientificNotation scientific();
230 
253  static ScientificNotation engineering();
254 
296  static CompactNotation compactShort();
297 
320  static CompactNotation compactLong();
321 
346  static SimpleNotation simple();
347 
348  private:
349  enum NotationType {
350  NTN_SCIENTIFIC, NTN_COMPACT, NTN_SIMPLE, NTN_ERROR
351  } fType;
352 
353  union NotationUnion {
354  // For NTN_SCIENTIFIC
365  } scientific;
366 
367  // For NTN_COMPACT
368  UNumberCompactStyle compactStyle;
369 
370  // For NTN_ERROR
371  UErrorCode errorCode;
372  } fUnion;
373 
375 
376  Notation(const NotationType &type, const NotationUnion &union_) : fType(type), fUnion(union_) {}
377 
378  Notation(UErrorCode errorCode) : fType(NTN_ERROR) {
379  fUnion.errorCode = errorCode;
380  }
381 
382  Notation() : fType(NTN_SIMPLE), fUnion() {}
383 
384  UBool copyErrorTo(UErrorCode &status) const {
385  if (fType == NTN_ERROR) {
386  status = fUnion.errorCode;
387  return true;
388  }
389  return false;
390  }
391 
392  // To allow MacroProps to initialize empty instances:
393  friend struct impl::MacroProps;
394  friend class ScientificNotation;
395 
396  // To allow implementation to access internal types:
397  friend class impl::NumberFormatterImpl;
398  friend class impl::ScientificModifier;
399  friend class impl::ScientificHandler;
400 
401  // To allow access to the skeleton generation code:
402  friend class impl::GeneratorHelpers;
403 };
404 
414  public:
428  ScientificNotation withMinExponentDigits(int32_t minExponentDigits) const;
429 
443  ScientificNotation withExponentSignDisplay(UNumberSignDisplay exponentSignDisplay) const;
444 
445  private:
446  // Inherit constructor
447  using Notation::Notation;
448 
449  // Raw constructor for NumberPropertyMapper
450  ScientificNotation(int8_t fEngineeringInterval, bool fRequireMinInt, impl::digits_t fMinExponentDigits,
451  UNumberSignDisplay fExponentSignDisplay);
452 
453  friend class Notation;
454 
455  // So that NumberPropertyMapper can create instances
456  friend class impl::NumberPropertyMapper;
457 };
458 
465 
474 class U_I18N_API Precision : public UMemory {
475 
476  public:
494  static Precision unlimited();
495 
502  static FractionPrecision integer();
503 
531  static FractionPrecision fixedFraction(int32_t minMaxFractionPlaces);
532 
546  static FractionPrecision minFraction(int32_t minFractionPlaces);
547 
558  static FractionPrecision maxFraction(int32_t maxFractionPlaces);
559 
573  static FractionPrecision minMaxFraction(int32_t minFractionPlaces, int32_t maxFractionPlaces);
574 
588  static SignificantDigitsPrecision fixedSignificantDigits(int32_t minMaxSignificantDigits);
589 
602  static SignificantDigitsPrecision minSignificantDigits(int32_t minSignificantDigits);
603 
612  static SignificantDigitsPrecision maxSignificantDigits(int32_t maxSignificantDigits);
613 
625  static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits,
626  int32_t maxSignificantDigits);
627 
647  static IncrementPrecision increment(double roundingIncrement);
648 
672  static IncrementPrecision incrementExact(uint64_t mantissa, int16_t magnitude);
673 
691  static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
692 
700  Precision trailingZeroDisplay(UNumberTrailingZeroDisplay trailingZeroDisplay) const;
701 
702  private:
703  enum PrecisionType {
704  RND_BOGUS,
705  RND_NONE,
706  RND_FRACTION,
707  RND_SIGNIFICANT,
708  RND_FRACTION_SIGNIFICANT,
709 
710  // Used for strange increments like 3.14.
711  RND_INCREMENT,
712 
713  // Used for increments with 1 as the only digit. This is different than fraction
714  // rounding because it supports having additional trailing zeros. For example, this
715  // class is used to round with the increment 0.010.
716  RND_INCREMENT_ONE,
717 
718  // Used for increments with 5 as the only digit (nickel rounding).
719  RND_INCREMENT_FIVE,
720 
721  RND_CURRENCY,
722  RND_ERROR
723  } fType;
724 
725  union PrecisionUnion {
728  // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT
743  bool fRetain;
744  } fracSig;
747  // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE
748  // Note: This is a union, so we shouldn't own memory, since
749  // the default destructor would leak it.
751  uint64_t fIncrement;
756  } increment;
757  UCurrencyUsage currencyUsage; // For RND_CURRENCY
758  UErrorCode errorCode; // For RND_ERROR
759  } fUnion;
760 
762 
765 
766  Precision(const PrecisionType& type, const PrecisionUnion& union_)
767  : fType(type), fUnion(union_) {}
768 
769  Precision(UErrorCode errorCode) : fType(RND_ERROR) {
770  fUnion.errorCode = errorCode;
771  }
772 
773  Precision() : fType(RND_BOGUS) {}
774 
775  bool isBogus() const {
776  return fType == RND_BOGUS;
777  }
778 
779  UBool copyErrorTo(UErrorCode &status) const {
780  if (fType == RND_ERROR) {
781  status = fUnion.errorCode;
782  return true;
783  }
784  return false;
785  }
786 
787  // On the parent type so that this method can be called internally on Precision instances.
788  Precision withCurrency(const CurrencyUnit &currency, UErrorCode &status) const;
789 
790  static FractionPrecision constructFraction(int32_t minFrac, int32_t maxFrac);
791 
792  static Precision constructSignificant(int32_t minSig, int32_t maxSig);
793 
794  static Precision constructFractionSignificant(
795  const FractionPrecision &base,
796  int32_t minSig,
797  int32_t maxSig,
798  UNumberRoundingPriority priority,
799  bool retain);
800 
801  static IncrementPrecision constructIncrement(uint64_t increment, impl::digits_t magnitude);
802 
803  static CurrencyPrecision constructCurrency(UCurrencyUsage usage);
804 
805  // To allow MacroProps/MicroProps to initialize bogus instances:
806  friend struct impl::MacroProps;
807  friend struct impl::MicroProps;
808 
809  // To allow NumberFormatterImpl to access isBogus() and other internal methods:
810  friend class impl::NumberFormatterImpl;
811 
812  // To allow NumberPropertyMapper to create instances from DecimalFormatProperties:
813  friend class impl::NumberPropertyMapper;
814 
815  // To allow access to the main implementation class:
816  friend class impl::RoundingImpl;
817 
818  // To allow child classes to call private methods:
819  friend class FractionPrecision;
820  friend class CurrencyPrecision;
821  friend class IncrementPrecision;
822 
823  // To allow access to the skeleton generation code:
824  friend class impl::GeneratorHelpers;
825 
826  // To allow access to isBogus and the default (bogus) constructor:
827  friend class units::UnitsRouter;
828 };
829 
840  public:
855  Precision withSignificantDigits(
856  int32_t minSignificantDigits,
857  int32_t maxSignificantDigits,
858  UNumberRoundingPriority priority) const;
859 
877  Precision withMinDigits(int32_t minSignificantDigits) const;
878 
896  Precision withMaxDigits(int32_t maxSignificantDigits) const;
897 
898  private:
899  // Inherit constructor
900  using Precision::Precision;
901 
902  // To allow parent class to call this class's constructor:
903  friend class Precision;
904 };
905 
916  public:
934  Precision withCurrency(const CurrencyUnit &currency) const;
935 
936  private:
937  // Inherit constructor
938  using Precision::Precision;
939 
940  // To allow parent class to call this class's constructor:
941  friend class Precision;
942 };
943 
954  public:
970  Precision withMinFraction(int32_t minFrac) const;
971 
972  private:
973  // Inherit constructor
974  using Precision::Precision;
975 
976  // To allow parent class to call this class's constructor:
977  friend class Precision;
978 };
979 
990  public:
1002  static IntegerWidth zeroFillTo(int32_t minInt);
1003 
1015  IntegerWidth truncateAt(int32_t maxInt);
1016 
1017  private:
1018  union {
1019  struct {
1020  impl::digits_t fMinInt;
1021  impl::digits_t fMaxInt;
1022  bool fFormatFailIfMoreThanMaxDigits;
1023  } minMaxInt;
1024  UErrorCode errorCode;
1025  } fUnion;
1026  bool fHasError = false;
1027 
1028  IntegerWidth(impl::digits_t minInt, impl::digits_t maxInt, bool formatFailIfMoreThanMaxDigits);
1029 
1030  IntegerWidth(UErrorCode errorCode) { // NOLINT
1031  fUnion.errorCode = errorCode;
1032  fHasError = true;
1033  }
1034 
1035  IntegerWidth() { // NOLINT
1036  fUnion.minMaxInt.fMinInt = -1;
1037  }
1038 
1040  static IntegerWidth standard() {
1041  return IntegerWidth::zeroFillTo(1);
1042  }
1043 
1044  bool isBogus() const {
1045  return !fHasError && fUnion.minMaxInt.fMinInt == -1;
1046  }
1047 
1048  UBool copyErrorTo(UErrorCode &status) const {
1049  if (fHasError) {
1050  status = fUnion.errorCode;
1051  return true;
1052  }
1053  return false;
1054  }
1055 
1056  void apply(impl::DecimalQuantity &quantity, UErrorCode &status) const;
1057 
1058  bool operator==(const IntegerWidth& other) const;
1059 
1060  // To allow MacroProps/MicroProps to initialize empty instances:
1061  friend struct impl::MacroProps;
1062  friend struct impl::MicroProps;
1063 
1064  // To allow NumberFormatterImpl to access isBogus():
1065  friend class impl::NumberFormatterImpl;
1066 
1067  // To allow the use of this class when formatting:
1068  friend class impl::MutablePatternModifier;
1069  friend class impl::ImmutablePatternModifier;
1070 
1071  // So that NumberPropertyMapper can create instances
1072  friend class impl::NumberPropertyMapper;
1073 
1074  // To allow access to the skeleton generation code:
1075  friend class impl::GeneratorHelpers;
1076 };
1077 
1086 class U_I18N_API Scale : public UMemory {
1087  public:
1094  static Scale none();
1095 
1106  static Scale powerOfTen(int32_t power);
1107 
1120  static Scale byDecimal(StringPiece multiplicand);
1121 
1130  static Scale byDouble(double multiplicand);
1131 
1138  static Scale byDoubleAndPowerOfTen(double multiplicand, int32_t power);
1139 
1140  // We need a custom destructor for the DecNum, which means we need to declare
1141  // the copy/move constructor/assignment quartet.
1142 
1144  Scale(const Scale& other);
1145 
1147  Scale& operator=(const Scale& other);
1148 
1150  Scale(Scale&& src) noexcept;
1151 
1153  Scale& operator=(Scale&& src) noexcept;
1154 
1156  ~Scale();
1157 
1158 #ifndef U_HIDE_INTERNAL_API
1159 
1160  Scale(int32_t magnitude, impl::DecNum* arbitraryToAdopt);
1161 #endif /* U_HIDE_INTERNAL_API */
1162 
1163  private:
1164  int32_t fMagnitude;
1165  impl::DecNum* fArbitrary;
1166  UErrorCode fError;
1167 
1168  Scale(UErrorCode error) : fMagnitude(0), fArbitrary(nullptr), fError(error) {}
1169 
1170  Scale() : fMagnitude(0), fArbitrary(nullptr), fError(U_ZERO_ERROR) {}
1171 
1172  bool isValid() const {
1173  return fMagnitude != 0 || fArbitrary != nullptr;
1174  }
1175 
1176  UBool copyErrorTo(UErrorCode &status) const {
1177  if (U_FAILURE(fError)) {
1178  status = fError;
1179  return true;
1180  }
1181  return false;
1182  }
1183 
1184  void applyTo(impl::DecimalQuantity& quantity) const;
1185 
1186  void applyReciprocalTo(impl::DecimalQuantity& quantity) const;
1187 
1188  // To allow MacroProps/MicroProps to initialize empty instances:
1189  friend struct impl::MacroProps;
1190  friend struct impl::MicroProps;
1191 
1192  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1193  friend class impl::NumberFormatterImpl;
1194 
1195  // To allow the helper class MultiplierFormatHandler access to private fields:
1196  friend class impl::MultiplierFormatHandler;
1197 
1198  // To allow access to the skeleton generation code:
1199  friend class impl::GeneratorHelpers;
1200 
1201  // To allow access to parsing code:
1202  friend class ::icu::numparse::impl::NumberParserImpl;
1203  friend class ::icu::numparse::impl::MultiplierParseHandler;
1204 };
1205 
1206 namespace impl {
1207 
1208 // Do not enclose entire StringProp with #ifndef U_HIDE_INTERNAL_API, needed for a protected field.
1209 // And do not enclose its class boilerplate within #ifndef U_HIDE_INTERNAL_API.
1215 
1216  public:
1218  ~StringProp();
1219 
1221  StringProp(const StringProp &other);
1222 
1224  StringProp &operator=(const StringProp &other);
1225 
1226 #ifndef U_HIDE_INTERNAL_API
1227 
1229  StringProp(StringProp &&src) noexcept;
1230 
1232  StringProp &operator=(StringProp &&src) noexcept;
1233 
1235  int16_t length() const {
1236  return fLength;
1237  }
1238 
1242  void set(StringPiece value);
1243 
1245  bool isSet() const {
1246  return fLength > 0;
1247  }
1248 
1249 #endif // U_HIDE_INTERNAL_API
1250 
1251  private:
1252  char *fValue;
1253  int16_t fLength;
1254  UErrorCode fError;
1255 
1256  StringProp() : fValue(nullptr), fLength(0), fError(U_ZERO_ERROR) {
1257  }
1258 
1260  UBool copyErrorTo(UErrorCode &status) const {
1261  if (U_FAILURE(fError)) {
1262  status = fError;
1263  return true;
1264  }
1265  return false;
1266  }
1267 
1268  // Allow NumberFormatterImpl to access fValue.
1269  friend class impl::NumberFormatterImpl;
1270 
1271  // Allow skeleton generation code to access private members.
1272  friend class impl::GeneratorHelpers;
1273 
1274  // Allow MacroProps/MicroProps to initialize empty instances and to call
1275  // copyErrorTo().
1276  friend struct impl::MacroProps;
1277 };
1278 
1279 // Do not enclose entire SymbolsWrapper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1282  public:
1284  SymbolsWrapper() : fType(SYMPTR_NONE), fPtr{nullptr} {}
1285 
1287  SymbolsWrapper(const SymbolsWrapper &other);
1288 
1290  SymbolsWrapper &operator=(const SymbolsWrapper &other);
1291 
1293  SymbolsWrapper(SymbolsWrapper&& src) noexcept;
1294 
1296  SymbolsWrapper &operator=(SymbolsWrapper&& src) noexcept;
1297 
1299  ~SymbolsWrapper();
1300 
1301 #ifndef U_HIDE_INTERNAL_API
1302 
1307  void setTo(const DecimalFormatSymbols &dfs);
1308 
1313  void setTo(const NumberingSystem *ns);
1314 
1319  bool isDecimalFormatSymbols() const;
1320 
1325  bool isNumberingSystem() const;
1326 
1331  const DecimalFormatSymbols *getDecimalFormatSymbols() const;
1332 
1337  const NumberingSystem *getNumberingSystem() const;
1338 
1339 #endif // U_HIDE_INTERNAL_API
1340 
1342  UBool copyErrorTo(UErrorCode &status) const {
1343  if (fType == SYMPTR_DFS && fPtr.dfs == nullptr) {
1344  status = U_MEMORY_ALLOCATION_ERROR;
1345  return true;
1346  } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) {
1347  status = U_MEMORY_ALLOCATION_ERROR;
1348  return true;
1349  }
1350  return false;
1351  }
1352 
1353  private:
1354  enum SymbolsPointerType {
1355  SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS
1356  } fType;
1357 
1358  union {
1359  const DecimalFormatSymbols *dfs;
1360  const NumberingSystem *ns;
1361  } fPtr;
1362 
1363  void doCopyFrom(const SymbolsWrapper &other);
1364 
1365  void doMoveFrom(SymbolsWrapper&& src);
1366 
1367  void doCleanup();
1368 };
1369 
1370 // Do not enclose entire Grouper with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1372 class U_I18N_API Grouper : public UMemory {
1373  public:
1374 #ifndef U_HIDE_INTERNAL_API
1375 
1376  static Grouper forStrategy(UNumberGroupingStrategy grouping);
1377 
1382  static Grouper forProperties(const DecimalFormatProperties& properties);
1383 
1384  // Future: static Grouper forProperties(DecimalFormatProperties& properties);
1385 
1387  Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy)
1388  : fGrouping1(grouping1),
1389  fGrouping2(grouping2),
1390  fMinGrouping(minGrouping),
1391  fStrategy(strategy) {}
1392 
1394  int16_t getPrimary() const;
1395 
1397  int16_t getSecondary() const;
1398 #endif // U_HIDE_INTERNAL_API
1399 
1400  private:
1409  int16_t fGrouping1;
1410  int16_t fGrouping2;
1411 
1419  int16_t fMinGrouping;
1420 
1425  UNumberGroupingStrategy fStrategy;
1426 
1427  Grouper() : fGrouping1(-3) {}
1428 
1429  bool isBogus() const {
1430  return fGrouping1 == -3;
1431  }
1432 
1434  void setLocaleData(const impl::ParsedPatternInfo &patternInfo, const Locale& locale);
1435 
1436  bool groupAtPosition(int32_t position, const impl::DecimalQuantity &value) const;
1437 
1438  // To allow MacroProps/MicroProps to initialize empty instances:
1439  friend struct MacroProps;
1440  friend struct MicroProps;
1441  friend struct SimpleMicroProps;
1442 
1443  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1444  friend class NumberFormatterImpl;
1445  friend class ::icu::number::SimpleNumberFormatter;
1446 
1447  // To allow NumberParserImpl to perform setLocaleData():
1448  friend class ::icu::numparse::impl::NumberParserImpl;
1449 
1450  // To allow access to the skeleton generation code:
1451  friend class impl::GeneratorHelpers;
1452 };
1453 
1454 // Do not enclose entire Padder with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1456 class U_I18N_API Padder : public UMemory {
1457  public:
1458 #ifndef U_HIDE_INTERNAL_API
1459 
1460  static Padder none();
1461 
1463  static Padder codePoints(UChar32 cp, int32_t targetWidth, UNumberFormatPadPosition position);
1464 
1466  static Padder forProperties(const DecimalFormatProperties& properties);
1467 #endif // U_HIDE_INTERNAL_API
1468 
1469  private:
1470  UChar32 fWidth; // -3 = error; -2 = bogus; -1 = no padding
1471  union {
1472  struct {
1473  int32_t fCp;
1474  UNumberFormatPadPosition fPosition;
1475  } padding;
1476  UErrorCode errorCode;
1477  } fUnion;
1478 
1479  Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position);
1480 
1481  Padder(int32_t width);
1482 
1483  Padder(UErrorCode errorCode) : fWidth(-3) { // NOLINT
1484  fUnion.errorCode = errorCode;
1485  }
1486 
1487  Padder() : fWidth(-2) {} // NOLINT
1488 
1489  bool isBogus() const {
1490  return fWidth == -2;
1491  }
1492 
1493  UBool copyErrorTo(UErrorCode &status) const {
1494  if (fWidth == -3) {
1495  status = fUnion.errorCode;
1496  return true;
1497  }
1498  return false;
1499  }
1500 
1501  bool isValid() const {
1502  return fWidth > 0;
1503  }
1504 
1505  int32_t padAndApply(const impl::Modifier &mod1, const impl::Modifier &mod2,
1506  FormattedStringBuilder &string, int32_t leftIndex, int32_t rightIndex,
1507  UErrorCode &status) const;
1508 
1509  // To allow MacroProps/MicroProps to initialize empty instances:
1510  friend struct MacroProps;
1511  friend struct MicroProps;
1512 
1513  // To allow NumberFormatterImpl to access isBogus() and perform other operations:
1514  friend class impl::NumberFormatterImpl;
1515 
1516  // To allow access to the skeleton generation code:
1517  friend class impl::GeneratorHelpers;
1518 };
1519 
1520 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
1522 struct U_I18N_API MacroProps : public UMemory {
1525 
1527  MeasureUnit unit; // = MeasureUnit(); (the base dimensionless unit)
1528 
1530  MeasureUnit perUnit; // = MeasureUnit(); (the base dimensionless unit)
1531 
1533  Precision precision; // = Precision(); (bogus)
1534 
1537 
1539  Grouper grouper; // = Grouper(); (bogus)
1540 
1542  Padder padder; // = Padder(); (bogus)
1543 
1545  IntegerWidth integerWidth; // = IntegerWidth(); (bogus)
1546 
1549 
1550  // UNUM_XYZ_COUNT denotes null (bogus) values.
1551 
1554 
1557 
1559  bool approximately = false;
1560 
1563 
1565  Scale scale; // = Scale(); (benign value)
1566 
1568  StringProp usage; // = StringProp(); (no usage)
1569 
1571  StringProp unitDisplayCase; // = StringProp(); (nominative)
1572 
1574  const AffixPatternProvider* affixProvider = nullptr; // no ownership
1575 
1577  const PluralRules* rules = nullptr; // no ownership
1578 
1580  int32_t threshold = kInternalDefaultThreshold;
1581 
1584 
1585  // NOTE: Uses default copy and move constructors.
1586 
1591  bool copyErrorTo(UErrorCode &status) const {
1592  return notation.copyErrorTo(status) || precision.copyErrorTo(status) ||
1593  padder.copyErrorTo(status) || integerWidth.copyErrorTo(status) ||
1594  symbols.copyErrorTo(status) || scale.copyErrorTo(status) || usage.copyErrorTo(status) ||
1595  unitDisplayCase.copyErrorTo(status);
1596  }
1597 };
1598 
1599 } // namespace impl
1600 
1601 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER)
1602 // Ignore MSVC warning 4661. This is generated for NumberFormatterSettings<>::toSkeleton() as this method
1603 // is defined elsewhere (in number_skeletons.cpp). The compiler is warning that the explicit template instantiation
1604 // inside this single translation unit (CPP file) is incomplete, and thus it isn't sure if the template class is
1605 // fully defined. However, since each translation unit explicitly instantiates all the necessary template classes,
1606 // they will all be passed to the linker, and the linker will still find and export all the class members.
1607 #pragma warning(push)
1608 #pragma warning(disable: 4661)
1609 #endif
1610 
1616 template<typename Derived>
1618  public:
1647  Derived notation(const Notation &notation) const &;
1648 
1658  Derived notation(const Notation &notation) &&;
1659 
1708  Derived unit(const icu::MeasureUnit &unit) const &;
1709 
1719  Derived unit(const icu::MeasureUnit &unit) &&;
1720 
1734  Derived adoptUnit(icu::MeasureUnit *unit) const &;
1735 
1745  Derived adoptUnit(icu::MeasureUnit *unit) &&;
1746 
1769  Derived perUnit(const icu::MeasureUnit &perUnit) const &;
1770 
1780  Derived perUnit(const icu::MeasureUnit &perUnit) &&;
1781 
1795  Derived adoptPerUnit(icu::MeasureUnit *perUnit) const &;
1796 
1806  Derived adoptPerUnit(icu::MeasureUnit *perUnit) &&;
1807 
1838  Derived precision(const Precision& precision) const &;
1839 
1849  Derived precision(const Precision& precision) &&;
1850 
1869  Derived roundingMode(UNumberFormatRoundingMode roundingMode) const &;
1870 
1879  Derived roundingMode(UNumberFormatRoundingMode roundingMode) &&;
1880 
1908  Derived grouping(UNumberGroupingStrategy strategy) const &;
1909 
1919  Derived grouping(UNumberGroupingStrategy strategy) &&;
1920 
1945  Derived integerWidth(const IntegerWidth &style) const &;
1946 
1956  Derived integerWidth(const IntegerWidth &style) &&;
1957 
1998  Derived symbols(const DecimalFormatSymbols &symbols) const &;
1999 
2009  Derived symbols(const DecimalFormatSymbols &symbols) &&;
2010 
2044  Derived adoptSymbols(NumberingSystem *symbols) const &;
2045 
2055  Derived adoptSymbols(NumberingSystem *symbols) &&;
2056 
2082  Derived unitWidth(UNumberUnitWidth width) const &;
2083 
2093  Derived unitWidth(UNumberUnitWidth width) &&;
2094 
2120  Derived sign(UNumberSignDisplay style) const &;
2121 
2131  Derived sign(UNumberSignDisplay style) &&;
2132 
2158  Derived decimal(UNumberDecimalSeparatorDisplay style) const &;
2159 
2169  Derived decimal(UNumberDecimalSeparatorDisplay style) &&;
2170 
2195  Derived scale(const Scale &scale) const &;
2196 
2206  Derived scale(const Scale &scale) &&;
2207 
2250  Derived usage(StringPiece usage) const &;
2251 
2259  Derived usage(StringPiece usage) &&;
2260 
2269  Derived displayOptions(const DisplayOptions &displayOptions) const &;
2270 
2278  Derived displayOptions(const DisplayOptions &displayOptions) &&;
2279 
2280 #ifndef U_HIDE_INTERNAL_API
2281 
2291  Derived unitDisplayCase(StringPiece unitDisplayCase) const &;
2292 
2302  Derived unitDisplayCase(StringPiece unitDisplayCase) &&;
2303 #endif // U_HIDE_INTERNAL_API
2304 
2305 #ifndef U_HIDE_INTERNAL_API
2306 
2312  Derived padding(const impl::Padder &padder) const &;
2313 
2315  Derived padding(const impl::Padder &padder) &&;
2316 
2323  Derived threshold(int32_t threshold) const &;
2324 
2326  Derived threshold(int32_t threshold) &&;
2327 
2333  Derived macros(const impl::MacroProps& macros) const &;
2334 
2336  Derived macros(const impl::MacroProps& macros) &&;
2337 
2339  Derived macros(impl::MacroProps&& macros) const &;
2340 
2342  Derived macros(impl::MacroProps&& macros) &&;
2343 
2344 #endif /* U_HIDE_INTERNAL_API */
2345 
2363  UnicodeString toSkeleton(UErrorCode& status) const;
2364 
2376  LocalPointer<Derived> clone() const &;
2377 
2385  LocalPointer<Derived> clone() &&;
2386 
2393  UBool copyErrorTo(UErrorCode &outErrorCode) const {
2394  if (U_FAILURE(outErrorCode)) {
2395  // Do not overwrite the older error code
2396  return true;
2397  }
2398  fMacros.copyErrorTo(outErrorCode);
2399  return U_FAILURE(outErrorCode);
2400  }
2401 
2402  // NOTE: Uses default copy and move constructors.
2403 
2404  private:
2405  impl::MacroProps fMacros;
2406 
2407  // Don't construct me directly! Use (Un)LocalizedNumberFormatter.
2408  NumberFormatterSettings() = default;
2409 
2410  friend class LocalizedNumberFormatter;
2411  friend class UnlocalizedNumberFormatter;
2412 
2413  // Give NumberRangeFormatter access to the MacroProps
2414  friend void impl::touchRangeLocales(impl::RangeMacroProps& macros);
2415  friend class impl::NumberRangeFormatterImpl;
2416 };
2417 
2418 // Explicit instantiations in source/i18n/number_fluent.cpp.
2419 // (MSVC treats imports/exports of explicit instantiations differently.)
2420 #ifndef _MSC_VER
2421 extern template class NumberFormatterSettings<UnlocalizedNumberFormatter>;
2422 extern template class NumberFormatterSettings<LocalizedNumberFormatter>;
2423 #endif
2424 
2435 
2436  public:
2446  LocalizedNumberFormatter locale(const icu::Locale &locale) const &;
2447 
2457  LocalizedNumberFormatter locale(const icu::Locale &locale) &&;
2458 
2464  UnlocalizedNumberFormatter() = default;
2465 
2471 
2478 
2483  UnlocalizedNumberFormatter& operator=(const UnlocalizedNumberFormatter& other);
2484 
2490  UnlocalizedNumberFormatter& operator=(UnlocalizedNumberFormatter&& src) noexcept;
2491 
2492  private:
2494 
2495  explicit UnlocalizedNumberFormatter(
2497 
2498  explicit UnlocalizedNumberFormatter(const impl::MacroProps &macros);
2499 
2500  explicit UnlocalizedNumberFormatter(impl::MacroProps &&macros);
2501 
2502  // To give the fluent setters access to this class's constructor:
2504 
2505  // To give NumberFormatter::with() access to this class's constructor:
2506  friend class NumberFormatter;
2507 
2508  // To give LNF::withoutLocale() access to this class's constructor:
2509  friend class LocalizedNumberFormatter;
2510 };
2511 
2522  public:
2534  FormattedNumber formatInt(int64_t value, UErrorCode &status) const;
2535 
2547  FormattedNumber formatDouble(double value, UErrorCode &status) const;
2548 
2563  FormattedNumber formatDecimal(StringPiece value, UErrorCode& status) const;
2564 
2565 #ifndef U_HIDE_INTERNAL_API
2566 
2567 
2571  const DecimalFormatSymbols* getDecimalFormatSymbols() const;
2572 
2576  FormattedNumber formatDecimalQuantity(const impl::DecimalQuantity& dq, UErrorCode& status) const;
2577 
2581  void getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const;
2582 
2587  const impl::NumberFormatterImpl* getCompiled() const;
2588 
2593  int32_t getCallCount() const;
2594 
2595 #endif /* U_HIDE_INTERNAL_API */
2596 
2610  Format* toFormat(UErrorCode& status) const;
2611 
2612 #ifndef U_HIDE_DRAFT_API
2613 
2619  UnlocalizedNumberFormatter withoutLocale() const &;
2620 
2628  UnlocalizedNumberFormatter withoutLocale() &&;
2629 #endif // U_HIDE_DRAFT_API
2630 
2636  LocalizedNumberFormatter() = default;
2637 
2643 
2650 
2655  LocalizedNumberFormatter& operator=(const LocalizedNumberFormatter& other);
2656 
2662  LocalizedNumberFormatter& operator=(LocalizedNumberFormatter&& src) noexcept;
2663 
2664 #ifndef U_HIDE_INTERNAL_API
2665 
2678  void formatImpl(impl::UFormattedNumberData *results, UErrorCode &status) const;
2679 
2680 #endif /* U_HIDE_INTERNAL_API */
2681 
2687 
2688  private:
2689  // Note: fCompiled can't be a LocalPointer because impl::NumberFormatterImpl is defined in an internal
2690  // header, and LocalPointer needs the full class definition in order to delete the instance.
2691  const impl::NumberFormatterImpl* fCompiled {nullptr};
2692  char fUnsafeCallCount[8] {}; // internally cast to u_atomic_int32_t
2693 
2694  // Owned pointer to a DecimalFormatWarehouse, used when copying a LocalizedNumberFormatter
2695  // from a DecimalFormat.
2696  const impl::DecimalFormatWarehouse* fWarehouse {nullptr};
2697 
2699 
2701 
2702  LocalizedNumberFormatter(const impl::MacroProps &macros, const Locale &locale);
2703 
2704  LocalizedNumberFormatter(impl::MacroProps &&macros, const Locale &locale);
2705 
2706  void resetCompiled();
2707 
2708  void lnfMoveHelper(LocalizedNumberFormatter&& src);
2709 
2710  void lnfCopyHelper(const LocalizedNumberFormatter& src, UErrorCode& status);
2711 
2715  bool computeCompiled(UErrorCode& status) const;
2716 
2717  // To give the fluent setters access to this class's constructor:
2720 
2721  // To give UnlocalizedNumberFormatter::locale() access to this class's constructor:
2722  friend class UnlocalizedNumberFormatter;
2723 };
2724 
2725 #if (U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(_MSC_VER)
2726 // Warning 4661.
2727 #pragma warning(pop)
2728 #endif
2729 
2736  public:
2744  static UnlocalizedNumberFormatter with();
2745 
2755  static LocalizedNumberFormatter withLocale(const Locale &locale);
2756 
2774  static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status);
2775 
2796  static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton,
2797  UParseError& perror, UErrorCode& status);
2798 
2802  NumberFormatter() = delete;
2803 };
2804 
2805 } // namespace number
2806 U_NAMESPACE_END
2807 
2808 #endif /* #if !UCONFIG_NO_FORMATTING */
2809 
2810 #endif /* U_SHOW_CPLUSPLUS_API */
2811 
2812 #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:409
C++ API: Currency Unit Information.
C API: Localized number formatting; not recommended for C++.
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:747
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).
"Smart pointer" 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:465
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:473
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:316
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.
void touchRangeLocales(impl::RangeMacroProps &macros)
Used for NumberRangeFormatter and implemented in numrange_fluent.cpp.
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:427
UBool copyErrorTo(UErrorCode &outErrorCode) const
Sets the UErrorCode if an error occurred in the fluent chain.
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.
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:430
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.
int16_t digits_t
Datatype for minimum/maximum fraction digits.
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:61
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.
bool copyErrorTo(UErrorCode &status) const
Check all members for errors.
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.
UBool copyErrorTo(UErrorCode &status) const
A Locale object represents a specific geographical, political, or cultural region.
Definition: locid.h:195