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
32U_NAMESPACE_BEGIN
33
34class NFSubstitution : public UObject {
35 int32_t pos;
36 const NFRuleSet* ruleSet;
37 DecimalFormat* numberFormat;
38
39protected:
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 */
49 const NFRuleSet* getRuleSet() const { return ruleSet; }
50
51 /**
52 * get the NumberFormat of this object.
53 * @return the numberformat of this object.
54 */
55 const DecimalFormat* getNumberFormat() const { return numberFormat; }
56
57public:
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 UBool 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 UBool 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
132protected:
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
155public:
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 */
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 UChar 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
247private:
248 NFSubstitution(const NFSubstitution &other); // forbid copying of this class
249 NFSubstitution &operator=(const NFSubstitution &other); // forbid copying of this class
250
251public:
252 static UClassID getStaticClassID(void);
253 virtual UClassID getDynamicClassID(void) const;
254};
255
256U_NAMESPACE_END
257
258/* U_HAVE_RBNF */
259#endif
260
261// NFSUBS_H
262#endif
263