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 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
>;
33 // Forward declaration
34 class MutablePatternModifier
;
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
{
39 ~ImmutablePatternModifier() U_OVERRIDE
= default;
41 void processQuantity(DecimalQuantity
&, MicroProps
& micros
, UErrorCode
& status
) const U_OVERRIDE
;
43 void applyToMicros(MicroProps
& micros
, DecimalQuantity
& quantity
) const;
45 const Modifier
* getModifier(int8_t signum
, StandardPlural::Form plural
) const;
48 ImmutablePatternModifier(ParameterizedModifier
* pm
, const PluralRules
* rules
,
49 const MicroPropsGenerator
* parent
);
51 const LocalPointer
<ParameterizedModifier
> pm
;
52 const PluralRules
* rules
;
53 const MicroPropsGenerator
* parent
;
55 friend class MutablePatternModifier
;
59 * This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in
60 * {@link Modifier#apply}.
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.
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.
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
77 class U_I18N_API MutablePatternModifier
78 : public MicroPropsGenerator
,
80 public SymbolProvider
,
84 ~MutablePatternModifier() U_OVERRIDE
= default;
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
92 explicit MutablePatternModifier(bool isStrong
);
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
99 void setPatternInfo(const AffixPatternProvider
*patternInfo
);
102 * Sets attributes that imply changes to the literal interpretation of the pattern string affixes.
105 * Whether to force a plus sign on positive numbers.
107 * Whether to substitute the percent sign in the pattern with a permille sign.
109 void setPatternAttributes(UNumberSignDisplay signDisplay
, bool perMille
);
112 * Sets locale-specific details that affect the symbols substituted into the pattern string affixes.
115 * The desired instance of DecimalFormatSymbols.
116 * @param currencySymbols
117 * The currency symbols to be used when substituting currency values into the affixes.
119 * The width used to render currencies.
121 * Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the
122 * convenience method {@link #needsPlurals()}.
124 void setSymbols(const DecimalFormatSymbols
* symbols
, const CurrencySymbols
* currencySymbols
,
125 UNumberUnitWidth unitWidth
, const PluralRules
* rules
);
128 * Sets attributes of the current number being processed.
131 * -1 if negative; +1 if positive; or 0 if zero.
133 * The plural form of the number, required only if the pattern contains the triple
134 * currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}).
136 void setNumberProperties(int8_t signum
, StandardPlural::Form plural
);
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 ("¤¤¤").
142 bool needsPlurals() const;
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.
150 * The resulting modifier cannot be used in a QuantityChain.
153 * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
155 * @return An immutable that supports both positive and negative numbers.
157 ImmutablePatternModifier
*createImmutable(UErrorCode
&status
);
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.
165 * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
168 * The QuantityChain to which to chain this immutable.
169 * @return An immutable that supports both positive and negative numbers.
171 ImmutablePatternModifier
*
172 createImmutableAndChain(const MicroPropsGenerator
*parent
, UErrorCode
&status
);
174 MicroPropsGenerator
&addToChain(const MicroPropsGenerator
*parent
);
176 void processQuantity(DecimalQuantity
&, MicroProps
µs
, UErrorCode
&status
) const U_OVERRIDE
;
178 int32_t apply(NumberStringBuilder
&output
, int32_t leftIndex
, int32_t rightIndex
,
179 UErrorCode
&status
) const U_OVERRIDE
;
181 int32_t getPrefixLength(UErrorCode
&status
) const U_OVERRIDE
;
183 int32_t getCodePointCount(UErrorCode
&status
) const U_OVERRIDE
;
185 bool isStrong() const U_OVERRIDE
;
188 * Returns the string that substitutes a given symbol type in a pattern.
190 UnicodeString
getSymbol(AffixPatternType type
) const U_OVERRIDE
;
192 UnicodeString
toUnicodeString() const;
195 // Modifier details (initialized in constructor)
198 // Pattern details (initialized in setPatternInfo and setPatternAttributes)
199 const AffixPatternProvider
*patternInfo
;
200 UNumberSignDisplay signDisplay
;
201 bool perMilleReplacesPercent
;
203 // Symbol details (initialized in setSymbols)
204 const DecimalFormatSymbols
*symbols
;
205 UNumberUnitWidth unitWidth
;
206 const CurrencySymbols
*currencySymbols
;
207 const PluralRules
*rules
;
209 // Number details (initialized in setNumberProperties)
211 StandardPlural::Form plural
;
213 // QuantityChain details (initialized in addToChain)
214 const MicroPropsGenerator
*parent
;
216 // Transient fields for rendering
217 UnicodeString currentAffix
;
220 * Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support
224 * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
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.
230 * Another working NumberStringBuilder object.
231 * @return The constant modifier object.
233 ConstantMultiFieldModifier
*createConstantModifier(UErrorCode
&status
);
235 int32_t insertPrefix(NumberStringBuilder
&sb
, int position
, UErrorCode
&status
);
237 int32_t insertSuffix(NumberStringBuilder
&sb
, int position
, UErrorCode
&status
);
239 void prepareAffix(bool isPrefix
);
244 } // namespace number
247 #endif //__NUMBER_PATTERNMODIFIER_H__
249 #endif /* #if !UCONFIG_NO_FORMATTING */