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