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