Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/unicode/numberrangeformatter.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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     // To give the fluent setters access to this class's constructor:
0466     friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
0467 
0468     // To give NumberRangeFormatter::with() access to this class's constructor:
0469     friend class NumberRangeFormatter;
0470 };
0471 
0472 /**
0473  * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available.
0474  *
0475  * Instances of this class are immutable and thread-safe.
0476  *
0477  * @see NumberFormatter
0478  * @stable ICU 63
0479  */
0480 class U_I18N_API LocalizedNumberRangeFormatter
0481         : public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory {
0482   public:
0483     /**
0484      * Format the given Formattables to a string using the settings specified in the NumberRangeFormatter fluent setting
0485      * chain.
0486      *
0487      * @param first
0488      *            The first number in the range, usually to the left in LTR locales.
0489      * @param second
0490      *            The second number in the range, usually to the right in LTR locales.
0491      * @param status
0492      *            Set if an error occurs while formatting.
0493      * @return A FormattedNumberRange object; call .toString() to get the string.
0494      * @stable ICU 63
0495      */
0496     FormattedNumberRange formatFormattableRange(
0497         const Formattable& first, const Formattable& second, UErrorCode& status) const;
0498 
0499     /**
0500      * Default constructor: puts the formatter into a valid but undefined state.
0501      *
0502      * @stable ICU 63
0503      */
0504     LocalizedNumberRangeFormatter() = default;
0505 
0506     /**
0507      * Returns a copy of this LocalizedNumberRangeFormatter.
0508      * @stable ICU 63
0509      */
0510     LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other);
0511 
0512     /**
0513      * Move constructor:
0514      * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
0515      * @stable ICU 63
0516      */
0517     LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) noexcept;
0518 
0519     /**
0520      * Copy assignment operator.
0521      * @stable ICU 63
0522      */
0523     LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other);
0524 
0525     /**
0526      * Move assignment operator:
0527      * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
0528      * @stable ICU 63
0529      */
0530     LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) noexcept;
0531 
0532 #ifndef U_HIDE_INTERNAL_API
0533 
0534     /**
0535      * @param results
0536      *            The results object. This method will mutate it to save the results.
0537      * @param equalBeforeRounding
0538      *            Whether the number was equal before copying it into a DecimalQuantity.
0539      *            Used for determining the identity fallback behavior.
0540      * @param status
0541      *            Set if an error occurs while formatting.
0542      * @internal
0543      */
0544     void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding,
0545                     UErrorCode& status) const;
0546 
0547 #endif  /* U_HIDE_INTERNAL_API */
0548 
0549     /**
0550      * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own.
0551      * @stable ICU 63
0552      */
0553     ~LocalizedNumberRangeFormatter();
0554 
0555   private:
0556     std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {};
0557 
0558     const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const;
0559 
0560     explicit LocalizedNumberRangeFormatter(
0561         const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other);
0562 
0563     explicit LocalizedNumberRangeFormatter(
0564         NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>&& src) noexcept;
0565 
0566     LocalizedNumberRangeFormatter(const impl::RangeMacroProps &macros, const Locale &locale);
0567 
0568     LocalizedNumberRangeFormatter(impl::RangeMacroProps &&macros, const Locale &locale);
0569 
0570     // To give the fluent setters access to this class's constructor:
0571     friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
0572     friend class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>;
0573 
0574     // To give UnlocalizedNumberRangeFormatter::locale() access to this class's constructor:
0575     friend class UnlocalizedNumberRangeFormatter;
0576 };
0577 
0578 /**
0579  * The result of a number range formatting operation. This class allows the result to be exported in several data types,
0580  * including a UnicodeString and a FieldPositionIterator.
0581  *
0582  * Instances of this class are immutable and thread-safe.
0583  *
0584  * @stable ICU 63
0585  */
0586 class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
0587   public:
0588     // Copybrief: this method is older than the parent method
0589     /**
0590      * @copybrief FormattedValue::toString()
0591      *
0592      * For more information, see FormattedValue::toString()
0593      *
0594      * @stable ICU 63
0595      */
0596     UnicodeString toString(UErrorCode& status) const override;
0597 
0598     // Copydoc: this method is new in ICU 64
0599     /** @copydoc FormattedValue::toTempString() */
0600     UnicodeString toTempString(UErrorCode& status) const override;
0601 
0602     // Copybrief: this method is older than the parent method
0603     /**
0604      * @copybrief FormattedValue::appendTo()
0605      *
0606      * For more information, see FormattedValue::appendTo()
0607      *
0608      * @stable ICU 63
0609      */
0610     Appendable &appendTo(Appendable &appendable, UErrorCode& status) const override;
0611 
0612     // Copydoc: this method is new in ICU 64
0613     /** @copydoc FormattedValue::nextPosition() */
0614     UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const override;
0615 
0616     /**
0617      * Extracts the formatted range as a pair of decimal numbers. This endpoint
0618      * is useful for obtaining the exact number being printed after scaling
0619      * and rounding have been applied by the number range formatting pipeline.
0620      * 
0621      * The syntax of the unformatted numbers is a "numeric string"
0622      * as defined in the Decimal Arithmetic Specification, available at
0623      * http://speleotrove.com/decimal
0624      *
0625      * Example C++17 call site:
0626      *
0627      *     auto [ first, second ] = range.getDecimalNumbers<std::string>(status);
0628      *
0629      * @tparam StringClass A string class compatible with StringByteSink;
0630      *         for example, std::string.
0631      * @param status Set if an error occurs.
0632      * @return A pair of StringClasses containing the numeric strings.
0633      * @stable ICU 68
0634      */
0635     template<typename StringClass>
0636     inline std::pair<StringClass, StringClass> getDecimalNumbers(UErrorCode& status) const;
0637 
0638     /**
0639      * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was
0640      * used. For example, if the first and second number were the same either before or after rounding occurred, an
0641      * identity fallback was used.
0642      *
0643      * @return An indication the resulting identity situation in the formatted number range.
0644      * @stable ICU 63
0645      * @see UNumberRangeIdentityFallback
0646      */
0647     UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const;
0648 
0649     /**
0650      * Default constructor; makes an empty FormattedNumberRange.
0651      * @stable ICU 70
0652      */
0653     FormattedNumberRange()
0654         : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
0655 
0656     /**
0657      * Copying not supported; use move constructor instead.
0658      */
0659     FormattedNumberRange(const FormattedNumberRange&) = delete;
0660 
0661     /**
0662      * Copying not supported; use move assignment instead.
0663      */
0664     FormattedNumberRange& operator=(const FormattedNumberRange&) = delete;
0665 
0666     /**
0667      * Move constructor:
0668      * Leaves the source FormattedNumberRange in an undefined state.
0669      * @stable ICU 63
0670      */
0671     FormattedNumberRange(FormattedNumberRange&& src) noexcept;
0672 
0673     /**
0674      * Move assignment:
0675      * Leaves the source FormattedNumberRange in an undefined state.
0676      * @stable ICU 63
0677      */
0678     FormattedNumberRange& operator=(FormattedNumberRange&& src) noexcept;
0679 
0680     /**
0681      * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own.
0682      * @stable ICU 63
0683      */
0684     ~FormattedNumberRange();
0685 
0686   private:
0687     // Can't use LocalPointer because UFormattedNumberRangeData is forward-declared
0688     const impl::UFormattedNumberRangeData *fData;
0689 
0690     // Error code for the terminal methods
0691     UErrorCode fErrorCode;
0692 
0693     /**
0694      * Internal constructor from data type. Adopts the data pointer.
0695      */
0696     explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results)
0697         : fData(results), fErrorCode(U_ZERO_ERROR) {}
0698 
0699     explicit FormattedNumberRange(UErrorCode errorCode)
0700         : fData(nullptr), fErrorCode(errorCode) {}
0701 
0702     void getDecimalNumbers(ByteSink& sink1, ByteSink& sink2, UErrorCode& status) const;
0703 
0704     const impl::UFormattedNumberRangeData* getData(UErrorCode& status) const;
0705 
0706     // To allow PluralRules to access the underlying data
0707     friend class ::icu::PluralRules;
0708 
0709     // To give LocalizedNumberRangeFormatter format methods access to this class's constructor:
0710     friend class LocalizedNumberRangeFormatter;
0711 
0712     // To give C API access to internals
0713     friend struct impl::UFormattedNumberRangeImpl;
0714 };
0715 
0716 // inline impl of @stable ICU 68 method
0717 template<typename StringClass>
0718 std::pair<StringClass, StringClass> FormattedNumberRange::getDecimalNumbers(UErrorCode& status) const {
0719     StringClass str1;
0720     StringClass str2;
0721     StringByteSink<StringClass> sink1(&str1);
0722     StringByteSink<StringClass> sink2(&str2);
0723     getDecimalNumbers(sink1, sink2, status);
0724     return std::make_pair(str1, str2);
0725 }
0726 
0727 /**
0728  * See the main description in numberrangeformatter.h for documentation and examples.
0729  *
0730  * @stable ICU 63
0731  */
0732 class U_I18N_API NumberRangeFormatter final {
0733   public:
0734     /**
0735      * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently
0736      * known at the call site.
0737      *
0738      * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
0739      * @stable ICU 63
0740      */
0741     static UnlocalizedNumberRangeFormatter with();
0742 
0743     /**
0744      * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call
0745      * site.
0746      *
0747      * @param locale
0748      *            The locale from which to load formats and symbols for number range formatting.
0749      * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
0750      * @stable ICU 63
0751      */
0752     static LocalizedNumberRangeFormatter withLocale(const Locale &locale);
0753 
0754     /**
0755      * Use factory methods instead of the constructor to create a NumberFormatter.
0756      */
0757     NumberRangeFormatter() = delete;
0758 };
0759 
0760 }  // namespace number
0761 U_NAMESPACE_END
0762 
0763 #endif /* #if !UCONFIG_NO_FORMATTING */
0764 
0765 #endif /* U_SHOW_CPLUSPLUS_API */
0766 
0767 #endif // __NUMBERRANGEFORMATTER_H__
0768