xref: /aosp_15_r20/external/icu/libicu/cts_headers/number_microprops.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_MICROPROPS_H__
8*0e209d39SAndroid Build Coastguard Worker #define __NUMBER_MICROPROPS_H__
9*0e209d39SAndroid Build Coastguard Worker 
10*0e209d39SAndroid Build Coastguard Worker // TODO: minimize includes
11*0e209d39SAndroid Build Coastguard Worker #include "unicode/numberformatter.h"
12*0e209d39SAndroid Build Coastguard Worker #include "number_types.h"
13*0e209d39SAndroid Build Coastguard Worker #include "number_decimalquantity.h"
14*0e209d39SAndroid Build Coastguard Worker #include "number_scientific.h"
15*0e209d39SAndroid Build Coastguard Worker #include "number_patternstring.h"
16*0e209d39SAndroid Build Coastguard Worker #include "number_modifiers.h"
17*0e209d39SAndroid Build Coastguard Worker #include "number_multiplier.h"
18*0e209d39SAndroid Build Coastguard Worker #include "number_roundingutils.h"
19*0e209d39SAndroid Build Coastguard Worker #include "decNumber.h"
20*0e209d39SAndroid Build Coastguard Worker #include "charstr.h"
21*0e209d39SAndroid Build Coastguard Worker #include "util.h"
22*0e209d39SAndroid Build Coastguard Worker 
23*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN
24*0e209d39SAndroid Build Coastguard Worker namespace number::impl {
25*0e209d39SAndroid Build Coastguard Worker 
26*0e209d39SAndroid Build Coastguard Worker /**
27*0e209d39SAndroid Build Coastguard Worker  * A copyable container for the integer values of mixed unit measurements.
28*0e209d39SAndroid Build Coastguard Worker  *
29*0e209d39SAndroid Build Coastguard Worker  * If memory allocation fails during copying, no values are copied and status is
30*0e209d39SAndroid Build Coastguard Worker  * set to U_MEMORY_ALLOCATION_ERROR.
31*0e209d39SAndroid Build Coastguard Worker  */
32*0e209d39SAndroid Build Coastguard Worker class IntMeasures : public MaybeStackArray<int64_t, 2> {
33*0e209d39SAndroid Build Coastguard Worker   public:
34*0e209d39SAndroid Build Coastguard Worker     /**
35*0e209d39SAndroid Build Coastguard Worker      * Default constructor initializes with internal T[stackCapacity] buffer.
36*0e209d39SAndroid Build Coastguard Worker      *
37*0e209d39SAndroid Build Coastguard Worker      * Stack Capacity: most mixed units are expected to consist of two or three
38*0e209d39SAndroid Build Coastguard Worker      * subunits, so one or two integer measures should be enough.
39*0e209d39SAndroid Build Coastguard Worker      */
IntMeasures()40*0e209d39SAndroid Build Coastguard Worker     IntMeasures() : MaybeStackArray<int64_t, 2>() {}
41*0e209d39SAndroid Build Coastguard Worker 
42*0e209d39SAndroid Build Coastguard Worker     /**
43*0e209d39SAndroid Build Coastguard Worker      * Copy constructor.
44*0e209d39SAndroid Build Coastguard Worker      *
45*0e209d39SAndroid Build Coastguard Worker      * If memory allocation fails during copying, no values are copied and
46*0e209d39SAndroid Build Coastguard Worker      * status is set to U_MEMORY_ALLOCATION_ERROR.
47*0e209d39SAndroid Build Coastguard Worker      */
IntMeasures(const IntMeasures & other)48*0e209d39SAndroid Build Coastguard Worker     IntMeasures(const IntMeasures &other) : MaybeStackArray<int64_t, 2>() {
49*0e209d39SAndroid Build Coastguard Worker         this->operator=(other);
50*0e209d39SAndroid Build Coastguard Worker     }
51*0e209d39SAndroid Build Coastguard Worker 
52*0e209d39SAndroid Build Coastguard Worker     // Assignment operator
53*0e209d39SAndroid Build Coastguard Worker     IntMeasures &operator=(const IntMeasures &rhs) {
54*0e209d39SAndroid Build Coastguard Worker         if (this == &rhs) {
55*0e209d39SAndroid Build Coastguard Worker             return *this;
56*0e209d39SAndroid Build Coastguard Worker         }
57*0e209d39SAndroid Build Coastguard Worker         copyFrom(rhs, status);
58*0e209d39SAndroid Build Coastguard Worker         return *this;
59*0e209d39SAndroid Build Coastguard Worker     }
60*0e209d39SAndroid Build Coastguard Worker 
61*0e209d39SAndroid Build Coastguard Worker     /** Move constructor */
62*0e209d39SAndroid Build Coastguard Worker     IntMeasures(IntMeasures &&src) = default;
63*0e209d39SAndroid Build Coastguard Worker 
64*0e209d39SAndroid Build Coastguard Worker     /** Move assignment */
65*0e209d39SAndroid Build Coastguard Worker     IntMeasures &operator=(IntMeasures &&src) = default;
66*0e209d39SAndroid Build Coastguard Worker 
67*0e209d39SAndroid Build Coastguard Worker     UErrorCode status = U_ZERO_ERROR;
68*0e209d39SAndroid Build Coastguard Worker };
69*0e209d39SAndroid Build Coastguard Worker 
70*0e209d39SAndroid Build Coastguard Worker struct SimpleMicroProps : public UMemory {
71*0e209d39SAndroid Build Coastguard Worker     Grouper grouping;
72*0e209d39SAndroid Build Coastguard Worker     bool useCurrency = false;
73*0e209d39SAndroid Build Coastguard Worker     UNumberDecimalSeparatorDisplay decimal = UNUM_DECIMAL_SEPARATOR_AUTO;
74*0e209d39SAndroid Build Coastguard Worker 
75*0e209d39SAndroid Build Coastguard Worker     // Currency symbol to be used as the decimal separator
76*0e209d39SAndroid Build Coastguard Worker     UnicodeString currencyAsDecimal = ICU_Utility::makeBogusString();
77*0e209d39SAndroid Build Coastguard Worker 
78*0e209d39SAndroid Build Coastguard Worker     // Note: This struct has no direct ownership of the following pointer.
79*0e209d39SAndroid Build Coastguard Worker     const DecimalFormatSymbols* symbols = nullptr;
80*0e209d39SAndroid Build Coastguard Worker };
81*0e209d39SAndroid Build Coastguard Worker 
82*0e209d39SAndroid Build Coastguard Worker /**
83*0e209d39SAndroid Build Coastguard Worker  * MicroProps is the first MicroPropsGenerator that should be should be called,
84*0e209d39SAndroid Build Coastguard Worker  * producing an initialized MicroProps instance that will be passed on and
85*0e209d39SAndroid Build Coastguard Worker  * modified throughout the rest of the chain of MicroPropsGenerator instances.
86*0e209d39SAndroid Build Coastguard Worker  */
87*0e209d39SAndroid Build Coastguard Worker struct MicroProps : public MicroPropsGenerator {
88*0e209d39SAndroid Build Coastguard Worker     SimpleMicroProps simple;
89*0e209d39SAndroid Build Coastguard Worker 
90*0e209d39SAndroid Build Coastguard Worker     // NOTE: All of these fields are properly initialized in NumberFormatterImpl.
91*0e209d39SAndroid Build Coastguard Worker     RoundingImpl rounder;
92*0e209d39SAndroid Build Coastguard Worker     Padder padding;
93*0e209d39SAndroid Build Coastguard Worker     IntegerWidth integerWidth;
94*0e209d39SAndroid Build Coastguard Worker     UNumberSignDisplay sign;
95*0e209d39SAndroid Build Coastguard Worker     char nsName[9];
96*0e209d39SAndroid Build Coastguard Worker 
97*0e209d39SAndroid Build Coastguard Worker     // No ownership: must point at a string which will outlive MicroProps
98*0e209d39SAndroid Build Coastguard Worker     // instances, e.g. a string with static storage duration, or just a string
99*0e209d39SAndroid Build Coastguard Worker     // that will never be deallocated or modified.
100*0e209d39SAndroid Build Coastguard Worker     const char *gender;
101*0e209d39SAndroid Build Coastguard Worker 
102*0e209d39SAndroid Build Coastguard Worker     // Note: This struct has no direct ownership of the following pointers.
103*0e209d39SAndroid Build Coastguard Worker 
104*0e209d39SAndroid Build Coastguard Worker     // Pointers to Modifiers provided by the number formatting pipeline (when
105*0e209d39SAndroid Build Coastguard Worker     // the value is known):
106*0e209d39SAndroid Build Coastguard Worker 
107*0e209d39SAndroid Build Coastguard Worker     // A Modifier provided by LongNameHandler, used for currency long names and
108*0e209d39SAndroid Build Coastguard Worker     // units. If there is no LongNameHandler needed, this should be an
109*0e209d39SAndroid Build Coastguard Worker     // EmptyModifier. (This is typically the third modifier applied.)
110*0e209d39SAndroid Build Coastguard Worker     const Modifier* modOuter;
111*0e209d39SAndroid Build Coastguard Worker     // A Modifier for short currencies and compact notation. (This is typically
112*0e209d39SAndroid Build Coastguard Worker     // the second modifier applied.)
113*0e209d39SAndroid Build Coastguard Worker     const Modifier* modMiddle = nullptr;
114*0e209d39SAndroid Build Coastguard Worker     // A Modifier provided by ScientificHandler, used for scientific notation.
115*0e209d39SAndroid Build Coastguard Worker     // This is typically the first modifier applied.
116*0e209d39SAndroid Build Coastguard Worker     const Modifier* modInner;
117*0e209d39SAndroid Build Coastguard Worker 
118*0e209d39SAndroid Build Coastguard Worker     // The following "helper" fields may optionally be used during the MicroPropsGenerator.
119*0e209d39SAndroid Build Coastguard Worker     // They live here to retain memory.
120*0e209d39SAndroid Build Coastguard Worker     struct {
121*0e209d39SAndroid Build Coastguard Worker         // The ScientificModifier for which ScientificHandler is responsible.
122*0e209d39SAndroid Build Coastguard Worker         // ScientificHandler::processQuantity() modifies this Modifier.
123*0e209d39SAndroid Build Coastguard Worker         ScientificModifier scientificModifier;
124*0e209d39SAndroid Build Coastguard Worker         // EmptyModifier used for modOuter
125*0e209d39SAndroid Build Coastguard Worker         EmptyModifier emptyWeakModifier{false};
126*0e209d39SAndroid Build Coastguard Worker         // EmptyModifier used for modInner
127*0e209d39SAndroid Build Coastguard Worker         EmptyModifier emptyStrongModifier{true};
128*0e209d39SAndroid Build Coastguard Worker         MultiplierFormatHandler multiplier;
129*0e209d39SAndroid Build Coastguard Worker         // A Modifier used for Mixed Units. When formatting mixed units,
130*0e209d39SAndroid Build Coastguard Worker         // LongNameHandler assigns this Modifier.
131*0e209d39SAndroid Build Coastguard Worker         SimpleModifier mixedUnitModifier;
132*0e209d39SAndroid Build Coastguard Worker     } helpers;
133*0e209d39SAndroid Build Coastguard Worker 
134*0e209d39SAndroid Build Coastguard Worker     // The MeasureUnit with which the output is represented. May also have
135*0e209d39SAndroid Build Coastguard Worker     // UMEASURE_UNIT_MIXED complexity, in which case mixedMeasures comes into
136*0e209d39SAndroid Build Coastguard Worker     // play.
137*0e209d39SAndroid Build Coastguard Worker     MeasureUnit outputUnit;
138*0e209d39SAndroid Build Coastguard Worker 
139*0e209d39SAndroid Build Coastguard Worker     // Contains all the values of each unit in mixed units. For quantity (which is the floating value of
140*0e209d39SAndroid Build Coastguard Worker     // the smallest unit in the mixed unit), the value stores in `quantity`.
141*0e209d39SAndroid Build Coastguard Worker     // NOTE: the value of quantity in `mixedMeasures` will be left unset.
142*0e209d39SAndroid Build Coastguard Worker     IntMeasures mixedMeasures;
143*0e209d39SAndroid Build Coastguard Worker 
144*0e209d39SAndroid Build Coastguard Worker     // Points to quantity position, -1 if the position is not set yet.
145*0e209d39SAndroid Build Coastguard Worker     int32_t indexOfQuantity = -1;
146*0e209d39SAndroid Build Coastguard Worker 
147*0e209d39SAndroid Build Coastguard Worker     // Number of mixedMeasures that have been populated
148*0e209d39SAndroid Build Coastguard Worker     int32_t mixedMeasuresCount = 0;
149*0e209d39SAndroid Build Coastguard Worker 
150*0e209d39SAndroid Build Coastguard Worker     MicroProps() = default;
151*0e209d39SAndroid Build Coastguard Worker 
152*0e209d39SAndroid Build Coastguard Worker     MicroProps(const MicroProps& other) = default;
153*0e209d39SAndroid Build Coastguard Worker 
154*0e209d39SAndroid Build Coastguard Worker     MicroProps& operator=(const MicroProps& other) = default;
155*0e209d39SAndroid Build Coastguard Worker 
156*0e209d39SAndroid Build Coastguard Worker     /**
157*0e209d39SAndroid Build Coastguard Worker      * As MicroProps is the "base instance", this implementation of
158*0e209d39SAndroid Build Coastguard Worker      * MicroPropsGenerator::processQuantity() just ensures that the output
159*0e209d39SAndroid Build Coastguard Worker      * `micros` is correctly initialized.
160*0e209d39SAndroid Build Coastguard Worker      *
161*0e209d39SAndroid Build Coastguard Worker      * For the "safe" invocation of this function, micros must not be *this,
162*0e209d39SAndroid Build Coastguard Worker      * such that a copy of the base instance is made. For the "unsafe" path,
163*0e209d39SAndroid Build Coastguard Worker      * this function can be used only once, because the base MicroProps instance
164*0e209d39SAndroid Build Coastguard Worker      * will be modified and thus not be available for re-use.
165*0e209d39SAndroid Build Coastguard Worker      *
166*0e209d39SAndroid Build Coastguard Worker      * @param quantity The quantity for consideration and optional mutation.
167*0e209d39SAndroid Build Coastguard Worker      * @param micros The MicroProps instance to populate. If this parameter is
168*0e209d39SAndroid Build Coastguard Worker      * not already `*this`, it will be overwritten with a copy of `*this`.
169*0e209d39SAndroid Build Coastguard Worker      */
processQuantityMicroProps170*0e209d39SAndroid Build Coastguard Worker     void processQuantity(DecimalQuantity &quantity, MicroProps &micros,
171*0e209d39SAndroid Build Coastguard Worker                          UErrorCode &status) const override {
172*0e209d39SAndroid Build Coastguard Worker         (void) quantity;
173*0e209d39SAndroid Build Coastguard Worker         (void) status;
174*0e209d39SAndroid Build Coastguard Worker         if (this == &micros) {
175*0e209d39SAndroid Build Coastguard Worker             // Unsafe path: no need to perform a copy.
176*0e209d39SAndroid Build Coastguard Worker             U_ASSERT(!exhausted);
177*0e209d39SAndroid Build Coastguard Worker             micros.exhausted = true;
178*0e209d39SAndroid Build Coastguard Worker             U_ASSERT(exhausted);
179*0e209d39SAndroid Build Coastguard Worker         } else {
180*0e209d39SAndroid Build Coastguard Worker             // Safe path: copy self into the output micros.
181*0e209d39SAndroid Build Coastguard Worker             U_ASSERT(!exhausted);
182*0e209d39SAndroid Build Coastguard Worker             micros = *this;
183*0e209d39SAndroid Build Coastguard Worker         }
184*0e209d39SAndroid Build Coastguard Worker     }
185*0e209d39SAndroid Build Coastguard Worker 
186*0e209d39SAndroid Build Coastguard Worker   private:
187*0e209d39SAndroid Build Coastguard Worker     // Internal fields:
188*0e209d39SAndroid Build Coastguard Worker     bool exhausted = false;
189*0e209d39SAndroid Build Coastguard Worker };
190*0e209d39SAndroid Build Coastguard Worker 
191*0e209d39SAndroid Build Coastguard Worker } // namespace number::impl
192*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END
193*0e209d39SAndroid Build Coastguard Worker 
194*0e209d39SAndroid Build Coastguard Worker #endif // __NUMBER_MICROPROPS_H__
195*0e209d39SAndroid Build Coastguard Worker 
196*0e209d39SAndroid Build Coastguard Worker #endif /* #if !UCONFIG_NO_FORMATTING */
197