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