#include "utypeinfo.h" // for 'typeid' to work
#include "nfsubs.h"
-#include "digitlst.h"
#include "fmtableimp.h"
+#include "putilimp.h"
+#include "number_decimalquantity.h"
#if U_HAVE_RBNF
U_NAMESPACE_BEGIN
+using number::impl::DecimalQuantity;
+
class SameValueSubstitution : public NFSubstitution {
public:
SameValueSubstitution(int32_t pos,
return newRuleValue * divisor;
}
- virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
+ virtual double calcUpperBound(double /*oldUpperBound*/) const { return static_cast<double>(divisor); }
virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
virtual int64_t transformNumber(int64_t number) const { return number % divisor; }
- virtual double transformNumber(double number) const { return uprv_fmod(number, divisor); }
+ virtual double transformNumber(double number) const { return uprv_fmod(number, static_cast<double>(divisor)); }
virtual UBool doParse(const UnicodeString& text,
ParsePosition& parsePosition,
double baseValue,
double upperBound,
UBool lenientParse,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& result) const;
virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const {
- return oldRuleValue - uprv_fmod(oldRuleValue, divisor) + newRuleValue;
+ return oldRuleValue - uprv_fmod(oldRuleValue, static_cast<double>(divisor)) + newRuleValue;
}
- virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
+ virtual double calcUpperBound(double /*oldUpperBound*/) const { return static_cast<double>(divisor); }
virtual UBool isModulusSubstitution() const { return TRUE; }
double baseValue,
double upperBound,
UBool lenientParse,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& result) const;
virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
double baseValue,
double upperBound,
UBool /*lenientParse*/,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& result) const;
virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue / oldRuleValue; }
double baseValue,
double upperBound,
UBool lenientParse,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& result) const
{
#ifdef RBNF_DEBUG
// on), then also try parsing the text using a default-
// constructed NumberFormat
if (ruleSet != NULL) {
- ruleSet->parse(text, parsePosition, upperBound, result);
+ ruleSet->parse(text, parsePosition, upperBound, nonNumericalExecutedRuleMask, result);
if (lenientParse && !ruleSet->isFractionRuleSet() && parsePosition.getIndex() == 0) {
UErrorCode status = U_ZERO_ERROR;
NumberFormat* fmt = NumberFormat::createInstance(status);
double baseValue,
double upperBound,
UBool lenientParse,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& result) const
{
// if this isn't a >>> substitution, we can just use the
// inherited parse() routine to do the parsing
if (ruleToUse == NULL) {
- return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, lenientParse, result);
+ return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, lenientParse, nonNumericalExecutedRuleMask, result);
// but if it IS a >>> substitution, we have to do it here: we
// use the specific rule's doParse() method, and then we have to
// do some of the other work of NFRuleSet.parse()
} else {
- ruleToUse->doParse(text, parsePosition, FALSE, upperBound, result);
+ ruleToUse->doParse(text, parsePosition, FALSE, upperBound, nonNumericalExecutedRuleMask, result);
if (parsePosition.getIndex() != 0) {
UErrorCode status = U_ZERO_ERROR;
// numberToFormat /= 10;
// }
- DigitList dl;
- dl.set(number);
- dl.roundFixedPoint(20); // round to 20 fraction digits.
- dl.reduce(); // Removes any trailing zeros.
+ DecimalQuantity dl;
+ dl.setToDouble(number);
+ dl.roundToMagnitude(-20, UNUM_ROUND_HALFEVEN, status); // round to 20 fraction digits.
UBool pad = FALSE;
- for (int32_t didx = dl.getCount()-1; didx>=dl.getDecimalAt(); didx--) {
+ for (int32_t didx = dl.getLowerDisplayMagnitude(); didx<0; didx++) {
// Loop iterates over fraction digits, starting with the LSD.
// include both real digits from the number, and zeros
// to the left of the MSD but to the right of the decimal point.
} else {
pad = TRUE;
}
- int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0;
+ int64_t digit = dl.getDigit(didx);
getRuleSet()->format(digit, toInsertInto, _pos + getPos(), recursionCount, status);
}
double baseValue,
double /*upperBound*/,
UBool lenientParse,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& resVal) const
{
// if we're not in byDigits mode, we can just use the inherited
// doParse()
if (!byDigits) {
- return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, resVal);
+ return NFSubstitution::doParse(text, parsePosition, baseValue, 0, lenientParse, nonNumericalExecutedRuleMask, resVal);
// if we ARE in byDigits mode, parse the text one digit at a time
// using this substitution's owning rule set (we do this by setting
int32_t digit;
// double p10 = 0.1;
- DigitList dl;
+ DecimalQuantity dl;
+ int32_t totalDigits = 0;
NumberFormat* fmt = NULL;
while (workText.length() > 0 && workPos.getIndex() != 0) {
workPos.setIndex(0);
Formattable temp;
- getRuleSet()->parse(workText, workPos, 10, temp);
+ getRuleSet()->parse(workText, workPos, 10, nonNumericalExecutedRuleMask, temp);
UErrorCode status = U_ZERO_ERROR;
digit = temp.getLong(status);
// digit = temp.getType() == Formattable::kLong ?
}
if (workPos.getIndex() != 0) {
- dl.append((char)('0' + digit));
+ dl.appendDigit(static_cast<int8_t>(digit), 0, true);
+ totalDigits++;
// result += digit * p10;
// p10 /= 10;
parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
}
delete fmt;
- result = dl.getCount() == 0 ? 0 : dl.getDouble();
+ dl.adjustMagnitude(-totalDigits);
+ result = dl.toDouble();
result = composeRuleValue(result, baseValue);
resVal.setDouble(result);
return TRUE;
double baseValue,
double upperBound,
UBool /*lenientParse*/,
+ uint32_t nonNumericalExecutedRuleMask,
Formattable& result) const
{
// we don't have to do anything special to do the parsing here,
while (workText.length() > 0 && workPos.getIndex() != 0) {
workPos.setIndex(0);
- getRuleSet()->parse(workText, workPos, 1, temp); // parse zero or nothing at all
+ getRuleSet()->parse(workText, workPos, 1, nonNumericalExecutedRuleMask, temp); // parse zero or nothing at all
if (workPos.getIndex() == 0) {
// we failed, either there were no more zeros, or the number was formatted with digits
// either way, we're done
}
// we've parsed off the zeros, now let's parse the rest from our current position
- NFSubstitution::doParse(workText, parsePosition, withZeros ? 1 : baseValue, upperBound, FALSE, result);
+ NFSubstitution::doParse(workText, parsePosition, withZeros ? 1 : baseValue, upperBound, FALSE, nonNumericalExecutedRuleMask, result);
if (withZeros) {
// any base value will do in this case. is there a way to