Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-29 08:33:53

0001 // © 2018 and later: Unicode, Inc. and others.
0002 // License & terms of use: http://www.unicode.org/copyright.html
0003 
0004 #ifndef __NUMBERRANGEFORMATTER_H__
0005 #define __NUMBERRANGEFORMATTER_H__
0006 
0007 #include "unicode/utypes.h"
0008 
0009 #if U_SHOW_CPLUSPLUS_API
0010 
0011 #if !UCONFIG_NO_FORMATTING
0012 
0013 #include <atomic>
0014 #include "unicode/appendable.h"
0015 #include "unicode/fieldpos.h"
0016 #include "unicode/formattedvalue.h"
0017 #include "unicode/fpositer.h"
0018 #include "unicode/numberformatter.h"
0019 #include "unicode/unumberrangeformatter.h"
0020 
0021 /**
0022  * \file
0023  * \brief C++ API: Library for localized formatting of number, currency, and unit ranges.
0024  *
0025  * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement.
0026  * <p>
0027  * Usage example:
0028  * <p>
0029  * <pre>
0030  * NumberRangeFormatter::with()
0031  *     .identityFallback(UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE)
0032  *     .numberFormatterFirst(NumberFormatter::with().adoptUnit(MeasureUnit::createMeter()))
0033  *     .numberFormatterSecond(NumberFormatter::with().adoptUnit(MeasureUnit::createKilometer()))
0034  *     .locale("en-GB")
0035  *     .formatFormattableRange(750, 1.2, status)
0036  *     .toString(status);
0037  * // => "750 m - 1.2 km"
0038  * </pre>
0039  * <p>
0040  * Like NumberFormatter, NumberRangeFormatter instances (i.e., LocalizedNumberRangeFormatter
0041  * and UnlocalizedNumberRangeFormatter) are immutable and thread-safe. This API is based on the
0042  * <em>fluent</em> design pattern popularized by libraries such as Google's Guava.
0043  *
0044  * @author Shane Carr
0045  */
0046 
0047 
0048 U_NAMESPACE_BEGIN
0049 
0050 // Forward declarations:
0051 class PluralRules;
0052 
0053 namespace number {  // icu::number
0054 
0055 // Forward declarations:
0056 class UnlocalizedNumberRangeFormatter;
0057 class LocalizedNumberRangeFormatter;
0058 class FormattedNumberRange;
0059 
0060 namespace impl {
0061 
0062 // Forward declarations:
0063 struct RangeMacroProps;
0064 class DecimalQuantity;
0065 class UFormattedNumberRangeData;
0066 class NumberRangeFormatterImpl;
0067 struct UFormattedNumberRangeImpl;
0068 
0069 } // namespace impl
0070 
0071 /**
0072  * \cond
0073  * Export an explicit template instantiation. See datefmt.h
0074  * (When building DLLs for Windows this is required.)
0075  */
0076 #if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN) && !defined(U_STATIC_IMPLEMENTATION)
0077 } // namespace icu::number
0078 U_NAMESPACE_END
0079 
0080 template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>;
0081 
0082 U_NAMESPACE_BEGIN
0083 namespace number {  // icu::number
0084 #endif
0085 /** \endcond */
0086 
0087 // Other helper classes would go here, but there are none.
0088 
0089 namespace impl {  // icu::number::impl
0090 
0091 // Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
0092 /** @internal */
0093 struct U_I18N_API RangeMacroProps : public UMemory {
0094     /** @internal */
0095     UnlocalizedNumberFormatter formatter1; // = NumberFormatter::with();
0096 
0097     /** @internal */
0098     UnlocalizedNumberFormatter formatter2; // = NumberFormatter::with();
0099 
0100     /** @internal */
0101     bool singleFormatter = true;
0102 
0103     /** @internal */
0104     UNumberRangeCollapse collapse = UNUM_RANGE_COLLAPSE_AUTO;
0105 
0106     /** @internal */
0107     UNumberRangeIdentityFallback identityFallback = UNUM_IDENTITY_FALLBACK_APPROXIMATELY;
0108 
0109     /** @internal */
0110     Locale locale;
0111 
0112     // NOTE: Uses default copy and move constructors.
0113 
0114     /**
0115      * Check all members for errors.
0116      * @internal
0117      */
0118     bool copyErrorTo(UErrorCode &status) const {
0119         return formatter1.copyErrorTo(status) || formatter2.copyErrorTo(status);
0120     }
0121 };
0122 
0123 } // namespace impl
0124 
0125 /**
0126  * An abstract base class for specifying settings related to number formatting. This class is implemented by
0127  * {@link UnlocalizedNumberRangeFormatter} and {@link LocalizedNumberRangeFormatter}. This class is not intended for
0128  * public subclassing.
0129  */
0130 template<typename Derived>
0131 class U_I18N_API NumberRangeFormatterSettings {
0132   public:
0133     /**
0134      * Sets the NumberFormatter instance to use for the numbers in the range. The same formatter is applied to both
0135      * sides of the range.
0136      * <p>
0137      * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
0138      * NumberRangeFormatter will be used.
0139      *
0140      * @param formatter
0141      *            The formatter to use for both numbers in the range.
0142      * @return The fluent chain.
0143      * @stable ICU 63
0144      */
0145     Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &;
0146 
0147     /**
0148      * Overload of numberFormatterBoth() for use on an rvalue reference.
0149      *
0150      * @param formatter
0151      *            The formatter to use for both numbers in the range.
0152      * @return The fluent chain.
0153      * @see #numberFormatterBoth
0154      * @stable ICU 63
0155      */
0156     Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&;
0157 
0158     /**
0159      * Overload of numberFormatterBoth() for use on an rvalue reference.
0160      *
0161      * @param formatter
0162      *            The formatter to use for both numbers in the range.
0163      * @return The fluent chain.
0164      * @see #numberFormatterBoth
0165      * @stable ICU 63
0166      */
0167     Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &;
0168 
0169     /**
0170      * Overload of numberFormatterBoth() for use on an rvalue reference.
0171      *
0172      * @param formatter
0173      *            The formatter to use for both numbers in the range.
0174      * @return The fluent chain.
0175      * @see #numberFormatterBoth
0176      * @stable ICU 63
0177      */
0178     Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&;
0179 
0180     /**
0181      * Sets the NumberFormatter instance to use for the first number in the range.
0182      * <p>
0183      * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
0184      * NumberRangeFormatter will be used.
0185      *
0186      * @param formatterFirst
0187      *            The formatter to use for the first number in the range.
0188      * @return The fluent chain.
0189      * @stable ICU 63
0190      */
0191     Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &;
0192 
0193     /**
0194      * Overload of numberFormatterFirst() for use on an rvalue reference.
0195      *
0196      * @param formatterFirst
0197      *            The formatter to use for the first number in the range.
0198      * @return The fluent chain.
0199      * @see #numberFormatterFirst
0200      * @stable ICU 63
0201      */
0202     Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&;
0203 
0204     /**
0205      * Overload of numberFormatterFirst() for use on an rvalue reference.
0206      *
0207      * @param formatterFirst
0208      *            The formatter to use for the first number in the range.
0209      * @return The fluent chain.
0210      * @see #numberFormatterFirst
0211      * @stable ICU 63
0212      */
0213     Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &;
0214 
0215     /**
0216      * Overload of numberFormatterFirst() for use on an rvalue reference.
0217      *
0218      * @param formatterFirst
0219      *            The formatter to use for the first number in the range.
0220      * @return The fluent chain.
0221      * @see #numberFormatterFirst
0222      * @stable ICU 63
0223      */
0224     Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&;
0225 
0226     /**
0227      * Sets the NumberFormatter instance to use for the second number in the range.
0228      * <p>
0229      * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
0230      * NumberRangeFormatter will be used.
0231      *
0232      * @param formatterSecond
0233      *            The formatter to use for the second number in the range.
0234      * @return The fluent chain.
0235      * @stable ICU 63
0236      */
0237     Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &;
0238 
0239     /**
0240      * Overload of numberFormatterSecond() for use on an rvalue reference.
0241      *
0242      * @param formatterSecond
0243      *            The formatter to use for the second number in the range.
0244      * @return The fluent chain.
0245      * @see #numberFormatterSecond
0246      * @stable ICU 63
0247      */
0248     Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&;
0249 
0250     /**
0251      * Overload of numberFormatterSecond() for use on an rvalue reference.
0252      *
0253      * @param formatterSecond
0254      *            The formatter to use for the second number in the range.
0255      * @return The fluent chain.
0256      * @see #numberFormatterSecond
0257      * @stable ICU 63
0258      */
0259     Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &;
0260 
0261     /**
0262      * Overload of numberFormatterSecond() for use on an rvalue reference.
0263      *
0264      * @param formatterSecond
0265      *            The formatter to use for the second number in the range.
0266      * @return The fluent chain.
0267      * @see #numberFormatterSecond
0268      * @stable ICU 63
0269      */
0270     Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&;
0271 
0272     /**
0273      * Sets the aggressiveness of "collapsing" fields across the range separator. Possible values:
0274      * <p>
0275      * <ul>
0276      * <li>ALL: "3-5K miles"</li>
0277      * <li>UNIT: "3K - 5K miles"</li>
0278      * <li>NONE: "3K miles - 5K miles"</li>
0279      * <li>AUTO: usually UNIT or NONE, depending on the locale and formatter settings</li>
0280      * </ul>
0281      * <p>
0282      * The default value is AUTO.
0283      *
0284      * @param collapse
0285      *            The collapsing strategy to use for this range.
0286      * @return The fluent chain.
0287      * @stable ICU 63
0288      */
0289     Derived collapse(UNumberRangeCollapse collapse) const &;
0290 
0291     /**
0292      * Overload of collapse() for use on an rvalue reference.
0293      *
0294      * @param collapse
0295      *            The collapsing strategy to use for this range.
0296      * @return The fluent chain.
0297      * @see #collapse
0298      * @stable ICU 63
0299      */
0300     Derived collapse(UNumberRangeCollapse collapse) &&;
0301 
0302     /**
0303      * Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are
0304      * passed to the formatFormattableRange function, or if different numbers are passed to the function but they
0305      * become the same after rounding rules are applied. Possible values:
0306      * <p>
0307      * <ul>
0308      * <li>SINGLE_VALUE: "5 miles"</li>
0309      * <li>APPROXIMATELY_OR_SINGLE_VALUE: "~5 miles" or "5 miles", depending on whether the number was the same before
0310      * rounding was applied</li>
0311      * <li>APPROXIMATELY: "~5 miles"</li>
0312      * <li>RANGE: "5-5 miles" (with collapse=UNIT)</li>
0313      * </ul>
0314      * <p>
0315      * The default value is APPROXIMATELY.
0316      *
0317      * @param identityFallback
0318      *            The strategy to use when formatting two numbers that end up being the same.
0319      * @return The fluent chain.
0320      * @stable ICU 63
0321      */
0322     Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &;
0323 
0324     /**
0325      * Overload of identityFallback() for use on an rvalue reference.
0326      *
0327      * @param identityFallback
0328      *            The strategy to use when formatting two numbers that end up being the same.
0329      * @return The fluent chain.
0330      * @see #identityFallback
0331      * @stable ICU 63
0332      */
0333     Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&;
0334 
0335     /**
0336      * Returns the current (Un)LocalizedNumberRangeFormatter as a LocalPointer
0337      * wrapping a heap-allocated copy of the current object.
0338      *
0339      * This is equivalent to new-ing the move constructor with a value object
0340      * as the argument.
0341      *
0342      * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped
0343      *         nullptr on failure.
0344      * @stable ICU 64
0345      */
0346     LocalPointer<Derived> clone() const &;
0347 
0348     /**
0349      * Overload of clone for use on an rvalue reference.
0350      *
0351      * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped
0352      *         nullptr on failure.
0353      * @stable ICU 64
0354      */
0355     LocalPointer<Derived> clone() &&;
0356 
0357     /**
0358      * Sets the UErrorCode if an error occurred in the fluent chain.
0359      * Preserves older error codes in the outErrorCode.
0360      * @return true if U_FAILURE(outErrorCode)
0361      * @stable ICU 63
0362      */
0363     UBool copyErrorTo(UErrorCode &outErrorCode) const {
0364         if (U_FAILURE(outErrorCode)) {
0365             // Do not overwrite the older error code
0366             return true;
0367         }
0368         fMacros.copyErrorTo(outErrorCode);
0369         return U_FAILURE(outErrorCode);
0370     }
0371 
0372     // NOTE: Uses default copy and move constructors.
0373 
0374   private:
0375     impl::RangeMacroProps fMacros;
0376 
0377     // Don't construct me directly!  Use (Un)LocalizedNumberFormatter.
0378     NumberRangeFormatterSettings() = default;
0379 
0380     friend class LocalizedNumberRangeFormatter;
0381     friend class UnlocalizedNumberRangeFormatter;
0382 };
0383 
0384 // Explicit instantiations in source/i18n/numrange_fluent.cpp.
0385 // (MSVC treats imports/exports of explicit instantiations differently.)
0386 #ifndef _MSC_VER
0387 extern template class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
0388 extern template class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>;
0389 #endif
0390 
0391 /**
0392  * A NumberRangeFormatter that does not yet have a locale. In order to format, a locale must be specified.
0393  *
0394  * Instances of this class are immutable and thread-safe.
0395  *
0396  * @see NumberRangeFormatter
0397  * @stable ICU 63
0398  */
0399 class U_I18N_API UnlocalizedNumberRangeFormatter
0400         : public NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>, public UMemory {
0401 
0402   public:
0403     /**
0404      * Associate the given locale with the number range formatter. The locale is used for picking the
0405      * appropriate symbols, formats, and other data for number display.
0406      *
0407      * @param locale
0408      *            The locale to use when loading data for number formatting.
0409      * @return The fluent chain.
0410      * @stable ICU 63
0411      */
0412     LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &;
0413 
0414     /**
0415      * Overload of locale() for use on an rvalue reference.
0416      *
0417      * @param locale
0418      *            The locale to use when loading data for number formatting.
0419      * @return The fluent chain.
0420      * @see #locale
0421      * @stable ICU 63
0422      */
0423     LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&;
0424 
0425     /**
0426      * Default constructor: puts the formatter into a valid but undefined state.
0427      *
0428      * @stable ICU 63
0429      */
0430     UnlocalizedNumberRangeFormatter() = default;
0431 
0432     /**
0433      * Returns a copy of this UnlocalizedNumberRangeFormatter.
0434      * @stable ICU 63
0435      */
0436     UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other);
0437 
0438     /**
0439      * Move constructor:
0440      * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
0441      * @stable ICU 63
0442      */
0443     UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) noexcept;
0444 
0445     /**
0446      * Copy assignment operator.
0447      * @stable ICU 63
0448      */
0449     UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other);
0450 
0451     /**
0452      * Move assignment operator:
0453      * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
0454      * @stable ICU 63
0455      */
0456     UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) noexcept;
0457 
0458   private:
0459     explicit UnlocalizedNumberRangeFormatter(
0460             const NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>& other);
0461 
0462     explicit UnlocalizedNumberRangeFormatter(
0463             NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>&& src) noexcept;
0464 
0465     explicit UnlocalizedNumberRangeFormatter(const impl::RangeMacroProps &macros);
0466 
0467     explicit UnlocalizedNumberRangeFormatter(impl::RangeMacroProps &&macros);
0468 
0469     // To give the fluent setters access to this class's constructor:
0470     friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
0471 
0472     // To give NumberRangeFormatter::with() access to this class's constructor:
0473     friend class NumberRangeFormatter;
0474 
0475     // To give LNRF::withoutLocale() access to this class's constructor:
0476     friend class LocalizedNumberRangeFormatter;
0477 };
0478 
0479 /**
0480  * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available.
0481  *
0482  * Instances of this class are immutable and thread-safe.
0483  *
0484  * @see NumberFormatter
0485  * @stable ICU 63
0486  */
0487 class U_I18N_API LocalizedNumberRangeFormatter
0488         : public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory {
0489   public:
0490     /**
0491      * Format the given Formattables to a string using the settings specified in the NumberRangeFormatter fluent setting
0492      * chain.
0493      *
0494      * @param first
0495      *            The first number in the range, usually to the left in LTR locales.
0496      * @param second
0497      *            The second number in the range, usually to the right in LTR locales.
0498      * @param status
0499      *            Set if an error occurs while formatting.
0500      * @return A FormattedNumberRange object; call .toString() to get the string.
0501      * @stable ICU 63
0502      */
0503     FormattedNumberRange formatFormattableRange(
0504         const Formattable& first, const Formattable& second, UErrorCode& status) const;
0505 
0506 #ifndef U_HIDE_DRAFT_API
0507     /**
0508      * Disassociate the locale from this formatter.
0509      *
0510      * @return The fluent chain.
0511      * @draft ICU 75
0512      */
0513     UnlocalizedNumberRangeFormatter withoutLocale() const &;
0514 
0515     /**
0516      * Overload of withoutLocale() for use on an rvalue reference.
0517      *
0518      * @return The fluent chain.
0519      * @see #withoutLocale
0520      * @draft ICU 75
0521      */
0522     UnlocalizedNumberRangeFormatter withoutLocale() &&;
0523 #endif // U_HIDE_DRAFT_API
0524 
0525     /**
0526      * Default constructor: puts the formatter into a valid but undefined state.
0527      *
0528      * @stable ICU 63
0529      */
0530     LocalizedNumberRangeFormatter() = default;
0531 
0532     /**
0533      * Returns a copy of this LocalizedNumberRangeFormatter.
0534      * @stable ICU 63
0535      */
0536     LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other);
0537 
0538     /**
0539      * Move constructor:
0540      * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
0541      * @stable ICU 63
0542      */
0543     LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) noexcept;
0544 
0545     /**
0546      * Copy assignment operator.
0547      * @stable ICU 63
0548      */
0549     LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other);
0550 
0551     /**
0552      * Move assignment operator:
0553      * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
0554      * @stable ICU 63
0555      */
0556     LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) noexcept;
0557 
0558 #ifndef U_HIDE_INTERNAL_API
0559 
0560     /**
0561      * @param results
0562      *            The results object. This method will mutate it to save the results.
0563      * @param equalBeforeRounding
0564      *            Whether the number was equal before copying it into a DecimalQuantity.
0565      *            Used for determining the identity fallback behavior.
0566      * @param status
0567      *            Set if an error occurs while formatting.
0568      * @internal
0569      */
0570     void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding,
0571                     UErrorCode& status) const;
0572 
0573 #endif  /* U_HIDE_INTERNAL_API */
0574 
0575     /**
0576      * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own.
0577      * @stable ICU 63
0578      */
0579     ~LocalizedNumberRangeFormatter();
0580 
0581   private:
0582     std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {};
0583 
0584     const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const;
0585 
0586     explicit LocalizedNumberRangeFormatter(
0587         const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other);
0588 
0589     explicit LocalizedNumberRangeFormatter(
0590         NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>&& src) noexcept;
0591 
0592     LocalizedNumberRangeFormatter(const impl::RangeMacroProps &macros, const Locale &locale);
0593 
0594     LocalizedNumberRangeFormatter(impl::RangeMacroProps &&macros, const Locale &locale);
0595 
0596     // To give the fluent setters access to this class's constructor:
0597     friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
0598     friend class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>;
0599 
0600     // To give UnlocalizedNumberRangeFormatter::locale() access to this class's constructor:
0601     friend class UnlocalizedNumberRangeFormatter;
0602 };
0603 
0604 /**
0605  * The result of a number range formatting operation. This class allows the result to be exported in several data types,
0606  * including a UnicodeString and a FieldPositionIterator.
0607  *
0608  * Instances of this class are immutable and thread-safe.
0609  *
0610  * @stable ICU 63
0611  */
0612 class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
0613   public:
0614     // Copybrief: this method is older than the parent method
0615     /**
0616      * @copybrief FormattedValue::toString()
0617      *
0618      * For more information, see FormattedValue::toString()
0619      *
0620      * @stable ICU 63
0621      */
0622     UnicodeString toString(UErrorCode& status) const override;
0623 
0624     // Copydoc: this method is new in ICU 64
0625     /** @copydoc FormattedValue::toTempString() */
0626     UnicodeString toTempString(UErrorCode& status) const override;
0627 
0628     // Copybrief: this method is older than the parent method
0629     /**
0630      * @copybrief FormattedValue::appendTo()
0631      *
0632      * For more information, see FormattedValue::appendTo()
0633      *
0634      * @stable ICU 63
0635      */
0636     Appendable &appendTo(Appendable &appendable, UErrorCode& status) const override;
0637 
0638     // Copydoc: this method is new in ICU 64
0639     /** @copydoc FormattedValue::nextPosition() */
0640     UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const override;
0641 
0642     /**
0643      * Extracts the formatted range as a pair of decimal numbers. This endpoint
0644      * is useful for obtaining the exact number being printed after scaling
0645      * and rounding have been applied by the number range formatting pipeline.
0646      * 
0647      * The syntax of the unformatted numbers is a "numeric string"
0648      * as defined in the Decimal Arithmetic Specification, available at
0649      * http://speleotrove.com/decimal
0650      *
0651      * Example C++17 call site:
0652      *
0653      *     auto [ first, second ] = range.getDecimalNumbers<std::string>(status);
0654      *
0655      * @tparam StringClass A string class compatible with StringByteSink;
0656      *         for example, std::string.
0657      * @param status Set if an error occurs.
0658      * @return A pair of StringClasses containing the numeric strings.
0659      * @stable ICU 68
0660      */
0661     template<typename StringClass>
0662     inline std::pair<StringClass, StringClass> getDecimalNumbers(UErrorCode& status) const;
0663 
0664     /**
0665      * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was
0666      * used. For example, if the first and second number were the same either before or after rounding occurred, an
0667      * identity fallback was used.
0668      *
0669      * @return An indication the resulting identity situation in the formatted number range.
0670      * @stable ICU 63
0671      * @see UNumberRangeIdentityFallback
0672      */
0673     UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const;
0674 
0675     /**
0676      * Default constructor; makes an empty FormattedNumberRange.
0677      * @stable ICU 70
0678      */
0679     FormattedNumberRange()
0680         : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
0681 
0682     /**
0683      * Copying not supported; use move constructor instead.
0684      */
0685     FormattedNumberRange(const FormattedNumberRange&) = delete;
0686 
0687     /**
0688      * Copying not supported; use move assignment instead.
0689      */
0690     FormattedNumberRange& operator=(const FormattedNumberRange&) = delete;
0691 
0692     /**
0693      * Move constructor:
0694      * Leaves the source FormattedNumberRange in an undefined state.
0695      * @stable ICU 63
0696      */
0697     FormattedNumberRange(FormattedNumberRange&& src) noexcept;
0698 
0699     /**
0700      * Move assignment:
0701      * Leaves the source FormattedNumberRange in an undefined state.
0702      * @stable ICU 63
0703      */
0704     FormattedNumberRange& operator=(FormattedNumberRange&& src) noexcept;
0705 
0706     /**
0707      * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own.
0708      * @stable ICU 63
0709      */
0710     ~FormattedNumberRange();
0711 
0712   private:
0713     // Can't use LocalPointer because UFormattedNumberRangeData is forward-declared
0714     const impl::UFormattedNumberRangeData *fData;
0715 
0716     // Error code for the terminal methods
0717     UErrorCode fErrorCode;
0718 
0719     /**
0720      * Internal constructor from data type. Adopts the data pointer.
0721      */
0722     explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results)
0723         : fData(results), fErrorCode(U_ZERO_ERROR) {}
0724 
0725     explicit FormattedNumberRange(UErrorCode errorCode)
0726         : fData(nullptr), fErrorCode(errorCode) {}
0727 
0728     void getDecimalNumbers(ByteSink& sink1, ByteSink& sink2, UErrorCode& status) const;
0729 
0730     const impl::UFormattedNumberRangeData* getData(UErrorCode& status) const;
0731 
0732     // To allow PluralRules to access the underlying data
0733     friend class ::icu::PluralRules;
0734 
0735     // To give LocalizedNumberRangeFormatter format methods access to this class's constructor:
0736     friend class LocalizedNumberRangeFormatter;
0737 
0738     // To give C API access to internals
0739     friend struct impl::UFormattedNumberRangeImpl;
0740 };
0741 
0742 // inline impl of @stable ICU 68 method
0743 template<typename StringClass>
0744 std::pair<StringClass, StringClass> FormattedNumberRange::getDecimalNumbers(UErrorCode& status) const {
0745     StringClass str1;
0746     StringClass str2;
0747     StringByteSink<StringClass> sink1(&str1);
0748     StringByteSink<StringClass> sink2(&str2);
0749     getDecimalNumbers(sink1, sink2, status);
0750     return std::make_pair(str1, str2);
0751 }
0752 
0753 /**
0754  * See the main description in numberrangeformatter.h for documentation and examples.
0755  *
0756  * @stable ICU 63
0757  */
0758 class U_I18N_API NumberRangeFormatter final {
0759   public:
0760     /**
0761      * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently
0762      * known at the call site.
0763      *
0764      * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
0765      * @stable ICU 63
0766      */
0767     static UnlocalizedNumberRangeFormatter with();
0768 
0769     /**
0770      * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call
0771      * site.
0772      *
0773      * @param locale
0774      *            The locale from which to load formats and symbols for number range formatting.
0775      * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
0776      * @stable ICU 63
0777      */
0778     static LocalizedNumberRangeFormatter withLocale(const Locale &locale);
0779 
0780     /**
0781      * Use factory methods instead of the constructor to create a NumberFormatter.
0782      */
0783     NumberRangeFormatter() = delete;
0784 };
0785 
0786 }  // namespace number
0787 U_NAMESPACE_END
0788 
0789 #endif /* #if !UCONFIG_NO_FORMATTING */
0790 
0791 #endif /* U_SHOW_CPLUSPLUS_API */
0792 
0793 #endif // __NUMBERRANGEFORMATTER_H__
0794