void CompactHandler::processQuantity(DecimalQuantity &quantity, MicroProps µs, UErrorCode &status) const { parent->processQuantity(quantity, micros, status); if (U_FAILURE(status)) { return; } // Treat zero as if it had magnitude 0 int32_t magnitude; if (quantity.isZero()) { magnitude = 0; micros.rounder.apply(quantity, status); } else { // TODO: Revisit chooseMultiplierAndApply int32_t multiplier = micros.rounder.chooseMultiplierAndApply(quantity, data, status); magnitude = quantity.isZero() ? 0 : quantity.getMagnitude(); magnitude -= multiplier; } StandardPlural::Form plural = utils::getStandardPlural(rules, quantity); const UChar *patternString = data.getPattern(magnitude, plural); if (patternString == nullptr) { // Use the default (non-compact) modifier. // No need to take any action. } else if (safe) { // Safe code path. // Java uses a hash set here for O(1) lookup. C++ uses a linear search. // TODO: Benchmark this and maybe change to a binary search or hash table. int32_t i = 0; for (; i < precomputedModsLength; i++) { const CompactModInfo &info = precomputedMods[i]; if (u_strcmp(patternString, info.patternString) == 0) { info.mod->applyToMicros(micros, quantity); break; } } // It should be guaranteed that we found the entry. U_ASSERT(i < precomputedModsLength); } else { // Unsafe code path. // Overwrite the PatternInfo in the existing modMiddle. // C++ Note: Use unsafePatternInfo for proper lifecycle. ParsedPatternInfo &patternInfo = const_cast<CompactHandler *>(this)->unsafePatternInfo; PatternParser::parseToPatternInfo(UnicodeString(patternString), patternInfo, status); static_cast<MutablePatternModifier*>(const_cast<Modifier*>(micros.modMiddle)) ->setPatternInfo(&patternInfo); } // We already performed rounding. Do not perform it again. micros.rounder = RoundingImpl::passThrough(); }
void ScientificHandler::processQuantity(DecimalQuantity &quantity, MicroProps µs, UErrorCode &status) const { fParent->processQuantity(quantity, micros, status); if (U_FAILURE(status)) { return; } // Treat zero as if it had magnitude 0 int32_t exponent; if (quantity.isZero()) { if (fSettings.fRequireMinInt && micros.rounder.isSignificantDigits()) { // Show "00.000E0" on pattern "00.000E0" micros.rounder.apply(quantity, fSettings.fEngineeringInterval, status); exponent = 0; } else { micros.rounder.apply(quantity, status); exponent = 0; } } else { exponent = -micros.rounder.chooseMultiplierAndApply(quantity, *this, status); } // Use MicroProps's helper ScientificModifier and save it as the modInner. ScientificModifier &mod = micros.helpers.scientificModifier; mod.set(exponent, this); micros.modInner = &mod; // We already performed rounding. Do not perform it again. micros.rounder = RoundingImpl::passThrough(); }