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
22U_NAMESPACE_BEGIN
23
24namespace number {
25namespace impl {
26
27enum 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
37namespace utils {
38
39inline 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
48inline bool unitIsCurrency(const MeasureUnit& unit) {
49 return uprv_strcmp("currency", unit.getType()) == 0;
50}
51
52inline bool unitIsNoUnit(const MeasureUnit& unit) {
53 return uprv_strcmp("none", unit.getType()) == 0;
54}
55
56inline bool unitIsPercent(const MeasureUnit& unit) {
57 return uprv_strcmp("percent", unit.getSubtype()) == 0;
58}
59
60inline 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
65const char16_t*
66getPatternForStyle(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 */
75inline 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 */
89inline 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
108U_NAMESPACE_END
109
110#endif //__NUMBER_UTILS_H__
111
112#endif /* #if !UCONFIG_NO_FORMATTING */
113