numberrangeformatter.h (26413B)
1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #ifndef __NUMBERRANGEFORMATTER_H__ 5 #define __NUMBERRANGEFORMATTER_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/fieldpos.h" 15 #include "unicode/formattedvalue.h" 16 #include "unicode/fpositer.h" 17 #include "unicode/numberformatter.h" 18 #include "unicode/unumberrangeformatter.h" 19 20 #ifndef __wasi__ 21 #include <atomic> 22 #endif 23 24 /** 25 * \file 26 * \brief C++ API: Library for localized formatting of number, currency, and unit ranges. 27 * 28 * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement. 29 * <p> 30 * Usage example: 31 * <p> 32 * <pre> 33 * NumberRangeFormatter::with() 34 * .identityFallback(UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE) 35 * .numberFormatterFirst(NumberFormatter::with().adoptUnit(MeasureUnit::createMeter())) 36 * .numberFormatterSecond(NumberFormatter::with().adoptUnit(MeasureUnit::createKilometer())) 37 * .locale("en-GB") 38 * .formatFormattableRange(750, 1.2, status) 39 * .toString(status); 40 * // => "750 m - 1.2 km" 41 * </pre> 42 * <p> 43 * Like NumberFormatter, NumberRangeFormatter instances (i.e., LocalizedNumberRangeFormatter 44 * and UnlocalizedNumberRangeFormatter) are immutable and thread-safe. This API is based on the 45 * <em>fluent</em> design pattern popularized by libraries such as Google's Guava. 46 * 47 * @author Shane Carr 48 */ 49 50 51 U_NAMESPACE_BEGIN 52 53 // Forward declarations: 54 class PluralRules; 55 56 namespace number { // icu::number 57 58 // Forward declarations: 59 class UnlocalizedNumberRangeFormatter; 60 class LocalizedNumberRangeFormatter; 61 class FormattedNumberRange; 62 63 namespace impl { 64 65 // Forward declarations: 66 struct RangeMacroProps; 67 class DecimalQuantity; 68 class UFormattedNumberRangeData; 69 class NumberRangeFormatterImpl; 70 struct UFormattedNumberRangeImpl; 71 72 } // namespace impl 73 74 // Other helper classes would go here, but there are none. 75 76 namespace impl { // icu::number::impl 77 78 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field 79 /** @internal */ 80 struct RangeMacroProps : public UMemory { 81 /** @internal */ 82 UnlocalizedNumberFormatter formatter1; // = NumberFormatter::with(); 83 84 /** @internal */ 85 UnlocalizedNumberFormatter formatter2; // = NumberFormatter::with(); 86 87 /** @internal */ 88 bool singleFormatter = true; 89 90 /** @internal */ 91 UNumberRangeCollapse collapse = UNUM_RANGE_COLLAPSE_AUTO; 92 93 /** @internal */ 94 UNumberRangeIdentityFallback identityFallback = UNUM_IDENTITY_FALLBACK_APPROXIMATELY; 95 96 /** @internal */ 97 Locale locale; 98 99 // NOTE: Uses default copy and move constructors. 100 101 /** 102 * Check all members for errors. 103 * @internal 104 */ 105 bool copyErrorTo(UErrorCode &status) const { 106 return formatter1.copyErrorTo(status) || formatter2.copyErrorTo(status); 107 } 108 }; 109 110 } // namespace impl 111 112 /** 113 * An abstract base class for specifying settings related to number formatting. This class is implemented by 114 * {@link UnlocalizedNumberRangeFormatter} and {@link LocalizedNumberRangeFormatter}. This class is not intended for 115 * public subclassing. 116 */ 117 template<typename Derived> 118 class U_I18N_API NumberRangeFormatterSettings { 119 public: 120 /** 121 * Sets the NumberFormatter instance to use for the numbers in the range. The same formatter is applied to both 122 * sides of the range. 123 * <p> 124 * The NumberFormatter instances must not have a locale applied yet; the locale specified on the 125 * NumberRangeFormatter will be used. 126 * 127 * @param formatter 128 * The formatter to use for both numbers in the range. 129 * @return The fluent chain. 130 * @stable ICU 63 131 */ 132 Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &; 133 134 /** 135 * Overload of numberFormatterBoth() for use on an rvalue reference. 136 * 137 * @param formatter 138 * The formatter to use for both numbers in the range. 139 * @return The fluent chain. 140 * @see #numberFormatterBoth 141 * @stable ICU 63 142 */ 143 Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&; 144 145 /** 146 * Overload of numberFormatterBoth() for use on an rvalue reference. 147 * 148 * @param formatter 149 * The formatter to use for both numbers in the range. 150 * @return The fluent chain. 151 * @see #numberFormatterBoth 152 * @stable ICU 63 153 */ 154 Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &; 155 156 /** 157 * Overload of numberFormatterBoth() for use on an rvalue reference. 158 * 159 * @param formatter 160 * The formatter to use for both numbers in the range. 161 * @return The fluent chain. 162 * @see #numberFormatterBoth 163 * @stable ICU 63 164 */ 165 Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&; 166 167 /** 168 * Sets the NumberFormatter instance to use for the first number in the range. 169 * <p> 170 * The NumberFormatter instances must not have a locale applied yet; the locale specified on the 171 * NumberRangeFormatter will be used. 172 * 173 * @param formatterFirst 174 * The formatter to use for the first number in the range. 175 * @return The fluent chain. 176 * @stable ICU 63 177 */ 178 Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &; 179 180 /** 181 * Overload of numberFormatterFirst() for use on an rvalue reference. 182 * 183 * @param formatterFirst 184 * The formatter to use for the first number in the range. 185 * @return The fluent chain. 186 * @see #numberFormatterFirst 187 * @stable ICU 63 188 */ 189 Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&; 190 191 /** 192 * Overload of numberFormatterFirst() for use on an rvalue reference. 193 * 194 * @param formatterFirst 195 * The formatter to use for the first number in the range. 196 * @return The fluent chain. 197 * @see #numberFormatterFirst 198 * @stable ICU 63 199 */ 200 Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &; 201 202 /** 203 * Overload of numberFormatterFirst() for use on an rvalue reference. 204 * 205 * @param formatterFirst 206 * The formatter to use for the first number in the range. 207 * @return The fluent chain. 208 * @see #numberFormatterFirst 209 * @stable ICU 63 210 */ 211 Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&; 212 213 /** 214 * Sets the NumberFormatter instance to use for the second number in the range. 215 * <p> 216 * The NumberFormatter instances must not have a locale applied yet; the locale specified on the 217 * NumberRangeFormatter will be used. 218 * 219 * @param formatterSecond 220 * The formatter to use for the second number in the range. 221 * @return The fluent chain. 222 * @stable ICU 63 223 */ 224 Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &; 225 226 /** 227 * Overload of numberFormatterSecond() for use on an rvalue reference. 228 * 229 * @param formatterSecond 230 * The formatter to use for the second number in the range. 231 * @return The fluent chain. 232 * @see #numberFormatterSecond 233 * @stable ICU 63 234 */ 235 Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&; 236 237 /** 238 * Overload of numberFormatterSecond() for use on an rvalue reference. 239 * 240 * @param formatterSecond 241 * The formatter to use for the second number in the range. 242 * @return The fluent chain. 243 * @see #numberFormatterSecond 244 * @stable ICU 63 245 */ 246 Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &; 247 248 /** 249 * Overload of numberFormatterSecond() for use on an rvalue reference. 250 * 251 * @param formatterSecond 252 * The formatter to use for the second number in the range. 253 * @return The fluent chain. 254 * @see #numberFormatterSecond 255 * @stable ICU 63 256 */ 257 Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&; 258 259 /** 260 * Sets the aggressiveness of "collapsing" fields across the range separator. Possible values: 261 * <p> 262 * <ul> 263 * <li>ALL: "3-5K miles"</li> 264 * <li>UNIT: "3K - 5K miles"</li> 265 * <li>NONE: "3K miles - 5K miles"</li> 266 * <li>AUTO: usually UNIT or NONE, depending on the locale and formatter settings</li> 267 * </ul> 268 * <p> 269 * The default value is AUTO. 270 * 271 * @param collapse 272 * The collapsing strategy to use for this range. 273 * @return The fluent chain. 274 * @stable ICU 63 275 */ 276 Derived collapse(UNumberRangeCollapse collapse) const &; 277 278 /** 279 * Overload of collapse() for use on an rvalue reference. 280 * 281 * @param collapse 282 * The collapsing strategy to use for this range. 283 * @return The fluent chain. 284 * @see #collapse 285 * @stable ICU 63 286 */ 287 Derived collapse(UNumberRangeCollapse collapse) &&; 288 289 /** 290 * Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are 291 * passed to the formatFormattableRange function, or if different numbers are passed to the function but they 292 * become the same after rounding rules are applied. Possible values: 293 * <p> 294 * <ul> 295 * <li>SINGLE_VALUE: "5 miles"</li> 296 * <li>APPROXIMATELY_OR_SINGLE_VALUE: "~5 miles" or "5 miles", depending on whether the number was the same before 297 * rounding was applied</li> 298 * <li>APPROXIMATELY: "~5 miles"</li> 299 * <li>RANGE: "5-5 miles" (with collapse=UNIT)</li> 300 * </ul> 301 * <p> 302 * The default value is APPROXIMATELY. 303 * 304 * @param identityFallback 305 * The strategy to use when formatting two numbers that end up being the same. 306 * @return The fluent chain. 307 * @stable ICU 63 308 */ 309 Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &; 310 311 /** 312 * Overload of identityFallback() for use on an rvalue reference. 313 * 314 * @param identityFallback 315 * The strategy to use when formatting two numbers that end up being the same. 316 * @return The fluent chain. 317 * @see #identityFallback 318 * @stable ICU 63 319 */ 320 Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&; 321 322 /** 323 * Returns the current (Un)LocalizedNumberRangeFormatter as a LocalPointer 324 * wrapping a heap-allocated copy of the current object. 325 * 326 * This is equivalent to new-ing the move constructor with a value object 327 * as the argument. 328 * 329 * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped 330 * nullptr on failure. 331 * @stable ICU 64 332 */ 333 LocalPointer<Derived> clone() const &; 334 335 /** 336 * Overload of clone for use on an rvalue reference. 337 * 338 * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped 339 * nullptr on failure. 340 * @stable ICU 64 341 */ 342 LocalPointer<Derived> clone() &&; 343 344 /** 345 * Sets the UErrorCode if an error occurred in the fluent chain. 346 * Preserves older error codes in the outErrorCode. 347 * @return true if U_FAILURE(outErrorCode) 348 * @stable ICU 63 349 */ 350 UBool copyErrorTo(UErrorCode &outErrorCode) const { 351 if (U_FAILURE(outErrorCode)) { 352 // Do not overwrite the older error code 353 return true; 354 } 355 fMacros.copyErrorTo(outErrorCode); 356 return U_FAILURE(outErrorCode); 357 } 358 359 // NOTE: Uses default copy and move constructors. 360 361 private: 362 impl::RangeMacroProps fMacros; 363 364 // Don't construct me directly! Use (Un)LocalizedNumberFormatter. 365 NumberRangeFormatterSettings() = default; 366 367 friend class LocalizedNumberRangeFormatter; 368 friend class UnlocalizedNumberRangeFormatter; 369 }; 370 371 // Explicit instantiations in source/i18n/numrange_fluent.cpp. 372 // (MSVC treats imports/exports of explicit instantiations differently.) 373 #ifndef _MSC_VER 374 extern template class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>; 375 extern template class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>; 376 #endif 377 378 /** 379 * A NumberRangeFormatter that does not yet have a locale. In order to format, a locale must be specified. 380 * 381 * Instances of this class are immutable and thread-safe. 382 * 383 * @see NumberRangeFormatter 384 * @stable ICU 63 385 */ 386 class U_I18N_API UnlocalizedNumberRangeFormatter 387 : public NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>, public UMemory { 388 389 public: 390 /** 391 * Associate the given locale with the number range formatter. The locale is used for picking the 392 * appropriate symbols, formats, and other data for number display. 393 * 394 * @param locale 395 * The locale to use when loading data for number formatting. 396 * @return The fluent chain. 397 * @stable ICU 63 398 */ 399 LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &; 400 401 /** 402 * Overload of locale() for use on an rvalue reference. 403 * 404 * @param locale 405 * The locale to use when loading data for number formatting. 406 * @return The fluent chain. 407 * @see #locale 408 * @stable ICU 63 409 */ 410 LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&; 411 412 /** 413 * Default constructor: puts the formatter into a valid but undefined state. 414 * 415 * @stable ICU 63 416 */ 417 UnlocalizedNumberRangeFormatter() = default; 418 419 /** 420 * Returns a copy of this UnlocalizedNumberRangeFormatter. 421 * @stable ICU 63 422 */ 423 UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other); 424 425 /** 426 * Move constructor: 427 * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state. 428 * @stable ICU 63 429 */ 430 UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) noexcept; 431 432 /** 433 * Copy assignment operator. 434 * @stable ICU 63 435 */ 436 UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other); 437 438 /** 439 * Move assignment operator: 440 * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state. 441 * @stable ICU 63 442 */ 443 UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) noexcept; 444 445 private: 446 explicit UnlocalizedNumberRangeFormatter( 447 const NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>& other); 448 449 explicit UnlocalizedNumberRangeFormatter( 450 NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>&& src) noexcept; 451 452 explicit UnlocalizedNumberRangeFormatter(const impl::RangeMacroProps ¯os); 453 454 explicit UnlocalizedNumberRangeFormatter(impl::RangeMacroProps &¯os); 455 456 // To give the fluent setters access to this class's constructor: 457 friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>; 458 459 // To give NumberRangeFormatter::with() access to this class's constructor: 460 friend class NumberRangeFormatter; 461 462 // To give LNRF::withoutLocale() access to this class's constructor: 463 friend class LocalizedNumberRangeFormatter; 464 }; 465 466 /** 467 * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available. 468 * 469 * Instances of this class are immutable and thread-safe. 470 * 471 * @see NumberFormatter 472 * @stable ICU 63 473 */ 474 class U_I18N_API_CLASS LocalizedNumberRangeFormatter 475 : public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory { 476 public: 477 /** 478 * Format the given Formattables to a string using the settings specified in the NumberRangeFormatter fluent setting 479 * chain. 480 * 481 * @param first 482 * The first number in the range, usually to the left in LTR locales. 483 * @param second 484 * The second number in the range, usually to the right in LTR locales. 485 * @param status 486 * Set if an error occurs while formatting. 487 * @return A FormattedNumberRange object; call .toString() to get the string. 488 * @stable ICU 63 489 */ 490 U_I18N_API FormattedNumberRange formatFormattableRange( 491 const Formattable& first, const Formattable& second, UErrorCode& status) const; 492 493 /** 494 * Disassociate the locale from this formatter. 495 * 496 * @return The fluent chain. 497 * @stable ICU 75 498 */ 499 U_I18N_API UnlocalizedNumberRangeFormatter withoutLocale() const &; 500 501 /** 502 * Overload of withoutLocale() for use on an rvalue reference. 503 * 504 * @return The fluent chain. 505 * @see #withoutLocale 506 * @stable ICU 75 507 */ 508 U_I18N_API UnlocalizedNumberRangeFormatter withoutLocale() &&; 509 510 /** 511 * Default constructor: puts the formatter into a valid but undefined state. 512 * 513 * @stable ICU 63 514 */ 515 U_I18N_API LocalizedNumberRangeFormatter() = default; 516 517 /** 518 * Returns a copy of this LocalizedNumberRangeFormatter. 519 * @stable ICU 63 520 */ 521 U_I18N_API LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other); 522 523 /** 524 * Move constructor: 525 * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state. 526 * @stable ICU 63 527 */ 528 U_I18N_API LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) noexcept; 529 530 /** 531 * Copy assignment operator. 532 * @stable ICU 63 533 */ 534 U_I18N_API LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other); 535 536 /** 537 * Move assignment operator: 538 * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state. 539 * @stable ICU 63 540 */ 541 U_I18N_API LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) noexcept; 542 543 #ifndef U_HIDE_INTERNAL_API 544 545 /** 546 * @param results 547 * The results object. This method will mutate it to save the results. 548 * @param equalBeforeRounding 549 * Whether the number was equal before copying it into a DecimalQuantity. 550 * Used for determining the identity fallback behavior. 551 * @param status 552 * Set if an error occurs while formatting. 553 * @internal 554 */ 555 U_I18N_API void formatImpl(impl::UFormattedNumberRangeData &results, bool equalBeforeRounding, 556 UErrorCode &status) const; 557 558 #endif /* U_HIDE_INTERNAL_API */ 559 560 /** 561 * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own. 562 * @stable ICU 63 563 */ 564 U_I18N_API ~LocalizedNumberRangeFormatter(); 565 566 private: 567 #ifndef __wasi__ 568 std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {}; 569 #else 570 impl::NumberRangeFormatterImpl* fAtomicFormatter = nullptr; 571 #endif 572 573 const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const; 574 575 explicit LocalizedNumberRangeFormatter( 576 const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other); 577 578 explicit LocalizedNumberRangeFormatter( 579 NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>&& src) noexcept; 580 581 LocalizedNumberRangeFormatter(const impl::RangeMacroProps ¯os, const Locale &locale); 582 583 LocalizedNumberRangeFormatter(impl::RangeMacroProps &¯os, const Locale &locale); 584 585 // To give the fluent setters access to this class's constructor: 586 friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>; 587 friend class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>; 588 589 // To give UnlocalizedNumberRangeFormatter::locale() access to this class's constructor: 590 friend class UnlocalizedNumberRangeFormatter; 591 }; 592 593 /** 594 * The result of a number range formatting operation. This class allows the result to be exported in several data types, 595 * including a UnicodeString and a FieldPositionIterator. 596 * 597 * Instances of this class are immutable and thread-safe. 598 * 599 * @stable ICU 63 600 */ 601 class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue { 602 public: 603 // Copybrief: this method is older than the parent method 604 /** 605 * @copybrief FormattedValue::toString() 606 * 607 * For more information, see FormattedValue::toString() 608 * 609 * @stable ICU 63 610 */ 611 UnicodeString toString(UErrorCode& status) const override; 612 613 // Copydoc: this method is new in ICU 64 614 /** @copydoc FormattedValue::toTempString() */ 615 UnicodeString toTempString(UErrorCode& status) const override; 616 617 // Copybrief: this method is older than the parent method 618 /** 619 * @copybrief FormattedValue::appendTo() 620 * 621 * For more information, see FormattedValue::appendTo() 622 * 623 * @stable ICU 63 624 */ 625 Appendable &appendTo(Appendable &appendable, UErrorCode& status) const override; 626 627 // Copydoc: this method is new in ICU 64 628 /** @copydoc FormattedValue::nextPosition() */ 629 UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const override; 630 631 /** 632 * Extracts the formatted range as a pair of decimal numbers. This endpoint 633 * is useful for obtaining the exact number being printed after scaling 634 * and rounding have been applied by the number range formatting pipeline. 635 * 636 * The syntax of the unformatted numbers is a "numeric string" 637 * as defined in the Decimal Arithmetic Specification, available at 638 * http://speleotrove.com/decimal 639 * 640 * Example C++17 call site: 641 * 642 * auto [ first, second ] = range.getDecimalNumbers<std::string>(status); 643 * 644 * @tparam StringClass A string class compatible with StringByteSink; 645 * for example, std::string. 646 * @param status Set if an error occurs. 647 * @return A pair of StringClasses containing the numeric strings. 648 * @stable ICU 68 649 */ 650 template<typename StringClass> 651 inline std::pair<StringClass, StringClass> getDecimalNumbers(UErrorCode& status) const; 652 653 /** 654 * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was 655 * used. For example, if the first and second number were the same either before or after rounding occurred, an 656 * identity fallback was used. 657 * 658 * @return An indication the resulting identity situation in the formatted number range. 659 * @stable ICU 63 660 * @see UNumberRangeIdentityFallback 661 */ 662 UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const; 663 664 /** 665 * Default constructor; makes an empty FormattedNumberRange. 666 * @stable ICU 70 667 */ 668 FormattedNumberRange() 669 : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {} 670 671 /** 672 * Copying not supported; use move constructor instead. 673 */ 674 FormattedNumberRange(const FormattedNumberRange&) = delete; 675 676 /** 677 * Copying not supported; use move assignment instead. 678 */ 679 FormattedNumberRange& operator=(const FormattedNumberRange&) = delete; 680 681 /** 682 * Move constructor: 683 * Leaves the source FormattedNumberRange in an undefined state. 684 * @stable ICU 63 685 */ 686 FormattedNumberRange(FormattedNumberRange&& src) noexcept; 687 688 /** 689 * Move assignment: 690 * Leaves the source FormattedNumberRange in an undefined state. 691 * @stable ICU 63 692 */ 693 FormattedNumberRange& operator=(FormattedNumberRange&& src) noexcept; 694 695 /** 696 * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own. 697 * @stable ICU 63 698 */ 699 ~FormattedNumberRange(); 700 701 private: 702 // Can't use LocalPointer because UFormattedNumberRangeData is forward-declared 703 const impl::UFormattedNumberRangeData *fData; 704 705 // Error code for the terminal methods 706 UErrorCode fErrorCode; 707 708 /** 709 * Internal constructor from data type. Adopts the data pointer. 710 */ 711 explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results) 712 : fData(results), fErrorCode(U_ZERO_ERROR) {} 713 714 explicit FormattedNumberRange(UErrorCode errorCode) 715 : fData(nullptr), fErrorCode(errorCode) {} 716 717 void getDecimalNumbers(ByteSink& sink1, ByteSink& sink2, UErrorCode& status) const; 718 719 const impl::UFormattedNumberRangeData* getData(UErrorCode& status) const; 720 721 // To allow PluralRules to access the underlying data 722 friend class ::icu::PluralRules; 723 724 // To give LocalizedNumberRangeFormatter format methods access to this class's constructor: 725 friend class LocalizedNumberRangeFormatter; 726 727 // To give C API access to internals 728 friend struct impl::UFormattedNumberRangeImpl; 729 }; 730 731 // inline impl of @stable ICU 68 method 732 template<typename StringClass> 733 std::pair<StringClass, StringClass> FormattedNumberRange::getDecimalNumbers(UErrorCode& status) const { 734 StringClass str1; 735 StringClass str2; 736 StringByteSink<StringClass> sink1(&str1); 737 StringByteSink<StringClass> sink2(&str2); 738 getDecimalNumbers(sink1, sink2, status); 739 return std::make_pair(str1, str2); 740 } 741 742 /** 743 * See the main description in numberrangeformatter.h for documentation and examples. 744 * 745 * @stable ICU 63 746 */ 747 class U_I18N_API NumberRangeFormatter final { 748 public: 749 /** 750 * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently 751 * known at the call site. 752 * 753 * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining. 754 * @stable ICU 63 755 */ 756 static UnlocalizedNumberRangeFormatter with(); 757 758 /** 759 * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call 760 * site. 761 * 762 * @param locale 763 * The locale from which to load formats and symbols for number range formatting. 764 * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining. 765 * @stable ICU 63 766 */ 767 static LocalizedNumberRangeFormatter withLocale(const Locale &locale); 768 769 /** 770 * Use factory methods instead of the constructor to create a NumberFormatter. 771 */ 772 NumberRangeFormatter() = delete; 773 }; 774 775 } // namespace number 776 U_NAMESPACE_END 777 778 #endif /* #if !UCONFIG_NO_FORMATTING */ 779 780 #endif /* U_SHOW_CPLUSPLUS_API */ 781 782 #endif // __NUMBERRANGEFORMATTER_H__