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
unitIsNoUnit(const MeasureUnit & unit)52 inline bool unitIsNoUnit(const MeasureUnit& unit) {
53 return uprv_strcmp("none", unit.getType()) == 0;
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