]> granicus.if.org Git - icu/commitdiff
ICU-11276 Wiring new NumberRangeFormatterImpl code into the API.
authorShane Carr <shane@unicode.org>
Thu, 6 Sep 2018 01:37:48 +0000 (18:37 -0700)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:40 +0000 (14:27 -0700)
icu4c/source/i18n/number_fluent.cpp
icu4c/source/i18n/number_formatimpl.cpp
icu4c/source/i18n/number_formatimpl.h
icu4c/source/i18n/numrange_fluent.cpp
icu4c/source/i18n/numrange_impl.cpp
icu4c/source/i18n/numrange_impl.h
icu4c/source/i18n/unicode/numberformatter.h
icu4c/source/i18n/unicode/numberrangeformatter.h
icu4c/source/test/intltest/numbertest_range.cpp

index cc2431cf72c7c9e558cb03028d419aa75cf4cf62..198c7caee0f0e0a6b41c9edc386d0b528d5b7bfe 100644 (file)
@@ -706,7 +706,11 @@ bool LocalizedNumberFormatter::computeCompiled(UErrorCode& status) const {
 
     if (currentCount == fMacros.threshold && fMacros.threshold > 0) {
         // Build the data structure and then use it (slow to fast path).
-        const NumberFormatterImpl* compiled = NumberFormatterImpl::fromMacros(fMacros, status);
+        const NumberFormatterImpl* compiled = new NumberFormatterImpl(fMacros, status);
+        if (compiled == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return false;
+        }
         U_ASSERT(fCompiled == nullptr);
         const_cast<LocalizedNumberFormatter*>(this)->fCompiled = compiled;
         umtx_storeRelease(*callCount, INT32_MIN);
index 183fe214ecfa0c410594e7f1f258ec5dfb2e8aed..d84ba2cfead78d8314a8854ade6d22de507a8a90 100644 (file)
@@ -67,8 +67,8 @@ getCurrencyFormatInfo(const Locale& locale, const char* isoCode, UErrorCode& sta
 MicroPropsGenerator::~MicroPropsGenerator() = default;
 
 
-NumberFormatterImpl* NumberFormatterImpl::fromMacros(const MacroProps& macros, UErrorCode& status) {
-    return new NumberFormatterImpl(macros, true, status);
+NumberFormatterImpl::NumberFormatterImpl(const MacroProps& macros, UErrorCode& status)
+    : NumberFormatterImpl(macros, true, status) {
 }
 
 void NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuantity& inValue,
index e8f0fc3f747ba10b76c34b1c78e031f59f167b75..9b89e5b88e61de04ab31677143f509b18c3b8eae 100644 (file)
@@ -29,7 +29,7 @@ class NumberFormatterImpl : public UMemory {
      * Builds a "safe" MicroPropsGenerator, which is thread-safe and can be used repeatedly.
      * The caller owns the returned NumberFormatterImpl.
      */
-    static NumberFormatterImpl *fromMacros(const MacroProps &macros, UErrorCode &status);
+    NumberFormatterImpl(const MacroProps &macros, UErrorCode &status);
 
     /**
      * Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper but can be used only once.
index 6a2704e5fdf34e0d6305a621b0afbd4ba8174cc5..0deb352055e2b1f3c8363439bef78b1ba01f34ca 100644 (file)
@@ -228,7 +228,7 @@ FormattedNumberRange LocalizedNumberRangeFormatter::formatFormattableRange(
         return FormattedNumberRange(status);
     }
 
-    formatImpl(results, status);
+    formatImpl(*results, first == second, status);
 
     // Do not save the results object if we encountered a failure.
     if (U_SUCCESS(status)) {
@@ -240,35 +240,20 @@ FormattedNumberRange LocalizedNumberRangeFormatter::formatFormattableRange(
 }
 
 void LocalizedNumberRangeFormatter::formatImpl(
-        UFormattedNumberRangeData* results, UErrorCode& status) const {
-
-    MicroProps microsFirst;
-    MicroProps microsSecond;
-
-    UFormattedNumberData r1;
-    r1.quantity = results->quantity1;
-    fMacros.formatter1.locale(fMacros.locale).formatImpl(&r1, status);
-    if (U_FAILURE(status)) {
-        return;
+        UFormattedNumberRangeData& results, bool equalBeforeRounding, UErrorCode& status) const {
+    if (fImpl == nullptr) {
+        // TODO: Fix this once the atomic is ready!
+        auto* nonConstThis = const_cast<LocalizedNumberRangeFormatter*>(this);
+        nonConstThis->fImpl = new NumberRangeFormatterImpl(fMacros, status);
+        if (U_FAILURE(status)) {
+            return;
+        }
+        if (fImpl == nullptr) {
+            status = U_MEMORY_ALLOCATION_ERROR;
+            return;
+        }
     }
-    results->quantity1 = r1.quantity;
-
-    UFormattedNumberData r2;
-    r2.quantity = results->quantity2;
-    fMacros.formatter2.locale(fMacros.locale).formatImpl(&r2, status);
-    if (U_FAILURE(status)) {
-        return;
-    }
-    results->quantity2 = r2.quantity;
-
-    results->string.append(r1.string, status);
-    results->string.append(u" --- ", UNUM_FIELD_COUNT, status);
-    results->string.append(r2.string, status);
-    if (U_FAILURE(status)) {
-        return;
-    }
-
-    results->identityResult = UNUM_IDENTITY_RESULT_NOT_EQUAL;
+    fImpl->format(results, equalBeforeRounding, status);
 }
 
 
index 42476bed993328ac113ef05db65eea4912f5fabb..f2da9b7043813b2f8029f396b30f5d3deb9873dc 100644 (file)
@@ -9,6 +9,7 @@
 // Helpful in toString methods and elsewhere.
 #define UNISTR_FROM_STRING_EXPLICIT
 
+#include "unicode/numberrangeformatter.h"
 #include "numrange_impl.h"
 
 using namespace icu;
@@ -24,6 +25,15 @@ constexpr int8_t identity2d(UNumberIdentityFallback a, UNumberRangeIdentityResul
 
 } // namespace
 
+
+NumberRangeFormatterImpl::NumberRangeFormatterImpl(const RangeMacroProps& macros, UErrorCode& status)
+    : formatterImpl1(macros.formatter1.fMacros, status),
+      formatterImpl2(macros.formatter2.fMacros, status),
+      fSameFormatters(true), // FIXME
+      fCollapse(macros.collapse),
+      fIdentityFallback(macros.identityFallback) {
+}
+
 void NumberRangeFormatterImpl::format(UFormattedNumberRangeData& data, bool equalBeforeRounding, UErrorCode& status) const {
     if (U_FAILURE(status)) {
         return;
@@ -199,7 +209,7 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data,
     // TODO: Use localized pattern
     lengthShared += string.insert(UPRV_INDEX_0, u" --- ", UNUM_FIELD_COUNT, status);
     length1 += NumberFormatterImpl::writeNumber(micros1, data.quantity1, string, UPRV_INDEX_0, status);
-    length2 += NumberFormatterImpl::writeNumber(micros2, data.quantity2, string, UPRV_INDEX_0, status);
+    length2 += NumberFormatterImpl::writeNumber(micros2, data.quantity2, string, UPRV_INDEX_2, status);
 
     // TODO: Support padding?
 
index d05ea85003773788d417bc42389744169e1ccc58..8a478abe29a17564cec59810b794382619b9727c 100644 (file)
@@ -45,6 +45,8 @@ struct UFormattedNumberRangeData : public UMemory {
 
 class NumberRangeFormatterImpl : public UMemory {
   public:
+    NumberRangeFormatterImpl(const RangeMacroProps& macros, UErrorCode& status);
+
     void format(UFormattedNumberRangeData& data, bool equalBeforeRounding, UErrorCode& status) const;
 
   private:
index 57bc1f30345216c338b0f33cb712d5eaf04d6a15..2a9743e6bd5b42f12e97478bfa538b1315e46230 100644 (file)
@@ -2110,6 +2110,9 @@ class U_I18N_API NumberFormatterSettings {
 
     friend class LocalizedNumberFormatter;
     friend class UnlocalizedNumberFormatter;
+
+    // Give NumberRangeFormatter access to the MacroProps
+    friend class impl::NumberRangeFormatterImpl;
 };
 
 /**
@@ -2189,9 +2192,6 @@ class U_I18N_API UnlocalizedNumberFormatter
 
     // To give NumberFormatter::with() access to this class's constructor:
     friend class NumberFormatter;
-
-    // Give NumberRangeFormatter access to the MacroProps
-    friend class NumberRangeFormatterImpl;
 };
 
 /**
index 208e533e22cb47a42346d6b479159d27ae5f7ede..7f4000f442340d6cf5dedc00d35bdd43c492fa0b 100644 (file)
@@ -175,6 +175,7 @@ namespace impl {
 struct RangeMacroProps;
 class DecimalQuantity;
 struct UFormattedNumberRangeData;
+class NumberRangeFormatterImpl;
 
 } // namespace impl
 
@@ -598,7 +599,8 @@ class U_I18N_API LocalizedNumberRangeFormatter
      *            Set if an error occurs while formatting.
      * @internal
      */
-    void formatImpl(impl::UFormattedNumberRangeData* results, UErrorCode& status) const;
+    void formatImpl(impl::UFormattedNumberRangeData& results, bool equalBeforeRounding,
+                    UErrorCode& status) const;
 
 #endif
 
@@ -609,6 +611,8 @@ class U_I18N_API LocalizedNumberRangeFormatter
     ~LocalizedNumberRangeFormatter();
 
   private:
+    // TODO: This is not thread-safe! Do NOT check this in without an atomic here.
+    impl::NumberRangeFormatterImpl* fImpl = nullptr;
 
     explicit LocalizedNumberRangeFormatter(
         const NumberRangeFormatterSettings<LocalizedNumberRangeFormatter>& other);
index 3370edc5301af611760618dfee12bb1647f68fb4..9e47bab6e98af96a0f0909677065933346b306bb 100644 (file)
@@ -38,14 +38,14 @@ void NumberRangeFormatterTest::testBasic() {
         NumberRangeFormatter::with(),
         Locale("en-us"),
         u"1 --- 5",
-        u"5 --- 5",
-        u"5 --- 5",
+        u"~5",
+        u"~5",
         u"0 --- 3",
-        u"0 --- 0",
+        u"~0",
         u"3 --- 3,000",
         u"3,000 --- 5,000",
         u"4,999 --- 5,001",
-        u"5,000 --- 5,000",
+        u"~5,000",
         u"5,000 --- 5,000,000");
 }