numberrangeformatter.h 26 KB

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