diff CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/unicode/numberrangeformatter.h @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/unicode/numberrangeformatter.h	Tue Mar 18 17:55:14 2025 -0400
@@ -0,0 +1,866 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __NUMBERRANGEFORMATTER_H__
+#define __NUMBERRANGEFORMATTER_H__
+
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#if !UCONFIG_NO_FORMATTING
+
+#include <atomic>
+#include "unicode/appendable.h"
+#include "unicode/fieldpos.h"
+#include "unicode/formattedvalue.h"
+#include "unicode/fpositer.h"
+#include "unicode/numberformatter.h"
+
+/**
+ * \file
+ * \brief C++ API: Library for localized formatting of number, currency, and unit ranges.
+ *
+ * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement.
+ * <p>
+ * Usage example:
+ * <p>
+ * <pre>
+ * NumberRangeFormatter::with()
+ *     .identityFallback(UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE)
+ *     .numberFormatterFirst(NumberFormatter::with().adoptUnit(MeasureUnit::createMeter()))
+ *     .numberFormatterSecond(NumberFormatter::with().adoptUnit(MeasureUnit::createKilometer()))
+ *     .locale("en-GB")
+ *     .formatRange(750, 1.2, status)
+ *     .toString(status);
+ * // => "750 m - 1.2 km"
+ * </pre>
+ * <p>
+ * Like NumberFormatter, NumberRangeFormatter instances (i.e., LocalizedNumberRangeFormatter
+ * and UnlocalizedNumberRangeFormatter) are immutable and thread-safe. This API is based on the
+ * <em>fluent</em> design pattern popularized by libraries such as Google's Guava.
+ *
+ * @author Shane Carr
+ */
+
+
+/**
+ * Defines how to merge fields that are identical across the range sign.
+ *
+ * @stable ICU 63
+ */
+typedef enum UNumberRangeCollapse {
+    /**
+     * Use locale data and heuristics to determine how much of the string to collapse. Could end up collapsing none,
+     * some, or all repeated pieces in a locale-sensitive way.
+     *
+     * The heuristics used for this option are subject to change over time.
+     *
+     * @stable ICU 63
+     */
+    UNUM_RANGE_COLLAPSE_AUTO,
+
+    /**
+     * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms"
+     *
+     * @stable ICU 63
+     */
+    UNUM_RANGE_COLLAPSE_NONE,
+
+    /**
+     * Collapse the unit part of the number, but not the notation, if present. Example: "3.2 thousand – 5.3 thousand
+     * kilograms"
+     *
+     * @stable ICU 63
+     */
+    UNUM_RANGE_COLLAPSE_UNIT,
+
+    /**
+     * Collapse any field that is equal across the range sign. May introduce ambiguity on the magnitude of the
+     * number. Example: "3.2 – 5.3 thousand kilograms"
+     *
+     * @stable ICU 63
+     */
+    UNUM_RANGE_COLLAPSE_ALL
+} UNumberRangeCollapse;
+
+/**
+ * Defines the behavior when the two numbers in the range are identical after rounding. To programmatically detect
+ * when the identity fallback is used, compare the lower and upper BigDecimals via FormattedNumber.
+ *
+ * @stable ICU 63
+ * @see NumberRangeFormatter
+ */
+typedef enum UNumberRangeIdentityFallback {
+    /**
+     * Show the number as a single value rather than a range. Example: "$5"
+     *
+     * @stable ICU 63
+     */
+    UNUM_IDENTITY_FALLBACK_SINGLE_VALUE,
+
+    /**
+     * Show the number using a locale-sensitive approximation pattern. If the numbers were the same before rounding,
+     * show the single value. Example: "~$5" or "$5"
+     *
+     * @stable ICU 63
+     */
+    UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE,
+
+    /**
+     * Show the number using a locale-sensitive approximation pattern. Use the range pattern always, even if the
+     * inputs are the same. Example: "~$5"
+     *
+     * @stable ICU 63
+     */
+    UNUM_IDENTITY_FALLBACK_APPROXIMATELY,
+
+    /**
+     * Show the number as the range of two equal values. Use the range pattern always, even if the inputs are the
+     * same. Example (with RangeCollapse.NONE): "$5 – $5"
+     *
+     * @stable ICU 63
+     */
+    UNUM_IDENTITY_FALLBACK_RANGE
+} UNumberRangeIdentityFallback;
+
+/**
+ * Used in the result class FormattedNumberRange to indicate to the user whether the numbers formatted in the range
+ * were equal or not, and whether or not the identity fallback was applied.
+ *
+ * @stable ICU 63
+ * @see NumberRangeFormatter
+ */
+typedef enum UNumberRangeIdentityResult {
+    /**
+     * Used to indicate that the two numbers in the range were equal, even before any rounding rules were applied.
+     *
+     * @stable ICU 63
+     * @see NumberRangeFormatter
+     */
+    UNUM_IDENTITY_RESULT_EQUAL_BEFORE_ROUNDING,
+
+    /**
+     * Used to indicate that the two numbers in the range were equal, but only after rounding rules were applied.
+     *
+     * @stable ICU 63
+     * @see NumberRangeFormatter
+     */
+    UNUM_IDENTITY_RESULT_EQUAL_AFTER_ROUNDING,
+
+    /**
+     * Used to indicate that the two numbers in the range were not equal, even after rounding rules were applied.
+     *
+     * @stable ICU 63
+     * @see NumberRangeFormatter
+     */
+    UNUM_IDENTITY_RESULT_NOT_EQUAL,
+
+#ifndef U_HIDE_INTERNAL_API
+    /**
+     * The number of entries in this enum.
+     * @internal
+     */
+    UNUM_IDENTITY_RESULT_COUNT
+#endif
+
+} UNumberRangeIdentityResult;
+
+U_NAMESPACE_BEGIN
+
+namespace number {  // icu::number
+
+// Forward declarations:
+class UnlocalizedNumberRangeFormatter;
+class LocalizedNumberRangeFormatter;
+class FormattedNumberRange;
+
+namespace impl {
+
+// Forward declarations:
+struct RangeMacroProps;
+class DecimalQuantity;
+class UFormattedNumberRangeData;
+class NumberRangeFormatterImpl;
+
+} // namespace impl
+
+/**
+ * \cond
+ * Export an explicit template instantiation. See datefmt.h
+ * (When building DLLs for Windows this is required.)
+ */
+#if U_PLATFORM == U_PF_WINDOWS && !defined(U_IN_DOXYGEN)
+} // namespace icu::number
+U_NAMESPACE_END
+
+template struct U_I18N_API std::atomic< U_NAMESPACE_QUALIFIER number::impl::NumberRangeFormatterImpl*>;
+
+U_NAMESPACE_BEGIN
+namespace number {  // icu::number
+#endif
+/** \endcond */
+
+// Other helper classes would go here, but there are none.
+
+namespace impl {  // icu::number::impl
+
+// Do not enclose entire MacroProps with #ifndef U_HIDE_INTERNAL_API, needed for a protected field
+/** @internal */
+struct U_I18N_API RangeMacroProps : public UMemory {
+    /** @internal */
+    UnlocalizedNumberFormatter formatter1; // = NumberFormatter::with();
+
+    /** @internal */
+    UnlocalizedNumberFormatter formatter2; // = NumberFormatter::with();
+
+    /** @internal */
+    bool singleFormatter = true;
+
+    /** @internal */
+    UNumberRangeCollapse collapse = UNUM_RANGE_COLLAPSE_AUTO;
+
+    /** @internal */
+    UNumberRangeIdentityFallback identityFallback = UNUM_IDENTITY_FALLBACK_APPROXIMATELY;
+
+    /** @internal */
+    Locale locale;
+
+    // NOTE: Uses default copy and move constructors.
+
+    /**
+     * Check all members for errors.
+     * @internal
+     */
+    bool copyErrorTo(UErrorCode &status) const {
+        return formatter1.copyErrorTo(status) || formatter2.copyErrorTo(status);
+    }
+};
+
+} // namespace impl
+
+/**
+ * An abstract base class for specifying settings related to number formatting. This class is implemented by
+ * {@link UnlocalizedNumberRangeFormatter} and {@link LocalizedNumberRangeFormatter}. This class is not intended for
+ * public subclassing.
+ */
+template<typename Derived>
+class U_I18N_API NumberRangeFormatterSettings {
+  public:
+    /**
+     * Sets the NumberFormatter instance to use for the numbers in the range. The same formatter is applied to both
+     * sides of the range.
+     * <p>
+     * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
+     * NumberRangeFormatter will be used.
+     *
+     * @param formatter
+     *            The formatter to use for both numbers in the range.
+     * @return The fluent chain.
+     * @stable ICU 63
+     */
+    Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) const &;
+
+    /**
+     * Overload of numberFormatterBoth() for use on an rvalue reference.
+     *
+     * @param formatter
+     *            The formatter to use for both numbers in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterBoth
+     * @stable ICU 63
+     */
+    Derived numberFormatterBoth(const UnlocalizedNumberFormatter &formatter) &&;
+
+    /**
+     * Overload of numberFormatterBoth() for use on an rvalue reference.
+     *
+     * @param formatter
+     *            The formatter to use for both numbers in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterBoth
+     * @stable ICU 63
+     */
+    Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) const &;
+
+    /**
+     * Overload of numberFormatterBoth() for use on an rvalue reference.
+     *
+     * @param formatter
+     *            The formatter to use for both numbers in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterBoth
+     * @stable ICU 63
+     */
+    Derived numberFormatterBoth(UnlocalizedNumberFormatter &&formatter) &&;
+
+    /**
+     * Sets the NumberFormatter instance to use for the first number in the range.
+     * <p>
+     * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
+     * NumberRangeFormatter will be used.
+     *
+     * @param formatterFirst
+     *            The formatter to use for the first number in the range.
+     * @return The fluent chain.
+     * @stable ICU 63
+     */
+    Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) const &;
+
+    /**
+     * Overload of numberFormatterFirst() for use on an rvalue reference.
+     *
+     * @param formatterFirst
+     *            The formatter to use for the first number in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterFirst
+     * @stable ICU 63
+     */
+    Derived numberFormatterFirst(const UnlocalizedNumberFormatter &formatterFirst) &&;
+
+    /**
+     * Overload of numberFormatterFirst() for use on an rvalue reference.
+     *
+     * @param formatterFirst
+     *            The formatter to use for the first number in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterFirst
+     * @stable ICU 63
+     */
+    Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) const &;
+
+    /**
+     * Overload of numberFormatterFirst() for use on an rvalue reference.
+     *
+     * @param formatterFirst
+     *            The formatter to use for the first number in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterFirst
+     * @stable ICU 63
+     */
+    Derived numberFormatterFirst(UnlocalizedNumberFormatter &&formatterFirst) &&;
+
+    /**
+     * Sets the NumberFormatter instance to use for the second number in the range.
+     * <p>
+     * The NumberFormatter instances must not have a locale applied yet; the locale specified on the
+     * NumberRangeFormatter will be used.
+     *
+     * @param formatterSecond
+     *            The formatter to use for the second number in the range.
+     * @return The fluent chain.
+     * @stable ICU 63
+     */
+    Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) const &;
+
+    /**
+     * Overload of numberFormatterSecond() for use on an rvalue reference.
+     *
+     * @param formatterSecond
+     *            The formatter to use for the second number in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterSecond
+     * @stable ICU 63
+     */
+    Derived numberFormatterSecond(const UnlocalizedNumberFormatter &formatterSecond) &&;
+
+    /**
+     * Overload of numberFormatterSecond() for use on an rvalue reference.
+     *
+     * @param formatterSecond
+     *            The formatter to use for the second number in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterSecond
+     * @stable ICU 63
+     */
+    Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) const &;
+
+    /**
+     * Overload of numberFormatterSecond() for use on an rvalue reference.
+     *
+     * @param formatterSecond
+     *            The formatter to use for the second number in the range.
+     * @return The fluent chain.
+     * @see #numberFormatterSecond
+     * @stable ICU 63
+     */
+    Derived numberFormatterSecond(UnlocalizedNumberFormatter &&formatterSecond) &&;
+
+    /**
+     * Sets the aggressiveness of "collapsing" fields across the range separator. Possible values:
+     * <p>
+     * <ul>
+     * <li>ALL: "3-5K miles"</li>
+     * <li>UNIT: "3K - 5K miles"</li>
+     * <li>NONE: "3K miles - 5K miles"</li>
+     * <li>AUTO: usually UNIT or NONE, depending on the locale and formatter settings</li>
+     * </ul>
+     * <p>
+     * The default value is AUTO.
+     *
+     * @param collapse
+     *            The collapsing strategy to use for this range.
+     * @return The fluent chain.
+     * @stable ICU 63
+     */
+    Derived collapse(UNumberRangeCollapse collapse) const &;
+
+    /**
+     * Overload of collapse() for use on an rvalue reference.
+     *
+     * @param collapse
+     *            The collapsing strategy to use for this range.
+     * @return The fluent chain.
+     * @see #collapse
+     * @stable ICU 63
+     */
+    Derived collapse(UNumberRangeCollapse collapse) &&;
+
+    /**
+     * Sets the behavior when the two sides of the range are the same. This could happen if the same two numbers are
+     * passed to the formatRange function, or if different numbers are passed to the function but they become the same
+     * after rounding rules are applied. Possible values:
+     * <p>
+     * <ul>
+     * <li>SINGLE_VALUE: "5 miles"</li>
+     * <li>APPROXIMATELY_OR_SINGLE_VALUE: "~5 miles" or "5 miles", depending on whether the number was the same before
+     * rounding was applied</li>
+     * <li>APPROXIMATELY: "~5 miles"</li>
+     * <li>RANGE: "5-5 miles" (with collapse=UNIT)</li>
+     * </ul>
+     * <p>
+     * The default value is APPROXIMATELY.
+     *
+     * @param identityFallback
+     *            The strategy to use when formatting two numbers that end up being the same.
+     * @return The fluent chain.
+     * @stable ICU 63
+     */
+    Derived identityFallback(UNumberRangeIdentityFallback identityFallback) const &;
+
+    /**
+     * Overload of identityFallback() for use on an rvalue reference.
+     *
+     * @param identityFallback
+     *            The strategy to use when formatting two numbers that end up being the same.
+     * @return The fluent chain.
+     * @see #identityFallback
+     * @stable ICU 63
+     */
+    Derived identityFallback(UNumberRangeIdentityFallback identityFallback) &&;
+
+    /**
+     * Returns the current (Un)LocalizedNumberRangeFormatter as a LocalPointer
+     * wrapping a heap-allocated copy of the current object.
+     *
+     * This is equivalent to new-ing the move constructor with a value object
+     * as the argument.
+     *
+     * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped
+     *         nullptr on failure.
+     * @stable ICU 64
+     */
+    LocalPointer<Derived> clone() const &;
+
+    /**
+     * Overload of clone for use on an rvalue reference.
+     *
+     * @return A wrapped (Un)LocalizedNumberRangeFormatter pointer, or a wrapped
+     *         nullptr on failure.
+     * @stable ICU 64
+     */
+    LocalPointer<Derived> clone() &&;
+
+    /**
+     * Sets the UErrorCode if an error occurred in the fluent chain.
+     * Preserves older error codes in the outErrorCode.
+     * @return TRUE if U_FAILURE(outErrorCode)
+     * @stable ICU 63
+     */
+    UBool copyErrorTo(UErrorCode &outErrorCode) const {
+        if (U_FAILURE(outErrorCode)) {
+            // Do not overwrite the older error code
+            return TRUE;
+        }
+        fMacros.copyErrorTo(outErrorCode);
+        return U_FAILURE(outErrorCode);
+    }
+
+    // NOTE: Uses default copy and move constructors.
+
+  private:
+    impl::RangeMacroProps fMacros;
+
+    // Don't construct me directly!  Use (Un)LocalizedNumberFormatter.
+    NumberRangeFormatterSettings() = default;
+
+    friend class LocalizedNumberRangeFormatter;
+    friend class UnlocalizedNumberRangeFormatter;
+};
+
+/**
+ * A NumberRangeFormatter that does not yet have a locale. In order to format, a locale must be specified.
+ *
+ * Instances of this class are immutable and thread-safe.
+ *
+ * @see NumberRangeFormatter
+ * @stable ICU 63
+ */
+class U_I18N_API UnlocalizedNumberRangeFormatter
+        : public NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>, public UMemory {
+
+  public:
+    /**
+     * Associate the given locale with the number range formatter. The locale is used for picking the
+     * appropriate symbols, formats, and other data for number display.
+     *
+     * @param locale
+     *            The locale to use when loading data for number formatting.
+     * @return The fluent chain.
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter locale(const icu::Locale &locale) const &;
+
+    /**
+     * Overload of locale() for use on an rvalue reference.
+     *
+     * @param locale
+     *            The locale to use when loading data for number formatting.
+     * @return The fluent chain.
+     * @see #locale
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&;
+
+    /**
+     * Default constructor: puts the formatter into a valid but undefined state.
+     *
+     * @stable ICU 63
+     */
+    UnlocalizedNumberRangeFormatter() = default;
+
+    /**
+     * Returns a copy of this UnlocalizedNumberRangeFormatter.
+     * @stable ICU 63
+     */
+    UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other);
+
+    /**
+     * Move constructor:
+     * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
+     * @stable ICU 63
+     */
+    UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
+
+    /**
+     * Copy assignment operator.
+     * @stable ICU 63
+     */
+    UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other);
+
+    /**
+     * Move assignment operator:
+     * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
+     * @stable ICU 63
+     */
+    UnlocalizedNumberRangeFormatter& operator=(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
+
+  private:
+    explicit UnlocalizedNumberRangeFormatter(
+            const NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>& other);
+
+    explicit UnlocalizedNumberRangeFormatter(
+            NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>&& src) U_NOEXCEPT;
+
+    // To give the fluent setters access to this class's constructor:
+    friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
+
+    // To give NumberRangeFormatter::with() access to this class's constructor:
+    friend class NumberRangeFormatter;
+};
+
+/**
+ * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available.
+ *
+ * Instances of this class are immutable and thread-safe.
+ *
+ * @see NumberFormatter
+ * @stable ICU 63
+ */
+class U_I18N_API LocalizedNumberRangeFormatter
+        : public NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>, public UMemory {
+  public:
+    /**
+     * Format the given Formattables to a string using the settings specified in the NumberRangeFormatter fluent setting
+     * chain.
+     *
+     * @param first
+     *            The first number in the range, usually to the left in LTR locales.
+     * @param second
+     *            The second number in the range, usually to the right in LTR locales.
+     * @param status
+     *            Set if an error occurs while formatting.
+     * @return A FormattedNumberRange object; call .toString() to get the string.
+     * @stable ICU 63
+     */
+    FormattedNumberRange formatFormattableRange(
+        const Formattable& first, const Formattable& second, UErrorCode& status) const;
+
+    /**
+     * Default constructor: puts the formatter into a valid but undefined state.
+     *
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter() = default;
+
+    /**
+     * Returns a copy of this LocalizedNumberRangeFormatter.
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other);
+
+    /**
+     * Move constructor:
+     * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
+
+    /**
+     * Copy assignment operator.
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other);
+
+    /**
+     * Move assignment operator:
+     * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
+     * @stable ICU 63
+     */
+    LocalizedNumberRangeFormatter& operator=(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT;
+
+#ifndef U_HIDE_INTERNAL_API
+
+    /**
+     * @param results
+     *            The results object. This method will mutate it to save the results.
+     * @param equalBeforeRounding
+     *            Whether the number was equal before copying it into a DecimalQuantity.
+     *            Used for determining the identity fallback behavior.
+     * @param status
+     *            Set if an error occurs while formatting.
+     * @internal
+     */
+    void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding,
+                    UErrorCode& status) const;
+
+#endif  /* U_HIDE_INTERNAL_API */
+
+    /**
+     * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own.
+     * @stable ICU 63
+     */
+    ~LocalizedNumberRangeFormatter();
+
+  private:
+    std::atomic<impl::NumberRangeFormatterImpl*> fAtomicFormatter = {};
+
+    const impl::NumberRangeFormatterImpl* getFormatter(UErrorCode& stauts) const;
+
+    explicit LocalizedNumberRangeFormatter(
+        const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other);
+
+    explicit LocalizedNumberRangeFormatter(
+        NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>&& src) U_NOEXCEPT;
+
+    LocalizedNumberRangeFormatter(const impl::RangeMacroProps &macros, const Locale &locale);
+
+    LocalizedNumberRangeFormatter(impl::RangeMacroProps &&macros, const Locale &locale);
+
+    void clear();
+
+    // To give the fluent setters access to this class's constructor:
+    friend class NumberRangeFormatterSettings<UnlocalizedNumberRangeFormatter>;
+    friend class NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>;
+
+    // To give UnlocalizedNumberRangeFormatter::locale() access to this class's constructor:
+    friend class UnlocalizedNumberRangeFormatter;
+};
+
+/**
+ * The result of a number range formatting operation. This class allows the result to be exported in several data types,
+ * including a UnicodeString and a FieldPositionIterator.
+ *
+ * Instances of this class are immutable and thread-safe.
+ *
+ * @stable ICU 63
+ */
+class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
+  public:
+    // Copybrief: this method is older than the parent method
+    /**
+     * @copybrief FormattedValue::toString()
+     *
+     * For more information, see FormattedValue::toString()
+     *
+     * @stable ICU 63
+     */
+    UnicodeString toString(UErrorCode& status) const U_OVERRIDE;
+
+    // Copydoc: this method is new in ICU 64
+    /** @copydoc FormattedValue::toTempString() */
+    UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE;
+
+    // Copybrief: this method is older than the parent method
+    /**
+     * @copybrief FormattedValue::appendTo()
+     *
+     * For more information, see FormattedValue::appendTo()
+     *
+     * @stable ICU 63
+     */
+    Appendable &appendTo(Appendable &appendable, UErrorCode& status) const U_OVERRIDE;
+
+    // Copydoc: this method is new in ICU 64
+    /** @copydoc FormattedValue::nextPosition() */
+    UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
+
+#ifndef U_HIDE_DRAFT_API
+    /**
+     * Export the first formatted number as a decimal number. This endpoint
+     * is useful for obtaining the exact number being printed after scaling
+     * and rounding have been applied by the number range formatting pipeline.
+     * 
+     * The syntax of the unformatted number is a "numeric string"
+     * as defined in the Decimal Arithmetic Specification, available at
+     * http://speleotrove.com/decimal
+     *
+     * @return A decimal representation of the first formatted number.
+     * @draft ICU 63
+     * @see NumberRangeFormatter
+     * @see #getSecondDecimal
+     */
+    UnicodeString getFirstDecimal(UErrorCode& status) const;
+
+    /**
+     * Export the second formatted number as a decimal number. This endpoint
+     * is useful for obtaining the exact number being printed after scaling
+     * and rounding have been applied by the number range formatting pipeline.
+     * 
+     * The syntax of the unformatted number is a "numeric string"
+     * as defined in the Decimal Arithmetic Specification, available at
+     * http://speleotrove.com/decimal
+     *
+     * @return A decimal representation of the second formatted number.
+     * @draft ICU 63
+     * @see NumberRangeFormatter
+     * @see #getFirstDecimal
+     */
+    UnicodeString getSecondDecimal(UErrorCode& status) const;
+#endif // U_HIDE_DRAFT_API
+
+    /**
+     * Returns whether the pair of numbers was successfully formatted as a range or whether an identity fallback was
+     * used. For example, if the first and second number were the same either before or after rounding occurred, an
+     * identity fallback was used.
+     *
+     * @return An indication the resulting identity situation in the formatted number range.
+     * @stable ICU 63
+     * @see UNumberRangeIdentityFallback
+     */
+    UNumberRangeIdentityResult getIdentityResult(UErrorCode& status) const;
+
+    /**
+     * Copying not supported; use move constructor instead.
+     */
+    FormattedNumberRange(const FormattedNumberRange&) = delete;
+
+    /**
+     * Copying not supported; use move assignment instead.
+     */
+    FormattedNumberRange& operator=(const FormattedNumberRange&) = delete;
+
+    /**
+     * Move constructor:
+     * Leaves the source FormattedNumberRange in an undefined state.
+     * @stable ICU 63
+     */
+    FormattedNumberRange(FormattedNumberRange&& src) U_NOEXCEPT;
+
+    /**
+     * Move assignment:
+     * Leaves the source FormattedNumberRange in an undefined state.
+     * @stable ICU 63
+     */
+    FormattedNumberRange& operator=(FormattedNumberRange&& src) U_NOEXCEPT;
+
+    /**
+     * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own.
+     * @stable ICU 63
+     */
+    ~FormattedNumberRange();
+
+  private:
+    // Can't use LocalPointer because UFormattedNumberRangeData is forward-declared
+    const impl::UFormattedNumberRangeData *fData;
+
+    // Error code for the terminal methods
+    UErrorCode fErrorCode;
+
+    /**
+     * Internal constructor from data type. Adopts the data pointer.
+     */
+    explicit FormattedNumberRange(impl::UFormattedNumberRangeData *results)
+        : fData(results), fErrorCode(U_ZERO_ERROR) {}
+
+    explicit FormattedNumberRange(UErrorCode errorCode)
+        : fData(nullptr), fErrorCode(errorCode) {}
+
+    void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
+
+    // To give LocalizedNumberRangeFormatter format methods access to this class's constructor:
+    friend class LocalizedNumberRangeFormatter;
+};
+
+/**
+ * See the main description in numberrangeformatter.h for documentation and examples.
+ *
+ * @stable ICU 63
+ */
+class U_I18N_API NumberRangeFormatter final {
+  public:
+    /**
+     * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is not currently
+     * known at the call site.
+     *
+     * @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
+     * @stable ICU 63
+     */
+    static UnlocalizedNumberRangeFormatter with();
+
+    /**
+     * Call this method at the beginning of a NumberRangeFormatter fluent chain in which the locale is known at the call
+     * site.
+     *
+     * @param locale
+     *            The locale from which to load formats and symbols for number range formatting.
+     * @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
+     * @stable ICU 63
+     */
+    static LocalizedNumberRangeFormatter withLocale(const Locale &locale);
+
+    /**
+     * Use factory methods instead of the constructor to create a NumberFormatter.
+     */
+    NumberRangeFormatter() = delete;
+};
+
+}  // namespace number
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif // __NUMBERRANGEFORMATTER_H__
+