/src/mozilla-central/intl/icu/source/i18n/number_patternmodifier.h
Line | Count | Source (jump to first uncovered line) |
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_PATTERNMODIFIER_H__ |
8 | | #define __NUMBER_PATTERNMODIFIER_H__ |
9 | | |
10 | | #include "standardplural.h" |
11 | | #include "unicode/numberformatter.h" |
12 | | #include "number_patternstring.h" |
13 | | #include "number_types.h" |
14 | | #include "number_modifiers.h" |
15 | | #include "number_utils.h" |
16 | | #include "number_currencysymbols.h" |
17 | | |
18 | | U_NAMESPACE_BEGIN |
19 | | |
20 | | // Export an explicit template instantiation of the LocalPointer that is used as a |
21 | | // data member of ParameterizedModifier. |
22 | | // (When building DLLs for Windows this is required.) |
23 | | #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN |
24 | | // Ignore warning 4661 as LocalPointerBase does not use operator== or operator!= |
25 | | #pragma warning(suppress: 4661) |
26 | | template class U_I18N_API LocalPointerBase<number::impl::ParameterizedModifier>; |
27 | | template class U_I18N_API LocalPointer<number::impl::ParameterizedModifier>; |
28 | | #endif |
29 | | |
30 | | namespace number { |
31 | | namespace impl { |
32 | | |
33 | | // Forward declaration |
34 | | class MutablePatternModifier; |
35 | | |
36 | | // Exported as U_I18N_API because it is needed for the unit test PatternModifierTest |
37 | | class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public UMemory { |
38 | | public: |
39 | 0 | ~ImmutablePatternModifier() U_OVERRIDE = default; |
40 | | |
41 | | void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const U_OVERRIDE; |
42 | | |
43 | | void applyToMicros(MicroProps& micros, DecimalQuantity& quantity) const; |
44 | | |
45 | | const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const; |
46 | | |
47 | | private: |
48 | | ImmutablePatternModifier(ParameterizedModifier* pm, const PluralRules* rules, |
49 | | const MicroPropsGenerator* parent); |
50 | | |
51 | | const LocalPointer<ParameterizedModifier> pm; |
52 | | const PluralRules* rules; |
53 | | const MicroPropsGenerator* parent; |
54 | | |
55 | | friend class MutablePatternModifier; |
56 | | }; |
57 | | |
58 | | /** |
59 | | * This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in |
60 | | * {@link Modifier#apply}. |
61 | | * |
62 | | * <p> |
63 | | * In addition to being a Modifier, this class contains the business logic for substituting the correct locale symbols |
64 | | * into the affixes of the decimal format pattern. |
65 | | * |
66 | | * <p> |
67 | | * In order to use this class, create a new instance and call the following four setters: {@link #setPatternInfo}, |
68 | | * {@link #setPatternAttributes}, {@link #setSymbols}, and {@link #setNumberProperties}. After calling these four |
69 | | * setters, the instance will be ready for use as a Modifier. |
70 | | * |
71 | | * <p> |
72 | | * This is a MUTABLE, NON-THREAD-SAFE class designed for performance. Do NOT save references to this or attempt to use |
73 | | * it from multiple threads! Instead, you can obtain a safe, immutable decimal format pattern modifier by calling |
74 | | * {@link MutablePatternModifier#createImmutable}, in effect treating this instance as a builder for the immutable |
75 | | * variant. |
76 | | */ |
77 | | class U_I18N_API MutablePatternModifier |
78 | | : public MicroPropsGenerator, |
79 | | public Modifier, |
80 | | public SymbolProvider, |
81 | | public UMemory { |
82 | | public: |
83 | | |
84 | 0 | ~MutablePatternModifier() U_OVERRIDE = default; |
85 | | |
86 | | /** |
87 | | * @param isStrong |
88 | | * Whether the modifier should be considered strong. For more information, see |
89 | | * {@link Modifier#isStrong()}. Most of the time, decimal format pattern modifiers should be considered |
90 | | * as non-strong. |
91 | | */ |
92 | | explicit MutablePatternModifier(bool isStrong); |
93 | | |
94 | | /** |
95 | | * Sets a reference to the parsed decimal format pattern, usually obtained from |
96 | | * {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of {@link AffixPatternProvider} is |
97 | | * accepted. |
98 | | */ |
99 | | void setPatternInfo(const AffixPatternProvider *patternInfo); |
100 | | |
101 | | /** |
102 | | * Sets attributes that imply changes to the literal interpretation of the pattern string affixes. |
103 | | * |
104 | | * @param signDisplay |
105 | | * Whether to force a plus sign on positive numbers. |
106 | | * @param perMille |
107 | | * Whether to substitute the percent sign in the pattern with a permille sign. |
108 | | */ |
109 | | void setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille); |
110 | | |
111 | | /** |
112 | | * Sets locale-specific details that affect the symbols substituted into the pattern string affixes. |
113 | | * |
114 | | * @param symbols |
115 | | * The desired instance of DecimalFormatSymbols. |
116 | | * @param currencySymbols |
117 | | * The currency symbols to be used when substituting currency values into the affixes. |
118 | | * @param unitWidth |
119 | | * The width used to render currencies. |
120 | | * @param rules |
121 | | * Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the |
122 | | * convenience method {@link #needsPlurals()}. |
123 | | */ |
124 | | void setSymbols(const DecimalFormatSymbols* symbols, const CurrencySymbols* currencySymbols, |
125 | | UNumberUnitWidth unitWidth, const PluralRules* rules); |
126 | | |
127 | | /** |
128 | | * Sets attributes of the current number being processed. |
129 | | * |
130 | | * @param signum |
131 | | * -1 if negative; +1 if positive; or 0 if zero. |
132 | | * @param plural |
133 | | * The plural form of the number, required only if the pattern contains the triple |
134 | | * currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}). |
135 | | */ |
136 | | void setNumberProperties(int8_t signum, StandardPlural::Form plural); |
137 | | |
138 | | /** |
139 | | * Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize. |
140 | | * This is currently true only if there is a currency long name placeholder in the pattern ("¤¤¤"). |
141 | | */ |
142 | | bool needsPlurals() const; |
143 | | |
144 | | /** |
145 | | * Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable |
146 | | * and can be saved for future use. The number properties in the current instance are mutated; all other properties |
147 | | * are left untouched. |
148 | | * |
149 | | * <p> |
150 | | * The resulting modifier cannot be used in a QuantityChain. |
151 | | * |
152 | | * <p> |
153 | | * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP. |
154 | | * |
155 | | * @return An immutable that supports both positive and negative numbers. |
156 | | */ |
157 | | ImmutablePatternModifier *createImmutable(UErrorCode &status); |
158 | | |
159 | | /** |
160 | | * Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable |
161 | | * and can be saved for future use. The number properties in the current instance are mutated; all other properties |
162 | | * are left untouched. |
163 | | * |
164 | | * <p> |
165 | | * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP. |
166 | | * |
167 | | * @param parent |
168 | | * The QuantityChain to which to chain this immutable. |
169 | | * @return An immutable that supports both positive and negative numbers. |
170 | | */ |
171 | | ImmutablePatternModifier * |
172 | | createImmutableAndChain(const MicroPropsGenerator *parent, UErrorCode &status); |
173 | | |
174 | | MicroPropsGenerator &addToChain(const MicroPropsGenerator *parent); |
175 | | |
176 | | void processQuantity(DecimalQuantity &, MicroProps µs, UErrorCode &status) const U_OVERRIDE; |
177 | | |
178 | | int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex, |
179 | | UErrorCode &status) const U_OVERRIDE; |
180 | | |
181 | | int32_t getPrefixLength(UErrorCode &status) const U_OVERRIDE; |
182 | | |
183 | | int32_t getCodePointCount(UErrorCode &status) const U_OVERRIDE; |
184 | | |
185 | | bool isStrong() const U_OVERRIDE; |
186 | | |
187 | | /** |
188 | | * Returns the string that substitutes a given symbol type in a pattern. |
189 | | */ |
190 | | UnicodeString getSymbol(AffixPatternType type) const U_OVERRIDE; |
191 | | |
192 | | UnicodeString toUnicodeString() const; |
193 | | |
194 | | private: |
195 | | // Modifier details (initialized in constructor) |
196 | | const bool fStrong; |
197 | | |
198 | | // Pattern details (initialized in setPatternInfo and setPatternAttributes) |
199 | | const AffixPatternProvider *patternInfo; |
200 | | UNumberSignDisplay signDisplay; |
201 | | bool perMilleReplacesPercent; |
202 | | |
203 | | // Symbol details (initialized in setSymbols) |
204 | | const DecimalFormatSymbols *symbols; |
205 | | UNumberUnitWidth unitWidth; |
206 | | const CurrencySymbols *currencySymbols; |
207 | | const PluralRules *rules; |
208 | | |
209 | | // Number details (initialized in setNumberProperties) |
210 | | int8_t signum; |
211 | | StandardPlural::Form plural; |
212 | | |
213 | | // QuantityChain details (initialized in addToChain) |
214 | | const MicroPropsGenerator *parent; |
215 | | |
216 | | // Transient fields for rendering |
217 | | UnicodeString currentAffix; |
218 | | |
219 | | /** |
220 | | * Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support |
221 | | * if required. |
222 | | * |
223 | | * <p> |
224 | | * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP. |
225 | | * |
226 | | * @param a |
227 | | * A working NumberStringBuilder object; passed from the outside to prevent the need to create many new |
228 | | * instances if this method is called in a loop. |
229 | | * @param b |
230 | | * Another working NumberStringBuilder object. |
231 | | * @return The constant modifier object. |
232 | | */ |
233 | | ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status); |
234 | | |
235 | | int32_t insertPrefix(NumberStringBuilder &sb, int position, UErrorCode &status); |
236 | | |
237 | | int32_t insertSuffix(NumberStringBuilder &sb, int position, UErrorCode &status); |
238 | | |
239 | | void prepareAffix(bool isPrefix); |
240 | | }; |
241 | | |
242 | | |
243 | | } // namespace impl |
244 | | } // namespace number |
245 | | U_NAMESPACE_END |
246 | | |
247 | | #endif //__NUMBER_PATTERNMODIFIER_H__ |
248 | | |
249 | | #endif /* #if !UCONFIG_NO_FORMATTING */ |