1 /* 2 ****************************************************************************** 3 * Copyright (C) 1997-2015, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ****************************************************************************** 6 * file name: nfsubs.h 7 * encoding: US-ASCII 8 * tab size: 8 (not used) 9 * indentation:4 10 * 11 * Modification history 12 * Date Name Comments 13 * 10/11/2001 Doug Ported from ICU4J 14 */ 15 16 #ifndef NFSUBS_H 17 #define NFSUBS_H 18 19 #include "unicode/utypes.h" 20 #include "unicode/uobject.h" 21 #include "nfrule.h" 22 23 #if U_HAVE_RBNF 24 25 #include "unicode/utypes.h" 26 #include "unicode/decimfmt.h" 27 #include "nfrs.h" 28 #include <float.h> 29 30 U_NAMESPACE_BEGIN 31 32 class NFSubstitution : public UObject { 33 int32_t pos; 34 const NFRuleSet* ruleSet; 35 DecimalFormat* numberFormat; 36 37 protected: 38 NFSubstitution(int32_t pos, 39 const NFRuleSet* ruleSet, 40 const UnicodeString& description, 41 UErrorCode& status); 42 43 /** 44 * Get the Ruleset of the object. 45 * @return the Ruleset of the object. 46 */ getRuleSet()47 const NFRuleSet* getRuleSet() const { return ruleSet; } 48 49 /** 50 * get the NumberFormat of this object. 51 * @return the numberformat of this object. 52 */ getNumberFormat()53 const DecimalFormat* getNumberFormat() const { return numberFormat; } 54 55 public: 56 static NFSubstitution* makeSubstitution(int32_t pos, 57 const NFRule* rule, 58 const NFRule* predecessor, 59 const NFRuleSet* ruleSet, 60 const RuleBasedNumberFormat* rbnf, 61 const UnicodeString& description, 62 UErrorCode& status); 63 64 /** 65 * Destructor. 66 */ 67 virtual ~NFSubstitution(); 68 69 /** 70 * Return true if the given Format objects are semantically equal. 71 * Objects of different subclasses are considered unequal. 72 * @param rhs the object to be compared with. 73 * @return true if the given Format objects are semantically equal. 74 */ 75 virtual UBool operator==(const NFSubstitution& rhs) const; 76 77 /** 78 * Return true if the given Format objects are semantically unequal. 79 * Objects of different subclasses are considered unequal. 80 * @param rhs the object to be compared with. 81 * @return true if the given Format objects are semantically unequal. 82 */ 83 UBool operator!=(const NFSubstitution& rhs) const { return !operator==(rhs); } 84 85 /** 86 * Sets the substitution's divisor. Used by NFRule.setBaseValue(). 87 * A no-op for all substitutions except multiplier and modulus 88 * substitutions. 89 * @param radix The radix of the divisor 90 * @param exponent The exponent of the divisor 91 */ 92 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status); 93 94 /** 95 * Replaces result with the string describing the substitution. 96 * @param result Output param which will receive the string. 97 */ 98 virtual void toString(UnicodeString& result) const; 99 100 void setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status); 101 102 //----------------------------------------------------------------------- 103 // formatting 104 //----------------------------------------------------------------------- 105 106 /** 107 * Performs a mathematical operation on the number, formats it using 108 * either ruleSet or decimalFormat, and inserts the result into 109 * toInsertInto. 110 * @param number The number being formatted. 111 * @param toInsertInto The string we insert the result into 112 * @param pos The position in toInsertInto where the owning rule's 113 * rule text begins (this value is added to this substitution's 114 * position to determine exactly where to insert the new text) 115 */ 116 virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const; 117 118 /** 119 * Performs a mathematical operation on the number, formats it using 120 * either ruleSet or decimalFormat, and inserts the result into 121 * toInsertInto. 122 * @param number The number being formatted. 123 * @param toInsertInto The string we insert the result into 124 * @param pos The position in toInsertInto where the owning rule's 125 * rule text begins (this value is added to this substitution's 126 * position to determine exactly where to insert the new text) 127 */ 128 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const; 129 130 protected: 131 /** 132 * Subclasses override this function to perform some kind of 133 * mathematical operation on the number. The result of this operation 134 * is formatted using the rule set or DecimalFormat that this 135 * substitution refers to, and the result is inserted into the result 136 * string. 137 * @param The number being formatted 138 * @return The result of performing the opreration on the number 139 */ 140 virtual int64_t transformNumber(int64_t number) const = 0; 141 142 /** 143 * Subclasses override this function to perform some kind of 144 * mathematical operation on the number. The result of this operation 145 * is formatted using the rule set or DecimalFormat that this 146 * substitution refers to, and the result is inserted into the result 147 * string. 148 * @param The number being formatted 149 * @return The result of performing the opreration on the number 150 */ 151 virtual double transformNumber(double number) const = 0; 152 153 public: 154 //----------------------------------------------------------------------- 155 // parsing 156 //----------------------------------------------------------------------- 157 158 /** 159 * Parses a string using the rule set or DecimalFormat belonging 160 * to this substitution. If there's a match, a mathematical 161 * operation (the inverse of the one used in formatting) is 162 * performed on the result of the parse and the value passed in 163 * and returned as the result. The parse position is updated to 164 * point to the first unmatched character in the string. 165 * @param text The string to parse 166 * @param parsePosition On entry, ignored, but assumed to be 0. 167 * On exit, this is updated to point to the first unmatched 168 * character (or 0 if the substitution didn't match) 169 * @param baseValue A partial parse result that should be 170 * combined with the result of this parse 171 * @param upperBound When searching the rule set for a rule 172 * matching the string passed in, only rules with base values 173 * lower than this are considered 174 * @param lenientParse If true and matching against rules fails, 175 * the substitution will also try matching the text against 176 * numerals using a default-costructed NumberFormat. If false, 177 * no extra work is done. (This value is false whenever the 178 * formatter isn't in lenient-parse mode, but is also false 179 * under some conditions even when the formatter _is_ in 180 * lenient-parse mode.) 181 * @return If there's a match, this is the result of composing 182 * baseValue with whatever was returned from matching the 183 * characters. This will be either a Long or a Double. If there's 184 * no match this is new Long(0) (not null), and parsePosition 185 * is left unchanged. 186 */ 187 virtual UBool doParse(const UnicodeString& text, 188 ParsePosition& parsePosition, 189 double baseValue, 190 double upperBound, 191 UBool lenientParse, 192 Formattable& result) const; 193 194 /** 195 * Derives a new value from the two values passed in. The two values 196 * are typically either the base values of two rules (the one containing 197 * the substitution and the one matching the substitution) or partial 198 * parse results derived in some other way. The operation is generally 199 * the inverse of the operation performed by transformNumber(). 200 * @param newRuleValue The value produced by matching this substitution 201 * @param oldRuleValue The value that was passed to the substitution 202 * by the rule that owns it 203 * @return A third value derived from the other two, representing a 204 * partial parse result 205 */ 206 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const = 0; 207 208 /** 209 * Calculates an upper bound when searching for a rule that matches 210 * this substitution. Rules with base values greater than or equal 211 * to upperBound are not considered. 212 * @param oldUpperBound The current upper-bound setting. The new 213 * upper bound can't be any higher. 214 * @return the upper bound when searching for a rule that matches 215 * this substitution. 216 */ 217 virtual double calcUpperBound(double oldUpperBound) const = 0; 218 219 //----------------------------------------------------------------------- 220 // simple accessors 221 //----------------------------------------------------------------------- 222 223 /** 224 * Returns the substitution's position in the rule that owns it. 225 * @return The substitution's position in the rule that owns it. 226 */ getPos()227 int32_t getPos() const { return pos; } 228 229 /** 230 * Returns the character used in the textual representation of 231 * substitutions of this type. Used by toString(). 232 * @return This substitution's token character. 233 */ 234 virtual UChar tokenChar() const = 0; 235 236 /** 237 * Returns true if this is a modulus substitution. (We didn't do this 238 * with instanceof partially because it causes source files to 239 * proliferate and partially because we have to port this to C++.) 240 * @return true if this object is an instance of ModulusSubstitution 241 */ 242 virtual UBool isModulusSubstitution() const; 243 244 private: 245 NFSubstitution(const NFSubstitution &other); // forbid copying of this class 246 NFSubstitution &operator=(const NFSubstitution &other); // forbid copying of this class 247 248 public: 249 static UClassID getStaticClassID(void); 250 virtual UClassID getDynamicClassID(void) const; 251 }; 252 253 U_NAMESPACE_END 254 255 /* U_HAVE_RBNF */ 256 #endif 257 258 // NFSUBS_H 259 #endif 260