// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#if !UCONFIG_NO_FORMATTING
#ifndef __NUMBERRANGEFORMATTER_H__
#define __NUMBERRANGEFORMATTER_H__

#include <atomic>
#include "unicode/appendable.h"
#include "unicode/fieldpos.h"
#include "unicode/formattedvalue.h"
#include "unicode/fpositer.h"
#include "unicode/numberformatter.h"

#ifndef U_HIDE_DRAFT_API

/**
 * \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.
 *
 * @draft 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.
     *
     * @draft ICU 63
     */
    UNUM_RANGE_COLLAPSE_AUTO,

    /**
     * Do not collapse any part of the number. Example: "3.2 thousand kilograms – 5.3 thousand kilograms"
     *
     * @draft 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"
     *
     * @draft 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"
     *
     * @draft 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.
 *
 * @draft ICU 63
 * @see NumberRangeFormatter
 */
typedef enum UNumberRangeIdentityFallback {
    /**
     * Show the number as a single value rather than a range. Example: "$5"
     *
     * @draft 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"
     *
     * @draft 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"
     *
     * @draft 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"
     *
     * @draft 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.
 *
 * @draft 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.
     *
     * @draft 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.
     *
     * @draft 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.
     *
     * @draft 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.
     * @draft 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
     * @draft 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
     * @draft 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
     * @draft 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.
     * @draft 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
     * @draft 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
     * @draft 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
     * @draft 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.
     * @draft 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
     * @draft 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
     * @draft 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
     * @draft 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.
     * @draft 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
     * @draft 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.
     * @draft 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
     * @draft 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.
     * @draft 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.
     * @draft 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)
     * @draft 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
 * @draft 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.
     * @draft 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
     * @draft ICU 63
     */
    LocalizedNumberRangeFormatter locale(const icu::Locale &locale) &&;

    /**
     * Default constructor: puts the formatter into a valid but undefined state.
     *
     * @draft ICU 63
     */
    UnlocalizedNumberRangeFormatter() = default;

    /**
     * Returns a copy of this UnlocalizedNumberRangeFormatter.
     * @draft ICU 63
     */
    UnlocalizedNumberRangeFormatter(const UnlocalizedNumberRangeFormatter &other);

    /**
     * Move constructor:
     * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
     * @draft ICU 63
     */
    UnlocalizedNumberRangeFormatter(UnlocalizedNumberRangeFormatter&& src) U_NOEXCEPT;

    /**
     * Copy assignment operator.
     * @draft ICU 63
     */
    UnlocalizedNumberRangeFormatter& operator=(const UnlocalizedNumberRangeFormatter& other);

    /**
     * Move assignment operator:
     * The source UnlocalizedNumberRangeFormatter will be left in a valid but undefined state.
     * @draft 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
 * @draft 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.
     * @draft ICU 63
     */
    FormattedNumberRange formatFormattableRange(
        const Formattable& first, const Formattable& second, UErrorCode& status) const;

    /**
     * Default constructor: puts the formatter into a valid but undefined state.
     *
     * @draft ICU 63
     */
    LocalizedNumberRangeFormatter() = default;

    /**
     * Returns a copy of this LocalizedNumberRangeFormatter.
     * @draft ICU 63
     */
    LocalizedNumberRangeFormatter(const LocalizedNumberRangeFormatter &other);

    /**
     * Move constructor:
     * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
     * @draft ICU 63
     */
    LocalizedNumberRangeFormatter(LocalizedNumberRangeFormatter&& src) U_NOEXCEPT;

    /**
     * Copy assignment operator.
     * @draft ICU 63
     */
    LocalizedNumberRangeFormatter& operator=(const LocalizedNumberRangeFormatter& other);

    /**
     * Move assignment operator:
     * The source LocalizedNumberRangeFormatter will be left in a valid but undefined state.
     * @draft 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

    /**
     * Destruct this LocalizedNumberRangeFormatter, cleaning up any memory it might own.
     * @draft 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.
 *
 * @draft 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()
     *
     * @draft 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()
     *
     * @draft 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;

    /**
     * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given
     * <em>field</em> in the output string. This allows you to determine the locations of, for example,
     * the integer part, fraction part, or symbols.
     *
     * If both sides of the range have the same field, the field will occur twice, once before the
     * range separator and once after the range separator, if applicable.
     *
     * If a field occurs just once, calling this method will find that occurrence and return it. If a
     * field occurs multiple times, this method may be called repeatedly with the following pattern:
     *
     * <pre>
     * FieldPosition fpos(UNUM_INTEGER_FIELD);
     * while (formattedNumberRange.nextFieldPosition(fpos, status)) {
     *   // do something with fpos.
     * }
     * </pre>
     *
     * This method is useful if you know which field to query. If you want all available field position
     * information, use #getAllFieldPositions().
     *
     * @param fieldPosition
     *            Input+output variable. See {@link FormattedNumber#nextFieldPosition}.
     * @param status
     *            Set if an error occurs while populating the FieldPosition.
     * @return TRUE if a new occurrence of the field was found; FALSE otherwise.
     * @draft ICU 63
     * @see UNumberFormatFields
     */
    UBool nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const;

    /**
     * Export the formatted number range to a FieldPositionIterator. This allows you to determine which characters in
     * the output string correspond to which <em>fields</em>, such as the integer part, fraction part, and sign.
     *
     * If information on only one field is needed, use #nextFieldPosition() instead.
     *
     * @param iterator
     *            The FieldPositionIterator to populate with all of the fields present in the formatted number.
     * @param status
     *            Set if an error occurs while populating the FieldPositionIterator.
     * @draft ICU 63
     * @see UNumberFormatFields
     */
    void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const;

    /**
     * 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;

    /**
     * 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.
     * @draft 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.
     * @draft ICU 63
     */
    FormattedNumberRange(FormattedNumberRange&& src) U_NOEXCEPT;

    /**
     * Move assignment:
     * Leaves the source FormattedNumberRange in an undefined state.
     * @draft ICU 63
     */
    FormattedNumberRange& operator=(FormattedNumberRange&& src) U_NOEXCEPT;

    /**
     * Destruct an instance of FormattedNumberRange, cleaning up any memory it might own.
     * @draft 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.
     * @internal
     */
    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.
 *
 * @draft 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.
     * @draft 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.
     * @draft 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  // U_HIDE_DRAFT_API

#endif // __NUMBERRANGEFORMATTER_H__

#endif /* #if !UCONFIG_NO_FORMATTING */
