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 µs, 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 == µs) { 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