]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/unicode/numberformatter.h
ICU-64232.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / unicode / numberformatter.h
index 3ab08319f73bc7ce93cfa0f58a06b9e2ed31f162..56c3a5a9d8ca4d3b4e6b87217fde2b357a4c5880 100644 (file)
 #include "unicode/dcfmtsym.h"
 #include "unicode/currunit.h"
 #include "unicode/fieldpos.h"
+#include "unicode/formattedvalue.h"
 #include "unicode/fpositer.h"
 #include "unicode/measunit.h"
 #include "unicode/nounit.h"
+#include "unicode/parseerr.h"
 #include "unicode/plurrule.h"
 #include "unicode/ucurr.h"
 #include "unicode/unum.h"
  *     .format(1234)
  *     .toString();  // €1.2K in en-US
  *
- * // Create a formatter in a singleton for use later:
+ * // Create a formatter in a singleton by value for use later:
  * static const LocalizedNumberFormatter formatter = NumberFormatter::withLocale(...)
  *     .unit(NoUnit::percent())
  *     .precision(Precision::fixedFraction(3));
  * formatter.format(5.9831).toString();  // 5.983% in en-US
  *
- * // Create a "template" in a singleton but without setting a locale until the call site:
- * static const UnlocalizedNumberFormatter template = NumberFormatter::with()
+ * // Create a "template" in a singleton unique_ptr but without setting a locale until the call site:
+ * std::unique_ptr<UnlocalizedNumberFormatter> template = NumberFormatter::with()
  *     .sign(UNumberSignDisplay::UNUM_SIGN_ALWAYS)
- *     .adoptUnit(MeasureUnit::createMeter(status))
- *     .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME);
- * template.locale(...).format(1234).toString();  // +1,234 meters in en-US
+ *     .unit(MeasureUnit::getMeter())
+ *     .unitWidth(UNumberUnitWidth::UNUM_UNIT_WIDTH_FULL_NAME)
+ *     .clone();
+ * template->locale(...).format(1234).toString();  // +1,234 meters in en-US
  * </pre>
  *
  * <p>
  * This API offers more features than DecimalFormat and is geared toward new users of ICU.
  *
  * <p>
- * NumberFormatter instances are immutable and thread safe. This means that invoking a configuration method has no
+ * NumberFormatter instances (i.e., LocalizedNumberFormatter and UnlocalizedNumberFormatter)
+ * are immutable and thread safe. This means that invoking a configuration method has no
  * effect on the receiving instance; you must store and use the new number formatter instance it returns instead.
  *
  * <pre>
@@ -108,6 +112,7 @@ class IntegerWidth;
 
 namespace impl {
 
+// can't be #ifndef U_HIDE_INTERNAL_API; referenced throughout this file in public classes
 /**
  * Datatype for minimum/maximum fraction digits. Must be able to hold kMaxIntFracSig.
  *
@@ -115,20 +120,21 @@ namespace impl {
  */
 typedef int16_t digits_t;
 
+// can't be #ifndef U_HIDE_INTERNAL_API; needed for struct initialization
 /**
  * Use a default threshold of 3. This means that the third time .format() is called, the data structures get built
  * using the "safe" code path. The first two calls to .format() will trigger the unsafe code path.
  *
  * @internal
  */
-static constexpr int32_t DEFAULT_THRESHOLD = 3;
+static constexpr int32_t kInternalDefaultThreshold = 3;
 
 // Forward declarations:
 class Padder;
 struct MacroProps;
 struct MicroProps;
 class DecimalQuantity;
-struct UFormattedNumberData;
+class UFormattedNumberData;
 class NumberFormatterImpl;
 struct ParsedPatternInfo;
 class ScientificModifier;
@@ -144,11 +150,32 @@ class MultiplierFormatHandler;
 class CurrencySymbols;
 class GeneratorHelpers;
 class DecNum;
+class NumberRangeFormatterImpl;
+struct RangeMacroProps;
+struct UFormattedNumberImpl;
+
+/**
+ * Used for NumberRangeFormatter and implemented in numrange_fluent.cpp.
+ * Declared here so it can be friended.
+ *
+ * @internal
+ */
+void touchRangeLocales(impl::RangeMacroProps& macros);
 
 } // namespace impl
 
-// Reserve extra names in case they are added as classes in the future:
+/**
+ * Extra name reserved in case it is needed in the future.
+ *
+ * @draft ICU 63
+ */
 typedef Notation CompactNotation;
+
+/**
+ * Extra name reserved in case it is needed in the future.
+ *
+ * @draft ICU 63
+ */
 typedef Notation SimpleNotation;
 
 /**
@@ -308,10 +335,15 @@ class U_I18N_API Notation : public UMemory {
 
     union NotationUnion {
         // For NTN_SCIENTIFIC
+        /** @internal */
         struct ScientificSettings {
+            /** @internal */
             int8_t fEngineeringInterval;
+            /** @internal */
             bool fRequireMinInt;
+            /** @internal */
             impl::digits_t fMinExponentDigits;
+            /** @internal */
             UNumberSignDisplay fExponentSignDisplay;
         } scientific;
 
@@ -407,17 +439,13 @@ class U_I18N_API ScientificNotation : public Notation {
     friend class impl::NumberPropertyMapper;
 };
 
-// Reserve extra names in case they are added as classes in the future:
+/**
+ * Extra name reserved in case it is needed in the future.
+ *
+ * @draft ICU 63
+ */
 typedef Precision SignificantDigitsPrecision;
 
-// Typedefs for ICU 60/61 compatibility.
-// These will be removed in ICU 64.
-// See http://bugs.icu-project.org/trac/ticket/13746
-typedef Precision Rounder;
-typedef FractionPrecision FractionRounder;
-typedef IncrementPrecision IncrementRounder;
-typedef CurrencyPrecision CurrencyRounder;
-
 /**
  * A class that defines the rounding precision to be used when formatting numbers in NumberFormatter.
  *
@@ -434,10 +462,11 @@ class U_I18N_API Precision : public UMemory {
      *
      * <p>
      * <strong>NOTE:</strong> When formatting a <em>double</em>, this method, along with {@link #minFraction} and
-     * {@link #minDigits}, will trigger complex algorithm similar to <em>Dragon4</em> to determine the low-order digits
-     * and the number of digits to display based on the value of the double. If the number of fraction places or
-     * significant digits can be bounded, consider using {@link #maxFraction} or {@link #maxDigits} instead to maximize
-     * performance. For more information, read the following blog post.
+     * {@link #minSignificantDigits}, will trigger complex algorithm similar to <em>Dragon4</em> to determine the
+     * low-order digits and the number of digits to display based on the value of the double.
+     * If the number of fraction places or significant digits can be bounded, consider using {@link #maxFraction}
+     * or {@link #maxSignificantDigits} instead to maximize performance.
+     * For more information, read the following blog post.
      *
      * <p>
      * http://www.serpentine.com/blog/2011/06/29/here-be-dragons-advances-in-problems-you-didnt-even-know-you-had/
@@ -531,7 +560,7 @@ class U_I18N_API Precision : public UMemory {
      * pad with zeros to ensure that this number of significant digits/figures are always shown.
      *
      * <p>
-     * This method is equivalent to {@link #minMaxDigits} with both arguments equal.
+     * This method is equivalent to {@link #minMaxSignificantDigits} with both arguments equal.
      *
      * @param minMaxSignificantDigits
      *            The minimum and maximum number of significant digits to display (rounding if too long or padding with
@@ -579,31 +608,6 @@ class U_I18N_API Precision : public UMemory {
     static SignificantDigitsPrecision minMaxSignificantDigits(int32_t minSignificantDigits,
                                                               int32_t maxSignificantDigits);
 
-#ifndef U_HIDE_DEPRECATED_API
-    // Compatiblity methods that will be removed in ICU 64.
-    // See http://bugs.icu-project.org/trac/ticket/13746
-
-    /** @deprecated ICU 62 */
-    static inline SignificantDigitsPrecision fixedDigits(int32_t a) {
-        return fixedSignificantDigits(a);
-    }
-
-    /** @deprecated ICU 62 */
-    static inline SignificantDigitsPrecision minDigits(int32_t a) {
-        return minSignificantDigits(a);
-    }
-
-    /** @deprecated ICU 62 */
-    static inline SignificantDigitsPrecision maxDigits(int32_t a) {
-        return maxSignificantDigits(a);
-    }
-
-    /** @deprecated ICU 62 */
-    static inline SignificantDigitsPrecision minMaxDigits(int32_t a, int32_t b) {
-        return minMaxSignificantDigits(a, b);
-    }
-#endif  /* U_HIDE_DEPRECATED_API */
-
     /**
      * Show numbers rounded if necessary to the closest multiple of a certain rounding increment. For example, if the
      * rounding increment is 0.5, then round 1.2 to 1 and round 1.3 to 1.5.
@@ -644,21 +648,6 @@ class U_I18N_API Precision : public UMemory {
      */
     static CurrencyPrecision currency(UCurrencyUsage currencyUsage);
 
-#ifndef U_HIDE_DEPRECATED_API
-    /**
-     * Sets the rounding mode to use when picking the direction to round (up or down). Common values
-     * include HALF_EVEN, HALF_UP, and FLOOR. The default is HALF_EVEN.
-     *
-     * @param roundingMode
-     *            The RoundingMode to use.
-     * @return A Precision for passing to the NumberFormatter precision() setter.
-     * @deprecated ICU 62 Use the top-level roundingMode() setting instead.
-     *            This method will be removed in ICU 64.
-     *            See http://bugs.icu-project.org/trac/ticket/13746
-     */
-    Precision withMode(UNumberFormatRoundingMode roundingMode) const;
-#endif  /* U_HIDE_DEPRECATED_API */
-
   private:
     enum PrecisionType {
         RND_BOGUS,
@@ -666,30 +655,63 @@ class U_I18N_API Precision : public UMemory {
         RND_FRACTION,
         RND_SIGNIFICANT,
         RND_FRACTION_SIGNIFICANT,
+
+        // Used for strange increments like 3.14.
         RND_INCREMENT,
+
+        // Used for increments with 1 as the only digit. This is different than fraction
+        // rounding because it supports having additional trailing zeros. For example, this
+        // class is used to round with the increment 0.010.
+        RND_INCREMENT_ONE,
+
+        // Used for increments with 5 as the only digit (nickel rounding).
+        RND_INCREMENT_FIVE,
+
         RND_CURRENCY,
+        RND_INCREMENT_SIGNIFICANT, // Apple addition rdar://52538227
         RND_ERROR
     } fType;
 
     union PrecisionUnion {
+        /** @internal */
         struct FractionSignificantSettings {
             // For RND_FRACTION, RND_SIGNIFICANT, and RND_FRACTION_SIGNIFICANT
+            /** @internal */
             impl::digits_t fMinFrac;
+            /** @internal */
             impl::digits_t fMaxFrac;
+            /** @internal */
             impl::digits_t fMinSig;
+            /** @internal */
             impl::digits_t fMaxSig;
         } fracSig;
+        /** @internal */
         struct IncrementSettings {
+            // For RND_INCREMENT, RND_INCREMENT_ONE, and RND_INCREMENT_FIVE
+            /** @internal */
             double fIncrement;
+            /** @internal */
             impl::digits_t fMinFrac;
+            /** @internal */
             impl::digits_t fMaxFrac;
-        } increment; // For RND_INCREMENT
+        } increment;
+        /** @internal */
+        struct IncrementSignificantSettings { // Apple addition rdar://52538227
+            // For  // Apple addition rdar://52538227
+            /** @internal */
+            double fIncrement;
+            /** @internal */
+            impl::digits_t fMinSig;
+            /** @internal */
+            impl::digits_t fMaxSig;
+        } incrSig;
         UCurrencyUsage currencyUsage; // For RND_CURRENCY
         UErrorCode errorCode; // For RND_ERROR
     } fUnion;
 
     typedef PrecisionUnion::FractionSignificantSettings FractionSignificantSettings;
     typedef PrecisionUnion::IncrementSettings IncrementSettings;
+    typedef PrecisionUnion::IncrementSignificantSettings IncrementSignificantSettings;
 
     /** The Precision encapsulates the RoundingMode when used within the implementation. */
     UNumberFormatRoundingMode fRoundingMode;
@@ -723,6 +745,8 @@ class U_I18N_API Precision : public UMemory {
 
     static Precision constructSignificant(int32_t minSig, int32_t maxSig);
 
+    static Precision constructIncrementSignificant(double increment, int32_t minSig, int32_t maxSig); // Apple
+
     static Precision
     constructFractionSignificant(const FractionPrecision &base, int32_t minSig, int32_t maxSig);
 
@@ -1132,6 +1156,13 @@ class U_I18N_API SymbolsWrapper : public UMemory {
 
 #ifndef U_HIDE_INTERNAL_API
 
+    /**
+     * Set whether DecimalFormatSymbols copy is deep (clone)
+     * or shallow (pointer copy). Apple <rdar://problem/49955427>
+     * @internal
+     */
+    void setDFSShallowCopy(UBool shallow);
+
     /**
      * The provided object is copied, but we do not adopt it.
      * @internal
@@ -1172,7 +1203,7 @@ class U_I18N_API SymbolsWrapper : public UMemory {
 
     /** @internal */
     UBool copyErrorTo(UErrorCode &status) const {
-        if (fType == SYMPTR_DFS && fPtr.dfs == nullptr) {
+        if ((fType == SYMPTR_DFS || fType == SYMPTR_DFS_SHALLOWCOPY) && fPtr.dfs == nullptr) {
             status = U_MEMORY_ALLOCATION_ERROR;
             return TRUE;
         } else if (fType == SYMPTR_NS && fPtr.ns == nullptr) {
@@ -1184,7 +1215,7 @@ class U_I18N_API SymbolsWrapper : public UMemory {
 
   private:
     enum SymbolsPointerType {
-        SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS
+        SYMPTR_NONE, SYMPTR_DFS, SYMPTR_NS, SYMPTR_DFS_SHALLOWCOPY // Apple <rdar://problem/49955427> add SHALLOWCOPY
     } fType;
 
     union {
@@ -1205,7 +1236,7 @@ class U_I18N_API Grouper : public UMemory {
   public:
 #ifndef U_HIDE_INTERNAL_API
     /** @internal */
-    static Grouper forStrategy(UGroupingStrategy grouping);
+    static Grouper forStrategy(UNumberGroupingStrategy grouping);
 
     /**
      * Resolve the values in Properties to a Grouper object.
@@ -1216,7 +1247,7 @@ class U_I18N_API Grouper : public UMemory {
     // Future: static Grouper forProperties(DecimalFormatProperties& properties);
 
     /** @internal */
-    Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UGroupingStrategy strategy)
+    Grouper(int16_t grouping1, int16_t grouping2, int16_t minGrouping, UNumberGroupingStrategy strategy)
             : fGrouping1(grouping1),
               fGrouping2(grouping2),
               fMinGrouping(minGrouping),
@@ -1251,12 +1282,12 @@ class U_I18N_API Grouper : public UMemory {
     int16_t fMinGrouping;
 
     /**
-     * The UGroupingStrategy that was used to create this Grouper, or UNUM_GROUPING_COUNT if this
-     * was not created from a UGroupingStrategy.
+     * The UNumberGroupingStrategy that was used to create this Grouper, or UNUM_GROUPING_COUNT if this
+     * was not created from a UNumberGroupingStrategy.
      */
-    UGroupingStrategy fStrategy;
+    UNumberGroupingStrategy fStrategy;
 
-    Grouper() : fGrouping1(-3) {};
+    Grouper() : fGrouping1(-3) {}
 
     bool isBogus() const {
         return fGrouping1 == -3;
@@ -1401,7 +1432,10 @@ struct U_I18N_API MacroProps : public UMemory {
     const CurrencySymbols* currencySymbols = nullptr;  // no ownership
 
     /** @internal */
-    int32_t threshold = DEFAULT_THRESHOLD;
+    int32_t threshold = kInternalDefaultThreshold;
+
+    /** @internal Apple addition for <rdar://problem/39240173> */
+    bool adjustDoublePrecision = false;
 
     /** @internal */
     Locale locale;
@@ -1423,7 +1457,8 @@ struct U_I18N_API MacroProps : public UMemory {
 
 /**
  * An abstract base class for specifying settings related to number formatting. This class is implemented by
- * {@link UnlocalizedNumberFormatter} and {@link LocalizedNumberFormatter}.
+ * {@link UnlocalizedNumberFormatter} and {@link LocalizedNumberFormatter}. This class is not intended for
+ * public subclassing.
  */
 template<typename Derived>
 class U_I18N_API NumberFormatterSettings {
@@ -1481,11 +1516,10 @@ class U_I18N_API NumberFormatterSettings {
      * All units will be properly localized with locale data, and all units are compatible with notation styles,
      * rounding precisions, and other number formatter settings.
      *
-     * Pass this method any instance of {@link MeasureUnit}. For units of measure (which often involve the
-     * factory methods that return a pointer):
+     * Pass this method any instance of {@link MeasureUnit}. For units of measure:
      *
      * <pre>
-     * NumberFormatter::with().adoptUnit(MeasureUnit::createMeter(status))
+     * NumberFormatter::with().unit(MeasureUnit::getMeter())
      * </pre>
      *
      * Currency:
@@ -1528,11 +1562,9 @@ class U_I18N_API NumberFormatterSettings {
 
     /**
      * Like unit(), but takes ownership of a pointer.  Convenient for use with the MeasureFormat factory
-     * methods, which return pointers that need ownership.  Example:
+     * methods that return pointers that need ownership.
      *
-     * <pre>
-     * NumberFormatter::with().adoptUnit(MeasureUnit::createMeter(status))
-     * </pre>
+     * Note: consider using the MeasureFormat factory methods that return by value.
      *
      * @param unit
      *            The unit to render.
@@ -1558,8 +1590,13 @@ class U_I18N_API NumberFormatterSettings {
      * Sets a unit to be used in the denominator. For example, to format "3 m/s", pass METER to the unit and SECOND to
      * the perUnit.
      *
-     * Pass this method any instance of {@link MeasureUnit}.  Since MeasureUnit factory methods return pointers, the
-     * {@link #adoptPerUnit} version of this method is often more useful.
+     * Pass this method any instance of {@link MeasureUnit}. Example:
+     *
+     * <pre>
+     * NumberFormatter::with()
+     *      .unit(MeasureUnit::getMeter())
+     *      .perUnit(MeasureUnit::getSecond())
+     * </pre>
      *
      * The default is not to display any unit in the denominator.
      *
@@ -1586,13 +1623,9 @@ class U_I18N_API NumberFormatterSettings {
 
     /**
      * Like perUnit(), but takes ownership of a pointer.  Convenient for use with the MeasureFormat factory
-     * methods, which return pointers that need ownership.  Example:
+     * methods that return pointers that need ownership.
      *
-     * <pre>
-     * NumberFormatter::with()
-     *      .adoptUnit(MeasureUnit::createMeter(status))
-     *      .adoptPerUnit(MeasureUnit::createSecond(status))
-     * </pre>
+     * Note: consider using the MeasureFormat factory methods that return by value.
      *
      * @param perUnit
      *            The unit to render in the denominator.
@@ -1657,16 +1690,6 @@ class U_I18N_API NumberFormatterSettings {
      */
     Derived precision(const Precision& precision) &&;
 
-#ifndef U_HIDE_DEPRECATED_API
-    // Compatibility method that will be removed in ICU 64.
-    // Use precision() instead.
-    // See http://bugs.icu-project.org/trac/ticket/13746
-    /** @deprecated ICU 62 */
-    Derived rounding(const Rounder& rounder) const & {
-        return precision(rounder);
-    }
-#endif  /* U_HIDE_DEPRECATED_API */
-
     /**
      * Specifies how to determine the direction to round a number when it has more digits than fit in the
      * desired precision.  When formatting 1.235:
@@ -1710,7 +1733,7 @@ class U_I18N_API NumberFormatterSettings {
      * The exact grouping widths will be chosen based on the locale.
      *
      * <p>
-     * Pass this method an element from the {@link UGroupingStrategy} enum. For example:
+     * Pass this method an element from the {@link UNumberGroupingStrategy} enum. For example:
      *
      * <pre>
      * NumberFormatter::with().grouping(UNUM_GROUPING_MIN2)
@@ -1724,7 +1747,7 @@ class U_I18N_API NumberFormatterSettings {
      * @return The fluent chain.
      * @draft ICU 61
      */
-    Derived grouping(UGroupingStrategy strategy) const &;
+    Derived grouping(UNumberGroupingStrategy strategy) const &;
 
     /**
      * Overload of grouping() for use on an rvalue reference.
@@ -1733,10 +1756,9 @@ class U_I18N_API NumberFormatterSettings {
      *            The grouping strategy to use.
      * @return The fluent chain.
      * @see #grouping
-     * @provisional This API might change or be removed in a future release.
      * @draft ICU 62
      */
-    Derived grouping(UGroupingStrategy strategy) &&;
+    Derived grouping(UNumberGroupingStrategy strategy) &&;
 
     /**
      * Specifies the minimum and maximum number of digits to render before the decimal mark.
@@ -1748,7 +1770,7 @@ class U_I18N_API NumberFormatterSettings {
      * </ul>
      *
      * <p>
-     * Pass this method the return value of {@link IntegerWidth#zeroFillTo(int)}. For example:
+     * Pass this method the return value of {@link IntegerWidth#zeroFillTo}. For example:
      *
      * <pre>
      * NumberFormatter::with().integerWidth(IntegerWidth::zeroFillTo(2))
@@ -2082,6 +2104,28 @@ class U_I18N_API NumberFormatterSettings {
      */
     UnicodeString toSkeleton(UErrorCode& status) const;
 
+    /**
+     * Returns the current (Un)LocalizedNumberFormatter 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)LocalizedNumberFormatter 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)LocalizedNumberFormatter 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.
@@ -2095,24 +2139,29 @@ class U_I18N_API NumberFormatterSettings {
         }
         fMacros.copyErrorTo(outErrorCode);
         return U_FAILURE(outErrorCode);
-    };
+    }
 
     // NOTE: Uses default copy and move constructors.
 
-  protected:
+  private:
     impl::MacroProps fMacros;
 
-  private:
     // Don't construct me directly!  Use (Un)LocalizedNumberFormatter.
     NumberFormatterSettings() = default;
 
     friend class LocalizedNumberFormatter;
     friend class UnlocalizedNumberFormatter;
+
+    // Give NumberRangeFormatter access to the MacroProps
+    friend void impl::touchRangeLocales(impl::RangeMacroProps& macros);
+    friend class impl::NumberRangeFormatterImpl;
 };
 
 /**
  * A NumberFormatter that does not yet have a locale. In order to format numbers, a locale must be specified.
  *
+ * Instances of this class are immutable and thread-safe.
+ *
  * @see NumberFormatter
  * @draft ICU 60
  */
@@ -2124,13 +2173,6 @@ class U_I18N_API UnlocalizedNumberFormatter
      * Associate the given locale with the number formatter. The locale is used for picking the appropriate symbols,
      * formats, and other data for number display.
      *
-     * <p>
-     * To use the Java default locale, call Locale::getDefault():
-     *
-     * <pre>
-     * NumberFormatter::with(). ... .locale(Locale::getDefault())
-     * </pre>
-     *
      * @param locale
      *            The locale to use when loading data for number formatting.
      * @return The fluent chain.
@@ -2156,7 +2198,6 @@ class U_I18N_API UnlocalizedNumberFormatter
      */
     UnlocalizedNumberFormatter() = default;
 
-    // Make default copy constructor call the NumberFormatterSettings copy constructor.
     /**
      * Returns a copy of this UnlocalizedNumberFormatter.
      * @draft ICU 60
@@ -2199,6 +2240,8 @@ class U_I18N_API UnlocalizedNumberFormatter
 /**
  * A NumberFormatter that has a locale associated with it; this means .format() methods are available.
  *
+ * Instances of this class are immutable and thread-safe.
+ *
  * @see NumberFormatter
  * @draft ICU 60
  */
@@ -2249,6 +2292,13 @@ class U_I18N_API LocalizedNumberFormatter
 
 #ifndef U_HIDE_INTERNAL_API
 
+    /**
+     * Set whether DecimalFormatSymbols copy is deep (clone)
+     * or shallow (pointer copy). Apple <rdar://problem/49955427>
+     * @internal
+     */
+    void setDFSShallowCopy(UBool shallow);
+
     /** Internal method.
      * @internal
      */
@@ -2271,7 +2321,7 @@ class U_I18N_API LocalizedNumberFormatter
      */
     int32_t getCallCount() const;
 
-#endif
+#endif  /* U_HIDE_INTERNAL_API */
 
     /**
      * Creates a representation of this LocalizedNumberFormat as an icu::Format, enabling the use
@@ -2295,7 +2345,6 @@ class U_I18N_API LocalizedNumberFormatter
      */
     LocalizedNumberFormatter() = default;
 
-    // Make default copy constructor call the NumberFormatterSettings copy constructor.
     /**
      * Returns a copy of this LocalizedNumberFormatter.
      * @draft ICU 60
@@ -2333,11 +2382,12 @@ class U_I18N_API LocalizedNumberFormatter
      *
      * @param results
      *            The results object. This method will mutate it to save the results.
+     * @param status
      * @internal
      */
     void formatImpl(impl::UFormattedNumberData *results, UErrorCode &status) const;
 
-#endif
+#endif  /* U_HIDE_INTERNAL_API */
 
     /**
      * Destruct this LocalizedNumberFormatter, cleaning up any memory it might own.
@@ -2359,6 +2409,8 @@ class U_I18N_API LocalizedNumberFormatter
 
     LocalizedNumberFormatter(impl::MacroProps &&macros, const Locale &locale);
 
+    void clear();
+
     void lnfMoveHelper(LocalizedNumberFormatter&& src);
 
     /**
@@ -2378,88 +2430,78 @@ class U_I18N_API LocalizedNumberFormatter
  * The result of a number 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 60
  */
-class U_I18N_API FormattedNumber : public UMemory {
+class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
   public:
-#ifndef U_HIDE_DEPRECATED_API
+
     /**
-     * Returns a UnicodeString representation of the formatted number.
-     *
-     * @return a UnicodeString containing the localized number.
-     * @deprecated ICU 62 Use the version of this method with an error code instead.
-     *                This method was never @stable and will be removed in a future release.
-     *                See http://bugs.icu-project.org/trac/ticket/13746
+     * Default constructor; makes an empty FormattedNumber.
+     * @draft ICU 64
      */
-    UnicodeString toString() const;
-#endif  /* U_HIDE_DEPRECATED_API */
+    FormattedNumber()
+        : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
 
     /**
-     * Returns a UnicodeString representation of the formatted number.
-     *
-     * @param status
-     *            Set if an error occurs while formatting the number to the UnicodeString.
-     * @return a UnicodeString containing the localized number.
+     * Move constructor: Leaves the source FormattedNumber in an undefined state.
      * @draft ICU 62
      */
-    UnicodeString toString(UErrorCode& status) const;
+    FormattedNumber(FormattedNumber&& src) U_NOEXCEPT;
 
-#ifndef U_HIDE_DEPRECATED_API
     /**
-     * Appends the formatted number to an Appendable.
-     *
-     * @param appendable
-     *            The Appendable to which to append the formatted number string.
-     * @return The same Appendable, for chaining.
-     * @deprecated ICU 62 Use the version of this method with an error code instead.
-     *                This method was never @stable and will be removed in a future release.
-     *                See http://bugs.icu-project.org/trac/ticket/13746
-     * @see Appendable
+     * Destruct an instance of FormattedNumber.
+     * @draft ICU 60
      */
-    Appendable &appendTo(Appendable &appendable);
-#endif  /* U_HIDE_DEPRECATED_API */
+    virtual ~FormattedNumber() U_OVERRIDE;
+
+    /** Copying not supported; use move constructor instead. */
+    FormattedNumber(const FormattedNumber&) = delete;
+
+    /** Copying not supported; use move assignment instead. */
+    FormattedNumber& operator=(const FormattedNumber&) = delete;
 
     /**
-     * Appends the formatted number to an Appendable.
-     *
-     * @param appendable
-     *            The Appendable to which to append the formatted number string.
-     * @param status
-     *            Set if an error occurs while formatting the number to the Appendable.
-     * @return The same Appendable, for chaining.
+     * Move assignment: Leaves the source FormattedNumber in an undefined state.
      * @draft ICU 62
-     * @see Appendable
      */
-    Appendable &appendTo(Appendable &appendable, UErrorCode& status);
+    FormattedNumber& operator=(FormattedNumber&& src) U_NOEXCEPT;
 
-#ifndef U_HIDE_DEPRECATED_API
+    // Copybrief: this method is older than the parent method
     /**
-     * Determine the start and end indices of the first occurrence of the given <em>field</em> in the output string.
-     * This allows you to determine the locations of the integer part, fraction part, and sign.
+     * @copybrief FormattedValue::toString()
      *
-     * <p>
-     * If multiple different field attributes are needed, this method can be called repeatedly, or if <em>all</em> field
-     * attributes are needed, consider using populateFieldPositionIterator().
+     * For more information, see FormattedValue::toString()
      *
-     * <p>
-     * If a field occurs multiple times in an output string, such as a grouping separator, this method will only ever
-     * return the first occurrence. Use populateFieldPositionIterator() to access all occurrences of an attribute.
+     * @draft ICU 62
+     */
+    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()
      *
-     * @param fieldPosition
-     *            The FieldPosition to populate with the start and end indices of the desired field.
-     * @param status
-     *            Set if an error occurs while populating the FieldPosition.
-     * @deprecated ICU 62 Use {@link #nextFieldPosition} instead. This method will be removed in a future
-     *             release. See http://bugs.icu-project.org/trac/ticket/13746
-     * @see UNumberFormatFields
+     * For more information, see FormattedValue::appendTo()
+     *
+     * @draft ICU 62
      */
-    void populateFieldPosition(FieldPosition &fieldPosition, UErrorCode &status);
-#endif  /* U_HIDE_DEPRECATED_API */
+    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 and end 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.
+     * 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.
+     *
+     * This is a simpler but less powerful alternative to {@link #nextPosition}.
      *
      * 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:
@@ -2472,13 +2514,13 @@ class U_I18N_API FormattedNumber : public UMemory {
      * </pre>
      *
      * This method is useful if you know which field to query. If you want all available field position
-     * information, use #getAllFieldPositions().
+     * information, use {@link #nextPosition} or {@link #getAllFieldPositions}.
      *
      * @param fieldPosition
      *            Input+output variable. On input, the "field" property determines which field to look
      *            up, and the "beginIndex" and "endIndex" properties determine where to begin the search.
      *            On output, the "beginIndex" is set to the beginning of the first occurrence of the
-     *            field with either begin or end indices after the input indices, "endIndex" is set to
+     *            field with either begin or end indices after the input indices; "endIndex" is set to
      *            the end of that occurrence of the field (exclusive index). If a field position is not
      *            found, the method returns FALSE and the FieldPosition may or may not be changed.
      * @param status
@@ -2489,30 +2531,13 @@ class U_I18N_API FormattedNumber : public UMemory {
      */
     UBool nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const;
 
-#ifndef U_HIDE_DEPRECATED_API
     /**
      * Export the formatted number 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.
      *
-     * <p>
-     * If information on only one field is needed, consider using populateFieldPosition() 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.
-     * @deprecated ICU 62 Use {@link #getAllFieldPositions} instead. This method will be removed in a
-     *             future release. See http://bugs.icu-project.org/trac/ticket/13746
-     * @see UNumberFormatFields
-     */
-    void populateFieldPositionIterator(FieldPositionIterator &iterator, UErrorCode &status);
-#endif  /* U_HIDE_DEPRECATED_API */
-
-    /**
-     * Export the formatted number 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.
+     * This is an alternative to the more powerful #nextPosition() API.
      *
-     * If information on only one field is needed, use #nextFieldPosition() instead.
+     * If information on only one field is needed, use #nextPosition() or #nextFieldPosition() instead.
      *
      * @param iterator
      *            The FieldPositionIterator to populate with all of the fields present in the formatted number.
@@ -2537,41 +2562,11 @@ class U_I18N_API FormattedNumber : public UMemory {
      */
     void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
 
-#endif
-
-    /**
-     * Copying not supported; use move constructor instead.
-     */
-    FormattedNumber(const FormattedNumber&) = delete;
-
-    /**
-     * Copying not supported; use move assignment instead.
-     */
-    FormattedNumber& operator=(const FormattedNumber&) = delete;
-
-    /**
-     * Move constructor:
-     * Leaves the source FormattedNumber in an undefined state.
-     * @draft ICU 62
-     */
-    FormattedNumber(FormattedNumber&& src) U_NOEXCEPT;
-
-    /**
-     * Move assignment:
-     * Leaves the source FormattedNumber in an undefined state.
-     * @draft ICU 62
-     */
-    FormattedNumber& operator=(FormattedNumber&& src) U_NOEXCEPT;
-
-    /**
-     * Destruct an instance of FormattedNumber, cleaning up any memory it might own.
-     * @draft ICU 60
-     */
-    ~FormattedNumber();
+#endif  /* U_HIDE_INTERNAL_API */
 
   private:
     // Can't use LocalPointer because UFormattedNumberData is forward-declared
-    const impl::UFormattedNumberData *fResults;
+    const impl::UFormattedNumberData *fData;
 
     // Error code for the terminal methods
     UErrorCode fErrorCode;
@@ -2581,13 +2576,16 @@ class U_I18N_API FormattedNumber : public UMemory {
      * @internal
      */
     explicit FormattedNumber(impl::UFormattedNumberData *results)
-        : fResults(results), fErrorCode(U_ZERO_ERROR) {};
+        : fData(results), fErrorCode(U_ZERO_ERROR) {}
 
     explicit FormattedNumber(UErrorCode errorCode)
-        : fResults(nullptr), fErrorCode(errorCode) {};
+        : fData(nullptr), fErrorCode(errorCode) {}
 
     // To give LocalizedNumberFormatter format methods access to this class's constructor:
     friend class LocalizedNumberFormatter;
+
+    // To give C API access to internals
+    friend struct impl::UFormattedNumberImpl;
 };
 
 /**
@@ -2621,6 +2619,9 @@ class U_I18N_API NumberFormatter final {
      * Call this method at the beginning of a NumberFormatter fluent chain to create an instance based
      * on a given number skeleton string.
      *
+     * It is possible for an error to occur while parsing. See the overload of this method if you are
+     * interested in the location of a possible parse error.
+     *
      * @param skeleton
      *            The skeleton string off of which to base this NumberFormatter.
      * @param status
@@ -2630,6 +2631,26 @@ class U_I18N_API NumberFormatter final {
      */
     static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton, UErrorCode& status);
 
+    /**
+     * Call this method at the beginning of a NumberFormatter fluent chain to create an instance based
+     * on a given number skeleton string.
+     *
+     * If an error occurs while parsing the skeleton string, the offset into the skeleton string at
+     * which the error occurred will be saved into the UParseError, if provided.
+     *
+     * @param skeleton
+     *            The skeleton string off of which to base this NumberFormatter.
+     * @param perror
+     *            A parse error struct populated if an error occurs when parsing.
+ *                If no error occurs, perror.offset will be set to -1.
+     * @param status
+     *            Set to U_NUMBER_SKELETON_SYNTAX_ERROR if the skeleton was invalid.
+     * @return An UnlocalizedNumberFormatter, to be used for chaining.
+     * @draft ICU 64
+     */
+    static UnlocalizedNumberFormatter forSkeleton(const UnicodeString& skeleton,
+                                                  UParseError& perror, UErrorCode& status);
+
     /**
      * Use factory methods instead of the constructor to create a NumberFormatter.
      */