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 8 #include "number_decimfmtprops.h" 9 #include "umutex.h" 10 11 using namespace icu; 12 using namespace icu::number; 13 using namespace icu::number::impl; 14 15 16 namespace { 17 18 alignas(DecimalFormatProperties) 19 char kRawDefaultProperties[sizeof(DecimalFormatProperties)]; 20 21 icu::UInitOnce gDefaultPropertiesInitOnce = U_INITONCE_INITIALIZER; 22 initDefaultProperties(UErrorCode &)23void U_CALLCONV initDefaultProperties(UErrorCode&) { 24 new(kRawDefaultProperties) DecimalFormatProperties(); // set to the default instance 25 } 26 27 } 28 29 DecimalFormatProperties()30DecimalFormatProperties::DecimalFormatProperties() { 31 clear(); 32 } 33 clear()34void DecimalFormatProperties::clear() { 35 compactStyle.nullify(); 36 currency.nullify(); 37 currencyPluralInfo.fPtr.adoptInstead(nullptr); 38 currencyUsage.nullify(); 39 decimalPatternMatchRequired = false; 40 decimalSeparatorAlwaysShown = false; 41 exponentSignAlwaysShown = false; 42 formatFailIfMoreThanMaxDigits = false; 43 formatWidth = -1; 44 groupingSize = -1; 45 groupingUsed = true; 46 magnitudeMultiplier = 0; 47 maximumFractionDigits = -1; 48 maximumIntegerDigits = -1; 49 maximumSignificantDigits = -1; 50 minimumExponentDigits = -1; 51 minimumFractionDigits = -1; 52 minimumGroupingDigits = -1; 53 minimumIntegerDigits = -1; 54 minimumSignificantDigits = -1; 55 multiplier = 1; 56 multiplierScale = 0; 57 negativePrefix.setToBogus(); 58 negativePrefixPattern.setToBogus(); 59 negativeSuffix.setToBogus(); 60 negativeSuffixPattern.setToBogus(); 61 padPosition.nullify(); 62 padString.setToBogus(); 63 parseCaseSensitive = false; 64 parseIntegerOnly = false; 65 parseMode.nullify(); 66 parseNoExponent = false; 67 parseToBigDecimal = false; 68 parseAllInput = UNUM_MAYBE; 69 positivePrefix.setToBogus(); 70 positivePrefixPattern.setToBogus(); 71 positiveSuffix.setToBogus(); 72 positiveSuffixPattern.setToBogus(); 73 roundingIncrement = 0.0; 74 roundingMode.nullify(); 75 secondaryGroupingSize = -1; 76 signAlwaysShown = false; 77 } 78 79 bool _equals(const DecimalFormatProperties & other,bool ignoreForFastFormat) const80DecimalFormatProperties::_equals(const DecimalFormatProperties& other, bool ignoreForFastFormat) const { 81 bool eq = true; 82 83 // Properties that must be equal both normally and for fast-path formatting 84 eq = eq && compactStyle == other.compactStyle; 85 eq = eq && currency == other.currency; 86 eq = eq && currencyPluralInfo.fPtr.getAlias() == other.currencyPluralInfo.fPtr.getAlias(); 87 eq = eq && currencyUsage == other.currencyUsage; 88 eq = eq && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown; 89 eq = eq && exponentSignAlwaysShown == other.exponentSignAlwaysShown; 90 eq = eq && formatFailIfMoreThanMaxDigits == other.formatFailIfMoreThanMaxDigits; 91 eq = eq && formatWidth == other.formatWidth; 92 eq = eq && magnitudeMultiplier == other.magnitudeMultiplier; 93 eq = eq && maximumSignificantDigits == other.maximumSignificantDigits; 94 eq = eq && minimumExponentDigits == other.minimumExponentDigits; 95 eq = eq && minimumGroupingDigits == other.minimumGroupingDigits; 96 eq = eq && minimumSignificantDigits == other.minimumSignificantDigits; 97 eq = eq && multiplier == other.multiplier; 98 eq = eq && multiplierScale == other.multiplierScale; 99 eq = eq && negativePrefix == other.negativePrefix; 100 eq = eq && negativeSuffix == other.negativeSuffix; 101 eq = eq && padPosition == other.padPosition; 102 eq = eq && padString == other.padString; 103 eq = eq && positivePrefix == other.positivePrefix; 104 eq = eq && positiveSuffix == other.positiveSuffix; 105 eq = eq && roundingIncrement == other.roundingIncrement; 106 eq = eq && roundingMode == other.roundingMode; 107 eq = eq && secondaryGroupingSize == other.secondaryGroupingSize; 108 eq = eq && signAlwaysShown == other.signAlwaysShown; 109 110 if (ignoreForFastFormat) { 111 return eq; 112 } 113 114 // Properties ignored by fast-path formatting 115 // Formatting (special handling required): 116 eq = eq && groupingSize == other.groupingSize; 117 eq = eq && groupingUsed == other.groupingUsed; 118 eq = eq && minimumFractionDigits == other.minimumFractionDigits; 119 eq = eq && maximumFractionDigits == other.maximumFractionDigits; 120 eq = eq && maximumIntegerDigits == other.maximumIntegerDigits; 121 eq = eq && minimumIntegerDigits == other.minimumIntegerDigits; 122 eq = eq && negativePrefixPattern == other.negativePrefixPattern; 123 eq = eq && negativeSuffixPattern == other.negativeSuffixPattern; 124 eq = eq && positivePrefixPattern == other.positivePrefixPattern; 125 eq = eq && positiveSuffixPattern == other.positiveSuffixPattern; 126 127 // Parsing (always safe to ignore): 128 eq = eq && decimalPatternMatchRequired == other.decimalPatternMatchRequired; 129 eq = eq && parseCaseSensitive == other.parseCaseSensitive; 130 eq = eq && parseIntegerOnly == other.parseIntegerOnly; 131 eq = eq && parseMode == other.parseMode; 132 eq = eq && parseNoExponent == other.parseNoExponent; 133 eq = eq && parseToBigDecimal == other.parseToBigDecimal; 134 eq = eq && parseAllInput == other.parseAllInput; 135 136 return eq; 137 } 138 equalsDefaultExceptFastFormat() const139bool DecimalFormatProperties::equalsDefaultExceptFastFormat() const { 140 UErrorCode localStatus = U_ZERO_ERROR; 141 umtx_initOnce(gDefaultPropertiesInitOnce, &initDefaultProperties, localStatus); 142 return _equals(*reinterpret_cast<DecimalFormatProperties*>(kRawDefaultProperties), true); 143 } 144 145 #endif /* #if !UCONFIG_NO_FORMATTING */ 146