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