]> granicus.if.org Git - icu/commitdiff
ICU-22056 Add a new unum_hasAttribute() method.
authorRich Gillam <62772518+richgillam@users.noreply.github.com>
Thu, 14 Jul 2022 00:43:27 +0000 (17:43 -0700)
committerRich Gillam <62772518+richgillam@users.noreply.github.com>
Fri, 15 Jul 2022 23:03:56 +0000 (16:03 -0700)
icu4c/source/i18n/unicode/unum.h
icu4c/source/i18n/unum.cpp
icu4c/source/test/cintltst/cnumtst.c

index 863695591ab2a5a74f425c360a604ea7b26e0eb0..bdc5fafe5dd00bc254454191db3f171ac51f2446 100644 (file)
@@ -1161,6 +1161,26 @@ typedef enum UNumberFormatAttribute {
 
 } UNumberFormatAttribute;
 
+#ifndef U_HIDE_DRAFT_API
+/**
+* Returns true if the formatter supports the specified attribute and false if not.
+* @param fmt The formatter to query.
+* @param attr The attribute to query.  This can be any value of UNumberFormatterAttribute,
+* regardless of type.
+* @return True if the requested attribute is supported by the formatter; false if not.
+* @see unum_getAttribute
+* @see unum_setAttribute
+* @see unum_getDoubleAttribute
+* @see unum_setDoubleAttribute
+* @see unum_getTextAttribute
+* @see unum_setTextAttribute
+* @draft ICU 72.0
+*/
+U_CAPI bool U_EXPORT2
+unum_hasAttribute(const UNumberFormat*          fmt,
+          UNumberFormatAttribute  attr);
+#endif // U_HIDE_DRAFT_API
+
 /**
 * Get a numeric attribute associated with a UNumberFormat.
 * An example of a numeric attribute is the number of integer digits a formatter will produce.
@@ -1170,12 +1190,12 @@ typedef enum UNumberFormatAttribute {
 * UNUM_MAX_FRACTION_DIGITS, UNUM_MIN_FRACTION_DIGITS, UNUM_FRACTION_DIGITS, UNUM_MULTIPLIER,
 * UNUM_GROUPING_SIZE, UNUM_ROUNDING_MODE, UNUM_FORMAT_WIDTH, UNUM_PADDING_POSITION, UNUM_SECONDARY_GROUPING_SIZE,
 * UNUM_SCALE, UNUM_MINIMUM_GROUPING_DIGITS.
-* @return The value of attr.
+* @return The value of attr, or -1 if the formatter doesn't have the requested attribute.  The caller should use unum_hasAttribute() to tell if the attribute
+* is available, rather than relaying on this function returning -1.
+* @see unum_hasAttribute
 * @see unum_setAttribute
 * @see unum_getDoubleAttribute
 * @see unum_setDoubleAttribute
-* @see unum_getTextAttribute
-* @see unum_setTextAttribute
 * @stable ICU 2.0
 */
 U_CAPI int32_t U_EXPORT2 
@@ -1186,7 +1206,7 @@ unum_getAttribute(const UNumberFormat*          fmt,
 * Set a numeric attribute associated with a UNumberFormat.
 * An example of a numeric attribute is the number of integer digits a formatter will produce.  If the
 * formatter does not understand the attribute, the call is ignored.  Rule-based formatters only understand
-* the lenient-parse attribute.
+* the lenient-parse attribute.  The caller can use unum_hasAttribute() to find out if the formatter supports the attribute.
 * @param fmt The formatter to set.
 * @param attr The attribute to set; one of UNUM_PARSE_INT_ONLY, UNUM_GROUPING_USED,
 * UNUM_DECIMAL_ALWAYS_SHOWN, UNUM_MAX_INTEGER_DIGITS, UNUM_MIN_INTEGER_DIGITS, UNUM_INTEGER_DIGITS,
@@ -1194,6 +1214,7 @@ unum_getAttribute(const UNumberFormat*          fmt,
 * UNUM_GROUPING_SIZE, UNUM_ROUNDING_MODE, UNUM_FORMAT_WIDTH, UNUM_PADDING_POSITION, UNUM_SECONDARY_GROUPING_SIZE,
 * UNUM_LENIENT_PARSE, UNUM_SCALE, UNUM_MINIMUM_GROUPING_DIGITS.
 * @param newValue The new value of attr.
+* @see unum_hasAttribute
 * @see unum_getAttribute
 * @see unum_getDoubleAttribute
 * @see unum_setDoubleAttribute
@@ -1210,10 +1231,12 @@ unum_setAttribute(    UNumberFormat*          fmt,
 /**
 * Get a numeric attribute associated with a UNumberFormat.
 * An example of a numeric attribute is the number of integer digits a formatter will produce.
-* If the formatter does not understand the attribute, -1 is returned.
+* If the formatter does not understand the attribute, -1 is returned.  The caller should use unum_hasAttribute()
+* to determine if the attribute is supported, rather than relying on this function returning -1.
 * @param fmt The formatter to query.
 * @param attr The attribute to query; e.g. UNUM_ROUNDING_INCREMENT.
-* @return The value of attr.
+* @return The value of attr, or -1 if the formatter doesn't understand the attribute.
+* @see unum_hasAttribute
 * @see unum_getAttribute
 * @see unum_setAttribute
 * @see unum_setDoubleAttribute
@@ -1228,10 +1251,12 @@ unum_getDoubleAttribute(const UNumberFormat*          fmt,
 /**
 * Set a numeric attribute associated with a UNumberFormat.
 * An example of a numeric attribute is the number of integer digits a formatter will produce.
-* If the formatter does not understand the attribute, this call is ignored.
+* If the formatter does not understand the attribute, this call is ignored.  The caller can use
+* unum_hasAttribute() to tell in advance whether the formatter understands the attribute.
 * @param fmt The formatter to set.
 * @param attr The attribute to set; e.g. UNUM_ROUNDING_INCREMENT.
 * @param newValue The new value of attr.
+* @see unum_hasAttribute
 * @see unum_getAttribute
 * @see unum_setAttribute
 * @see unum_getDoubleAttribute
index 7043f7adc12308cd8a34c012a52e08800e69d128..769d59290e7865e89e60e660f1803fb3d044525c 100644 (file)
@@ -508,6 +508,28 @@ unum_countAvailable()
     return uloc_countAvailable();
 }
 
+U_CAPI bool U_EXPORT2
+unum_hasAttribute(const UNumberFormat*          fmt,
+          UNumberFormatAttribute  attr)
+{
+    const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
+    bool isDecimalFormat = dynamic_cast<const DecimalFormat*>(nf) != NULL;
+    
+    switch (attr) {
+        case UNUM_LENIENT_PARSE:
+        case UNUM_MAX_INTEGER_DIGITS:
+        case UNUM_MIN_INTEGER_DIGITS:
+        case UNUM_INTEGER_DIGITS:
+        case UNUM_MAX_FRACTION_DIGITS:
+        case UNUM_MIN_FRACTION_DIGITS:
+        case UNUM_FRACTION_DIGITS:
+        case UNUM_ROUNDING_MODE:
+            return true;
+        default:
+            return isDecimalFormat;
+    }
+}
+
 U_CAPI int32_t U_EXPORT2
 unum_getAttribute(const UNumberFormat*          fmt,
           UNumberFormatAttribute  attr)
index 3f00bcf899969df57536d278ed1e203b9a987110..e80e021fe8623c1b2bcc408db4ae8cbcf4374bcb 100644 (file)
@@ -764,6 +764,7 @@ free(result);
     /*Testing unum_getAttribute and  unum_setAttribute() */
     log_verbose("\nTesting get and set Attributes\n");
     attr=UNUM_GROUPING_SIZE;
+    assertTrue("unum_hasAttribute returned false for UNUM_GROUPING_SIZE", unum_hasAttribute(def, attr));
     newvalue=unum_getAttribute(def, attr);
     newvalue=2;
     unum_setAttribute(def, attr, newvalue);
@@ -773,6 +774,7 @@ free(result);
         log_verbose("Pass: setting and getting attributes for UNUM_GROUPING_SIZE works fine\n");
 
     attr=UNUM_MULTIPLIER;
+    assertTrue("unum_hasAttribute returned false for UNUM_MULTIPLIER", unum_hasAttribute(def, attr));
     newvalue=unum_getAttribute(def, attr);
     newvalue=8;
     unum_setAttribute(def, attr, newvalue);
@@ -782,6 +784,7 @@ free(result);
         log_verbose("Pass:setting and getting attributes for UNUM_MULTIPLIER works fine\n");
 
     attr=UNUM_SECONDARY_GROUPING_SIZE;
+    assertTrue("unum_hasAttribute returned false for UNUM_SECONDARY_GROUPING_SIZE", unum_hasAttribute(def, attr));
     newvalue=unum_getAttribute(def, attr);
     newvalue=2;
     unum_setAttribute(def, attr, newvalue);
@@ -795,6 +798,7 @@ free(result);
     log_verbose("\nTesting get and set attributes extensively\n");
     for(attr=UNUM_PARSE_INT_ONLY; attr<= UNUM_PADDING_POSITION; attr=(UNumberFormatAttribute)((int32_t)attr + 1) )
     {
+        assertTrue("unum_hasAttribute returned false", unum_hasAttribute(fr, attr));
         newvalue=unum_getAttribute(fr, attr);
         unum_setAttribute(def, attr, newvalue);
         if(unum_getAttribute(def,attr)!=unum_getAttribute(fr, attr))
@@ -807,6 +811,10 @@ free(result);
     log_verbose("\nTesting spellout format\n");
     if (spellout_def)
     {
+        // check that unum_hasAttribute() works right with a spellout formatter
+        assertTrue("unum_hasAttribute() returned true for UNUM_MULTIPLIER on a spellout formatter", !unum_hasAttribute(spellout_def, UNUM_MULTIPLIER));
+        assertTrue("unum_hasAttribute() returned false for UNUM_LENIENT_PARSE on a spellout formatter", unum_hasAttribute(spellout_def, UNUM_LENIENT_PARSE));
+
         static const int32_t values[] = { 0, -5, 105, 1005, 105050 };
         for (i = 0; i < UPRV_LENGTHOF(values); ++i) {
             UChar buffer[128];