number_mapper.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // © 2018 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. #include "unicode/utypes.h"
  4. #if !UCONFIG_NO_FORMATTING
  5. #ifndef __NUMBER_MAPPER_H__
  6. #define __NUMBER_MAPPER_H__
  7. #include <atomic>
  8. #include "number_types.h"
  9. #include "unicode/currpinf.h"
  10. #include "standardplural.h"
  11. #include "number_patternstring.h"
  12. #include "number_currencysymbols.h"
  13. #include "numparse_impl.h"
  14. U_NAMESPACE_BEGIN
  15. namespace number {
  16. namespace impl {
  17. class AutoAffixPatternProvider;
  18. class CurrencyPluralInfoAffixProvider;
  19. class PropertiesAffixPatternProvider : public AffixPatternProvider, public UMemory {
  20. public:
  21. bool isBogus() const {
  22. return fBogus;
  23. }
  24. void setToBogus() {
  25. fBogus = true;
  26. }
  27. void setTo(const DecimalFormatProperties& properties, UErrorCode& status);
  28. // AffixPatternProvider Methods:
  29. char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;
  30. int32_t length(int32_t flags) const U_OVERRIDE;
  31. UnicodeString getString(int32_t flags) const U_OVERRIDE;
  32. bool hasCurrencySign() const U_OVERRIDE;
  33. bool positiveHasPlusSign() const U_OVERRIDE;
  34. bool hasNegativeSubpattern() const U_OVERRIDE;
  35. bool negativeHasMinusSign() const U_OVERRIDE;
  36. bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;
  37. bool hasBody() const U_OVERRIDE;
  38. private:
  39. UnicodeString posPrefix;
  40. UnicodeString posSuffix;
  41. UnicodeString negPrefix;
  42. UnicodeString negSuffix;
  43. bool isCurrencyPattern;
  44. PropertiesAffixPatternProvider() = default; // puts instance in valid but undefined state
  45. const UnicodeString& getStringInternal(int32_t flags) const;
  46. bool fBogus{true};
  47. friend class AutoAffixPatternProvider;
  48. friend class CurrencyPluralInfoAffixProvider;
  49. };
  50. class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory {
  51. public:
  52. bool isBogus() const {
  53. return fBogus;
  54. }
  55. void setToBogus() {
  56. fBogus = true;
  57. }
  58. void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties,
  59. UErrorCode& status);
  60. // AffixPatternProvider Methods:
  61. char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;
  62. int32_t length(int32_t flags) const U_OVERRIDE;
  63. UnicodeString getString(int32_t flags) const U_OVERRIDE;
  64. bool hasCurrencySign() const U_OVERRIDE;
  65. bool positiveHasPlusSign() const U_OVERRIDE;
  66. bool hasNegativeSubpattern() const U_OVERRIDE;
  67. bool negativeHasMinusSign() const U_OVERRIDE;
  68. bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;
  69. bool hasBody() const U_OVERRIDE;
  70. private:
  71. PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT];
  72. CurrencyPluralInfoAffixProvider() = default;
  73. bool fBogus{true};
  74. friend class AutoAffixPatternProvider;
  75. };
  76. class AutoAffixPatternProvider {
  77. public:
  78. inline AutoAffixPatternProvider() = default;
  79. inline AutoAffixPatternProvider(const DecimalFormatProperties& properties, UErrorCode& status) {
  80. setTo(properties, status);
  81. }
  82. inline void setTo(const DecimalFormatProperties& properties, UErrorCode& status) {
  83. if (properties.currencyPluralInfo.fPtr.isNull()) {
  84. propertiesAPP.setTo(properties, status);
  85. currencyPluralInfoAPP.setToBogus();
  86. } else {
  87. propertiesAPP.setToBogus();
  88. currencyPluralInfoAPP.setTo(*properties.currencyPluralInfo.fPtr, properties, status);
  89. }
  90. }
  91. inline const AffixPatternProvider& get() const {
  92. if (!currencyPluralInfoAPP.isBogus()) {
  93. return currencyPluralInfoAPP;
  94. } else {
  95. return propertiesAPP;
  96. }
  97. }
  98. private:
  99. PropertiesAffixPatternProvider propertiesAPP;
  100. CurrencyPluralInfoAffixProvider currencyPluralInfoAPP;
  101. };
  102. /**
  103. * A struct for ownership of a few objects needed for formatting.
  104. */
  105. struct DecimalFormatWarehouse {
  106. AutoAffixPatternProvider affixProvider;
  107. };
  108. /**
  109. * Internal fields for DecimalFormat.
  110. * TODO: Make some of these fields by value instead of by LocalPointer?
  111. */
  112. struct DecimalFormatFields : public UMemory {
  113. DecimalFormatFields() {}
  114. DecimalFormatFields(const DecimalFormatProperties& propsToCopy)
  115. : properties(propsToCopy) {}
  116. /** The property bag corresponding to user-specified settings and settings from the pattern string. */
  117. DecimalFormatProperties properties;
  118. /** The symbols for the current locale. */
  119. LocalPointer<const DecimalFormatSymbols> symbols;
  120. /**
  121. * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link
  122. * #format} method uses the formatter directly without needing to synchronize.
  123. */
  124. LocalizedNumberFormatter formatter;
  125. /** The lazy-computed parser for .parse() */
  126. std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};
  127. /** The lazy-computed parser for .parseCurrency() */
  128. std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {};
  129. /** Small object ownership warehouse for the formatter and parser */
  130. DecimalFormatWarehouse warehouse;
  131. /** The effective properties as exported from the formatter object. Used by some getters. */
  132. DecimalFormatProperties exportedProperties;
  133. // Data for fastpath
  134. bool canUseFastFormat = false;
  135. struct FastFormatData {
  136. char16_t cpZero;
  137. char16_t cpGroupingSeparator;
  138. char16_t cpMinusSign;
  139. int8_t minInt;
  140. int8_t maxInt;
  141. } fastData;
  142. };
  143. /**
  144. * Utilities for converting between a DecimalFormatProperties and a MacroProps.
  145. */
  146. class NumberPropertyMapper {
  147. public:
  148. /** Convenience method to create a NumberFormatter directly from Properties. */
  149. static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
  150. const DecimalFormatSymbols& symbols,
  151. DecimalFormatWarehouse& warehouse, UErrorCode& status);
  152. /** Convenience method to create a NumberFormatter directly from Properties. */
  153. static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
  154. const DecimalFormatSymbols& symbols,
  155. DecimalFormatWarehouse& warehouse,
  156. DecimalFormatProperties& exportedProperties,
  157. UErrorCode& status);
  158. /**
  159. * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
  160. * object. In other words, maps Properties to MacroProps. This function is used by the
  161. * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
  162. *
  163. * @param properties
  164. * The property bag to be mapped.
  165. * @param symbols
  166. * The symbols associated with the property bag.
  167. * @param exportedProperties
  168. * A property bag in which to store validated properties. Used by some DecimalFormat
  169. * getters.
  170. * @return A new MacroProps containing all of the information in the Properties.
  171. */
  172. static MacroProps oldToNew(const DecimalFormatProperties& properties,
  173. const DecimalFormatSymbols& symbols, DecimalFormatWarehouse& warehouse,
  174. DecimalFormatProperties* exportedProperties, UErrorCode& status);
  175. };
  176. } // namespace impl
  177. } // namespace numparse
  178. U_NAMESPACE_END
  179. #endif //__NUMBER_MAPPER_H__
  180. #endif /* #if !UCONFIG_NO_FORMATTING */