1 // © 2022 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #ifndef __SIMPLENUMBERFORMATTERH__ 5 #define __SIMPLENUMBERFORMATTERH__ 6 7 #include "unicode/utypes.h" 8 9 #if U_SHOW_CPLUSPLUS_API 10 11 #if !UCONFIG_NO_FORMATTING 12 13 #include "unicode/dcfmtsym.h" 14 #include "unicode/usimplenumberformatter.h" 15 #include "unicode/formattednumber.h" 16 17 /** 18 * \file 19 * \brief C++ API: Simple number formatting focused on low memory and code size. 20 * 21 * These functions render locale-aware number strings but without the bells and whistles found in 22 * other number formatting APIs such as those in numberformatter.h, like units and currencies. 23 * 24 * <pre> 25 * SimpleNumberFormatter snf = SimpleNumberFormatter::forLocale("de-CH", status); 26 * FormattedNumber result = snf.formatInt64(-1000007, status); 27 * assertEquals("", u"-1’000’007", result.toString(status)); 28 * </pre> 29 */ 30 31 U_NAMESPACE_BEGIN 32 33 /* forward declaration */ 34 class SimpleDateFormat; 35 36 namespace number { // icu::number 37 38 39 namespace impl { 40 class UFormattedNumberData; 41 struct SimpleMicroProps; 42 class AdoptingSignumModifierStore; 43 } // icu::number::impl 44 45 46 /** 47 * An input type for SimpleNumberFormatter. 48 * 49 * This class is mutable and not intended for public subclassing. This class is movable but not copyable. 50 * 51 * @stable ICU 73 52 */ 53 class U_I18N_API SimpleNumber : public UMemory { 54 public: 55 /** 56 * Creates a SimpleNumber for an integer. 57 * 58 * @stable ICU 73 59 */ 60 static SimpleNumber forInt64(int64_t value, UErrorCode& status); 61 62 /** 63 * Changes the value of the SimpleNumber by a power of 10. 64 * 65 * This function immediately mutates the inner value. 66 * 67 * @stable ICU 73 68 */ 69 void multiplyByPowerOfTen(int32_t power, UErrorCode& status); 70 71 /** 72 * Rounds the value currently stored in the SimpleNumber to the given power of 10, 73 * which can be before or after the decimal separator. 74 * 75 * This function does not change minimum integer digits. 76 * 77 * @stable ICU 73 78 */ 79 void roundTo(int32_t power, UNumberFormatRoundingMode roundingMode, UErrorCode& status); 80 81 #ifndef U_HIDE_DRAFT_API 82 /** 83 * Sets the number of integer digits to the given amount, truncating if necessary. 84 * 85 * @draft ICU 75 86 */ 87 void setMaximumIntegerDigits(uint32_t maximumIntegerDigits, UErrorCode& status); 88 #endif // U_HIDE_DRAFT_API 89 90 #ifndef U_HIDE_DEPRECATED_API 91 /** 92 * Alias for setMaximumIntegerDigits. 93 * Will be removed after ICU 75. 94 * 95 * @deprecated ICU 75 96 */ 97 void truncateStart(uint32_t maximumIntegerDigits, UErrorCode& status); 98 #endif // U_HIDE_DEPRECATED_API 99 100 /** 101 * Pads the beginning of the number with zeros up to the given minimum number of integer digits. 102 * 103 * @stable ICU 73 104 */ 105 void setMinimumIntegerDigits(uint32_t minimumIntegerDigits, UErrorCode& status); 106 107 /** 108 * Pads the end of the number with zeros up to the given minimum number of fraction digits. 109 * 110 * @stable ICU 73 111 */ 112 void setMinimumFractionDigits(uint32_t minimumFractionDigits, UErrorCode& status); 113 114 /** 115 * Sets the sign of the number: an explicit plus sign, explicit minus sign, or no sign. 116 * 117 * This setting is applied upon formatting the number. 118 * 119 * NOTE: This does not support accounting sign notation. 120 * 121 * @stable ICU 73 122 */ 123 void setSign(USimpleNumberSign sign, UErrorCode& status); 124 125 /** 126 * Creates a new, empty SimpleNumber that does not contain a value. 127 * 128 * NOTE: This number will fail to format; use forInt64() to create a SimpleNumber with a value. 129 * 130 * @stable ICU 73 131 */ 132 SimpleNumber() = default; 133 134 /** 135 * Destruct this SimpleNumber, cleaning up any memory it might own. 136 * 137 * @stable ICU 73 138 */ ~SimpleNumber()139 ~SimpleNumber() { 140 cleanup(); 141 } 142 143 /** 144 * SimpleNumber move constructor. 145 * 146 * @stable ICU 73 147 */ SimpleNumber(SimpleNumber && other)148 SimpleNumber(SimpleNumber&& other) noexcept { 149 fData = other.fData; 150 fSign = other.fSign; 151 other.fData = nullptr; 152 } 153 154 /** 155 * SimpleNumber move assignment. 156 * 157 * @stable ICU 73 158 */ 159 SimpleNumber& operator=(SimpleNumber&& other) noexcept { 160 cleanup(); 161 fData = other.fData; 162 fSign = other.fSign; 163 other.fData = nullptr; 164 return *this; 165 } 166 167 private: 168 SimpleNumber(impl::UFormattedNumberData* data, UErrorCode& status); 169 SimpleNumber(const SimpleNumber&) = delete; 170 SimpleNumber& operator=(const SimpleNumber&) = delete; 171 172 void cleanup(); 173 174 impl::UFormattedNumberData* fData = nullptr; 175 USimpleNumberSign fSign = UNUM_SIMPLE_NUMBER_NO_SIGN; 176 177 friend class SimpleNumberFormatter; 178 179 // Uses the private constructor to avoid a heap allocation 180 friend class icu::SimpleDateFormat; 181 }; 182 183 184 /** 185 * A special NumberFormatter focused on smaller binary size and memory use. 186 * 187 * SimpleNumberFormatter is capable of basic number formatting, including grouping separators, 188 * sign display, and rounding. It is not capable of currencies, compact notation, or units. 189 * 190 * This class is immutable and not intended for public subclassing. This class is movable but not copyable. 191 * 192 * @stable ICU 73 193 */ 194 class U_I18N_API SimpleNumberFormatter : public UMemory { 195 public: 196 /** 197 * Creates a new SimpleNumberFormatter with all locale defaults. 198 * 199 * @stable ICU 73 200 */ 201 static SimpleNumberFormatter forLocale( 202 const icu::Locale &locale, 203 UErrorCode &status); 204 205 /** 206 * Creates a new SimpleNumberFormatter, overriding the grouping strategy. 207 * 208 * @stable ICU 73 209 */ 210 static SimpleNumberFormatter forLocaleAndGroupingStrategy( 211 const icu::Locale &locale, 212 UNumberGroupingStrategy groupingStrategy, 213 UErrorCode &status); 214 215 /** 216 * Creates a new SimpleNumberFormatter, overriding the grouping strategy and symbols. 217 * 218 * IMPORTANT: For efficiency, this function borrows the symbols. The symbols MUST remain valid 219 * for the lifetime of the SimpleNumberFormatter. 220 * 221 * @stable ICU 73 222 */ 223 static SimpleNumberFormatter forLocaleAndSymbolsAndGroupingStrategy( 224 const icu::Locale &locale, 225 const DecimalFormatSymbols &symbols, 226 UNumberGroupingStrategy groupingStrategy, 227 UErrorCode &status); 228 229 /** 230 * Formats a value using this SimpleNumberFormatter. 231 * 232 * The SimpleNumber argument is "consumed". A new SimpleNumber object should be created for 233 * every formatting operation. 234 * 235 * @stable ICU 73 236 */ 237 FormattedNumber format(SimpleNumber value, UErrorCode &status) const; 238 239 /** 240 * Formats an integer using this SimpleNumberFormatter. 241 * 242 * For more control over the formatting, use SimpleNumber. 243 * 244 * @stable ICU 73 245 */ formatInt64(int64_t value,UErrorCode & status)246 FormattedNumber formatInt64(int64_t value, UErrorCode &status) const { 247 return format(SimpleNumber::forInt64(value, status), status); 248 } 249 250 #ifndef U_HIDE_INTERNAL_API 251 /** 252 * Run the formatter with the internal types. 253 * @internal 254 */ 255 void formatImpl(impl::UFormattedNumberData* data, USimpleNumberSign sign, UErrorCode& status) const; 256 #endif // U_HIDE_INTERNAL_API 257 258 /** 259 * Destruct this SimpleNumberFormatter, cleaning up any memory it might own. 260 * 261 * @stable ICU 73 262 */ ~SimpleNumberFormatter()263 ~SimpleNumberFormatter() { 264 cleanup(); 265 } 266 267 /** 268 * Creates a shell, initialized but non-functional SimpleNumberFormatter. 269 * 270 * @stable ICU 73 271 */ 272 SimpleNumberFormatter() = default; 273 274 /** 275 * SimpleNumberFormatter: Move constructor. 276 * 277 * @stable ICU 73 278 */ SimpleNumberFormatter(SimpleNumberFormatter && other)279 SimpleNumberFormatter(SimpleNumberFormatter&& other) noexcept { 280 fGroupingStrategy = other.fGroupingStrategy; 281 fOwnedSymbols = other.fOwnedSymbols; 282 fMicros = other.fMicros; 283 fPatternModifier = other.fPatternModifier; 284 other.fOwnedSymbols = nullptr; 285 other.fMicros = nullptr; 286 other.fPatternModifier = nullptr; 287 } 288 289 /** 290 * SimpleNumberFormatter: Move assignment. 291 * 292 * @stable ICU 73 293 */ 294 SimpleNumberFormatter& operator=(SimpleNumberFormatter&& other) noexcept { 295 cleanup(); 296 fGroupingStrategy = other.fGroupingStrategy; 297 fOwnedSymbols = other.fOwnedSymbols; 298 fMicros = other.fMicros; 299 fPatternModifier = other.fPatternModifier; 300 other.fOwnedSymbols = nullptr; 301 other.fMicros = nullptr; 302 other.fPatternModifier = nullptr; 303 return *this; 304 } 305 306 private: 307 void initialize( 308 const icu::Locale &locale, 309 const DecimalFormatSymbols &symbols, 310 UNumberGroupingStrategy groupingStrategy, 311 UErrorCode &status); 312 313 void cleanup(); 314 315 SimpleNumberFormatter(const SimpleNumberFormatter&) = delete; 316 317 SimpleNumberFormatter& operator=(const SimpleNumberFormatter&) = delete; 318 319 UNumberGroupingStrategy fGroupingStrategy = UNUM_GROUPING_AUTO; 320 321 // Owned Pointers: 322 DecimalFormatSymbols* fOwnedSymbols = nullptr; // can be empty 323 impl::SimpleMicroProps* fMicros = nullptr; 324 impl::AdoptingSignumModifierStore* fPatternModifier = nullptr; 325 }; 326 327 328 } // namespace number 329 U_NAMESPACE_END 330 331 #endif /* #if !UCONFIG_NO_FORMATTING */ 332 333 #endif /* U_SHOW_CPLUSPLUS_API */ 334 335 #endif // __SIMPLENUMBERFORMATTERH__ 336 337