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