xref: /aosp_15_r20/external/icu/libicu/cts_headers/number_modifiers.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_MODIFIERS_H__
8*0e209d39SAndroid Build Coastguard Worker #define __NUMBER_MODIFIERS_H__
9*0e209d39SAndroid Build Coastguard Worker 
10*0e209d39SAndroid Build Coastguard Worker #include <algorithm>
11*0e209d39SAndroid Build Coastguard Worker #include <cstdint>
12*0e209d39SAndroid Build Coastguard Worker #include "unicode/uniset.h"
13*0e209d39SAndroid Build Coastguard Worker #include "unicode/simpleformatter.h"
14*0e209d39SAndroid Build Coastguard Worker #include "standardplural.h"
15*0e209d39SAndroid Build Coastguard Worker #include "formatted_string_builder.h"
16*0e209d39SAndroid Build Coastguard Worker #include "number_types.h"
17*0e209d39SAndroid Build Coastguard Worker 
18*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN
19*0e209d39SAndroid Build Coastguard Worker namespace number::impl {
20*0e209d39SAndroid Build Coastguard Worker 
21*0e209d39SAndroid Build Coastguard Worker /**
22*0e209d39SAndroid Build Coastguard Worker  * The canonical implementation of {@link Modifier}, containing a prefix and suffix string.
23*0e209d39SAndroid Build Coastguard Worker  * TODO: This is not currently being used by real code and could be removed.
24*0e209d39SAndroid Build Coastguard Worker  */
25*0e209d39SAndroid Build Coastguard Worker class U_I18N_API ConstantAffixModifier : public Modifier, public UObject {
26*0e209d39SAndroid Build Coastguard Worker   public:
ConstantAffixModifier(const UnicodeString & prefix,const UnicodeString & suffix,Field field,bool strong)27*0e209d39SAndroid Build Coastguard Worker     ConstantAffixModifier(const UnicodeString &prefix, const UnicodeString &suffix, Field field,
28*0e209d39SAndroid Build Coastguard Worker                           bool strong)
29*0e209d39SAndroid Build Coastguard Worker             : fPrefix(prefix), fSuffix(suffix), fField(field), fStrong(strong) {}
30*0e209d39SAndroid Build Coastguard Worker 
31*0e209d39SAndroid Build Coastguard Worker     int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
32*0e209d39SAndroid Build Coastguard Worker                   UErrorCode &status) const override;
33*0e209d39SAndroid Build Coastguard Worker 
34*0e209d39SAndroid Build Coastguard Worker     int32_t getPrefixLength() const override;
35*0e209d39SAndroid Build Coastguard Worker 
36*0e209d39SAndroid Build Coastguard Worker     int32_t getCodePointCount() const override;
37*0e209d39SAndroid Build Coastguard Worker 
38*0e209d39SAndroid Build Coastguard Worker     bool isStrong() const override;
39*0e209d39SAndroid Build Coastguard Worker 
40*0e209d39SAndroid Build Coastguard Worker     bool containsField(Field field) const override;
41*0e209d39SAndroid Build Coastguard Worker 
42*0e209d39SAndroid Build Coastguard Worker     void getParameters(Parameters& output) const override;
43*0e209d39SAndroid Build Coastguard Worker 
44*0e209d39SAndroid Build Coastguard Worker     bool strictEquals(const Modifier& other) const override;
45*0e209d39SAndroid Build Coastguard Worker 
46*0e209d39SAndroid Build Coastguard Worker   private:
47*0e209d39SAndroid Build Coastguard Worker     UnicodeString fPrefix;
48*0e209d39SAndroid Build Coastguard Worker     UnicodeString fSuffix;
49*0e209d39SAndroid Build Coastguard Worker     Field fField;
50*0e209d39SAndroid Build Coastguard Worker     bool fStrong;
51*0e209d39SAndroid Build Coastguard Worker };
52*0e209d39SAndroid Build Coastguard Worker 
53*0e209d39SAndroid Build Coastguard Worker /**
54*0e209d39SAndroid Build Coastguard Worker  * The second primary implementation of {@link Modifier}, this one consuming a {@link SimpleFormatter}
55*0e209d39SAndroid Build Coastguard Worker  * pattern.
56*0e209d39SAndroid Build Coastguard Worker  */
57*0e209d39SAndroid Build Coastguard Worker class U_I18N_API SimpleModifier : public Modifier, public UMemory {
58*0e209d39SAndroid Build Coastguard Worker   public:
59*0e209d39SAndroid Build Coastguard Worker     SimpleModifier(const SimpleFormatter &simpleFormatter, Field field, bool strong);
60*0e209d39SAndroid Build Coastguard Worker 
61*0e209d39SAndroid Build Coastguard Worker     SimpleModifier(const SimpleFormatter &simpleFormatter, Field field, bool strong,
62*0e209d39SAndroid Build Coastguard Worker                    const Modifier::Parameters parameters);
63*0e209d39SAndroid Build Coastguard Worker 
64*0e209d39SAndroid Build Coastguard Worker     // Default constructor for LongNameHandler.h
65*0e209d39SAndroid Build Coastguard Worker     SimpleModifier();
66*0e209d39SAndroid Build Coastguard Worker 
67*0e209d39SAndroid Build Coastguard Worker     int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
68*0e209d39SAndroid Build Coastguard Worker                   UErrorCode &status) const override;
69*0e209d39SAndroid Build Coastguard Worker 
70*0e209d39SAndroid Build Coastguard Worker     int32_t getPrefixLength() const override;
71*0e209d39SAndroid Build Coastguard Worker 
72*0e209d39SAndroid Build Coastguard Worker     int32_t getCodePointCount() const override;
73*0e209d39SAndroid Build Coastguard Worker 
74*0e209d39SAndroid Build Coastguard Worker     bool isStrong() const override;
75*0e209d39SAndroid Build Coastguard Worker 
76*0e209d39SAndroid Build Coastguard Worker     bool containsField(Field field) const override;
77*0e209d39SAndroid Build Coastguard Worker 
78*0e209d39SAndroid Build Coastguard Worker     void getParameters(Parameters& output) const override;
79*0e209d39SAndroid Build Coastguard Worker 
80*0e209d39SAndroid Build Coastguard Worker     bool strictEquals(const Modifier& other) const override;
81*0e209d39SAndroid Build Coastguard Worker 
82*0e209d39SAndroid Build Coastguard Worker     /**
83*0e209d39SAndroid Build Coastguard Worker      * TODO: This belongs in SimpleFormatterImpl. The only reason I haven't moved it there yet is because
84*0e209d39SAndroid Build Coastguard Worker      * FormattedStringBuilder is an internal class and SimpleFormatterImpl feels like it should not depend on it.
85*0e209d39SAndroid Build Coastguard Worker      *
86*0e209d39SAndroid Build Coastguard Worker      * <p>
87*0e209d39SAndroid Build Coastguard Worker      * Formats a value that is already stored inside the StringBuilder <code>result</code> between the indices
88*0e209d39SAndroid Build Coastguard Worker      * <code>startIndex</code> and <code>endIndex</code> by inserting characters before the start index and after the
89*0e209d39SAndroid Build Coastguard Worker      * end index.
90*0e209d39SAndroid Build Coastguard Worker      *
91*0e209d39SAndroid Build Coastguard Worker      * <p>
92*0e209d39SAndroid Build Coastguard Worker      * This is well-defined only for patterns with exactly one argument.
93*0e209d39SAndroid Build Coastguard Worker      *
94*0e209d39SAndroid Build Coastguard Worker      * @param result
95*0e209d39SAndroid Build Coastguard Worker      *            The StringBuilder containing the value argument.
96*0e209d39SAndroid Build Coastguard Worker      * @param startIndex
97*0e209d39SAndroid Build Coastguard Worker      *            The left index of the value within the string builder.
98*0e209d39SAndroid Build Coastguard Worker      * @param endIndex
99*0e209d39SAndroid Build Coastguard Worker      *            The right index of the value within the string builder.
100*0e209d39SAndroid Build Coastguard Worker      * @return The number of characters (UTF-16 code points) that were added to the StringBuilder.
101*0e209d39SAndroid Build Coastguard Worker      */
102*0e209d39SAndroid Build Coastguard Worker     int32_t
103*0e209d39SAndroid Build Coastguard Worker     formatAsPrefixSuffix(FormattedStringBuilder& result, int32_t startIndex, int32_t endIndex,
104*0e209d39SAndroid Build Coastguard Worker                          UErrorCode& status) const;
105*0e209d39SAndroid Build Coastguard Worker 
106*0e209d39SAndroid Build Coastguard Worker     /**
107*0e209d39SAndroid Build Coastguard Worker      * TODO: Like above, this belongs with the rest of the SimpleFormatterImpl code.
108*0e209d39SAndroid Build Coastguard Worker      * I put it here so that the SimpleFormatter uses in FormattedStringBuilder are near each other.
109*0e209d39SAndroid Build Coastguard Worker      *
110*0e209d39SAndroid Build Coastguard Worker      * <p>
111*0e209d39SAndroid Build Coastguard Worker      * Applies the compiled two-argument pattern to the FormattedStringBuilder.
112*0e209d39SAndroid Build Coastguard Worker      *
113*0e209d39SAndroid Build Coastguard Worker      * <p>
114*0e209d39SAndroid Build Coastguard Worker      * This method is optimized for the case where the prefix and suffix are often empty, such as
115*0e209d39SAndroid Build Coastguard Worker      * in the range pattern like "{0}-{1}".
116*0e209d39SAndroid Build Coastguard Worker      */
117*0e209d39SAndroid Build Coastguard Worker     static int32_t
118*0e209d39SAndroid Build Coastguard Worker     formatTwoArgPattern(const SimpleFormatter& compiled, FormattedStringBuilder& result,
119*0e209d39SAndroid Build Coastguard Worker                         int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength,
120*0e209d39SAndroid Build Coastguard Worker                         Field field, UErrorCode& status);
121*0e209d39SAndroid Build Coastguard Worker 
122*0e209d39SAndroid Build Coastguard Worker   private:
123*0e209d39SAndroid Build Coastguard Worker     UnicodeString fCompiledPattern;
124*0e209d39SAndroid Build Coastguard Worker     Field fField;
125*0e209d39SAndroid Build Coastguard Worker     bool fStrong = false;
126*0e209d39SAndroid Build Coastguard Worker     int32_t fPrefixLength = 0;
127*0e209d39SAndroid Build Coastguard Worker     int32_t fSuffixOffset = -1;
128*0e209d39SAndroid Build Coastguard Worker     int32_t fSuffixLength = 0;
129*0e209d39SAndroid Build Coastguard Worker     Modifier::Parameters fParameters;
130*0e209d39SAndroid Build Coastguard Worker };
131*0e209d39SAndroid Build Coastguard Worker 
132*0e209d39SAndroid Build Coastguard Worker /**
133*0e209d39SAndroid Build Coastguard Worker  * An implementation of {@link Modifier} that allows for multiple types of fields in the same modifier. Constructed
134*0e209d39SAndroid Build Coastguard Worker  * based on the contents of two {@link FormattedStringBuilder} instances (one for the prefix, one for the suffix).
135*0e209d39SAndroid Build Coastguard Worker  */
136*0e209d39SAndroid Build Coastguard Worker class U_I18N_API ConstantMultiFieldModifier : public Modifier, public UMemory {
137*0e209d39SAndroid Build Coastguard Worker   public:
ConstantMultiFieldModifier(const FormattedStringBuilder & prefix,const FormattedStringBuilder & suffix,bool overwrite,bool strong,const Modifier::Parameters parameters)138*0e209d39SAndroid Build Coastguard Worker     ConstantMultiFieldModifier(
139*0e209d39SAndroid Build Coastguard Worker             const FormattedStringBuilder &prefix,
140*0e209d39SAndroid Build Coastguard Worker             const FormattedStringBuilder &suffix,
141*0e209d39SAndroid Build Coastguard Worker             bool overwrite,
142*0e209d39SAndroid Build Coastguard Worker             bool strong,
143*0e209d39SAndroid Build Coastguard Worker             const Modifier::Parameters parameters)
144*0e209d39SAndroid Build Coastguard Worker       : fPrefix(prefix),
145*0e209d39SAndroid Build Coastguard Worker         fSuffix(suffix),
146*0e209d39SAndroid Build Coastguard Worker         fOverwrite(overwrite),
147*0e209d39SAndroid Build Coastguard Worker         fStrong(strong),
148*0e209d39SAndroid Build Coastguard Worker         fParameters(parameters) {}
149*0e209d39SAndroid Build Coastguard Worker 
ConstantMultiFieldModifier(const FormattedStringBuilder & prefix,const FormattedStringBuilder & suffix,bool overwrite,bool strong)150*0e209d39SAndroid Build Coastguard Worker     ConstantMultiFieldModifier(
151*0e209d39SAndroid Build Coastguard Worker             const FormattedStringBuilder &prefix,
152*0e209d39SAndroid Build Coastguard Worker             const FormattedStringBuilder &suffix,
153*0e209d39SAndroid Build Coastguard Worker             bool overwrite,
154*0e209d39SAndroid Build Coastguard Worker             bool strong)
155*0e209d39SAndroid Build Coastguard Worker       : fPrefix(prefix),
156*0e209d39SAndroid Build Coastguard Worker         fSuffix(suffix),
157*0e209d39SAndroid Build Coastguard Worker         fOverwrite(overwrite),
158*0e209d39SAndroid Build Coastguard Worker         fStrong(strong) {}
159*0e209d39SAndroid Build Coastguard Worker 
160*0e209d39SAndroid Build Coastguard Worker     int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
161*0e209d39SAndroid Build Coastguard Worker                   UErrorCode &status) const override;
162*0e209d39SAndroid Build Coastguard Worker 
163*0e209d39SAndroid Build Coastguard Worker     int32_t getPrefixLength() const override;
164*0e209d39SAndroid Build Coastguard Worker 
165*0e209d39SAndroid Build Coastguard Worker     int32_t getCodePointCount() const override;
166*0e209d39SAndroid Build Coastguard Worker 
167*0e209d39SAndroid Build Coastguard Worker     bool isStrong() const override;
168*0e209d39SAndroid Build Coastguard Worker 
169*0e209d39SAndroid Build Coastguard Worker     bool containsField(Field field) const override;
170*0e209d39SAndroid Build Coastguard Worker 
171*0e209d39SAndroid Build Coastguard Worker     void getParameters(Parameters& output) const override;
172*0e209d39SAndroid Build Coastguard Worker 
173*0e209d39SAndroid Build Coastguard Worker     bool strictEquals(const Modifier& other) const override;
174*0e209d39SAndroid Build Coastguard Worker 
175*0e209d39SAndroid Build Coastguard Worker   protected:
176*0e209d39SAndroid Build Coastguard Worker     // NOTE: In Java, these are stored as array pointers. In C++, the FormattedStringBuilder is stored by
177*0e209d39SAndroid Build Coastguard Worker     // value and is treated internally as immutable.
178*0e209d39SAndroid Build Coastguard Worker     FormattedStringBuilder fPrefix;
179*0e209d39SAndroid Build Coastguard Worker     FormattedStringBuilder fSuffix;
180*0e209d39SAndroid Build Coastguard Worker     bool fOverwrite;
181*0e209d39SAndroid Build Coastguard Worker     bool fStrong;
182*0e209d39SAndroid Build Coastguard Worker     Modifier::Parameters fParameters;
183*0e209d39SAndroid Build Coastguard Worker };
184*0e209d39SAndroid Build Coastguard Worker 
185*0e209d39SAndroid Build Coastguard Worker /** Identical to {@link ConstantMultiFieldModifier}, but supports currency spacing. */
186*0e209d39SAndroid Build Coastguard Worker class U_I18N_API CurrencySpacingEnabledModifier : public ConstantMultiFieldModifier {
187*0e209d39SAndroid Build Coastguard Worker   public:
188*0e209d39SAndroid Build Coastguard Worker     /** Safe code path */
189*0e209d39SAndroid Build Coastguard Worker     CurrencySpacingEnabledModifier(
190*0e209d39SAndroid Build Coastguard Worker             const FormattedStringBuilder &prefix,
191*0e209d39SAndroid Build Coastguard Worker             const FormattedStringBuilder &suffix,
192*0e209d39SAndroid Build Coastguard Worker             bool overwrite,
193*0e209d39SAndroid Build Coastguard Worker             bool strong,
194*0e209d39SAndroid Build Coastguard Worker             const DecimalFormatSymbols &symbols,
195*0e209d39SAndroid Build Coastguard Worker             UErrorCode &status);
196*0e209d39SAndroid Build Coastguard Worker 
197*0e209d39SAndroid Build Coastguard Worker     int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
198*0e209d39SAndroid Build Coastguard Worker                   UErrorCode &status) const override;
199*0e209d39SAndroid Build Coastguard Worker 
200*0e209d39SAndroid Build Coastguard Worker     /** Unsafe code path */
201*0e209d39SAndroid Build Coastguard Worker     static int32_t
202*0e209d39SAndroid Build Coastguard Worker     applyCurrencySpacing(FormattedStringBuilder &output, int32_t prefixStart, int32_t prefixLen,
203*0e209d39SAndroid Build Coastguard Worker                          int32_t suffixStart, int32_t suffixLen, const DecimalFormatSymbols &symbols,
204*0e209d39SAndroid Build Coastguard Worker                          UErrorCode &status);
205*0e209d39SAndroid Build Coastguard Worker 
206*0e209d39SAndroid Build Coastguard Worker   private:
207*0e209d39SAndroid Build Coastguard Worker     UnicodeSet fAfterPrefixUnicodeSet;
208*0e209d39SAndroid Build Coastguard Worker     UnicodeString fAfterPrefixInsert;
209*0e209d39SAndroid Build Coastguard Worker     UnicodeSet fBeforeSuffixUnicodeSet;
210*0e209d39SAndroid Build Coastguard Worker     UnicodeString fBeforeSuffixInsert;
211*0e209d39SAndroid Build Coastguard Worker 
212*0e209d39SAndroid Build Coastguard Worker     enum EAffix {
213*0e209d39SAndroid Build Coastguard Worker         PREFIX, SUFFIX
214*0e209d39SAndroid Build Coastguard Worker     };
215*0e209d39SAndroid Build Coastguard Worker 
216*0e209d39SAndroid Build Coastguard Worker     enum EPosition {
217*0e209d39SAndroid Build Coastguard Worker         IN_CURRENCY, IN_NUMBER
218*0e209d39SAndroid Build Coastguard Worker     };
219*0e209d39SAndroid Build Coastguard Worker 
220*0e209d39SAndroid Build Coastguard Worker     /** Unsafe code path */
221*0e209d39SAndroid Build Coastguard Worker     static int32_t applyCurrencySpacingAffix(FormattedStringBuilder &output, int32_t index, EAffix affix,
222*0e209d39SAndroid Build Coastguard Worker                                              const DecimalFormatSymbols &symbols, UErrorCode &status);
223*0e209d39SAndroid Build Coastguard Worker 
224*0e209d39SAndroid Build Coastguard Worker     static UnicodeSet
225*0e209d39SAndroid Build Coastguard Worker     getUnicodeSet(const DecimalFormatSymbols &symbols, EPosition position, EAffix affix,
226*0e209d39SAndroid Build Coastguard Worker                   UErrorCode &status);
227*0e209d39SAndroid Build Coastguard Worker 
228*0e209d39SAndroid Build Coastguard Worker     static UnicodeString
229*0e209d39SAndroid Build Coastguard Worker     getInsertString(const DecimalFormatSymbols &symbols, EAffix affix, UErrorCode &status);
230*0e209d39SAndroid Build Coastguard Worker };
231*0e209d39SAndroid Build Coastguard Worker 
232*0e209d39SAndroid Build Coastguard Worker /** A Modifier that does not do anything. */
233*0e209d39SAndroid Build Coastguard Worker class U_I18N_API EmptyModifier : public Modifier, public UMemory {
234*0e209d39SAndroid Build Coastguard Worker   public:
EmptyModifier(bool isStrong)235*0e209d39SAndroid Build Coastguard Worker     explicit EmptyModifier(bool isStrong) : fStrong(isStrong) {}
236*0e209d39SAndroid Build Coastguard Worker 
apply(FormattedStringBuilder & output,int32_t leftIndex,int32_t rightIndex,UErrorCode & status)237*0e209d39SAndroid Build Coastguard Worker     int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
238*0e209d39SAndroid Build Coastguard Worker                   UErrorCode &status) const override {
239*0e209d39SAndroid Build Coastguard Worker         (void)output;
240*0e209d39SAndroid Build Coastguard Worker         (void)leftIndex;
241*0e209d39SAndroid Build Coastguard Worker         (void)rightIndex;
242*0e209d39SAndroid Build Coastguard Worker         (void)status;
243*0e209d39SAndroid Build Coastguard Worker         return 0;
244*0e209d39SAndroid Build Coastguard Worker     }
245*0e209d39SAndroid Build Coastguard Worker 
getPrefixLength()246*0e209d39SAndroid Build Coastguard Worker     int32_t getPrefixLength() const override {
247*0e209d39SAndroid Build Coastguard Worker         return 0;
248*0e209d39SAndroid Build Coastguard Worker     }
249*0e209d39SAndroid Build Coastguard Worker 
getCodePointCount()250*0e209d39SAndroid Build Coastguard Worker     int32_t getCodePointCount() const override {
251*0e209d39SAndroid Build Coastguard Worker         return 0;
252*0e209d39SAndroid Build Coastguard Worker     }
253*0e209d39SAndroid Build Coastguard Worker 
isStrong()254*0e209d39SAndroid Build Coastguard Worker     bool isStrong() const override {
255*0e209d39SAndroid Build Coastguard Worker         return fStrong;
256*0e209d39SAndroid Build Coastguard Worker     }
257*0e209d39SAndroid Build Coastguard Worker 
containsField(Field field)258*0e209d39SAndroid Build Coastguard Worker     bool containsField(Field field) const override {
259*0e209d39SAndroid Build Coastguard Worker         (void)field;
260*0e209d39SAndroid Build Coastguard Worker         return false;
261*0e209d39SAndroid Build Coastguard Worker     }
262*0e209d39SAndroid Build Coastguard Worker 
getParameters(Parameters & output)263*0e209d39SAndroid Build Coastguard Worker     void getParameters(Parameters& output) const override {
264*0e209d39SAndroid Build Coastguard Worker         output.obj = nullptr;
265*0e209d39SAndroid Build Coastguard Worker     }
266*0e209d39SAndroid Build Coastguard Worker 
strictEquals(const Modifier & other)267*0e209d39SAndroid Build Coastguard Worker     bool strictEquals(const Modifier& other) const override {
268*0e209d39SAndroid Build Coastguard Worker         return other.getCodePointCount() == 0;
269*0e209d39SAndroid Build Coastguard Worker     }
270*0e209d39SAndroid Build Coastguard Worker 
271*0e209d39SAndroid Build Coastguard Worker   private:
272*0e209d39SAndroid Build Coastguard Worker     bool fStrong;
273*0e209d39SAndroid Build Coastguard Worker };
274*0e209d39SAndroid Build Coastguard Worker 
275*0e209d39SAndroid Build Coastguard Worker /** An adopting Modifier store that varies by signum but not plural form. */
276*0e209d39SAndroid Build Coastguard Worker class U_I18N_API AdoptingSignumModifierStore : public UMemory {
277*0e209d39SAndroid Build Coastguard Worker   public:
278*0e209d39SAndroid Build Coastguard Worker     virtual ~AdoptingSignumModifierStore();
279*0e209d39SAndroid Build Coastguard Worker 
280*0e209d39SAndroid Build Coastguard Worker     AdoptingSignumModifierStore() = default;
281*0e209d39SAndroid Build Coastguard Worker 
282*0e209d39SAndroid Build Coastguard Worker     // No copying!
283*0e209d39SAndroid Build Coastguard Worker     AdoptingSignumModifierStore(const AdoptingSignumModifierStore &other) = delete;
284*0e209d39SAndroid Build Coastguard Worker     AdoptingSignumModifierStore& operator=(const AdoptingSignumModifierStore& other) = delete;
285*0e209d39SAndroid Build Coastguard Worker 
286*0e209d39SAndroid Build Coastguard Worker     // Moving is OK
AdoptingSignumModifierStore(AdoptingSignumModifierStore && other)287*0e209d39SAndroid Build Coastguard Worker     AdoptingSignumModifierStore(AdoptingSignumModifierStore &&other) noexcept {
288*0e209d39SAndroid Build Coastguard Worker         *this = std::move(other);
289*0e209d39SAndroid Build Coastguard Worker     }
290*0e209d39SAndroid Build Coastguard Worker     AdoptingSignumModifierStore& operator=(AdoptingSignumModifierStore&& other) noexcept;
291*0e209d39SAndroid Build Coastguard Worker 
292*0e209d39SAndroid Build Coastguard Worker     /** Take ownership of the Modifier and slot it in at the given Signum. */
adoptModifier(Signum signum,const Modifier * mod)293*0e209d39SAndroid Build Coastguard Worker     void adoptModifier(Signum signum, const Modifier* mod) {
294*0e209d39SAndroid Build Coastguard Worker         U_ASSERT(mods[signum] == nullptr);
295*0e209d39SAndroid Build Coastguard Worker         mods[signum] = mod;
296*0e209d39SAndroid Build Coastguard Worker     }
297*0e209d39SAndroid Build Coastguard Worker 
298*0e209d39SAndroid Build Coastguard Worker     inline const Modifier*& operator[](Signum signum) {
299*0e209d39SAndroid Build Coastguard Worker         return mods[signum];
300*0e209d39SAndroid Build Coastguard Worker     }
301*0e209d39SAndroid Build Coastguard Worker     inline Modifier const* operator[](Signum signum) const {
302*0e209d39SAndroid Build Coastguard Worker         return mods[signum];
303*0e209d39SAndroid Build Coastguard Worker     }
304*0e209d39SAndroid Build Coastguard Worker 
305*0e209d39SAndroid Build Coastguard Worker   private:
306*0e209d39SAndroid Build Coastguard Worker     const Modifier* mods[SIGNUM_COUNT] = {};
307*0e209d39SAndroid Build Coastguard Worker };
308*0e209d39SAndroid Build Coastguard Worker 
309*0e209d39SAndroid Build Coastguard Worker /**
310*0e209d39SAndroid Build Coastguard Worker  * This implementation of ModifierStore adopts Modifier pointers.
311*0e209d39SAndroid Build Coastguard Worker  */
312*0e209d39SAndroid Build Coastguard Worker class U_I18N_API AdoptingModifierStore : public ModifierStore, public UMemory {
313*0e209d39SAndroid Build Coastguard Worker   public:
314*0e209d39SAndroid Build Coastguard Worker     static constexpr StandardPlural::Form DEFAULT_STANDARD_PLURAL = StandardPlural::OTHER;
315*0e209d39SAndroid Build Coastguard Worker 
316*0e209d39SAndroid Build Coastguard Worker     AdoptingModifierStore() = default;
317*0e209d39SAndroid Build Coastguard Worker 
318*0e209d39SAndroid Build Coastguard Worker     // No copying!
319*0e209d39SAndroid Build Coastguard Worker     AdoptingModifierStore(const AdoptingModifierStore &other) = delete;
320*0e209d39SAndroid Build Coastguard Worker 
321*0e209d39SAndroid Build Coastguard Worker     // Moving is OK
322*0e209d39SAndroid Build Coastguard Worker     AdoptingModifierStore(AdoptingModifierStore &&other) = default;
323*0e209d39SAndroid Build Coastguard Worker 
324*0e209d39SAndroid Build Coastguard Worker     /** Sets the modifiers for a specific plural form. */
adoptSignumModifierStore(StandardPlural::Form plural,AdoptingSignumModifierStore other)325*0e209d39SAndroid Build Coastguard Worker     void adoptSignumModifierStore(StandardPlural::Form plural, AdoptingSignumModifierStore other) {
326*0e209d39SAndroid Build Coastguard Worker         mods[plural] = std::move(other);
327*0e209d39SAndroid Build Coastguard Worker     }
328*0e209d39SAndroid Build Coastguard Worker 
329*0e209d39SAndroid Build Coastguard Worker     /** Sets the modifiers for the default plural form. */
adoptSignumModifierStoreNoPlural(AdoptingSignumModifierStore other)330*0e209d39SAndroid Build Coastguard Worker     void adoptSignumModifierStoreNoPlural(AdoptingSignumModifierStore other) {
331*0e209d39SAndroid Build Coastguard Worker         mods[DEFAULT_STANDARD_PLURAL] = std::move(other);
332*0e209d39SAndroid Build Coastguard Worker     }
333*0e209d39SAndroid Build Coastguard Worker 
334*0e209d39SAndroid Build Coastguard Worker     /** Returns a reference to the modifier; no ownership change. */
getModifier(Signum signum,StandardPlural::Form plural)335*0e209d39SAndroid Build Coastguard Worker     const Modifier *getModifier(Signum signum, StandardPlural::Form plural) const override {
336*0e209d39SAndroid Build Coastguard Worker         const Modifier* modifier = mods[plural][signum];
337*0e209d39SAndroid Build Coastguard Worker         if (modifier == nullptr && plural != DEFAULT_STANDARD_PLURAL) {
338*0e209d39SAndroid Build Coastguard Worker             modifier = mods[DEFAULT_STANDARD_PLURAL][signum];
339*0e209d39SAndroid Build Coastguard Worker         }
340*0e209d39SAndroid Build Coastguard Worker         return modifier;
341*0e209d39SAndroid Build Coastguard Worker     }
342*0e209d39SAndroid Build Coastguard Worker 
343*0e209d39SAndroid Build Coastguard Worker     /** Returns a reference to the modifier; no ownership change. */
getModifierWithoutPlural(Signum signum)344*0e209d39SAndroid Build Coastguard Worker     const Modifier *getModifierWithoutPlural(Signum signum) const {
345*0e209d39SAndroid Build Coastguard Worker         return mods[DEFAULT_STANDARD_PLURAL][signum];
346*0e209d39SAndroid Build Coastguard Worker     }
347*0e209d39SAndroid Build Coastguard Worker 
348*0e209d39SAndroid Build Coastguard Worker   private:
349*0e209d39SAndroid Build Coastguard Worker     // NOTE: mods is zero-initialized (to nullptr)
350*0e209d39SAndroid Build Coastguard Worker     AdoptingSignumModifierStore mods[StandardPlural::COUNT] = {};
351*0e209d39SAndroid Build Coastguard Worker };
352*0e209d39SAndroid Build Coastguard Worker 
353*0e209d39SAndroid Build Coastguard Worker } // namespace number::impl
354*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END
355*0e209d39SAndroid Build Coastguard Worker 
356*0e209d39SAndroid Build Coastguard Worker 
357*0e209d39SAndroid Build Coastguard Worker #endif //__NUMBER_MODIFIERS_H__
358*0e209d39SAndroid Build Coastguard Worker 
359*0e209d39SAndroid Build Coastguard Worker #endif /* #if !UCONFIG_NO_FORMATTING */
360