summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/number_modifiers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/number_modifiers.cpp')
-rw-r--r--deps/icu-small/source/i18n/number_modifiers.cpp178
1 files changed, 164 insertions, 14 deletions
diff --git a/deps/icu-small/source/i18n/number_modifiers.cpp b/deps/icu-small/source/i18n/number_modifiers.cpp
index 4385499b54..d92ec63b08 100644
--- a/deps/icu-small/source/i18n/number_modifiers.cpp
+++ b/deps/icu-small/source/i18n/number_modifiers.cpp
@@ -53,6 +53,21 @@ void U_CALLCONV initDefaultCurrencySpacing(UErrorCode &status) {
Modifier::~Modifier() = default;
+Modifier::Parameters::Parameters()
+ : obj(nullptr) {}
+
+Modifier::Parameters::Parameters(
+ const ModifierStore* _obj, int8_t _signum, StandardPlural::Form _plural)
+ : obj(_obj), signum(_signum), plural(_plural) {}
+
+ModifierStore::~ModifierStore() = default;
+
+AdoptingModifierStore::~AdoptingModifierStore() {
+ for (const Modifier *mod : mods) {
+ delete mod;
+ }
+}
+
int32_t ConstantAffixModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
@@ -62,13 +77,11 @@ int32_t ConstantAffixModifier::apply(NumberStringBuilder &output, int leftIndex,
return length;
}
-int32_t ConstantAffixModifier::getPrefixLength(UErrorCode &status) const {
- (void)status;
+int32_t ConstantAffixModifier::getPrefixLength() const {
return fPrefix.length();
}
-int32_t ConstantAffixModifier::getCodePointCount(UErrorCode &status) const {
- (void)status;
+int32_t ConstantAffixModifier::getCodePointCount() const {
return fPrefix.countChar32() + fSuffix.countChar32();
}
@@ -76,8 +89,38 @@ bool ConstantAffixModifier::isStrong() const {
return fStrong;
}
+bool ConstantAffixModifier::containsField(UNumberFormatFields field) const {
+ (void)field;
+ // This method is not currently used.
+ U_ASSERT(false);
+ return false;
+}
+
+void ConstantAffixModifier::getParameters(Parameters& output) const {
+ (void)output;
+ // This method is not currently used.
+ U_ASSERT(false);
+}
+
+bool ConstantAffixModifier::semanticallyEquivalent(const Modifier& other) const {
+ auto* _other = dynamic_cast<const ConstantAffixModifier*>(&other);
+ if (_other == nullptr) {
+ return false;
+ }
+ return fPrefix == _other->fPrefix
+ && fSuffix == _other->fSuffix
+ && fField == _other->fField
+ && fStrong == _other->fStrong;
+}
+
+
SimpleModifier::SimpleModifier(const SimpleFormatter &simpleFormatter, Field field, bool strong)
- : fCompiledPattern(simpleFormatter.compiledPattern), fField(field), fStrong(strong) {
+ : SimpleModifier(simpleFormatter, field, strong, {}) {}
+
+SimpleModifier::SimpleModifier(const SimpleFormatter &simpleFormatter, Field field, bool strong,
+ const Modifier::Parameters parameters)
+ : fCompiledPattern(simpleFormatter.compiledPattern), fField(field), fStrong(strong),
+ fParameters(parameters) {
int32_t argLimit = SimpleFormatter::getArgumentLimit(
fCompiledPattern.getBuffer(), fCompiledPattern.length());
if (argLimit == 0) {
@@ -90,15 +133,19 @@ SimpleModifier::SimpleModifier(const SimpleFormatter &simpleFormatter, Field fie
} else {
U_ASSERT(argLimit == 1);
if (fCompiledPattern.charAt(1) != 0) {
+ // Found prefix
fPrefixLength = fCompiledPattern.charAt(1) - ARG_NUM_LIMIT;
fSuffixOffset = 3 + fPrefixLength;
} else {
+ // No prefix
fPrefixLength = 0;
fSuffixOffset = 2;
}
if (3 + fPrefixLength < fCompiledPattern.length()) {
+ // Found suffix
fSuffixLength = fCompiledPattern.charAt(fSuffixOffset) - ARG_NUM_LIMIT;
} else {
+ // No suffix
fSuffixLength = 0;
}
}
@@ -113,13 +160,11 @@ int32_t SimpleModifier::apply(NumberStringBuilder &output, int leftIndex, int ri
return formatAsPrefixSuffix(output, leftIndex, rightIndex, fField, status);
}
-int32_t SimpleModifier::getPrefixLength(UErrorCode &status) const {
- (void)status;
+int32_t SimpleModifier::getPrefixLength() const {
return fPrefixLength;
}
-int32_t SimpleModifier::getCodePointCount(UErrorCode &status) const {
- (void)status;
+int32_t SimpleModifier::getCodePointCount() const {
int32_t count = 0;
if (fPrefixLength > 0) {
count += fCompiledPattern.countChar32(2, fPrefixLength);
@@ -134,10 +179,35 @@ bool SimpleModifier::isStrong() const {
return fStrong;
}
+bool SimpleModifier::containsField(UNumberFormatFields field) const {
+ (void)field;
+ // This method is not currently used.
+ U_ASSERT(false);
+ return false;
+}
+
+void SimpleModifier::getParameters(Parameters& output) const {
+ output = fParameters;
+}
+
+bool SimpleModifier::semanticallyEquivalent(const Modifier& other) const {
+ auto* _other = dynamic_cast<const SimpleModifier*>(&other);
+ if (_other == nullptr) {
+ return false;
+ }
+ if (fParameters.obj != nullptr) {
+ return fParameters.obj == _other->fParameters.obj;
+ }
+ return fCompiledPattern == _other->fCompiledPattern
+ && fField == _other->fField
+ && fStrong == _other->fStrong;
+}
+
+
int32_t
SimpleModifier::formatAsPrefixSuffix(NumberStringBuilder &result, int32_t startIndex, int32_t endIndex,
Field field, UErrorCode &status) const {
- if (fSuffixOffset == -1) {
+ if (fSuffixOffset == -1 && fPrefixLength + fSuffixLength > 0) {
// There is no argument for the inner number; overwrite the entire segment with our string.
return result.splice(startIndex, endIndex, fCompiledPattern, 2, 2 + fPrefixLength, field, status);
} else {
@@ -157,6 +227,65 @@ SimpleModifier::formatAsPrefixSuffix(NumberStringBuilder &result, int32_t startI
}
}
+
+int32_t
+SimpleModifier::formatTwoArgPattern(const SimpleFormatter& compiled, NumberStringBuilder& result,
+ int32_t index, int32_t* outPrefixLength, int32_t* outSuffixLength,
+ Field field, UErrorCode& status) {
+ const UnicodeString& compiledPattern = compiled.compiledPattern;
+ int32_t argLimit = SimpleFormatter::getArgumentLimit(
+ compiledPattern.getBuffer(), compiledPattern.length());
+ if (argLimit != 2) {
+ status = U_INTERNAL_PROGRAM_ERROR;
+ return 0;
+ }
+ int32_t offset = 1; // offset into compiledPattern
+ int32_t length = 0; // chars added to result
+
+ int32_t prefixLength = compiledPattern.charAt(offset);
+ offset++;
+ if (prefixLength < ARG_NUM_LIMIT) {
+ // No prefix
+ prefixLength = 0;
+ } else {
+ prefixLength -= ARG_NUM_LIMIT;
+ result.insert(index + length, compiledPattern, offset, offset + prefixLength, field, status);
+ offset += prefixLength;
+ length += prefixLength;
+ offset++;
+ }
+
+ int32_t infixLength = compiledPattern.charAt(offset);
+ offset++;
+ if (infixLength < ARG_NUM_LIMIT) {
+ // No infix
+ infixLength = 0;
+ } else {
+ infixLength -= ARG_NUM_LIMIT;
+ result.insert(index + length, compiledPattern, offset, offset + infixLength, field, status);
+ offset += infixLength;
+ length += infixLength;
+ offset++;
+ }
+
+ int32_t suffixLength;
+ if (offset == compiledPattern.length()) {
+ // No suffix
+ suffixLength = 0;
+ } else {
+ suffixLength = compiledPattern.charAt(offset) - ARG_NUM_LIMIT;
+ offset++;
+ result.insert(index + length, compiledPattern, offset, offset + suffixLength, field, status);
+ length += suffixLength;
+ }
+
+ *outPrefixLength = prefixLength;
+ *outSuffixLength = suffixLength;
+
+ return length;
+}
+
+
int32_t ConstantMultiFieldModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
int32_t length = output.insert(leftIndex, fPrefix, status);
@@ -171,13 +300,11 @@ int32_t ConstantMultiFieldModifier::apply(NumberStringBuilder &output, int leftI
return length;
}
-int32_t ConstantMultiFieldModifier::getPrefixLength(UErrorCode &status) const {
- (void)status;
+int32_t ConstantMultiFieldModifier::getPrefixLength() const {
return fPrefix.length();
}
-int32_t ConstantMultiFieldModifier::getCodePointCount(UErrorCode &status) const {
- (void)status;
+int32_t ConstantMultiFieldModifier::getCodePointCount() const {
return fPrefix.codePointCount() + fSuffix.codePointCount();
}
@@ -185,6 +312,29 @@ bool ConstantMultiFieldModifier::isStrong() const {
return fStrong;
}
+bool ConstantMultiFieldModifier::containsField(UNumberFormatFields field) const {
+ return fPrefix.containsField(field) || fSuffix.containsField(field);
+}
+
+void ConstantMultiFieldModifier::getParameters(Parameters& output) const {
+ output = fParameters;
+}
+
+bool ConstantMultiFieldModifier::semanticallyEquivalent(const Modifier& other) const {
+ auto* _other = dynamic_cast<const ConstantMultiFieldModifier*>(&other);
+ if (_other == nullptr) {
+ return false;
+ }
+ if (fParameters.obj != nullptr) {
+ return fParameters.obj == _other->fParameters.obj;
+ }
+ return fPrefix.contentEquals(_other->fPrefix)
+ && fSuffix.contentEquals(_other->fSuffix)
+ && fOverwrite == _other->fOverwrite
+ && fStrong == _other->fStrong;
+}
+
+
CurrencySpacingEnabledModifier::CurrencySpacingEnabledModifier(const NumberStringBuilder &prefix,
const NumberStringBuilder &suffix,
bool overwrite,