scuffed-code/icu4c/source/i18n/nfrule.h
George Rhoten e097e1b9ee ICU-8223 Add rule syntax for NaN, infinity and alternate decimal points.
Other issues addressed:
* Some performance enhancements were added for good measure. Creating new RuleBasedNumberFormat objects can take a long time due to all the rule parsing. This was ported from ICU4J.
* I fixed a potential infinite recursion problem when RuleBasedNumberFormat used NumberFormat.createInstance, which could occasionally depend on creating RuleBasedNumberFormat for itself, which was bad. This was ported from ICU4J.
* I fixed a potential memory leak due to lazy initialization of some RBNF data members in a multithreaded environment, which is fine in Java, but it's not okay in C++. We no longer cast away const due to this, which is good.
* There were some compiler warnings and errors found while trying to debug this code on my machine. I fixed those too.

X-SVN-Rev: 37810
2015-08-25 16:55:52 +00:00

127 lines
4.2 KiB
C++

/*
*******************************************************************************
* Copyright (C) 1997-2015, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
#ifndef NFRULE_H
#define NFRULE_H
#include "unicode/rbnf.h"
#if U_HAVE_RBNF
#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "unicode/unistr.h"
#include "putilimp.h"
U_NAMESPACE_BEGIN
class FieldPosition;
class Formattable;
class NFRuleList;
class NFRuleSet;
class NFSubstitution;
class ParsePosition;
class PluralFormat;
class RuleBasedNumberFormat;
class UnicodeString;
class NFRule : public UMemory {
public:
enum ERuleType {
kNoBase = 0,
kNegativeNumberRule = -1,
kImproperFractionRule = -2,
kProperFractionRule = -3,
kMasterRule = -4,
kInfinityRule = -5,
kNaNRule = -6,
kOtherRule = -7
};
static void makeRules(UnicodeString& definition,
NFRuleSet* ruleSet,
const NFRule* predecessor,
const RuleBasedNumberFormat* rbnf,
NFRuleList& ruleList,
UErrorCode& status);
NFRule(const RuleBasedNumberFormat* rbnf, const UnicodeString &ruleText, UErrorCode &status);
~NFRule();
UBool operator==(const NFRule& rhs) const;
UBool operator!=(const NFRule& rhs) const { return !operator==(rhs); }
ERuleType getType() const { return (ERuleType)(baseValue <= kNoBase ? (ERuleType)baseValue : kOtherRule); }
void setType(ERuleType ruleType) { baseValue = (int32_t)ruleType; }
int64_t getBaseValue() const { return baseValue; }
void setBaseValue(int64_t value, UErrorCode& status);
UChar getDecimalPoint() const { return decimalPoint; }
double getDivisor() const { return uprv_pow(radix, exponent); }
void doFormat(int64_t number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
void doFormat(double number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
UBool doParse(const UnicodeString& text,
ParsePosition& pos,
UBool isFractional,
double upperBound,
Formattable& result) const;
UBool shouldRollBack(double number) const;
void _appendRuleText(UnicodeString& result) const;
int32_t findTextLenient(const UnicodeString& str, const UnicodeString& key,
int32_t startingAt, int32_t* resultCount) const;
void setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status);
private:
void parseRuleDescriptor(UnicodeString& descriptor, UErrorCode& status);
void extractSubstitutions(const NFRuleSet* ruleSet, const UnicodeString &ruleText, const NFRule* predecessor, UErrorCode& status);
NFSubstitution* extractSubstitution(const NFRuleSet* ruleSet, const NFRule* predecessor, UErrorCode& status);
int16_t expectedExponent() const;
int32_t indexOfAnyRulePrefix() const;
double matchToDelimiter(const UnicodeString& text, int32_t startPos, double baseValue,
const UnicodeString& delimiter, ParsePosition& pp, const NFSubstitution* sub,
double upperBound) const;
void stripPrefix(UnicodeString& text, const UnicodeString& prefix, ParsePosition& pp) const;
int32_t prefixLength(const UnicodeString& str, const UnicodeString& prefix, UErrorCode& status) const;
UBool allIgnorable(const UnicodeString& str, UErrorCode& status) const;
int32_t findText(const UnicodeString& str, const UnicodeString& key,
int32_t startingAt, int32_t* resultCount) const;
private:
int64_t baseValue;
int32_t radix;
int16_t exponent;
UChar decimalPoint;
UnicodeString ruleText;
NFSubstitution* sub1;
NFSubstitution* sub2;
const RuleBasedNumberFormat* formatter;
const PluralFormat* rulePatternFormat;
NFRule(const NFRule &other); // forbid copying of this class
NFRule &operator=(const NFRule &other); // forbid copying of this class
};
U_NAMESPACE_END
/* U_HAVE_RBNF */
#endif
// NFRULE_H
#endif