Coverage Report

Created: 2023-03-04 07:00

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