diff options
Diffstat (limited to 'intl/icu/source/i18n/number_microprops.h')
-rw-r--r-- | intl/icu/source/i18n/number_microprops.h | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/intl/icu/source/i18n/number_microprops.h b/intl/icu/source/i18n/number_microprops.h new file mode 100644 index 0000000000..18addaae08 --- /dev/null +++ b/intl/icu/source/i18n/number_microprops.h @@ -0,0 +1,197 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_FORMATTING +#ifndef __NUMBER_MICROPROPS_H__ +#define __NUMBER_MICROPROPS_H__ + +// TODO: minimize includes +#include "unicode/numberformatter.h" +#include "number_types.h" +#include "number_decimalquantity.h" +#include "number_scientific.h" +#include "number_patternstring.h" +#include "number_modifiers.h" +#include "number_multiplier.h" +#include "number_roundingutils.h" +#include "decNumber.h" +#include "charstr.h" +#include "util.h" + +U_NAMESPACE_BEGIN namespace number { +namespace impl { + +/** + * A copyable container for the integer values of mixed unit measurements. + * + * If memory allocation fails during copying, no values are copied and status is + * set to U_MEMORY_ALLOCATION_ERROR. + */ +class IntMeasures : public MaybeStackArray<int64_t, 2> { + public: + /** + * Default constructor initializes with internal T[stackCapacity] buffer. + * + * Stack Capacity: most mixed units are expected to consist of two or three + * subunits, so one or two integer measures should be enough. + */ + IntMeasures() : MaybeStackArray<int64_t, 2>() {} + + /** + * Copy constructor. + * + * If memory allocation fails during copying, no values are copied and + * status is set to U_MEMORY_ALLOCATION_ERROR. + */ + IntMeasures(const IntMeasures &other) : MaybeStackArray<int64_t, 2>() { + this->operator=(other); + } + + // Assignment operator + IntMeasures &operator=(const IntMeasures &rhs) { + if (this == &rhs) { + return *this; + } + copyFrom(rhs, status); + return *this; + } + + /** Move constructor */ + IntMeasures(IntMeasures &&src) = default; + + /** Move assignment */ + IntMeasures &operator=(IntMeasures &&src) = default; + + UErrorCode status = U_ZERO_ERROR; +}; + +struct SimpleMicroProps : public UMemory { + Grouper grouping; + bool useCurrency = false; + UNumberDecimalSeparatorDisplay decimal = UNUM_DECIMAL_SEPARATOR_AUTO; + + // Currency symbol to be used as the decimal separator + UnicodeString currencyAsDecimal = ICU_Utility::makeBogusString(); + + // Note: This struct has no direct ownership of the following pointer. + const DecimalFormatSymbols* symbols = nullptr; +}; + +/** + * MicroProps is the first MicroPropsGenerator that should be should be called, + * producing an initialized MicroProps instance that will be passed on and + * modified throughout the rest of the chain of MicroPropsGenerator instances. + */ +struct MicroProps : public MicroPropsGenerator { + SimpleMicroProps simple; + + // NOTE: All of these fields are properly initialized in NumberFormatterImpl. + RoundingImpl rounder; + Padder padding; + IntegerWidth integerWidth; + UNumberSignDisplay sign; + char nsName[9]; + + // No ownership: must point at a string which will outlive MicroProps + // instances, e.g. a string with static storage duration, or just a string + // that will never be deallocated or modified. + const char *gender; + + // Note: This struct has no direct ownership of the following pointers. + + // Pointers to Modifiers provided by the number formatting pipeline (when + // the value is known): + + // A Modifier provided by LongNameHandler, used for currency long names and + // units. If there is no LongNameHandler needed, this should be an + // EmptyModifier. (This is typically the third modifier applied.) + const Modifier* modOuter; + // A Modifier for short currencies and compact notation. (This is typically + // the second modifier applied.) + const Modifier* modMiddle = nullptr; + // A Modifier provided by ScientificHandler, used for scientific notation. + // This is typically the first modifier applied. + const Modifier* modInner; + + // The following "helper" fields may optionally be used during the MicroPropsGenerator. + // They live here to retain memory. + struct { + // The ScientificModifier for which ScientificHandler is responsible. + // ScientificHandler::processQuantity() modifies this Modifier. + ScientificModifier scientificModifier; + // EmptyModifier used for modOuter + EmptyModifier emptyWeakModifier{false}; + // EmptyModifier used for modInner + EmptyModifier emptyStrongModifier{true}; + MultiplierFormatHandler multiplier; + // A Modifier used for Mixed Units. When formatting mixed units, + // LongNameHandler assigns this Modifier. + SimpleModifier mixedUnitModifier; + } helpers; + + // The MeasureUnit with which the output is represented. May also have + // UMEASURE_UNIT_MIXED complexity, in which case mixedMeasures comes into + // play. + MeasureUnit outputUnit; + + // Contains all the values of each unit in mixed units. For quantity (which is the floating value of + // the smallest unit in the mixed unit), the value stores in `quantity`. + // NOTE: the value of quantity in `mixedMeasures` will be left unset. + IntMeasures mixedMeasures; + + // Points to quantity position, -1 if the position is not set yet. + int32_t indexOfQuantity = -1; + + // Number of mixedMeasures that have been populated + int32_t mixedMeasuresCount = 0; + + MicroProps() = default; + + MicroProps(const MicroProps& other) = default; + + MicroProps& operator=(const MicroProps& other) = default; + + /** + * As MicroProps is the "base instance", this implementation of + * MicroPropsGenerator::processQuantity() just ensures that the output + * `micros` is correctly initialized. + * + * For the "safe" invocation of this function, micros must not be *this, + * such that a copy of the base instance is made. For the "unsafe" path, + * this function can be used only once, because the base MicroProps instance + * will be modified and thus not be available for re-use. + * + * @param quantity The quantity for consideration and optional mutation. + * @param micros The MicroProps instance to populate. If this parameter is + * not already `*this`, it will be overwritten with a copy of `*this`. + */ + void processQuantity(DecimalQuantity &quantity, MicroProps µs, + UErrorCode &status) const override { + (void) quantity; + (void) status; + if (this == µs) { + // Unsafe path: no need to perform a copy. + U_ASSERT(!exhausted); + micros.exhausted = true; + U_ASSERT(exhausted); + } else { + // Safe path: copy self into the output micros. + U_ASSERT(!exhausted); + micros = *this; + } + } + + private: + // Internal fields: + bool exhausted = false; +}; + +} // namespace impl +} // namespace number +U_NAMESPACE_END + +#endif // __NUMBER_MICROPROPS_H__ + +#endif /* #if !UCONFIG_NO_FORMATTING */ |