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 {
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();
}
return fStrong;
}
+bool ConstantAffixModifier::containsField(UNumberFormatFields field) const {
+ (void)field;
+ // This method is not currently used.
+ UPRV_UNREACHABLE;
+}
+
+void ConstantAffixModifier::getParameters(Parameters& output) const {
+ (void)output;
+ // This method is not currently used.
+ UPRV_UNREACHABLE;
+}
+
+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) {
} 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;
}
}
int32_t SimpleModifier::apply(NumberStringBuilder &output, int leftIndex, int rightIndex,
UErrorCode &status) const {
- return formatAsPrefixSuffix(output, leftIndex, rightIndex, fField, status);
+ return formatAsPrefixSuffix(output, leftIndex, rightIndex, 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);
return fStrong;
}
+bool SimpleModifier::containsField(UNumberFormatFields field) const {
+ (void)field;
+ // This method is not currently used.
+ UPRV_UNREACHABLE;
+}
+
+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) {
+ UErrorCode &status) const {
+ 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);
+ return result.splice(startIndex, endIndex, fCompiledPattern, 2, 2 + fPrefixLength, fField, status);
} else {
if (fPrefixLength > 0) {
- result.insert(startIndex, fCompiledPattern, 2, 2 + fPrefixLength, field, status);
+ result.insert(startIndex, fCompiledPattern, 2, 2 + fPrefixLength, fField, status);
}
if (fSuffixLength > 0) {
result.insert(
fCompiledPattern,
1 + fSuffixOffset,
1 + fSuffixOffset + fSuffixLength,
- field,
+ fField,
status);
}
return fPrefixLength + fSuffixLength;
}
}
+
+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);
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();
}
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,