Skip to content

Commit

Permalink
Merge pull request #5 from hugovdm/usage_glue
Browse files Browse the repository at this point in the history
Implement Usage "Glue Code"
  • Loading branch information
hugovdm authored Jul 1, 2020
2 parents 0e65ad4 + 34f5e0c commit 08132e7
Show file tree
Hide file tree
Showing 24 changed files with 666 additions and 100 deletions.
13 changes: 4 additions & 9 deletions icu4c/source/common/cmemory.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,6 @@ class MaybeStackArray {
* @return the array pointer
*/
T *getAlias() const { return ptr; }
/**
* Access without ownership change.
* @return the array pointer
*/
const T *getConstAlias() const { return ptr; }
/**
* Returns the array limit. Simple convenience method.
* @return getAlias()+getCapacity()
Expand Down Expand Up @@ -793,12 +788,12 @@ class MaybeStackVector : protected MemoryPool<T, stackCapacity> {
return this->fCount;
}

T** getAlias() const {
T** getAlias() {
return this->fPool.getAlias();
}

const T *const *getConstAlias() const {
return this->fPool.getConstAlias();
const T *const *getAlias() const {
return this->fPool.getAlias();
}

/**
Expand All @@ -822,7 +817,7 @@ class MaybeStackVector : protected MemoryPool<T, stackCapacity> {
}

/**
* Append all the items from another MaybeStackVector to this one.
* Append copies of all the items from another MaybeStackVector to this one.
*/
void appendAll(const MaybeStackVector& other, UErrorCode& status) {
for (int32_t i = 0; i < other.fCount; i++) {
Expand Down
2 changes: 1 addition & 1 deletion icu4c/source/i18n/formatted_string_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class FormattedValueStringBuilderImpl;
*
* <ol>
* <li>Efficient prepend as well as append.
* <li>Keeps tracks of Fields in an efficient manner.
* <li>Keeps track of Fields in an efficient manner.
* </ol>
*
* See also FormattedValueStringBuilderImpl.
Expand Down
2 changes: 2 additions & 0 deletions icu4c/source/i18n/i18n.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
<ClCompile Include="number_rounding.cpp" />
<ClCompile Include="number_scientific.cpp" />
<ClCompile Include="formatted_string_builder.cpp" />
<ClCompile Include="number_usageprefs.cpp" />
<ClCompile Include="number_utils.cpp" />
<ClCompile Include="number_mapper.cpp" />
<ClCompile Include="number_multiplier.cpp" />
Expand Down Expand Up @@ -485,6 +486,7 @@
<ClInclude Include="number_scientific.h" />
<ClInclude Include="formatted_string_builder.h" />
<ClInclude Include="number_types.h" />
<ClCompile Include="number_usageprefs.h" />
<ClInclude Include="number_utypes.h" />
<ClInclude Include="number_utils.h" />
<ClInclude Include="number_mapper.h" />
Expand Down
10 changes: 8 additions & 2 deletions icu4c/source/i18n/number_decimalquantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace impl {
class DecNum;

/**
* An class for representing a number to be processed by the decimal formatting pipeline. Includes
* A class for representing a number to be processed by the decimal formatting pipeline. Includes
* methods for rounding, plural rules, and decimal digit extraction.
*
* <p>By design, this is NOT IMMUTABLE and NOT THREAD SAFE. It is intended to be an intermediate
Expand Down Expand Up @@ -217,7 +217,13 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {

DecimalQuantity &setToDouble(double n);

/** decNumber is similar to BigDecimal in Java. */
/**
* Produces a DecimalQuantity that was parsed from a string by the decNumber
* C Library.
*
* decNumber is similar to BigDecimal in Java, and supports parsing strings
* such as "123.456621E+40".
*/
DecimalQuantity &setToDecNumber(StringPiece n, UErrorCode& status);

/** Internal method if the caller already has a DecNum. */
Expand Down
18 changes: 16 additions & 2 deletions icu4c/source/i18n/number_fluent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,20 @@ Derived NumberFormatterSettings<Derived>::scale(const Scale& scale)&& {
return move;
}

template<typename Derived>
Derived NumberFormatterSettings<Derived>::usage(const StringPiece usage) const& {
Derived copy(*this);
copy.fMacros.usage.set(usage);
return copy;
}

template<typename Derived>
Derived NumberFormatterSettings<Derived>::usage(const StringPiece usage)&& {
Derived move(std::move(*this));
move.fMacros.usage.set(usage);
return move;
}

template<typename Derived>
Derived NumberFormatterSettings<Derived>::padding(const Padder& padder) const& {
Derived copy(*this);
Expand Down Expand Up @@ -702,9 +716,9 @@ LocalizedNumberFormatter::formatDecimalQuantity(const DecimalQuantity& dq, UErro

void LocalizedNumberFormatter::formatImpl(impl::UFormattedNumberData* results, UErrorCode& status) const {
if (computeCompiled(status)) {
fCompiled->format(results->quantity, results->getStringRef(), status);
fCompiled->format(results, status);
} else {
NumberFormatterImpl::formatStatic(fMacros, results->quantity, results->getStringRef(), status);
NumberFormatterImpl::formatStatic(fMacros, results, status);
}
if (U_FAILURE(status)) {
return;
Expand Down
68 changes: 46 additions & 22 deletions icu4c/source/i18n/number_formatimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ NumberFormatterImpl::NumberFormatterImpl(const MacroProps& macros, UErrorCode& s
: NumberFormatterImpl(macros, true, status) {
}

int32_t NumberFormatterImpl::formatStatic(const MacroProps& macros, DecimalQuantity& inValue,
FormattedStringBuilder& outString, UErrorCode& status) {
int32_t NumberFormatterImpl::formatStatic(const MacroProps &macros, UFormattedNumberData *results,
UErrorCode &status) {
DecimalQuantity &inValue = results->quantity;
FormattedStringBuilder &outString = results->getStringRef();
NumberFormatterImpl impl(macros, false, status);
MicroProps& micros = impl.preProcessUnsafe(inValue, status);
if (U_FAILURE(status)) { return 0; }
int32_t length = writeNumber(micros, inValue, outString, 0, status);
length += writeAffixes(micros, outString, 0, length, status);
results->outputUnit = std::move(micros.outputUnit);
return length;
}

Expand All @@ -54,13 +57,15 @@ int32_t NumberFormatterImpl::getPrefixSuffixStatic(const MacroProps& macros, Sig
// The "unsafe" method simply re-uses fMicros, eliminating the extra copy operation.
// See MicroProps::processQuantity() for details.

int32_t NumberFormatterImpl::format(DecimalQuantity& inValue, FormattedStringBuilder& outString,
UErrorCode& status) const {
int32_t NumberFormatterImpl::format(UFormattedNumberData *results, UErrorCode &status) const {
DecimalQuantity &inValue = results->quantity;
FormattedStringBuilder &outString = results->getStringRef();
MicroProps micros;
preProcess(inValue, micros, status);
if (U_FAILURE(status)) { return 0; }
int32_t length = writeNumber(micros, inValue, outString, 0, status);
length += writeAffixes(micros, outString, 0, length, status);
results->outputUnit = std::move(micros.outputUnit);
return length;
}

Expand Down Expand Up @@ -222,6 +227,19 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
/// START POPULATING THE DEFAULT MICROPROPS AND BUILDING THE MICROPROPS GENERATOR ///
/////////////////////////////////////////////////////////////////////////////////////

// Unit Preferences and Conversions as our first step
if (macros.usage.isSet()) {
if (!isCldrUnit) {
// We only support "usage" when the input unit is a CLDR Unit.
status = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
auto usagePrefsHandler =
new UsagePrefsHandler(macros.locale, macros.unit, macros.usage.fUsage, chain, status);
fUsagePrefsHandler.adoptInsteadAndCheckErrorCode(usagePrefsHandler, status);
chain = fUsagePrefsHandler.getAlias();
}

// Multiplier
if (macros.scale.isValid()) {
fMicros.helpers.multiplier.setAndChain(macros.scale, chain);
Expand Down Expand Up @@ -330,32 +348,35 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
patternModifier->setSymbols(fMicros.symbols, currency, unitWidth, nullptr, status);
}
if (safe) {
fImmutablePatternModifier.adoptInstead(patternModifier->createImmutable(status));
fImmutablePatternModifier.adoptInsteadAndCheckErrorCode(patternModifier->createImmutable(status),
status);
}
if (U_FAILURE(status)) {
return nullptr;
}

// Outer modifier (CLDR units and currency long names)
if (isCldrUnit) {
fLongNameHandler.adoptInstead(
LongNameHandler::forMeasureUnit(
macros.locale,
macros.unit,
macros.perUnit,
unitWidth,
resolvePluralRules(macros.rules, macros.locale, status),
chain,
status));
chain = fLongNameHandler.getAlias();
if (macros.usage.isSet()) {
fLongNameMultiplexer.adoptInsteadAndCheckErrorCode(
LongNameMultiplexer::forMeasureUnits(
macros.locale, *fUsagePrefsHandler->getOutputUnits(), unitWidth,
resolvePluralRules(macros.rules, macros.locale, status), chain, status),
status);
chain = fLongNameMultiplexer.getAlias();
} else {
fLongNameHandler.adoptInsteadAndCheckErrorCode(new LongNameHandler(), status);
LongNameHandler::forMeasureUnit(macros.locale, macros.unit, macros.perUnit, unitWidth,
resolvePluralRules(macros.rules, macros.locale, status),
chain, fLongNameHandler.getAlias(), status);
chain = fLongNameHandler.getAlias();
}
} else if (isCurrency && unitWidth == UNUM_UNIT_WIDTH_FULL_NAME) {
fLongNameHandler.adoptInstead(
LongNameHandler::forCurrencyLongNames(
macros.locale,
currency,
resolvePluralRules(macros.rules, macros.locale, status),
chain,
status));
fLongNameHandler.adoptInsteadAndCheckErrorCode(
LongNameHandler::forCurrencyLongNames(
macros.locale, currency, resolvePluralRules(macros.rules, macros.locale, status), chain,
status),
status);
chain = fLongNameHandler.getAlias();
} else {
// No outer modifier required
Expand All @@ -379,6 +400,9 @@ NumberFormatterImpl::macrosToMicroGenerator(const MacroProps& macros, bool safe,
safe,
chain,
status);
if (U_FAILURE(status)) {
return nullptr;
}
if (newCompactHandler == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return nullptr;
Expand Down
17 changes: 11 additions & 6 deletions icu4c/source/i18n/number_formatimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
#include "number_types.h"
#include "formatted_string_builder.h"
#include "number_patternstring.h"
#include "number_usageprefs.h"
#include "number_utils.h"
#include "number_patternmodifier.h"
#include "number_longnames.h"
#include "number_compact.h"
#include "number_microprops.h"
#include "number_utypes.h"

U_NAMESPACE_BEGIN namespace number {
namespace impl {
Expand All @@ -34,9 +36,8 @@ class NumberFormatterImpl : public UMemory {
/**
* Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper but can be used only once.
*/
static int32_t
formatStatic(const MacroProps &macros, DecimalQuantity &inValue, FormattedStringBuilder &outString,
UErrorCode &status);
static int32_t formatStatic(const MacroProps &macros, UFormattedNumberData *results,
UErrorCode &status);

/**
* Prints only the prefix and suffix; used for DecimalFormat getters.
Expand All @@ -51,7 +52,7 @@ class NumberFormatterImpl : public UMemory {
/**
* Evaluates the "safe" MicroPropsGenerator created by "fromMacros".
*/
int32_t format(DecimalQuantity& inValue, FormattedStringBuilder& outString, UErrorCode& status) const;
int32_t format(UFormattedNumberData *results, UErrorCode &status) const;

/**
* Like format(), but saves the result into an output MicroProps without additional processing.
Expand Down Expand Up @@ -82,21 +83,25 @@ class NumberFormatterImpl : public UMemory {
int32_t end, UErrorCode& status);

private:
// Head of the MicroPropsGenerator linked list:
// Head of the MicroPropsGenerator linked list. Subclasses' processQuantity
// methods process this list in a parent-first order, such that the last
// item added, which this points to, typically has its logic executed last.
const MicroPropsGenerator *fMicroPropsGenerator = nullptr;

// Tail of the list:
MicroProps fMicros;

// Other fields possibly used by the number formatting pipeline:
// TODO: Convert more of these LocalPointers to value objects to reduce the number of news?
LocalPointer<const UsagePrefsHandler> fUsagePrefsHandler;
LocalPointer<const DecimalFormatSymbols> fSymbols;
LocalPointer<const PluralRules> fRules;
LocalPointer<const ParsedPatternInfo> fPatternInfo;
LocalPointer<const ScientificHandler> fScientificHandler;
LocalPointer<MutablePatternModifier> fPatternModifier;
LocalPointer<ImmutablePatternModifier> fImmutablePatternModifier;
LocalPointer<const LongNameHandler> fLongNameHandler;
LocalPointer<LongNameHandler> fLongNameHandler;
LocalPointer<const LongNameMultiplexer> fLongNameMultiplexer;
LocalPointer<const CompactHandler> fCompactHandler;

// Value objects possibly used by the number formatting pipeline:
Expand Down
Loading

0 comments on commit 08132e7

Please sign in to comment.