/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 */  |