1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #include "unicode/utypes.h"
5 
6 #if !UCONFIG_NO_FORMATTING
7 #ifndef __NUMBER_UTILS_H__
8 #define __NUMBER_UTILS_H__
9 
10 #include "unicode/numberformatter.h"
11 #include "number_types.h"
12 #include "number_decimalquantity.h"
13 #include "number_scientific.h"
14 #include "number_patternstring.h"
15 #include "number_modifiers.h"
16 #include "number_multiplier.h"
17 #include "number_roundingutils.h"
18 #include "decNumber.h"
19 #include "charstr.h"
20 #include "formatted_string_builder.h"
21 
22 U_NAMESPACE_BEGIN
23 
24 namespace number {
25 namespace impl {
26 
27 enum CldrPatternStyle {
28     CLDR_PATTERN_STYLE_DECIMAL,
29     CLDR_PATTERN_STYLE_CURRENCY,
30     CLDR_PATTERN_STYLE_ACCOUNTING,
31     CLDR_PATTERN_STYLE_PERCENT,
32     CLDR_PATTERN_STYLE_SCIENTIFIC,
33     CLDR_PATTERN_STYLE_COUNT,
34 };
35 
36 // Namespace for naked functions
37 namespace utils {
38 
insertDigitFromSymbols(FormattedStringBuilder & output,int32_t index,int8_t digit,const DecimalFormatSymbols & symbols,Field field,UErrorCode & status)39 inline int32_t insertDigitFromSymbols(FormattedStringBuilder& output, int32_t index, int8_t digit,
40                                       const DecimalFormatSymbols& symbols, Field field,
41                                       UErrorCode& status) {
42     if (symbols.getCodePointZero() != -1) {
43         return output.insertCodePoint(index, symbols.getCodePointZero() + digit, field, status);
44     }
45     return output.insert(index, symbols.getConstDigitSymbol(digit), field, status);
46 }
47 
unitIsCurrency(const MeasureUnit & unit)48 inline bool unitIsCurrency(const MeasureUnit& unit) {
49     return uprv_strcmp("currency", unit.getType()) == 0;
50 }
51 
unitIsBaseUnit(const MeasureUnit & unit)52 inline bool unitIsBaseUnit(const MeasureUnit& unit) {
53     return unit == MeasureUnit();
54 }
55 
unitIsPercent(const MeasureUnit & unit)56 inline bool unitIsPercent(const MeasureUnit& unit) {
57     return uprv_strcmp("percent", unit.getSubtype()) == 0;
58 }
59 
unitIsPermille(const MeasureUnit & unit)60 inline bool unitIsPermille(const MeasureUnit& unit) {
61     return uprv_strcmp("permille", unit.getSubtype()) == 0;
62 }
63 
64 // NOTE: In Java, this method is in NumberFormat.java
65 const char16_t*
66 getPatternForStyle(const Locale& locale, const char* nsName, CldrPatternStyle style, UErrorCode& status);
67 
68 /**
69  * Computes the plural form for this number based on the specified set of rules.
70  *
71  * @param rules A {@link PluralRules} object representing the set of rules.
72  * @return The {@link StandardPlural} according to the PluralRules. If the plural form is not in
73  *     the set of standard plurals, {@link StandardPlural#OTHER} is returned instead.
74  */
getStandardPlural(const PluralRules * rules,const IFixedDecimal & fdec)75 inline StandardPlural::Form getStandardPlural(const PluralRules *rules,
76                                               const IFixedDecimal &fdec) {
77     if (rules == nullptr) {
78         // Fail gracefully if the user didn't provide a PluralRules
79         return StandardPlural::Form::OTHER;
80     } else {
81         UnicodeString ruleString = rules->select(fdec);
82         return StandardPlural::orOtherFromString(ruleString);
83     }
84 }
85 
86 /**
87  * Computes the plural form after copying the number and applying rounding rules.
88  */
getPluralSafe(const RoundingImpl & rounder,const PluralRules * rules,const DecimalQuantity & dq,UErrorCode & status)89 inline StandardPlural::Form getPluralSafe(
90         const RoundingImpl& rounder,
91         const PluralRules* rules,
92         const DecimalQuantity& dq,
93         UErrorCode& status) {
94     // TODO(ICU-20500): Avoid the copy?
95     DecimalQuantity copy(dq);
96     rounder.apply(copy, status);
97     if (U_FAILURE(status)) {
98         return StandardPlural::Form::OTHER;
99     }
100     return getStandardPlural(rules, copy);
101 }
102 
103 } // namespace utils
104 
105 } // namespace impl
106 } // namespace number
107 
108 U_NAMESPACE_END
109 
110 #endif //__NUMBER_UTILS_H__
111 
112 #endif /* #if !UCONFIG_NO_FORMATTING */
113