1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 #include "unicode/utypes.h"
6 #if !UCONFIG_NO_FORMATTING
7 #ifndef __NUMBER_PATTERNMODIFIER_H__
8 #define __NUMBER_PATTERNMODIFIER_H__
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"
20 // Export an explicit template instantiation of the LocalPointer that is used as a
21 // data member of AdoptingModifierStore.
22 // (When building DLLs for Windows this is required.)
23 #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
25 // Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
27 #pragma warning(disable : 4661)
29 template class U_I18N_API LocalPointerBase
<number::impl::AdoptingModifierStore
>;
30 template class U_I18N_API LocalPointer
<number::impl::AdoptingModifierStore
>;
39 // Forward declaration
40 class MutablePatternModifier
;
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
{
45 ~ImmutablePatternModifier() U_OVERRIDE
= default;
47 void processQuantity(DecimalQuantity
&, MicroProps
& micros
, UErrorCode
& status
) const U_OVERRIDE
;
49 void applyToMicros(MicroProps
& micros
, const DecimalQuantity
& quantity
, UErrorCode
& status
) const;
51 const Modifier
* getModifier(int8_t signum
, StandardPlural::Form plural
) const;
54 ImmutablePatternModifier(AdoptingModifierStore
* pm
, const PluralRules
* rules
,
55 const MicroPropsGenerator
* parent
);
57 const LocalPointer
<AdoptingModifierStore
> pm
;
58 const PluralRules
* rules
;
59 const MicroPropsGenerator
* parent
;
61 friend class MutablePatternModifier
;
65 * This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in
66 * {@link Modifier#apply}.
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.
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.
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
83 class U_I18N_API MutablePatternModifier
84 : public MicroPropsGenerator
,
86 public SymbolProvider
,
90 ~MutablePatternModifier() U_OVERRIDE
= default;
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
98 explicit MutablePatternModifier(bool isStrong
);
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
106 * Which field to use for literal characters in the pattern.
108 void setPatternInfo(const AffixPatternProvider
*patternInfo
, Field field
);
111 * Sets attributes that imply changes to the literal interpretation of the pattern string affixes.
114 * Whether to force a plus sign on positive numbers.
116 * Whether to substitute the percent sign in the pattern with a permille sign.
118 void setPatternAttributes(UNumberSignDisplay signDisplay
, bool perMille
);
121 * Sets locale-specific details that affect the symbols substituted into the pattern string affixes.
124 * The desired instance of DecimalFormatSymbols.
125 * @param currencySymbols
126 * The currency symbols to be used when substituting currency values into the affixes.
128 * The width used to render currencies.
130 * Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the
131 * convenience method {@link #needsPlurals()}.
133 void setSymbols(const DecimalFormatSymbols
* symbols
, const CurrencySymbols
* currencySymbols
,
134 UNumberUnitWidth unitWidth
, const PluralRules
* rules
);
137 * Sets attributes of the current number being processed.
140 * -1 if negative; +1 if positive; or 0 if zero.
142 * The plural form of the number, required only if the pattern contains the triple
143 * currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}).
145 void setNumberProperties(int8_t signum
, StandardPlural::Form plural
);
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 ("¤¤¤").
151 bool needsPlurals() const;
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.
159 * The resulting modifier cannot be used in a QuantityChain.
162 * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
164 * @return An immutable that supports both positive and negative numbers.
166 ImmutablePatternModifier
*createImmutable(UErrorCode
&status
);
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.
174 * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
177 * The QuantityChain to which to chain this immutable.
178 * @return An immutable that supports both positive and negative numbers.
180 ImmutablePatternModifier
*
181 createImmutableAndChain(const MicroPropsGenerator
*parent
, UErrorCode
&status
);
183 MicroPropsGenerator
&addToChain(const MicroPropsGenerator
*parent
);
185 void processQuantity(DecimalQuantity
&, MicroProps
µs
, UErrorCode
&status
) const U_OVERRIDE
;
187 int32_t apply(NumberStringBuilder
&output
, int32_t leftIndex
, int32_t rightIndex
,
188 UErrorCode
&status
) const U_OVERRIDE
;
190 int32_t getPrefixLength() const U_OVERRIDE
;
192 int32_t getCodePointCount() const U_OVERRIDE
;
194 bool isStrong() const U_OVERRIDE
;
196 bool containsField(UNumberFormatFields field
) const U_OVERRIDE
;
198 void getParameters(Parameters
& output
) const U_OVERRIDE
;
200 bool semanticallyEquivalent(const Modifier
& other
) const U_OVERRIDE
;
203 * Returns the string that substitutes a given symbol type in a pattern.
205 UnicodeString
getSymbol(AffixPatternType type
) const U_OVERRIDE
;
207 UnicodeString
toUnicodeString() const;
210 // Modifier details (initialized in constructor)
213 // Pattern details (initialized in setPatternInfo and setPatternAttributes)
214 const AffixPatternProvider
*fPatternInfo
;
216 UNumberSignDisplay fSignDisplay
;
217 bool fPerMilleReplacesPercent
;
219 // Symbol details (initialized in setSymbols)
220 const DecimalFormatSymbols
*fSymbols
;
221 UNumberUnitWidth fUnitWidth
;
222 const CurrencySymbols
*fCurrencySymbols
;
223 const PluralRules
*fRules
;
225 // Number details (initialized in setNumberProperties)
227 StandardPlural::Form fPlural
;
229 // QuantityChain details (initialized in addToChain)
230 const MicroPropsGenerator
*fParent
;
232 // Transient fields for rendering
233 UnicodeString currentAffix
;
236 * Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support
240 * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
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.
246 * Another working NumberStringBuilder object.
247 * @return The constant modifier object.
249 ConstantMultiFieldModifier
*createConstantModifier(UErrorCode
&status
);
251 int32_t insertPrefix(NumberStringBuilder
&sb
, int position
, UErrorCode
&status
);
253 int32_t insertSuffix(NumberStringBuilder
&sb
, int position
, UErrorCode
&status
);
255 void prepareAffix(bool isPrefix
);
260 } // namespace number
263 #endif //__NUMBER_PATTERNMODIFIER_H__
265 #endif /* #if !UCONFIG_NO_FORMATTING */