unumberrangeformatter.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. // © 2020 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. #ifndef __UNUMBERRANGEFORMATTER_H__
  4. #define __UNUMBERRANGEFORMATTER_H__
  5. #include "unicode/utypes.h"
  6. #if !UCONFIG_NO_FORMATTING
  7. #include "unicode/parseerr.h"
  8. #include "unicode/ufieldpositer.h"
  9. #include "unicode/umisc.h"
  10. #include "unicode/uformattedvalue.h"
  11. #include "unicode/uformattable.h"
  12. /**
  13. * \file
  14. * \brief C API: Localized number range formatting
  15. *
  16. * This is the C-compatible version of the NumberRangeFormatter API. C++ users
  17. * should include unicode/numberrangeformatter.h and use the proper C++ APIs.
  18. *
  19. * First create a UNumberRangeFormatter, which is immutable, and then format to
  20. * a UFormattedNumberRange.
  21. *
  22. * Example code:
  23. * <pre>
  24. * // Setup:
  25. * UErrorCode ec = U_ZERO_ERROR;
  26. * UNumberRangeFormatter* uformatter = unumrf_openForSkeletonCollapseIdentityFallbackAndLocaleWithError(
  27. * u"currency/USD precision-integer",
  28. * -1,
  29. * UNUM_RANGE_COLLAPSE_AUTO,
  30. * UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
  31. * "en-US",
  32. * NULL,
  33. * &ec);
  34. * UFormattedNumberRange* uresult = unumrf_openResult(&ec);
  35. * if (U_FAILURE(ec)) { return; }
  36. *
  37. * // Format a double range:
  38. * unumrf_formatDoubleRange(uformatter, 3.0, 5.0, uresult, &ec);
  39. * if (U_FAILURE(ec)) { return; }
  40. *
  41. * // Get the result string:
  42. * int32_t len;
  43. * const UChar* str = ufmtval_getString(unumrf_resultAsValue(uresult, &ec), &len, &ec);
  44. * if (U_FAILURE(ec)) { return; }
  45. * // str should equal "$3 – $5"
  46. *
  47. * // Cleanup:
  48. * unumf_close(uformatter);
  49. * unumf_closeResult(uresult);
  50. * </pre>
  51. *
  52. * If you are a C++ user linking against the C libraries, you can use the LocalPointer versions of these
  53. * APIs. The following example uses LocalPointer with the decimal number and field position APIs:
  54. *
  55. * <pre>
  56. * // Setup:
  57. * LocalUNumberRangeFormatterPointer uformatter(
  58. * unumrf_openForSkeletonCollapseIdentityFallbackAndLocaleWithError(...));
  59. * LocalUFormattedNumberRangePointer uresult(unumrf_openResult(&ec));
  60. * if (U_FAILURE(ec)) { return; }
  61. *
  62. * // Format a double number range:
  63. * unumrf_formatDoubleRange(uformatter.getAlias(), 3.0, 5.0, uresult.getAlias(), &ec);
  64. * if (U_FAILURE(ec)) { return; }
  65. *
  66. * // No need to do any cleanup since we are using LocalPointer.
  67. * </pre>
  68. *
  69. * You can also get field positions. For more information, see uformattedvalue.h.
  70. */
  71. /**
  72. * Defines how to merge fields that are identical across the range sign.
  73. *
  74. * @stable ICU 63
  75. */
  76. typedef enum UNumberRangeCollapse {
  77. /**
  78. * Use locale data and heuristics to determine how much of the string to collapse. Could end up collapsing none,
  79. * some, or all repeated pieces in a locale-sensitive way.
  80. *
  81. * The heuristics used for this option are subject to change over time.
  82. *
  83. * @stable ICU 63
  84. */
  85. UNUM_RANGE_COLLAPSE_AUTO,
  86. /**
  87. * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms"
  88. *
  89. * @stable ICU 63
  90. */
  91. UNUM_RANGE_COLLAPSE_NONE,
  92. /**
  93. * Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand
  94. * kilograms"
  95. *
  96. * @stable ICU 63
  97. */
  98. UNUM_RANGE_COLLAPSE_UNIT,
  99. /**
  100. * Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the
  101. * number. Example: "3.2 – 5.3 thousand kilograms"
  102. *
  103. * @stable ICU 63
  104. */
  105. UNUM_RANGE_COLLAPSE_ALL
  106. } UNumberRangeCollapse;
  107. /**
  108. * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect
  109. * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber.
  110. *
  111. * @stable ICU 63
  112. * @see NumberRangeFormatter
  113. */
  114. typedef enum UNumberRangeIdentityFallback {
  115. /**
  116. * Show the number as a single value rather than a range. Example: "$5"
  117. *
  118. * @stable ICU 63
  119. */
  120. UNUM_IDENTITY_FALLBACK_SINGLE_VALUE,
  121. /**
  122. * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding,
  123. * show the single value. Example: "~$5" or "$5"
  124. *
  125. * @stable ICU 63
  126. */
  127. UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE,
  128. /**
  129. * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the
  130. * inputs are the same. Example: "~$5"
  131. *
  132. * @stable ICU 63
  133. */
  134. UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
  135. /**
  136. * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the
  137. * same. Example (with RangeCollapse.NONE): "$5 – $5"
  138. *
  139. * @stable ICU 63
  140. */
  141. UNUM_IDENTITY_FALLBACK_RANGE
  142. } UNumberRangeIdentityFallback;
  143. /**
  144. * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range
  145. * were equal or not, and whether or not the identity fallback was applied.
  146. *
  147. * @stable ICU 63
  148. * @see NumberRangeFormatter
  149. */
  150. typedef enum UNumberRangeIdentityResult {
  151. /**
  152. * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied.
  153. *
  154. * @stable ICU 63
  155. * @see NumberRangeFormatter
  156. */
  157. UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING,
  158. /**
  159. * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied.
  160. *
  161. * @stable ICU 63
  162. * @see NumberRangeFormatter
  163. */
  164. UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING,
  165. /**
  166. * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied.
  167. *
  168. * @stable ICU 63
  169. * @see NumberRangeFormatter
  170. */
  171. UNUM_IDENTITY_RESULT_NOT_EQUAL,
  172. #ifndef U_HIDE_INTERNAL_API
  173. /**
  174. * The number of entries in this enum.
  175. * @internal
  176. */
  177. UNUM_IDENTITY_RESULT_COUNT
  178. #endif /* U_HIDE_INTERNAL_API */
  179. } UNumberRangeIdentityResult;
  180. struct UNumberRangeFormatter;
  181. /**
  182. * C-compatible version of icu::number::LocalizedNumberRangeFormatter.
  183. *
  184. * NOTE: This is a C-compatible API; C++ users should build against numberrangeformatter.h instead.
  185. *
  186. * @stable ICU 68
  187. */
  188. typedef struct UNumberRangeFormatter UNumberRangeFormatter;
  189. struct UFormattedNumberRange;
  190. /**
  191. * C-compatible version of icu::number::FormattedNumberRange.
  192. *
  193. * NOTE: This is a C-compatible API; C++ users should build against numberrangeformatter.h instead.
  194. *
  195. * @stable ICU 68
  196. */
  197. typedef struct UFormattedNumberRange UFormattedNumberRange;
  198. /**
  199. * Creates a new UNumberFormatter for the given skeleton string, collapse option, identity fallback
  200. * option, and locale. This is currently the only method for creating a new UNumberRangeFormatter.
  201. *
  202. * Objects of type UNumberRangeFormatter returned by this method are threadsafe.
  203. *
  204. * For more details on skeleton strings, see the documentation in numberrangeformatter.h. For more
  205. * details on the usage of this API, see the documentation at the top of unumberrangeformatter.h.
  206. *
  207. * NOTE: This is a C-compatible API; C++ users should build against numberrangeformatter.h instead.
  208. *
  209. * @param skeleton The skeleton string, like u"percent precision-integer"
  210. * @param skeletonLen The number of UChars in the skeleton string, or -1 if it is NUL-terminated.
  211. * @param collapse Option for how to merge affixes (if unsure, use UNUM_RANGE_COLLAPSE_AUTO)
  212. * @param identityFallback Option for resolving when both sides of the range are equal.
  213. * @param locale The NUL-terminated locale ID.
  214. * @param perror A parse error struct populated if an error occurs when parsing. Can be NULL.
  215. * If no error occurs, perror->offset will be set to -1.
  216. * @param ec Set if an error occurs.
  217. * @stable ICU 68
  218. */
  219. U_CAPI UNumberRangeFormatter* U_EXPORT2
  220. unumrf_openForSkeletonWithCollapseAndIdentityFallback(
  221. const UChar* skeleton,
  222. int32_t skeletonLen,
  223. UNumberRangeCollapse collapse,
  224. UNumberRangeIdentityFallback identityFallback,
  225. const char* locale,
  226. UParseError* perror,
  227. UErrorCode* ec);
  228. /**
  229. * Creates an object to hold the result of a UNumberRangeFormatter
  230. * operation. The object can be used repeatedly; it is cleared whenever
  231. * passed to a format function.
  232. *
  233. * @param ec Set if an error occurs.
  234. * @stable ICU 68
  235. */
  236. U_CAPI UFormattedNumberRange* U_EXPORT2
  237. unumrf_openResult(UErrorCode* ec);
  238. /**
  239. * Uses a UNumberRangeFormatter to format a range of doubles.
  240. *
  241. * The UNumberRangeFormatter can be shared between threads. Each thread should have its own local
  242. * UFormattedNumberRange, however, for storing the result of the formatting operation.
  243. *
  244. * NOTE: This is a C-compatible API; C++ users should build against numberrangeformatter.h instead.
  245. *
  246. * @param uformatter A formatter object; see unumberrangeformatter.h.
  247. * @param first The first (usually smaller) number in the range.
  248. * @param second The second (usually larger) number in the range.
  249. * @param uresult The object that will be mutated to store the result; see unumrf_openResult.
  250. * @param ec Set if an error occurs.
  251. * @stable ICU 68
  252. */
  253. U_CAPI void U_EXPORT2
  254. unumrf_formatDoubleRange(
  255. const UNumberRangeFormatter* uformatter,
  256. double first,
  257. double second,
  258. UFormattedNumberRange* uresult,
  259. UErrorCode* ec);
  260. /**
  261. * Uses a UNumberRangeFormatter to format a range of decimal numbers.
  262. *
  263. * With a decimal number string, you can specify an input with arbitrary precision.
  264. *
  265. * The UNumberRangeFormatter can be shared between threads. Each thread should have its own local
  266. * UFormattedNumberRange, however, for storing the result of the formatting operation.
  267. *
  268. * NOTE: This is a C-compatible API; C++ users should build against numberrangeformatter.h instead.
  269. *
  270. * @param uformatter A formatter object; see unumberrangeformatter.h.
  271. * @param first The first (usually smaller) number in the range.
  272. * @param firstLen The length of the first decimal number string.
  273. * @param second The second (usually larger) number in the range.
  274. * @param secondLen The length of the second decimal number string.
  275. * @param uresult The object that will be mutated to store the result; see unumrf_openResult.
  276. * @param ec Set if an error occurs.
  277. * @stable ICU 68
  278. */
  279. U_CAPI void U_EXPORT2
  280. unumrf_formatDecimalRange(
  281. const UNumberRangeFormatter* uformatter,
  282. const char* first,
  283. int32_t firstLen,
  284. const char* second,
  285. int32_t secondLen,
  286. UFormattedNumberRange* uresult,
  287. UErrorCode* ec);
  288. /**
  289. * Returns a representation of a UFormattedNumberRange as a UFormattedValue,
  290. * which can be subsequently passed to any API requiring that type.
  291. *
  292. * The returned object is owned by the UFormattedNumberRange and is valid
  293. * only as long as the UFormattedNumber is present and unchanged in memory.
  294. *
  295. * You can think of this method as a cast between types.
  296. *
  297. * @param uresult The object containing the formatted number range.
  298. * @param ec Set if an error occurs.
  299. * @return A UFormattedValue owned by the input object.
  300. * @stable ICU 68
  301. */
  302. U_CAPI const UFormattedValue* U_EXPORT2
  303. unumrf_resultAsValue(const UFormattedNumberRange* uresult, UErrorCode* ec);
  304. /**
  305. * Extracts the identity result from a UFormattedNumberRange.
  306. *
  307. * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead.
  308. *
  309. * @param uresult The object containing the formatted number range.
  310. * @param ec Set if an error occurs.
  311. * @return The identity result; see UNumberRangeIdentityResult.
  312. * @stable ICU 68
  313. */
  314. U_CAPI UNumberRangeIdentityResult U_EXPORT2
  315. unumrf_resultGetIdentityResult(
  316. const UFormattedNumberRange* uresult,
  317. UErrorCode* ec);
  318. /**
  319. * Extracts the first formatted number as a decimal number. This endpoint
  320. * is useful for obtaining the exact number being printed after scaling
  321. * and rounding have been applied by the number range formatting pipeline.
  322. *
  323. * The syntax of the unformatted number is a "numeric string"
  324. * as defined in the Decimal Arithmetic Specification, available at
  325. * http://speleotrove.com/decimal
  326. *
  327. * @param uresult The input object containing the formatted number range.
  328. * @param dest the 8-bit char buffer into which the decimal number is placed
  329. * @param destCapacity The size, in chars, of the destination buffer. May be zero
  330. * for precomputing the required size.
  331. * @param ec receives any error status.
  332. * If U_BUFFER_OVERFLOW_ERROR: Returns number of chars for
  333. * preflighting.
  334. * @return Number of chars in the data. Does not include a trailing NUL.
  335. * @stable ICU 68
  336. */
  337. U_CAPI int32_t U_EXPORT2
  338. unumrf_resultGetFirstDecimalNumber(
  339. const UFormattedNumberRange* uresult,
  340. char* dest,
  341. int32_t destCapacity,
  342. UErrorCode* ec);
  343. /**
  344. * Extracts the second formatted number as a decimal number. This endpoint
  345. * is useful for obtaining the exact number being printed after scaling
  346. * and rounding have been applied by the number range formatting pipeline.
  347. *
  348. * The syntax of the unformatted number is a "numeric string"
  349. * as defined in the Decimal Arithmetic Specification, available at
  350. * http://speleotrove.com/decimal
  351. *
  352. * @param uresult The input object containing the formatted number range.
  353. * @param dest the 8-bit char buffer into which the decimal number is placed
  354. * @param destCapacity The size, in chars, of the destination buffer. May be zero
  355. * for precomputing the required size.
  356. * @param ec receives any error status.
  357. * If U_BUFFER_OVERFLOW_ERROR: Returns number of chars for
  358. * preflighting.
  359. * @return Number of chars in the data. Does not include a trailing NUL.
  360. * @stable ICU 68
  361. */
  362. U_CAPI int32_t U_EXPORT2
  363. unumrf_resultGetSecondDecimalNumber(
  364. const UFormattedNumberRange* uresult,
  365. char* dest,
  366. int32_t destCapacity,
  367. UErrorCode* ec);
  368. /**
  369. * Releases the UNumberFormatter created by unumf_openForSkeletonAndLocale().
  370. *
  371. * @param uformatter An object created by unumf_openForSkeletonAndLocale().
  372. * @stable ICU 68
  373. */
  374. U_CAPI void U_EXPORT2
  375. unumrf_close(UNumberRangeFormatter* uformatter);
  376. /**
  377. * Releases the UFormattedNumber created by unumf_openResult().
  378. *
  379. * @param uresult An object created by unumf_openResult().
  380. * @stable ICU 68
  381. */
  382. U_CAPI void U_EXPORT2
  383. unumrf_closeResult(UFormattedNumberRange* uresult);
  384. #if U_SHOW_CPLUSPLUS_API
  385. U_NAMESPACE_BEGIN
  386. /**
  387. * \class LocalUNumberRangeFormatterPointer
  388. * "Smart pointer" class; closes a UNumberFormatter via unumf_close().
  389. * For most methods see the LocalPointerBase base class.
  390. *
  391. * Usage:
  392. * <pre>
  393. * LocalUNumberRangeFormatterPointer uformatter(
  394. * unumrf_openForSkeletonCollapseIdentityFallbackAndLocaleWithError(...));
  395. * // no need to explicitly call unumrf_close()
  396. * </pre>
  397. *
  398. * @see LocalPointerBase
  399. * @see LocalPointer
  400. * @stable ICU 68
  401. */
  402. U_DEFINE_LOCAL_OPEN_POINTER(LocalUNumberRangeFormatterPointer, UNumberRangeFormatter, unumrf_close);
  403. /**
  404. * \class LocalUFormattedNumberPointer
  405. * "Smart pointer" class; closes a UFormattedNumber via unumf_closeResult().
  406. * For most methods see the LocalPointerBase base class.
  407. *
  408. * Usage:
  409. * <pre>
  410. * LocalUFormattedNumberRangePointer uresult(unumrf_openResult(...));
  411. * // no need to explicitly call unumrf_closeResult()
  412. * </pre>
  413. *
  414. * @see LocalPointerBase
  415. * @see LocalPointer
  416. * @stable ICU 68
  417. */
  418. U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattedNumberRangePointer, UFormattedNumberRange, unumrf_closeResult);
  419. U_NAMESPACE_END
  420. #endif // U_SHOW_CPLUSPLUS_API
  421. #endif /* #if !UCONFIG_NO_FORMATTING */
  422. #endif //__UNUMBERRANGEFORMATTER_H__