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