mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 06:25:30 +00:00
ICU-13667 update/fix/improve dependencies; better layering formatting->numberparser->numberformatter->number_representation
X-SVN-Rev: 41461
This commit is contained in:
parent
87122b9084
commit
d8f9a47637
29 changed files with 531 additions and 374 deletions
|
@ -102,7 +102,7 @@ number_affixutils.o number_compact.o number_decimalquantity.o \
|
|||
number_decimfmtprops.o number_fluent.o number_formatimpl.o number_grouping.o \
|
||||
number_integerwidth.o number_longnames.o number_modifiers.o number_notation.o \
|
||||
number_padding.o number_patternmodifier.o number_patternstring.o \
|
||||
number_rounding.o number_scientific.o number_stringbuilder.o number_utils.o \
|
||||
number_rounding.o number_scientific.o number_stringbuilder.o number_utils.o number_asformat.o \
|
||||
number_mapper.o number_multiplier.o number_currencysymbols.o number_skeletons.o number_capi.o \
|
||||
double-conversion.o double-conversion-bignum-dtoa.o double-conversion-bignum.o \
|
||||
double-conversion-cached-powers.o double-conversion-diy-fp.o \
|
||||
|
|
|
@ -253,6 +253,7 @@
|
|||
<ClCompile Include="nfsubs.cpp" />
|
||||
<ClCompile Include="nounit.cpp" />
|
||||
<ClCompile Include="number_affixutils.cpp" />
|
||||
<ClCompile Include="number_asformat.cpp" />
|
||||
<ClCompile Include="number_compact.cpp" />
|
||||
<ClCompile Include="number_decimalquantity.cpp" />
|
||||
<ClCompile Include="number_decimfmtprops.cpp" />
|
||||
|
@ -515,11 +516,14 @@
|
|||
<ClInclude Include="uspoof_conf.h" />
|
||||
<ClInclude Include="uspoof_impl.h" />
|
||||
<ClInclude Include="number_affixutils.h" />
|
||||
<ClInclude Include="number_asformat.h" />
|
||||
<ClInclude Include="number_compact.h" />
|
||||
<ClInclude Include="number_decimalquantity.h" />
|
||||
<ClInclude Include="number_decimfmtprops.h" />
|
||||
<ClInclude Include="number_decnum.h" />
|
||||
<ClInclude Include="number_formatimpl.h" />
|
||||
<ClInclude Include="number_longnames.h" />
|
||||
<ClInclude Include="number_microprops.h" />
|
||||
<ClInclude Include="number_modifiers.h" />
|
||||
<ClInclude Include="number_patternmodifier.h" />
|
||||
<ClInclude Include="number_patternstring.h" />
|
||||
|
@ -553,4 +557,4 @@
|
|||
<Import Project="$(SolutionDir)\Windows.CopyUnicodeHeaderFiles.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -519,6 +519,9 @@
|
|||
<ClCompile Include="number_affixutils.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="number_asformat.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="number_compact.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
|
@ -803,6 +806,9 @@
|
|||
<ClInclude Include="number_affixutils.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_asformat.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_compact.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
|
@ -812,12 +818,18 @@
|
|||
<ClInclude Include="number_decimfmtprops.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_decnum.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_formatimpl.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_longnames.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_microprops.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="number_modifiers.h">
|
||||
<Filter>formatting</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1414,4 +1426,4 @@
|
|||
<Filter>formatting</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -360,6 +360,7 @@
|
|||
<ClCompile Include="nfsubs.cpp" />
|
||||
<ClCompile Include="nounit.cpp" />
|
||||
<ClCompile Include="number_affixutils.cpp" />
|
||||
<ClCompile Include="number_asformat.cpp" />
|
||||
<ClCompile Include="number_compact.cpp" />
|
||||
<ClCompile Include="number_decimalquantity.cpp" />
|
||||
<ClCompile Include="number_decimfmtprops.cpp" />
|
||||
|
@ -620,11 +621,14 @@
|
|||
<ClInclude Include="uspoof_conf.h" />
|
||||
<ClInclude Include="uspoof_impl.h" />
|
||||
<ClInclude Include="number_affixutils.h" />
|
||||
<ClInclude Include="number_asformat.h" />
|
||||
<ClInclude Include="number_compact.h" />
|
||||
<ClInclude Include="number_decimalquantity.h" />
|
||||
<ClInclude Include="number_decimfmtprops.h" />
|
||||
<ClInclude Include="number_decnum.h" />
|
||||
<ClInclude Include="number_formatimpl.h" />
|
||||
<ClInclude Include="number_longnames.h" />
|
||||
<ClInclude Include="number_microprops.h" />
|
||||
<ClInclude Include="number_modifiers.h" />
|
||||
<ClInclude Include="number_patternmodifier.h" />
|
||||
<ClInclude Include="number_patternstring.h" />
|
||||
|
@ -656,4 +660,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
103
icu4c/source/i18n/number_asformat.cpp
Normal file
103
icu4c/source/i18n/number_asformat.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
// © 2018 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
// Allow implicit conversion from char16_t* to UnicodeString for this file:
|
||||
// Helpful in toString methods and elsewhere.
|
||||
#define UNISTR_FROM_STRING_EXPLICIT
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cmath>
|
||||
#include "number_asformat.h"
|
||||
#include "number_types.h"
|
||||
#include "number_utils.h"
|
||||
#include "fphdlimp.h"
|
||||
#include "number_utypes.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
using namespace icu::number::impl;
|
||||
|
||||
LocalizedNumberFormatterAsFormat::LocalizedNumberFormatterAsFormat(
|
||||
const LocalizedNumberFormatter& formatter, const Locale& locale)
|
||||
: fFormatter(formatter), fLocale(locale) {
|
||||
const char* localeName = locale.getName();
|
||||
setLocaleIDs(localeName, localeName);
|
||||
}
|
||||
|
||||
LocalizedNumberFormatterAsFormat::~LocalizedNumberFormatterAsFormat() = default;
|
||||
|
||||
UBool LocalizedNumberFormatterAsFormat::operator==(const Format& other) const {
|
||||
auto* _other = dynamic_cast<const LocalizedNumberFormatterAsFormat*>(&other);
|
||||
if (_other == nullptr) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Change this to use LocalizedNumberFormatter::operator== if it is ever proposed.
|
||||
// This implementation is fine, but not particularly efficient.
|
||||
UErrorCode localStatus = U_ZERO_ERROR;
|
||||
return fFormatter.toSkeleton(localStatus) == _other->fFormatter.toSkeleton(localStatus);
|
||||
}
|
||||
|
||||
Format* LocalizedNumberFormatterAsFormat::clone() const {
|
||||
return new LocalizedNumberFormatterAsFormat(*this);
|
||||
}
|
||||
|
||||
UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, UnicodeString& appendTo,
|
||||
FieldPosition& pos, UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) { return appendTo; }
|
||||
UFormattedNumberData data;
|
||||
obj.populateDecimalQuantity(data.quantity, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
fFormatter.formatImpl(&data, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
// always return first occurrence:
|
||||
pos.setBeginIndex(0);
|
||||
pos.setEndIndex(0);
|
||||
bool found = data.string.nextFieldPosition(pos, status);
|
||||
if (found && appendTo.length() != 0) {
|
||||
pos.setBeginIndex(pos.getBeginIndex() + appendTo.length());
|
||||
pos.setEndIndex(pos.getEndIndex() + appendTo.length());
|
||||
}
|
||||
appendTo.append(data.string.toTempUnicodeString());
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) { return appendTo; }
|
||||
UFormattedNumberData data;
|
||||
obj.populateDecimalQuantity(data.quantity, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
fFormatter.formatImpl(&data, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
appendTo.append(data.string.toTempUnicodeString());
|
||||
if (posIter != nullptr) {
|
||||
FieldPositionIteratorHandler fpih(posIter, status);
|
||||
data.string.getAllFieldPositions(fpih, status);
|
||||
}
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
void LocalizedNumberFormatterAsFormat::parseObject(const UnicodeString&, Formattable&,
|
||||
ParsePosition& parse_pos) const {
|
||||
// Not supported.
|
||||
parse_pos.setErrorIndex(0);
|
||||
}
|
||||
|
||||
const LocalizedNumberFormatter& LocalizedNumberFormatterAsFormat::getNumberFormatter() const {
|
||||
return fFormatter;
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
104
icu4c/source/i18n/number_asformat.h
Normal file
104
icu4c/source/i18n/number_asformat.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
// © 2017 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
#ifndef __NUMBER_ASFORMAT_H__
|
||||
#define __NUMBER_ASFORMAT_H__
|
||||
|
||||
#include "unicode/numberformatter.h"
|
||||
#include "number_types.h"
|
||||
#include "number_decimalquantity.h"
|
||||
#include "number_scientific.h"
|
||||
#include "number_patternstring.h"
|
||||
#include "number_modifiers.h"
|
||||
#include "number_multiplier.h"
|
||||
#include "number_roundingutils.h"
|
||||
#include "decNumber.h"
|
||||
#include "charstr.h"
|
||||
|
||||
U_NAMESPACE_BEGIN namespace number {
|
||||
namespace impl {
|
||||
|
||||
/**
|
||||
* A wrapper around LocalizedNumberFormatter implementing the Format interface, enabling improved
|
||||
* compatibility with other APIs.
|
||||
*
|
||||
* @draft ICU 62
|
||||
* @see NumberFormatter
|
||||
*/
|
||||
class U_I18N_API LocalizedNumberFormatterAsFormat : public Format {
|
||||
public:
|
||||
LocalizedNumberFormatterAsFormat(const LocalizedNumberFormatter& formatter, const Locale& locale);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~LocalizedNumberFormatterAsFormat() U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Equals operator.
|
||||
*/
|
||||
UBool operator==(const Format& other) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Creates a copy of this object.
|
||||
*/
|
||||
Format* clone() const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Formats a Number using the wrapped LocalizedNumberFormatter. The provided formattable must be a
|
||||
* number type.
|
||||
*/
|
||||
UnicodeString& format(const Formattable& obj, UnicodeString& appendTo, FieldPosition& pos,
|
||||
UErrorCode& status) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Formats a Number using the wrapped LocalizedNumberFormatter. The provided formattable must be a
|
||||
* number type.
|
||||
*/
|
||||
UnicodeString& format(const Formattable& obj, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Not supported: sets an error index and returns.
|
||||
*/
|
||||
void parseObject(const UnicodeString& source, Formattable& result,
|
||||
ParsePosition& parse_pos) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Gets the LocalizedNumberFormatter that this wrapper class uses to format numbers.
|
||||
*
|
||||
* For maximum efficiency, this function returns by const reference. You must copy the return value
|
||||
* into a local variable if you want to use it beyond the lifetime of the current object:
|
||||
*
|
||||
* <pre>
|
||||
* LocalizedNumberFormatter localFormatter = fmt->getNumberFormatter();
|
||||
* </pre>
|
||||
*
|
||||
* You can however use the return value directly when chaining:
|
||||
*
|
||||
* <pre>
|
||||
* FormattedNumber result = fmt->getNumberFormatter().formatDouble(514.23, status);
|
||||
* </pre>
|
||||
*
|
||||
* @return The unwrapped LocalizedNumberFormatter.
|
||||
*/
|
||||
const LocalizedNumberFormatter& getNumberFormatter() const;
|
||||
|
||||
private:
|
||||
LocalizedNumberFormatter fFormatter;
|
||||
|
||||
// Even though the locale is inside the LocalizedNumberFormatter, we have to keep it here, too, because
|
||||
// LocalizedNumberFormatter doesn't have a getLocale() method, and ICU-TC didn't want to add one.
|
||||
Locale fLocale;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
} // namespace number
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif // __NUMBER_ASFORMAT_H__
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
@ -5,12 +5,13 @@
|
|||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "resource.h"
|
||||
#include "number_compact.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "cstring.h"
|
||||
#include "charstr.h"
|
||||
#include "resource.h"
|
||||
#include "number_compact.h"
|
||||
#include "number_microprops.h"
|
||||
#include "uresimp.h"
|
||||
|
||||
using namespace icu;
|
||||
|
@ -283,7 +284,7 @@ void CompactHandler::processQuantity(DecimalQuantity &quantity, MicroProps &micr
|
|||
magnitude -= multiplier;
|
||||
}
|
||||
|
||||
StandardPlural::Form plural = quantity.getStandardPlural(rules);
|
||||
StandardPlural::Form plural = utils::getStandardPlural(rules, quantity);
|
||||
const UChar *patternString = data.getPattern(magnitude, plural);
|
||||
if (patternString == nullptr) {
|
||||
// Use the default (non-compact) modifier.
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "unicode/plurrule.h"
|
||||
#include "cmemory.h"
|
||||
#include "number_decnum.h"
|
||||
#include "putilimp.h"
|
||||
#include "number_decimalquantity.h"
|
||||
#include "number_roundingutils.h"
|
||||
|
@ -68,6 +69,7 @@ static double DOUBLE_MULTIPLIERS[] = {
|
|||
|
||||
} // namespace
|
||||
|
||||
icu::IFixedDecimal::~IFixedDecimal() = default;
|
||||
|
||||
DecimalQuantity::DecimalQuantity() {
|
||||
setBcdToZero();
|
||||
|
@ -236,16 +238,6 @@ bool DecimalQuantity::adjustMagnitude(int32_t delta) {
|
|||
return false;
|
||||
}
|
||||
|
||||
StandardPlural::Form DecimalQuantity::getStandardPlural(const PluralRules *rules) const {
|
||||
if (rules == nullptr) {
|
||||
// Fail gracefully if the user didn't provide a PluralRules
|
||||
return StandardPlural::Form::OTHER;
|
||||
} else {
|
||||
UnicodeString ruleString = rules->select(*this);
|
||||
return StandardPlural::orOtherFromString(ruleString);
|
||||
}
|
||||
}
|
||||
|
||||
double DecimalQuantity::getPluralOperand(PluralOperand operand) const {
|
||||
// If this assertion fails, you need to call roundToInfinity() or some other rounding method.
|
||||
// See the comment at the top of this file explaining the "isApproximate" field.
|
||||
|
|
|
@ -194,15 +194,6 @@ class U_I18N_API DecimalQuantity : public IFixedDecimal, public UMemory {
|
|||
*/
|
||||
void appendDigit(int8_t value, int32_t leadingZeros, bool appendAsInteger);
|
||||
|
||||
/**
|
||||
* Computes the plural form for this number based on the specified set of rules.
|
||||
*
|
||||
* @param rules A {@link PluralRules} object representing the set of rules.
|
||||
* @return The {@link StandardPlural} according to the PluralRules. If the plural form is not in
|
||||
* the set of standard plurals, {@link StandardPlural#OTHER} is returned instead.
|
||||
*/
|
||||
StandardPlural::Form getStandardPlural(const PluralRules *rules) const;
|
||||
|
||||
double getPluralOperand(PluralOperand operand) const U_OVERRIDE;
|
||||
|
||||
bool hasIntegerValue() const U_OVERRIDE;
|
||||
|
|
77
icu4c/source/i18n/number_decnum.h
Normal file
77
icu4c/source/i18n/number_decnum.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
// © 2017 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
#ifndef __NUMBER_DECNUM_H__
|
||||
#define __NUMBER_DECNUM_H__
|
||||
|
||||
#include "decNumber.h"
|
||||
#include "charstr.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#define DECNUM_INITIAL_CAPACITY 34
|
||||
|
||||
// Export an explicit template instantiation of the MaybeStackHeaderAndArray that is used as a data member of DecNum.
|
||||
// When building DLLs for Windows this is required even though no direct access to the MaybeStackHeaderAndArray leaks out of the i18n library.
|
||||
// (See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.)
|
||||
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
|
||||
template class U_I18N_API MaybeStackHeaderAndArray<decNumber, char, DECNUM_INITIAL_CAPACITY>;
|
||||
#endif
|
||||
|
||||
namespace number {
|
||||
namespace impl {
|
||||
|
||||
/** A very thin C++ wrapper around decNumber.h */
|
||||
// Exported as U_I18N_API for tests
|
||||
class U_I18N_API DecNum : public UMemory {
|
||||
public:
|
||||
DecNum(); // leaves object in valid but undefined state
|
||||
|
||||
// Copy-like constructor; use the default move operators.
|
||||
DecNum(const DecNum& other, UErrorCode& status);
|
||||
|
||||
/** Sets the decNumber to the StringPiece. */
|
||||
void setTo(StringPiece str, UErrorCode& status);
|
||||
|
||||
/** Sets the decNumber to the NUL-terminated char string. */
|
||||
void setTo(const char* str, UErrorCode& status);
|
||||
|
||||
/** Uses double_conversion to set this decNumber to the given double. */
|
||||
void setTo(double d, UErrorCode& status);
|
||||
|
||||
/** Sets the decNumber to the BCD representation. */
|
||||
void setTo(const uint8_t* bcd, int32_t length, int32_t scale, bool isNegative, UErrorCode& status);
|
||||
|
||||
void normalize();
|
||||
|
||||
void multiplyBy(const DecNum& rhs, UErrorCode& status);
|
||||
|
||||
void divideBy(const DecNum& rhs, UErrorCode& status);
|
||||
|
||||
bool isNegative() const;
|
||||
|
||||
bool isZero() const;
|
||||
|
||||
inline const decNumber* getRawDecNumber() const {
|
||||
return fData.getAlias();
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int32_t kDefaultDigits = DECNUM_INITIAL_CAPACITY;
|
||||
MaybeStackHeaderAndArray<decNumber, char, kDefaultDigits> fData;
|
||||
decContext fContext;
|
||||
|
||||
void _setTo(const char* str, int32_t maxDigits, UErrorCode& status);
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
} // namespace number
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif // __NUMBER_DECNUM_H__
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
@ -10,6 +10,7 @@
|
|||
#include "number_decimalquantity.h"
|
||||
#include "number_formatimpl.h"
|
||||
#include "umutex.h"
|
||||
#include "number_asformat.h"
|
||||
#include "number_skeletons.h"
|
||||
#include "number_utils.h"
|
||||
#include "number_utypes.h"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "number_patternmodifier.h"
|
||||
#include "number_longnames.h"
|
||||
#include "number_compact.h"
|
||||
#include "number_microprops.h"
|
||||
|
||||
U_NAMESPACE_BEGIN namespace number {
|
||||
namespace impl {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "charstr.h"
|
||||
#include "uresimp.h"
|
||||
#include "number_longnames.h"
|
||||
#include "number_microprops.h"
|
||||
#include <algorithm>
|
||||
#include "cstring.h"
|
||||
|
||||
|
@ -261,7 +262,7 @@ void LongNameHandler::processQuantity(DecimalQuantity &quantity, MicroProps &mic
|
|||
// TODO: Avoid the copy here?
|
||||
DecimalQuantity copy(quantity);
|
||||
micros.rounder.apply(copy, status);
|
||||
micros.modOuter = &fModifiers[copy.getStandardPlural(rules)];
|
||||
micros.modOuter = &fModifiers[utils::getStandardPlural(rules, copy)];
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
82
icu4c/source/i18n/number_microprops.h
Normal file
82
icu4c/source/i18n/number_microprops.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
// © 2017 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
#ifndef __NUMBER_MICROPROPS_H__
|
||||
#define __NUMBER_MICROPROPS_H__
|
||||
|
||||
// TODO: minimize includes
|
||||
#include "unicode/numberformatter.h"
|
||||
#include "number_types.h"
|
||||
#include "number_decimalquantity.h"
|
||||
#include "number_scientific.h"
|
||||
#include "number_patternstring.h"
|
||||
#include "number_modifiers.h"
|
||||
#include "number_multiplier.h"
|
||||
#include "number_roundingutils.h"
|
||||
#include "decNumber.h"
|
||||
#include "charstr.h"
|
||||
|
||||
U_NAMESPACE_BEGIN namespace number {
|
||||
namespace impl {
|
||||
|
||||
struct MicroProps : public MicroPropsGenerator {
|
||||
|
||||
// NOTE: All of these fields are properly initialized in NumberFormatterImpl.
|
||||
RoundingImpl rounder;
|
||||
Grouper grouping;
|
||||
Padder padding;
|
||||
IntegerWidth integerWidth;
|
||||
UNumberSignDisplay sign;
|
||||
UNumberDecimalSeparatorDisplay decimal;
|
||||
bool useCurrency;
|
||||
|
||||
// Note: This struct has no direct ownership of the following pointers.
|
||||
const DecimalFormatSymbols* symbols;
|
||||
const Modifier* modOuter;
|
||||
const Modifier* modMiddle;
|
||||
const Modifier* modInner;
|
||||
|
||||
// The following "helper" fields may optionally be used during the MicroPropsGenerator.
|
||||
// They live here to retain memory.
|
||||
struct {
|
||||
ScientificModifier scientificModifier;
|
||||
EmptyModifier emptyWeakModifier{false};
|
||||
EmptyModifier emptyStrongModifier{true};
|
||||
MultiplierFormatHandler multiplier;
|
||||
} helpers;
|
||||
|
||||
|
||||
MicroProps() = default;
|
||||
|
||||
MicroProps(const MicroProps& other) = default;
|
||||
|
||||
MicroProps& operator=(const MicroProps& other) = default;
|
||||
|
||||
void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const U_OVERRIDE {
|
||||
(void) status;
|
||||
if (this == µs) {
|
||||
// Unsafe path: no need to perform a copy.
|
||||
U_ASSERT(!exhausted);
|
||||
micros.exhausted = true;
|
||||
U_ASSERT(exhausted);
|
||||
} else {
|
||||
// Safe path: copy self into the output micros.
|
||||
micros = *this;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal fields:
|
||||
bool exhausted = false;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
} // namespace number
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif // __NUMBER_MICROPROPS_H__
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
@ -9,6 +9,7 @@
|
|||
// Helpful in toString methods and elsewhere.
|
||||
#define UNISTR_FROM_STRING_EXPLICIT
|
||||
|
||||
#include "number_decnum.h"
|
||||
#include "number_types.h"
|
||||
#include "number_multiplier.h"
|
||||
#include "numparse_validators.h"
|
||||
|
@ -152,21 +153,4 @@ void MultiplierFormatHandler::processQuantity(DecimalQuantity& quantity, MicroPr
|
|||
multiplier.applyTo(quantity);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: MultiplierParseHandler is declared in the header numparse_validators.h
|
||||
MultiplierParseHandler::MultiplierParseHandler(::icu::number::Scale multiplier)
|
||||
: fMultiplier(std::move(multiplier)) {}
|
||||
|
||||
void MultiplierParseHandler::postProcess(ParsedNumber& result) const {
|
||||
if (!result.quantity.bogus) {
|
||||
fMultiplier.applyReciprocalTo(result.quantity);
|
||||
// NOTE: It is okay if the multiplier was negative.
|
||||
}
|
||||
}
|
||||
|
||||
UnicodeString MultiplierParseHandler::toString() const {
|
||||
return u"<Scale>";
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "unicode/dcfmtsym.h"
|
||||
#include "unicode/ucurr.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "number_microprops.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
|
@ -136,7 +137,7 @@ void ImmutablePatternModifier::applyToMicros(MicroProps& micros, DecimalQuantity
|
|||
// TODO: Fix this. Avoid the copy.
|
||||
DecimalQuantity copy(quantity);
|
||||
copy.roundToInfinity();
|
||||
StandardPlural::Form plural = copy.getStandardPlural(rules);
|
||||
StandardPlural::Form plural = utils::getStandardPlural(rules, copy);
|
||||
micros.modMiddle = pm->getModifier(quantity.signum(), plural);
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +167,7 @@ void MutablePatternModifier::processQuantity(DecimalQuantity& fq, MicroProps& mi
|
|||
// TODO: Fix this. Avoid the copy.
|
||||
DecimalQuantity copy(fq);
|
||||
micros.rounder.apply(copy, status);
|
||||
nonConstThis->setNumberProperties(fq.signum(), copy.getStandardPlural(rules));
|
||||
nonConstThis->setNumberProperties(fq.signum(), utils::getStandardPlural(rules, copy));
|
||||
} else {
|
||||
nonConstThis->setNumberProperties(fq.signum(), StandardPlural::Form::COUNT);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "number_utils.h"
|
||||
#include "number_stringbuilder.h"
|
||||
#include "unicode/unum.h"
|
||||
#include "number_microprops.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// Helpful in toString methods and elsewhere.
|
||||
#define UNISTR_FROM_STRING_EXPLICIT
|
||||
|
||||
#include "number_decnum.h"
|
||||
#include "number_skeletons.h"
|
||||
#include "umutex.h"
|
||||
#include "ucln_in.h"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <cmath>
|
||||
#include "number_decnum.h"
|
||||
#include "number_types.h"
|
||||
#include "number_utils.h"
|
||||
#include "charstr.h"
|
||||
|
@ -20,7 +21,6 @@
|
|||
#include "fphdlimp.h"
|
||||
#include "uresimp.h"
|
||||
#include "ureslocs.h"
|
||||
#include "number_utypes.h"
|
||||
|
||||
using namespace icu;
|
||||
using namespace icu::number;
|
||||
|
@ -49,86 +49,6 @@ doGetPattern(UResourceBundle* res, const char* nsName, const char* patternKey, U
|
|||
}
|
||||
|
||||
|
||||
LocalizedNumberFormatterAsFormat::LocalizedNumberFormatterAsFormat(
|
||||
const LocalizedNumberFormatter& formatter, const Locale& locale)
|
||||
: fFormatter(formatter), fLocale(locale) {
|
||||
const char* localeName = locale.getName();
|
||||
setLocaleIDs(localeName, localeName);
|
||||
}
|
||||
|
||||
LocalizedNumberFormatterAsFormat::~LocalizedNumberFormatterAsFormat() = default;
|
||||
|
||||
UBool LocalizedNumberFormatterAsFormat::operator==(const Format& other) const {
|
||||
auto* _other = dynamic_cast<const LocalizedNumberFormatterAsFormat*>(&other);
|
||||
if (_other == nullptr) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Change this to use LocalizedNumberFormatter::operator== if it is ever proposed.
|
||||
// This implementation is fine, but not particularly efficient.
|
||||
UErrorCode localStatus = U_ZERO_ERROR;
|
||||
return fFormatter.toSkeleton(localStatus) == _other->fFormatter.toSkeleton(localStatus);
|
||||
}
|
||||
|
||||
Format* LocalizedNumberFormatterAsFormat::clone() const {
|
||||
return new LocalizedNumberFormatterAsFormat(*this);
|
||||
}
|
||||
|
||||
UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, UnicodeString& appendTo,
|
||||
FieldPosition& pos, UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) { return appendTo; }
|
||||
UFormattedNumberData data;
|
||||
obj.populateDecimalQuantity(data.quantity, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
fFormatter.formatImpl(&data, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
// always return first occurrence:
|
||||
pos.setBeginIndex(0);
|
||||
pos.setEndIndex(0);
|
||||
bool found = data.string.nextFieldPosition(pos, status);
|
||||
if (found && appendTo.length() != 0) {
|
||||
pos.setBeginIndex(pos.getBeginIndex() + appendTo.length());
|
||||
pos.setEndIndex(pos.getEndIndex() + appendTo.length());
|
||||
}
|
||||
appendTo.append(data.string.toTempUnicodeString());
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
UnicodeString& LocalizedNumberFormatterAsFormat::format(const Formattable& obj, UnicodeString& appendTo,
|
||||
FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) { return appendTo; }
|
||||
UFormattedNumberData data;
|
||||
obj.populateDecimalQuantity(data.quantity, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
fFormatter.formatImpl(&data, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
appendTo.append(data.string.toTempUnicodeString());
|
||||
if (posIter != nullptr) {
|
||||
FieldPositionIteratorHandler fpih(posIter, status);
|
||||
data.string.getAllFieldPositions(fpih, status);
|
||||
}
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
void LocalizedNumberFormatterAsFormat::parseObject(const UnicodeString&, Formattable&,
|
||||
ParsePosition& parse_pos) const {
|
||||
// Not supported.
|
||||
parse_pos.setErrorIndex(0);
|
||||
}
|
||||
|
||||
const LocalizedNumberFormatter& LocalizedNumberFormatterAsFormat::getNumberFormatter() const {
|
||||
return fFormatter;
|
||||
}
|
||||
|
||||
|
||||
const char16_t* utils::getPatternForStyle(const Locale& locale, const char* nsName, CldrPatternStyle style,
|
||||
UErrorCode& status) {
|
||||
const char* patternKey;
|
||||
|
@ -330,6 +250,4 @@ bool DecNum::isZero() const {
|
|||
return decNumberIsZero(fData.getAlias());
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -20,145 +20,9 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#define DECNUM_INITIAL_CAPACITY 34
|
||||
|
||||
// Export an explicit template instantiation of the MaybeStackHeaderAndArray that is used as a data member of DecNum.
|
||||
// When building DLLs for Windows this is required even though no direct access to the MaybeStackHeaderAndArray leaks out of the i18n library.
|
||||
// (See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.)
|
||||
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
|
||||
template class U_I18N_API MaybeStackHeaderAndArray<decNumber, char, DECNUM_INITIAL_CAPACITY>;
|
||||
#endif
|
||||
|
||||
namespace number {
|
||||
namespace impl {
|
||||
|
||||
struct MicroProps : public MicroPropsGenerator {
|
||||
|
||||
// NOTE: All of these fields are properly initialized in NumberFormatterImpl.
|
||||
RoundingImpl rounder;
|
||||
Grouper grouping;
|
||||
Padder padding;
|
||||
IntegerWidth integerWidth;
|
||||
UNumberSignDisplay sign;
|
||||
UNumberDecimalSeparatorDisplay decimal;
|
||||
bool useCurrency;
|
||||
|
||||
// Note: This struct has no direct ownership of the following pointers.
|
||||
const DecimalFormatSymbols* symbols;
|
||||
const Modifier* modOuter;
|
||||
const Modifier* modMiddle;
|
||||
const Modifier* modInner;
|
||||
|
||||
// The following "helper" fields may optionally be used during the MicroPropsGenerator.
|
||||
// They live here to retain memory.
|
||||
struct {
|
||||
ScientificModifier scientificModifier;
|
||||
EmptyModifier emptyWeakModifier{false};
|
||||
EmptyModifier emptyStrongModifier{true};
|
||||
MultiplierFormatHandler multiplier;
|
||||
} helpers;
|
||||
|
||||
|
||||
MicroProps() = default;
|
||||
|
||||
MicroProps(const MicroProps& other) = default;
|
||||
|
||||
MicroProps& operator=(const MicroProps& other) = default;
|
||||
|
||||
void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const U_OVERRIDE {
|
||||
(void) status;
|
||||
if (this == µs) {
|
||||
// Unsafe path: no need to perform a copy.
|
||||
U_ASSERT(!exhausted);
|
||||
micros.exhausted = true;
|
||||
U_ASSERT(exhausted);
|
||||
} else {
|
||||
// Safe path: copy self into the output micros.
|
||||
micros = *this;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Internal fields:
|
||||
bool exhausted = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A wrapper around LocalizedNumberFormatter implementing the Format interface, enabling improved
|
||||
* compatibility with other APIs.
|
||||
*
|
||||
* @draft ICU 62
|
||||
* @see NumberFormatter
|
||||
*/
|
||||
class U_I18N_API LocalizedNumberFormatterAsFormat : public Format {
|
||||
public:
|
||||
LocalizedNumberFormatterAsFormat(const LocalizedNumberFormatter& formatter, const Locale& locale);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~LocalizedNumberFormatterAsFormat() U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Equals operator.
|
||||
*/
|
||||
UBool operator==(const Format& other) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Creates a copy of this object.
|
||||
*/
|
||||
Format* clone() const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Formats a Number using the wrapped LocalizedNumberFormatter. The provided formattable must be a
|
||||
* number type.
|
||||
*/
|
||||
UnicodeString& format(const Formattable& obj, UnicodeString& appendTo, FieldPosition& pos,
|
||||
UErrorCode& status) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Formats a Number using the wrapped LocalizedNumberFormatter. The provided formattable must be a
|
||||
* number type.
|
||||
*/
|
||||
UnicodeString& format(const Formattable& obj, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Not supported: sets an error index and returns.
|
||||
*/
|
||||
void parseObject(const UnicodeString& source, Formattable& result,
|
||||
ParsePosition& parse_pos) const U_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Gets the LocalizedNumberFormatter that this wrapper class uses to format numbers.
|
||||
*
|
||||
* For maximum efficiency, this function returns by const reference. You must copy the return value
|
||||
* into a local variable if you want to use it beyond the lifetime of the current object:
|
||||
*
|
||||
* <pre>
|
||||
* LocalizedNumberFormatter localFormatter = fmt->getNumberFormatter();
|
||||
* </pre>
|
||||
*
|
||||
* You can however use the return value directly when chaining:
|
||||
*
|
||||
* <pre>
|
||||
* FormattedNumber result = fmt->getNumberFormatter().formatDouble(514.23, status);
|
||||
* </pre>
|
||||
*
|
||||
* @return The unwrapped LocalizedNumberFormatter.
|
||||
*/
|
||||
const LocalizedNumberFormatter& getNumberFormatter() const;
|
||||
|
||||
private:
|
||||
LocalizedNumberFormatter fFormatter;
|
||||
|
||||
// Even though the locale is inside the LocalizedNumberFormatter, we have to keep it here, too, because
|
||||
// LocalizedNumberFormatter doesn't have a getLocale() method, and ICU-TC didn't want to add one.
|
||||
Locale fLocale;
|
||||
};
|
||||
|
||||
|
||||
enum CldrPatternStyle {
|
||||
CLDR_PATTERN_STYLE_DECIMAL,
|
||||
CLDR_PATTERN_STYLE_CURRENCY,
|
||||
|
@ -200,55 +64,29 @@ inline bool unitIsPermille(const MeasureUnit& unit) {
|
|||
const char16_t*
|
||||
getPatternForStyle(const Locale& locale, const char* nsName, CldrPatternStyle style, UErrorCode& status);
|
||||
|
||||
} // namespace utils
|
||||
|
||||
|
||||
/** A very thin C++ wrapper around decNumber.h */
|
||||
// Exported as U_I18N_API for tests
|
||||
class U_I18N_API DecNum : public UMemory {
|
||||
public:
|
||||
DecNum(); // leaves object in valid but undefined state
|
||||
|
||||
// Copy-like constructor; use the default move operators.
|
||||
DecNum(const DecNum& other, UErrorCode& status);
|
||||
|
||||
/** Sets the decNumber to the StringPiece. */
|
||||
void setTo(StringPiece str, UErrorCode& status);
|
||||
|
||||
/** Sets the decNumber to the NUL-terminated char string. */
|
||||
void setTo(const char* str, UErrorCode& status);
|
||||
|
||||
/** Uses double_conversion to set this decNumber to the given double. */
|
||||
void setTo(double d, UErrorCode& status);
|
||||
|
||||
/** Sets the decNumber to the BCD representation. */
|
||||
void setTo(const uint8_t* bcd, int32_t length, int32_t scale, bool isNegative, UErrorCode& status);
|
||||
|
||||
void normalize();
|
||||
|
||||
void multiplyBy(const DecNum& rhs, UErrorCode& status);
|
||||
|
||||
void divideBy(const DecNum& rhs, UErrorCode& status);
|
||||
|
||||
bool isNegative() const;
|
||||
|
||||
bool isZero() const;
|
||||
|
||||
inline const decNumber* getRawDecNumber() const {
|
||||
return fData.getAlias();
|
||||
/**
|
||||
* Computes the plural form for this number based on the specified set of rules.
|
||||
*
|
||||
* @param rules A {@link PluralRules} object representing the set of rules.
|
||||
* @return The {@link StandardPlural} according to the PluralRules. If the plural form is not in
|
||||
* the set of standard plurals, {@link StandardPlural#OTHER} is returned instead.
|
||||
*/
|
||||
inline StandardPlural::Form getStandardPlural(const PluralRules *rules,
|
||||
const IFixedDecimal &fdec) {
|
||||
if (rules == nullptr) {
|
||||
// Fail gracefully if the user didn't provide a PluralRules
|
||||
return StandardPlural::Form::OTHER;
|
||||
} else {
|
||||
UnicodeString ruleString = rules->select(fdec);
|
||||
return StandardPlural::orOtherFromString(ruleString);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int32_t kDefaultDigits = DECNUM_INITIAL_CAPACITY;
|
||||
MaybeStackHeaderAndArray<decNumber, char, kDefaultDigits> fData;
|
||||
decContext fContext;
|
||||
|
||||
void _setTo(const char* str, int32_t maxDigits, UErrorCode& status);
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
|
||||
} // namespace impl
|
||||
} // namespace number
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif //__NUMBER_UTILS_H__
|
||||
|
|
|
@ -68,5 +68,18 @@ UnicodeString RequireNumberValidator::toString() const {
|
|||
return u"<ReqNumber>";
|
||||
}
|
||||
|
||||
MultiplierParseHandler::MultiplierParseHandler(::icu::number::Scale multiplier)
|
||||
: fMultiplier(std::move(multiplier)) {}
|
||||
|
||||
void MultiplierParseHandler::postProcess(ParsedNumber& result) const {
|
||||
if (!result.quantity.bogus) {
|
||||
fMultiplier.applyReciprocalTo(result.quantity);
|
||||
// NOTE: It is okay if the multiplier was negative.
|
||||
}
|
||||
}
|
||||
|
||||
UnicodeString MultiplierParseHandler::toString() const {
|
||||
return u"<Scale>";
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -71,8 +71,6 @@ class RequireNumberValidator : public ValidationMatcher, public UMemory {
|
|||
|
||||
/**
|
||||
* Wraps a {@link Multiplier} for use in the number parsing pipeline.
|
||||
*
|
||||
* NOTE: Implemented in number_multiplier.cpp
|
||||
*/
|
||||
class MultiplierParseHandler : public ValidationMatcher, public UMemory {
|
||||
public:
|
||||
|
|
|
@ -248,26 +248,6 @@ PluralRules::select(double number) const {
|
|||
return select(FixedDecimal(number));
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
PluralRules::select(const Formattable& obj, const NumberFormat& fmt, UErrorCode& status) const {
|
||||
if (U_SUCCESS(status)) {
|
||||
const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
|
||||
if (decFmt != NULL) {
|
||||
number::impl::DecimalQuantity dq;
|
||||
decFmt->formatToDecimalQuantity(obj, dq, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return select(dq);
|
||||
}
|
||||
} else {
|
||||
double number = obj.getDouble(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return select(number);
|
||||
}
|
||||
}
|
||||
}
|
||||
return UnicodeString();
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
PluralRules::select(const IFixedDecimal &number) const {
|
||||
if (mRules == NULL) {
|
||||
|
@ -1418,8 +1398,6 @@ PluralOperand tokenTypeToPluralOperand(tokenType tt) {
|
|||
}
|
||||
}
|
||||
|
||||
IFixedDecimal::~IFixedDecimal() = default;
|
||||
|
||||
FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) {
|
||||
init(n, v, f);
|
||||
// check values. TODO make into unit test.
|
||||
|
|
|
@ -347,22 +347,6 @@ public:
|
|||
UnicodeString select(double number) const;
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* Given a number and a format, returns the keyword of the first applicable
|
||||
* rule for this PluralRules object.
|
||||
* Note: This internal preview interface may be removed in the future if
|
||||
* an architecturally cleaner solution reaches stable status.
|
||||
* @param obj The numeric object for which the rule should be determined.
|
||||
* @param fmt The NumberFormat specifying how the number will be formatted
|
||||
* (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
|
||||
* @param status Input/output parameter. If at entry this indicates a
|
||||
* failure status, the method returns immediately; otherwise
|
||||
* this is set to indicate the outcome of the call.
|
||||
* @return The keyword of the selected rule. Undefined in the case of an error.
|
||||
* @internal ICU 59 technology preview, may be removed in the future
|
||||
*/
|
||||
UnicodeString select(const Formattable& obj, const NumberFormat& fmt, UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -17,9 +17,44 @@
|
|||
#include "unicode/unistr.h"
|
||||
#include "unicode/unum.h"
|
||||
#include "unicode/numfmt.h"
|
||||
#include "number_decimalquantity.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Given a number and a format, returns the keyword of the first applicable
|
||||
* rule for the PluralRules object.
|
||||
* @param rules The plural rules.
|
||||
* @param obj The numeric object for which the rule should be determined.
|
||||
* @param fmt The NumberFormat specifying how the number will be formatted
|
||||
* (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
|
||||
* @param status Input/output parameter. If at entry this indicates a
|
||||
* failure status, the method returns immediately; otherwise
|
||||
* this is set to indicate the outcome of the call.
|
||||
* @return The keyword of the selected rule. Undefined in the case of an error.
|
||||
*/
|
||||
UnicodeString select(const PluralRules &rules, const Formattable& obj, const NumberFormat& fmt, UErrorCode& status) {
|
||||
if (U_SUCCESS(status)) {
|
||||
const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
|
||||
if (decFmt != NULL) {
|
||||
number::impl::DecimalQuantity dq;
|
||||
decFmt->formatToDecimalQuantity(obj, dq, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return rules.select(dq);
|
||||
}
|
||||
} else {
|
||||
double number = obj.getDouble(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return rules.select(number);
|
||||
}
|
||||
}
|
||||
}
|
||||
return UnicodeString();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
U_CAPI UPluralRules* U_EXPORT2
|
||||
uplrules_open(const char *locale, UErrorCode *status)
|
||||
|
@ -73,7 +108,7 @@ uplrules_selectWithFormat(const UPluralRules *uplrules,
|
|||
return 0;
|
||||
}
|
||||
Formattable obj(number);
|
||||
UnicodeString result = plrules->select(obj, *nf, *status);
|
||||
UnicodeString result = select(*plrules, obj, *nf, *status);
|
||||
return result.extract(keyword, capacity, *status);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ system_symbols:
|
|||
# C
|
||||
PIC system_misc system_debug malloc_functions ubsan
|
||||
c_strings c_string_formatting
|
||||
floating_point trigonometry
|
||||
int_functions floating_point trigonometry
|
||||
stdlib_qsort
|
||||
pthread system_locale
|
||||
stdio_input stdio_output file_io readlink_function dir_io mmap_functions dlfcn
|
||||
|
@ -58,8 +58,11 @@ group: c_string_formatting
|
|||
# Additional symbols in an optimized build.
|
||||
__sprintf_chk
|
||||
|
||||
group: int_functions
|
||||
div
|
||||
|
||||
group: floating_point
|
||||
abs fabs floor ceil modf fmod log pow round sqrt
|
||||
abs fabs floor ceil modf fmod log pow round sqrt trunc
|
||||
|
||||
group: trigonometry
|
||||
acos asin atan atan2 cos sin tan
|
||||
|
@ -154,6 +157,7 @@ library: common
|
|||
unistr_props unistr_case unistr_case_locale unistr_titlecase_brkiter unistr_cnv
|
||||
cstr
|
||||
uniset_core uniset_props uniset_closure usetiter uset uset_props
|
||||
static_unicode_sets
|
||||
uiter edits
|
||||
ucasemap ucasemap_titlecase_brkiter script_runs
|
||||
uprops ubidi_props ucase uscript uscript_props
|
||||
|
@ -281,6 +285,11 @@ group: punycode
|
|||
deps
|
||||
platform
|
||||
|
||||
group: static_unicode_sets
|
||||
static_unicode_sets.o
|
||||
deps
|
||||
resourcebundle uniset_props
|
||||
|
||||
group: uset_props
|
||||
uset_props.o
|
||||
deps
|
||||
|
@ -475,6 +484,8 @@ group: ustr_titlecase_brkiter
|
|||
group: edits
|
||||
edits.o
|
||||
deps
|
||||
# Edits::Iterator::toString() calls ICU_Utility::appendNumber()
|
||||
icu_utility
|
||||
platform
|
||||
|
||||
group: ucasemap_titlecase_brkiter
|
||||
|
@ -574,6 +585,7 @@ group: currency
|
|||
deps
|
||||
loclikely resourcebundle ulist ustring_case_locale
|
||||
stdlib_qsort # for ucurr.o (which does not use ICU's uarrsort.o)
|
||||
static_unicode_sets usetiter
|
||||
|
||||
group: icudataver # u_getDataVersion()
|
||||
icudataver.o
|
||||
|
@ -804,7 +816,7 @@ library: i18n
|
|||
alphabetic_index collation collation_builder string_search
|
||||
dayperiodrules
|
||||
formatting formattable_cnv regex regex_cnv translit
|
||||
double_conversion numberformatter
|
||||
double_conversion number_representation numberformatter numberparser
|
||||
universal_time_scale
|
||||
uclean_i18n
|
||||
|
||||
|
@ -881,39 +893,57 @@ group: dayperiodrules
|
|||
group: double_conversion
|
||||
double-conversion.o double-conversion-bignum.o double-conversion-bignum-dtoa.o
|
||||
double-conversion-cached-powers.o double-conversion-diy-fp.o
|
||||
double-conversion-fast-dtoa.o
|
||||
double-conversion-fast-dtoa.o double-conversion-strtod.o
|
||||
deps
|
||||
platform
|
||||
|
||||
group: number_representation
|
||||
number_decimalquantity.o number_stringbuilder.o numparse_stringsegment.o number_utils.o
|
||||
deps
|
||||
decnumber double_conversion
|
||||
# for data loading; that could be split off
|
||||
resourcebundle
|
||||
int_functions
|
||||
ucase uniset_core
|
||||
|
||||
group: numberformatter
|
||||
# ICU 60+ NumberFormatter API
|
||||
number_affixutils.o number_compact.o number_decimalquantity.o
|
||||
number_decimfmtprops.o number_fluent.o number_formatimpl.o
|
||||
number_affixutils.o number_asformat.o
|
||||
number_capi.o number_compact.o number_currencysymbols.o
|
||||
number_decimfmtprops.o
|
||||
number_fluent.o number_formatimpl.o
|
||||
number_grouping.o number_integerwidth.o number_longnames.o
|
||||
number_modifiers.o number_notation.o number_padding.o
|
||||
number_mapper.o number_modifiers.o number_multiplier.o
|
||||
number_notation.o number_padding.o
|
||||
number_patternmodifier.o number_patternstring.o number_rounding.o
|
||||
number_scientific.o number_stringbuilder.o
|
||||
number_scientific.o number_skeletons.o
|
||||
currpinf.o dcfmtsym.o numsys.o
|
||||
# pluralrules
|
||||
standardplural.o plurrule.o
|
||||
deps
|
||||
digitlist formattable format units
|
||||
# TODO: fix: dependency on formatting needed for circular dependency pluralrules <-> decimfmt.o
|
||||
# We should be able to have a small pluralrules group and depend on that here.
|
||||
formatting
|
||||
decnumber double_conversion formattable format units
|
||||
number_representation
|
||||
uclean_i18n common
|
||||
|
||||
group: numberparser
|
||||
numparse_affixes.o numparse_compositions.o numparse_currency.o
|
||||
numparse_decimal.o numparse_impl.o numparse_parsednumber.o
|
||||
numparse_scientific.o numparse_symbols.o
|
||||
numparse_validators.o
|
||||
deps
|
||||
numberformatter
|
||||
|
||||
group: formatting
|
||||
# TODO: Try to subdivide this ball of wax.
|
||||
# currencyformat
|
||||
curramt.o currfmt.o currpinf.o
|
||||
curramt.o currfmt.o
|
||||
# pluralrules C API
|
||||
upluralrules.o
|
||||
# decimalformat
|
||||
dcfmtsym.o numsys.o unumsys.o
|
||||
affixpatternparser.o decimfmtimpl.o digitaffix.o digitaffixesandpadding.o
|
||||
digitformatter.o digitgrouping.o digitinterval.o
|
||||
pluralaffix.o precision.o smallintformatter.o valueformatter.o
|
||||
decfmtst.o decimfmt.o decimalformatpattern.o compactdecimalformat.o
|
||||
unumsys.o
|
||||
decimfmt.o compactdecimalformat.o
|
||||
numfmt.o unum.o
|
||||
winnmfmt.o
|
||||
# pluralrules
|
||||
standardplural.o plurrule.o upluralrules.o
|
||||
# scientificnumberformatter - would depend on dcfmtsym, so would be circular.
|
||||
scientificnumberformatter.o
|
||||
# rbnf
|
||||
|
@ -934,7 +964,7 @@ group: formatting
|
|||
# messageformat
|
||||
choicfmt.o msgfmt.o plurfmt.o selfmt.o umsg.o
|
||||
deps
|
||||
digitlist formattable format units
|
||||
decnumber formattable format units numberformatter numberparser
|
||||
dayperiodrules
|
||||
collation collation_builder # for rbnf
|
||||
common
|
||||
|
@ -953,8 +983,8 @@ group: units
|
|||
deps
|
||||
stringenumeration
|
||||
|
||||
group: digitlist
|
||||
digitlst.o decContext.o decNumber.o visibledigits.o
|
||||
group: decnumber
|
||||
decContext.o decNumber.o
|
||||
deps
|
||||
double_conversion uclean_i18n
|
||||
|
||||
|
@ -962,7 +992,7 @@ group: formattable
|
|||
fmtable.o
|
||||
measure.o
|
||||
deps
|
||||
digitlist
|
||||
decnumber number_representation
|
||||
|
||||
group: formattable_cnv
|
||||
fmtable_cnv.o
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <cmath>
|
||||
#include "unicode/unum.h"
|
||||
#include "unicode/numberformatter.h"
|
||||
#include "number_asformat.h"
|
||||
#include "number_types.h"
|
||||
#include "number_utils.h"
|
||||
#include "numbertest.h"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "number_decimalquantity.h"
|
||||
#include "number_decnum.h"
|
||||
#include "math.h"
|
||||
#include <cmath>
|
||||
#include "number_utils.h"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "numbertest.h"
|
||||
#include "number_microprops.h"
|
||||
#include "number_patternmodifier.h"
|
||||
|
||||
void PatternModifierTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
|
||||
|
|
Loading…
Add table
Reference in a new issue