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_PATTERNMODIFIER_H__ 8*0e209d39SAndroid Build Coastguard Worker #define __NUMBER_PATTERNMODIFIER_H__ 9*0e209d39SAndroid Build Coastguard Worker 10*0e209d39SAndroid Build Coastguard Worker #include "standardplural.h" 11*0e209d39SAndroid Build Coastguard Worker #include "unicode/numberformatter.h" 12*0e209d39SAndroid Build Coastguard Worker #include "number_patternstring.h" 13*0e209d39SAndroid Build Coastguard Worker #include "number_types.h" 14*0e209d39SAndroid Build Coastguard Worker #include "number_modifiers.h" 15*0e209d39SAndroid Build Coastguard Worker #include "number_utils.h" 16*0e209d39SAndroid Build Coastguard Worker #include "number_currencysymbols.h" 17*0e209d39SAndroid Build Coastguard Worker 18*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN 19*0e209d39SAndroid Build Coastguard Worker 20*0e209d39SAndroid Build Coastguard Worker // Export an explicit template instantiation of the LocalPointer that is used as a 21*0e209d39SAndroid Build Coastguard Worker // data member of AdoptingModifierStore. 22*0e209d39SAndroid Build Coastguard Worker // (When building DLLs for Windows this is required.) 23*0e209d39SAndroid Build Coastguard Worker #if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN 24*0e209d39SAndroid Build Coastguard Worker #if defined(_MSC_VER) 25*0e209d39SAndroid Build Coastguard Worker // Ignore warning 4661 as LocalPointerBase does not use operator== or operator!= 26*0e209d39SAndroid Build Coastguard Worker #pragma warning(push) 27*0e209d39SAndroid Build Coastguard Worker #pragma warning(disable : 4661) 28*0e209d39SAndroid Build Coastguard Worker #endif 29*0e209d39SAndroid Build Coastguard Worker template class U_I18N_API LocalPointerBase<number::impl::AdoptingModifierStore>; 30*0e209d39SAndroid Build Coastguard Worker template class U_I18N_API LocalPointer<number::impl::AdoptingModifierStore>; 31*0e209d39SAndroid Build Coastguard Worker #if defined(_MSC_VER) 32*0e209d39SAndroid Build Coastguard Worker #pragma warning(pop) 33*0e209d39SAndroid Build Coastguard Worker #endif 34*0e209d39SAndroid Build Coastguard Worker #endif 35*0e209d39SAndroid Build Coastguard Worker 36*0e209d39SAndroid Build Coastguard Worker namespace number::impl { 37*0e209d39SAndroid Build Coastguard Worker 38*0e209d39SAndroid Build Coastguard Worker // Forward declaration 39*0e209d39SAndroid Build Coastguard Worker class MutablePatternModifier; 40*0e209d39SAndroid Build Coastguard Worker 41*0e209d39SAndroid Build Coastguard Worker // Exported as U_I18N_API because it is needed for the unit test PatternModifierTest 42*0e209d39SAndroid Build Coastguard Worker class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public UMemory { 43*0e209d39SAndroid Build Coastguard Worker public: 44*0e209d39SAndroid Build Coastguard Worker ~ImmutablePatternModifier() override = default; 45*0e209d39SAndroid Build Coastguard Worker 46*0e209d39SAndroid Build Coastguard Worker void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const override; 47*0e209d39SAndroid Build Coastguard Worker 48*0e209d39SAndroid Build Coastguard Worker void applyToMicros(MicroProps& micros, const DecimalQuantity& quantity, UErrorCode& status) const; 49*0e209d39SAndroid Build Coastguard Worker 50*0e209d39SAndroid Build Coastguard Worker const Modifier* getModifier(Signum signum, StandardPlural::Form plural) const; 51*0e209d39SAndroid Build Coastguard Worker 52*0e209d39SAndroid Build Coastguard Worker // Non-const method: 53*0e209d39SAndroid Build Coastguard Worker void addToChain(const MicroPropsGenerator* parent); 54*0e209d39SAndroid Build Coastguard Worker 55*0e209d39SAndroid Build Coastguard Worker private: 56*0e209d39SAndroid Build Coastguard Worker ImmutablePatternModifier(AdoptingModifierStore* pm, const PluralRules* rules); 57*0e209d39SAndroid Build Coastguard Worker 58*0e209d39SAndroid Build Coastguard Worker const LocalPointer<AdoptingModifierStore> pm; 59*0e209d39SAndroid Build Coastguard Worker const PluralRules* rules; 60*0e209d39SAndroid Build Coastguard Worker const MicroPropsGenerator* parent; 61*0e209d39SAndroid Build Coastguard Worker 62*0e209d39SAndroid Build Coastguard Worker friend class MutablePatternModifier; 63*0e209d39SAndroid Build Coastguard Worker }; 64*0e209d39SAndroid Build Coastguard Worker 65*0e209d39SAndroid Build Coastguard Worker /** 66*0e209d39SAndroid Build Coastguard Worker * This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in 67*0e209d39SAndroid Build Coastguard Worker * {@link Modifier#apply}. 68*0e209d39SAndroid Build Coastguard Worker * 69*0e209d39SAndroid Build Coastguard Worker * <p> 70*0e209d39SAndroid Build Coastguard Worker * In addition to being a Modifier, this class contains the business logic for substituting the correct locale symbols 71*0e209d39SAndroid Build Coastguard Worker * into the affixes of the decimal format pattern. 72*0e209d39SAndroid Build Coastguard Worker * 73*0e209d39SAndroid Build Coastguard Worker * <p> 74*0e209d39SAndroid Build Coastguard Worker * In order to use this class, create a new instance and call the following four setters: {@link #setPatternInfo}, 75*0e209d39SAndroid Build Coastguard Worker * {@link #setPatternAttributes}, {@link #setSymbols}, and {@link #setNumberProperties}. After calling these four 76*0e209d39SAndroid Build Coastguard Worker * setters, the instance will be ready for use as a Modifier. 77*0e209d39SAndroid Build Coastguard Worker * 78*0e209d39SAndroid Build Coastguard Worker * <p> 79*0e209d39SAndroid Build Coastguard Worker * This is a MUTABLE, NON-THREAD-SAFE class designed for performance. Do NOT save references to this or attempt to use 80*0e209d39SAndroid Build Coastguard Worker * it from multiple threads! Instead, you can obtain a safe, immutable decimal format pattern modifier by calling 81*0e209d39SAndroid Build Coastguard Worker * {@link MutablePatternModifier#createImmutable}, in effect treating this instance as a builder for the immutable 82*0e209d39SAndroid Build Coastguard Worker * variant. 83*0e209d39SAndroid Build Coastguard Worker */ 84*0e209d39SAndroid Build Coastguard Worker class U_I18N_API MutablePatternModifier 85*0e209d39SAndroid Build Coastguard Worker : public MicroPropsGenerator, 86*0e209d39SAndroid Build Coastguard Worker public Modifier, 87*0e209d39SAndroid Build Coastguard Worker public SymbolProvider, 88*0e209d39SAndroid Build Coastguard Worker public UMemory { 89*0e209d39SAndroid Build Coastguard Worker public: 90*0e209d39SAndroid Build Coastguard Worker 91*0e209d39SAndroid Build Coastguard Worker ~MutablePatternModifier() override = default; 92*0e209d39SAndroid Build Coastguard Worker 93*0e209d39SAndroid Build Coastguard Worker /** 94*0e209d39SAndroid Build Coastguard Worker * @param isStrong 95*0e209d39SAndroid Build Coastguard Worker * Whether the modifier should be considered strong. For more information, see 96*0e209d39SAndroid Build Coastguard Worker * {@link Modifier#isStrong()}. Most of the time, decimal format pattern modifiers should be considered 97*0e209d39SAndroid Build Coastguard Worker * as non-strong. 98*0e209d39SAndroid Build Coastguard Worker */ 99*0e209d39SAndroid Build Coastguard Worker explicit MutablePatternModifier(bool isStrong); 100*0e209d39SAndroid Build Coastguard Worker 101*0e209d39SAndroid Build Coastguard Worker /** 102*0e209d39SAndroid Build Coastguard Worker * Sets a reference to the parsed decimal format pattern, usually obtained from 103*0e209d39SAndroid Build Coastguard Worker * {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of {@link AffixPatternProvider} is 104*0e209d39SAndroid Build Coastguard Worker * accepted. 105*0e209d39SAndroid Build Coastguard Worker * 106*0e209d39SAndroid Build Coastguard Worker * @param field 107*0e209d39SAndroid Build Coastguard Worker * Which field to use for literal characters in the pattern. 108*0e209d39SAndroid Build Coastguard Worker */ 109*0e209d39SAndroid Build Coastguard Worker void setPatternInfo(const AffixPatternProvider *patternInfo, Field field); 110*0e209d39SAndroid Build Coastguard Worker 111*0e209d39SAndroid Build Coastguard Worker /** 112*0e209d39SAndroid Build Coastguard Worker * Sets attributes that imply changes to the literal interpretation of the pattern string affixes. 113*0e209d39SAndroid Build Coastguard Worker * 114*0e209d39SAndroid Build Coastguard Worker * @param signDisplay 115*0e209d39SAndroid Build Coastguard Worker * Whether to force a plus sign on positive numbers. 116*0e209d39SAndroid Build Coastguard Worker * @param perMille 117*0e209d39SAndroid Build Coastguard Worker * Whether to substitute the percent sign in the pattern with a permille sign. 118*0e209d39SAndroid Build Coastguard Worker * @param approximately 119*0e209d39SAndroid Build Coastguard Worker * Whether to prepend approximately to the sign 120*0e209d39SAndroid Build Coastguard Worker */ 121*0e209d39SAndroid Build Coastguard Worker void setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille, bool approximately); 122*0e209d39SAndroid Build Coastguard Worker 123*0e209d39SAndroid Build Coastguard Worker /** 124*0e209d39SAndroid Build Coastguard Worker * Sets locale-specific details that affect the symbols substituted into the pattern string affixes. 125*0e209d39SAndroid Build Coastguard Worker * 126*0e209d39SAndroid Build Coastguard Worker * @param symbols 127*0e209d39SAndroid Build Coastguard Worker * The desired instance of DecimalFormatSymbols. 128*0e209d39SAndroid Build Coastguard Worker * @param currency 129*0e209d39SAndroid Build Coastguard Worker * The currency to be used when substituting currency values into the affixes. 130*0e209d39SAndroid Build Coastguard Worker * @param unitWidth 131*0e209d39SAndroid Build Coastguard Worker * The width used to render currencies. 132*0e209d39SAndroid Build Coastguard Worker * @param rules 133*0e209d39SAndroid Build Coastguard Worker * Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the 134*0e209d39SAndroid Build Coastguard Worker * convenience method {@link #needsPlurals()}. 135*0e209d39SAndroid Build Coastguard Worker * @param status 136*0e209d39SAndroid Build Coastguard Worker * Set if an error occurs while loading currency data. 137*0e209d39SAndroid Build Coastguard Worker */ 138*0e209d39SAndroid Build Coastguard Worker void setSymbols(const DecimalFormatSymbols* symbols, const CurrencyUnit& currency, 139*0e209d39SAndroid Build Coastguard Worker UNumberUnitWidth unitWidth, const PluralRules* rules, UErrorCode& status); 140*0e209d39SAndroid Build Coastguard Worker 141*0e209d39SAndroid Build Coastguard Worker /** 142*0e209d39SAndroid Build Coastguard Worker * Sets attributes of the current number being processed. 143*0e209d39SAndroid Build Coastguard Worker * 144*0e209d39SAndroid Build Coastguard Worker * @param signum 145*0e209d39SAndroid Build Coastguard Worker * -1 if negative; +1 if positive; or 0 if zero. 146*0e209d39SAndroid Build Coastguard Worker * @param plural 147*0e209d39SAndroid Build Coastguard Worker * The plural form of the number, required only if the pattern contains the triple 148*0e209d39SAndroid Build Coastguard Worker * currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}). 149*0e209d39SAndroid Build Coastguard Worker */ 150*0e209d39SAndroid Build Coastguard Worker void setNumberProperties(Signum signum, StandardPlural::Form plural); 151*0e209d39SAndroid Build Coastguard Worker 152*0e209d39SAndroid Build Coastguard Worker /** 153*0e209d39SAndroid Build Coastguard Worker * Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize. 154*0e209d39SAndroid Build Coastguard Worker * This is currently true only if there is a currency long name placeholder in the pattern ("¤¤¤"). 155*0e209d39SAndroid Build Coastguard Worker */ 156*0e209d39SAndroid Build Coastguard Worker bool needsPlurals() const; 157*0e209d39SAndroid Build Coastguard Worker 158*0e209d39SAndroid Build Coastguard Worker /** Creates a quantity-dependent Modifier for the specified plural form. */ 159*0e209d39SAndroid Build Coastguard Worker AdoptingSignumModifierStore createImmutableForPlural(StandardPlural::Form plural, UErrorCode& status); 160*0e209d39SAndroid Build Coastguard Worker 161*0e209d39SAndroid Build Coastguard Worker /** 162*0e209d39SAndroid Build Coastguard Worker * Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable 163*0e209d39SAndroid Build Coastguard Worker * and can be saved for future use. The number properties in the current instance are mutated; all other properties 164*0e209d39SAndroid Build Coastguard Worker * are left untouched. 165*0e209d39SAndroid Build Coastguard Worker * 166*0e209d39SAndroid Build Coastguard Worker * <p> 167*0e209d39SAndroid Build Coastguard Worker * The resulting modifier cannot be used in a QuantityChain. 168*0e209d39SAndroid Build Coastguard Worker * 169*0e209d39SAndroid Build Coastguard Worker * <p> 170*0e209d39SAndroid Build Coastguard Worker * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP. 171*0e209d39SAndroid Build Coastguard Worker * 172*0e209d39SAndroid Build Coastguard Worker * @return An immutable that supports both positive and negative numbers. 173*0e209d39SAndroid Build Coastguard Worker */ 174*0e209d39SAndroid Build Coastguard Worker ImmutablePatternModifier *createImmutable(UErrorCode &status); 175*0e209d39SAndroid Build Coastguard Worker 176*0e209d39SAndroid Build Coastguard Worker MicroPropsGenerator &addToChain(const MicroPropsGenerator *parent); 177*0e209d39SAndroid Build Coastguard Worker 178*0e209d39SAndroid Build Coastguard Worker void processQuantity(DecimalQuantity &, MicroProps µs, UErrorCode &status) const override; 179*0e209d39SAndroid Build Coastguard Worker 180*0e209d39SAndroid Build Coastguard Worker int32_t apply(FormattedStringBuilder &output, int32_t leftIndex, int32_t rightIndex, 181*0e209d39SAndroid Build Coastguard Worker UErrorCode &status) const override; 182*0e209d39SAndroid Build Coastguard Worker 183*0e209d39SAndroid Build Coastguard Worker int32_t getPrefixLength() const override; 184*0e209d39SAndroid Build Coastguard Worker 185*0e209d39SAndroid Build Coastguard Worker int32_t getCodePointCount() const override; 186*0e209d39SAndroid Build Coastguard Worker 187*0e209d39SAndroid Build Coastguard Worker bool isStrong() const override; 188*0e209d39SAndroid Build Coastguard Worker 189*0e209d39SAndroid Build Coastguard Worker bool containsField(Field field) const override; 190*0e209d39SAndroid Build Coastguard Worker 191*0e209d39SAndroid Build Coastguard Worker void getParameters(Parameters& output) const override; 192*0e209d39SAndroid Build Coastguard Worker 193*0e209d39SAndroid Build Coastguard Worker bool strictEquals(const Modifier& other) const override; 194*0e209d39SAndroid Build Coastguard Worker 195*0e209d39SAndroid Build Coastguard Worker /** 196*0e209d39SAndroid Build Coastguard Worker * Returns the string that substitutes a given symbol type in a pattern. 197*0e209d39SAndroid Build Coastguard Worker */ 198*0e209d39SAndroid Build Coastguard Worker UnicodeString getSymbol(AffixPatternType type) const override; 199*0e209d39SAndroid Build Coastguard Worker 200*0e209d39SAndroid Build Coastguard Worker /** 201*0e209d39SAndroid Build Coastguard Worker * Returns the currency symbol for the unit width specified in setSymbols() 202*0e209d39SAndroid Build Coastguard Worker */ 203*0e209d39SAndroid Build Coastguard Worker UnicodeString getCurrencySymbolForUnitWidth(UErrorCode& status) const; 204*0e209d39SAndroid Build Coastguard Worker 205*0e209d39SAndroid Build Coastguard Worker UnicodeString toUnicodeString() const; 206*0e209d39SAndroid Build Coastguard Worker 207*0e209d39SAndroid Build Coastguard Worker private: 208*0e209d39SAndroid Build Coastguard Worker // Modifier details (initialized in constructor) 209*0e209d39SAndroid Build Coastguard Worker const bool fStrong; 210*0e209d39SAndroid Build Coastguard Worker 211*0e209d39SAndroid Build Coastguard Worker // Pattern details (initialized in setPatternInfo and setPatternAttributes) 212*0e209d39SAndroid Build Coastguard Worker const AffixPatternProvider *fPatternInfo; 213*0e209d39SAndroid Build Coastguard Worker Field fField; 214*0e209d39SAndroid Build Coastguard Worker UNumberSignDisplay fSignDisplay; 215*0e209d39SAndroid Build Coastguard Worker bool fPerMilleReplacesPercent; 216*0e209d39SAndroid Build Coastguard Worker bool fApproximately; 217*0e209d39SAndroid Build Coastguard Worker 218*0e209d39SAndroid Build Coastguard Worker // Symbol details (initialized in setSymbols) 219*0e209d39SAndroid Build Coastguard Worker const DecimalFormatSymbols *fSymbols; 220*0e209d39SAndroid Build Coastguard Worker UNumberUnitWidth fUnitWidth; 221*0e209d39SAndroid Build Coastguard Worker CurrencySymbols fCurrencySymbols; 222*0e209d39SAndroid Build Coastguard Worker const PluralRules *fRules; 223*0e209d39SAndroid Build Coastguard Worker 224*0e209d39SAndroid Build Coastguard Worker // Number details (initialized in setNumberProperties) 225*0e209d39SAndroid Build Coastguard Worker Signum fSignum; 226*0e209d39SAndroid Build Coastguard Worker StandardPlural::Form fPlural; 227*0e209d39SAndroid Build Coastguard Worker 228*0e209d39SAndroid Build Coastguard Worker // QuantityChain details (initialized in addToChain) 229*0e209d39SAndroid Build Coastguard Worker const MicroPropsGenerator *fParent; 230*0e209d39SAndroid Build Coastguard Worker 231*0e209d39SAndroid Build Coastguard Worker // Transient fields for rendering 232*0e209d39SAndroid Build Coastguard Worker UnicodeString currentAffix; 233*0e209d39SAndroid Build Coastguard Worker 234*0e209d39SAndroid Build Coastguard Worker /** 235*0e209d39SAndroid Build Coastguard Worker * Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support 236*0e209d39SAndroid Build Coastguard Worker * if required. 237*0e209d39SAndroid Build Coastguard Worker * 238*0e209d39SAndroid Build Coastguard Worker * <p> 239*0e209d39SAndroid Build Coastguard Worker * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP. 240*0e209d39SAndroid Build Coastguard Worker * 241*0e209d39SAndroid Build Coastguard Worker * @param a 242*0e209d39SAndroid Build Coastguard Worker * A working FormattedStringBuilder object; passed from the outside to prevent the need to create many new 243*0e209d39SAndroid Build Coastguard Worker * instances if this method is called in a loop. 244*0e209d39SAndroid Build Coastguard Worker * @param b 245*0e209d39SAndroid Build Coastguard Worker * Another working FormattedStringBuilder object. 246*0e209d39SAndroid Build Coastguard Worker * @return The constant modifier object. 247*0e209d39SAndroid Build Coastguard Worker */ 248*0e209d39SAndroid Build Coastguard Worker ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status); 249*0e209d39SAndroid Build Coastguard Worker 250*0e209d39SAndroid Build Coastguard Worker int32_t insertPrefix(FormattedStringBuilder &sb, int position, UErrorCode &status); 251*0e209d39SAndroid Build Coastguard Worker 252*0e209d39SAndroid Build Coastguard Worker int32_t insertSuffix(FormattedStringBuilder &sb, int position, UErrorCode &status); 253*0e209d39SAndroid Build Coastguard Worker 254*0e209d39SAndroid Build Coastguard Worker void prepareAffix(bool isPrefix); 255*0e209d39SAndroid Build Coastguard Worker }; 256*0e209d39SAndroid Build Coastguard Worker 257*0e209d39SAndroid Build Coastguard Worker } // namespace number::impl 258*0e209d39SAndroid Build Coastguard Worker 259*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END 260*0e209d39SAndroid Build Coastguard Worker 261*0e209d39SAndroid Build Coastguard Worker #endif //__NUMBER_PATTERNMODIFIER_H__ 262*0e209d39SAndroid Build Coastguard Worker 263*0e209d39SAndroid Build Coastguard Worker #endif /* #if !UCONFIG_NO_FORMATTING */ 264