]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/i18n/nfsubs.h
ICU-6.2.14.tar.gz
[apple/icu.git] / icuSources / i18n / nfsubs.h
... / ...
CommitLineData
1/*
2******************************************************************************
3* Copyright (C) 1997-2004, 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
30U_NAMESPACE_BEGIN
31
32class NFSubstitution : public UObject {
33 int32_t pos;
34 const NFRuleSet* ruleSet;
35 const DecimalFormat* numberFormat;
36
37protected:
38 NFSubstitution(int32_t pos,
39 const NFRuleSet* ruleSet,
40 const RuleBasedNumberFormat* rbnf,
41 const UnicodeString& description,
42 UErrorCode& status);
43
44 /**
45 * Get the Ruleset of the object.
46 * @return the Ruleset of the object.
47 */
48 const NFRuleSet* getRuleSet() const { return ruleSet; }
49
50 /**
51 * get the NumberFormat of this object.
52 * @return the numberformat of this object.
53 */
54 const DecimalFormat* getNumberFormat() const { return numberFormat; }
55
56public:
57 static NFSubstitution* makeSubstitution(int32_t pos,
58 const NFRule* rule,
59 const NFRule* predecessor,
60 const NFRuleSet* ruleSet,
61 const RuleBasedNumberFormat* rbnf,
62 const UnicodeString& description,
63 UErrorCode& status);
64
65 /**
66 * Destructor.
67 */
68 virtual ~NFSubstitution();
69
70 /**
71 * Return true if the given Format objects are semantically equal.
72 * Objects of different subclasses are considered unequal.
73 * @param rhs the object to be compared with.
74 * @return true if the given Format objects are semantically equal.
75 */
76 virtual UBool operator==(const NFSubstitution& rhs) const;
77
78 /**
79 * Return true if the given Format objects are semantically unequal.
80 * Objects of different subclasses are considered unequal.
81 * @param rhs the object to be compared with.
82 * @return true if the given Format objects are semantically unequal.
83 */
84 UBool operator!=(const NFSubstitution& rhs) const { return !operator==(rhs); }
85
86 /**
87 * Sets the substitution's divisor. Used by NFRule.setBaseValue().
88 * A no-op for all substitutions except multiplier and modulus
89 * substitutions.
90 * @param radix The radix of the divisor
91 * @param exponent The exponent of the divisor
92 */
93 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status);
94
95 /**
96 * Replaces result with the string describing the substitution.
97 * @param result Output param which will receive the string.
98 */
99 virtual void toString(UnicodeString& result) const;
100
101 //-----------------------------------------------------------------------
102 // formatting
103 //-----------------------------------------------------------------------
104
105 /**
106 * Performs a mathematical operation on the number, formats it using
107 * either ruleSet or decimalFormat, and inserts the result into
108 * toInsertInto.
109 * @param number The number being formatted.
110 * @param toInsertInto The string we insert the result into
111 * @param pos The position in toInsertInto where the owning rule's
112 * rule text begins (this value is added to this substitution's
113 * position to determine exactly where to insert the new text)
114 */
115 virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos) const;
116
117 /**
118 * Performs a mathematical operation on the number, formats it using
119 * either ruleSet or decimalFormat, and inserts the result into
120 * toInsertInto.
121 * @param number The number being formatted.
122 * @param toInsertInto The string we insert the result into
123 * @param pos The position in toInsertInto where the owning rule's
124 * rule text begins (this value is added to this substitution's
125 * position to determine exactly where to insert the new text)
126 */
127 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
128
129protected:
130 /**
131 * Subclasses override this function to perform some kind of
132 * mathematical operation on the number. The result of this operation
133 * is formatted using the rule set or DecimalFormat that this
134 * substitution refers to, and the result is inserted into the result
135 * string.
136 * @param The number being formatted
137 * @return The result of performing the opreration on the number
138 */
139 virtual int64_t transformNumber(int64_t number) const = 0;
140
141 /**
142 * Subclasses override this function to perform some kind of
143 * mathematical operation on the number. The result of this operation
144 * is formatted using the rule set or DecimalFormat that this
145 * substitution refers to, and the result is inserted into the result
146 * string.
147 * @param The number being formatted
148 * @return The result of performing the opreration on the number
149 */
150 virtual double transformNumber(double number) const = 0;
151
152public:
153 //-----------------------------------------------------------------------
154 // parsing
155 //-----------------------------------------------------------------------
156
157 /**
158 * Parses a string using the rule set or DecimalFormat belonging
159 * to this substitution. If there's a match, a mathematical
160 * operation (the inverse of the one used in formatting) is
161 * performed on the result of the parse and the value passed in
162 * and returned as the result. The parse position is updated to
163 * point to the first unmatched character in the string.
164 * @param text The string to parse
165 * @param parsePosition On entry, ignored, but assumed to be 0.
166 * On exit, this is updated to point to the first unmatched
167 * character (or 0 if the substitution didn't match)
168 * @param baseValue A partial parse result that should be
169 * combined with the result of this parse
170 * @param upperBound When searching the rule set for a rule
171 * matching the string passed in, only rules with base values
172 * lower than this are considered
173 * @param lenientParse If true and matching against rules fails,
174 * the substitution will also try matching the text against
175 * numerals using a default-costructed NumberFormat. If false,
176 * no extra work is done. (This value is false whenever the
177 * formatter isn't in lenient-parse mode, but is also false
178 * under some conditions even when the formatter _is_ in
179 * lenient-parse mode.)
180 * @return If there's a match, this is the result of composing
181 * baseValue with whatever was returned from matching the
182 * characters. This will be either a Long or a Double. If there's
183 * no match this is new Long(0) (not null), and parsePosition
184 * is left unchanged.
185 */
186 virtual UBool doParse(const UnicodeString& text,
187 ParsePosition& parsePosition,
188 double baseValue,
189 double upperBound,
190 UBool lenientParse,
191 Formattable& result) const;
192
193 /**
194 * Derives a new value from the two values passed in. The two values
195 * are typically either the base values of two rules (the one containing
196 * the substitution and the one matching the substitution) or partial
197 * parse results derived in some other way. The operation is generally
198 * the inverse of the operation performed by transformNumber().
199 * @param newRuleValue The value produced by matching this substitution
200 * @param oldRuleValue The value that was passed to the substitution
201 * by the rule that owns it
202 * @return A third value derived from the other two, representing a
203 * partial parse result
204 */
205 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const = 0;
206
207 /**
208 * Calculates an upper bound when searching for a rule that matches
209 * this substitution. Rules with base values greater than or equal
210 * to upperBound are not considered.
211 * @param oldUpperBound The current upper-bound setting. The new
212 * upper bound can't be any higher.
213 * @return the upper bound when searching for a rule that matches
214 * this substitution.
215 */
216 virtual double calcUpperBound(double oldUpperBound) const = 0;
217
218 //-----------------------------------------------------------------------
219 // simple accessors
220 //-----------------------------------------------------------------------
221
222 /**
223 * Returns the substitution's position in the rule that owns it.
224 * @return The substitution's position in the rule that owns it.
225 */
226 int32_t getPos() const { return pos; }
227
228 /**
229 * Returns the character used in the textual representation of
230 * substitutions of this type. Used by toString().
231 * @return This substitution's token character.
232 */
233 virtual UChar tokenChar() const = 0;
234
235 /**
236 * Returns true if this is a null substitution. (We didn't do this
237 * with instanceof partially because it causes source files to
238 * proliferate and partially because we have to port this to C++.)
239 * @return true if this object is an instance of NullSubstitution
240 */
241 virtual UBool isNullSubstitution() const;
242
243 /**
244 * Returns true if this is a modulus substitution. (We didn't do this
245 * with instanceof partially because it causes source files to
246 * proliferate and partially because we have to port this to C++.)
247 * @return true if this object is an instance of ModulusSubstitution
248 */
249 virtual UBool isModulusSubstitution() const;
250
251private:
252 NFSubstitution(const NFSubstitution &other); // forbid copying of this class
253 NFSubstitution &operator=(const NFSubstitution &other); // forbid copying of this class
254
255 static const char fgClassID;
256
257public:
258 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
259 virtual UClassID getDynamicClassID(void) const;
260};
261
262class SameValueSubstitution : public NFSubstitution {
263public:
264 SameValueSubstitution(int32_t pos,
265 const NFRuleSet* ruleset,
266 const RuleBasedNumberFormat* formatter,
267 const UnicodeString& description,
268 UErrorCode& status);
269
270 virtual int64_t transformNumber(int64_t number) const { return number; }
271 virtual double transformNumber(double number) const { return number; }
272 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/) const { return newRuleValue; }
273 virtual double calcUpperBound(double oldUpperBound) const { return oldUpperBound; }
274 virtual UChar tokenChar() const { return (UChar)0x003d; } // '='
275private:
276 static const char fgClassID;
277
278public:
279 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
280 virtual UClassID getDynamicClassID(void) const;
281};
282
283class MultiplierSubstitution : public NFSubstitution {
284 double divisor;
285 int64_t ldivisor;
286
287public:
288 MultiplierSubstitution(int32_t _pos,
289 double _divisor,
290 const NFRuleSet* _ruleSet,
291 const RuleBasedNumberFormat* formatter,
292 const UnicodeString& description,
293 UErrorCode& status)
294 : NFSubstitution(_pos, _ruleSet, formatter, description, status), divisor(_divisor)
295 {
296 ldivisor = util64_fromDouble(divisor);
297 if (divisor == 0) {
298 status = U_PARSE_ERROR;
299 }
300 }
301
302 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) {
303 divisor = uprv_pow(radix, exponent);
304 ldivisor = util64_fromDouble(divisor);
305
306 if(divisor == 0) {
307 status = U_PARSE_ERROR;
308 }
309 }
310
311 virtual UBool operator==(const NFSubstitution& rhs) const;
312
313 virtual int64_t transformNumber(int64_t number) const {
314 return number / ldivisor;
315 }
316
317 virtual double transformNumber(double number) const {
318 return uprv_floor(number / divisor);
319 }
320
321 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/) const {
322 return newRuleValue * divisor;
323 }
324
325 virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
326
327 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
328private:
329 static const char fgClassID;
330
331public:
332 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
333 virtual UClassID getDynamicClassID(void) const;
334};
335
336class ModulusSubstitution : public NFSubstitution {
337 double divisor;
338 int64_t ldivisor;
339 const NFRule* ruleToUse;
340public:
341 ModulusSubstitution(int32_t pos,
342 double _divisor,
343 const NFRule* rulePredecessor,
344 const NFRuleSet* ruleSet,
345 const RuleBasedNumberFormat* formatter,
346 const UnicodeString& description,
347 UErrorCode& status);
348
349 virtual void setDivisor(int32_t radix, int32_t exponent, UErrorCode& status) {
350 divisor = uprv_pow(radix, exponent);
351 ldivisor = util64_fromDouble(divisor);
352
353 if (divisor == 0) {
354 status = U_PARSE_ERROR;
355 }
356 }
357
358 virtual UBool operator==(const NFSubstitution& rhs) const;
359
360 virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos) const;
361 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
362
363 virtual int64_t transformNumber(int64_t number) const { return number % ldivisor; }
364 virtual double transformNumber(double number) const { return uprv_fmod(number, divisor); }
365
366 virtual UBool doParse(const UnicodeString& text,
367 ParsePosition& parsePosition,
368 double baseValue,
369 double upperBound,
370 UBool lenientParse,
371 Formattable& result) const;
372
373 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const {
374 return oldRuleValue - uprv_fmod(oldRuleValue, divisor) + newRuleValue;
375 }
376
377 virtual double calcUpperBound(double /*oldUpperBound*/) const { return divisor; }
378
379 virtual UBool isModulusSubstitution() const { return TRUE; }
380
381 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>'
382private:
383 static const char fgClassID;
384
385public:
386 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
387 virtual UClassID getDynamicClassID(void) const;
388};
389
390class IntegralPartSubstitution : public NFSubstitution {
391public:
392 IntegralPartSubstitution(int32_t _pos,
393 const NFRuleSet* _ruleSet,
394 const RuleBasedNumberFormat* formatter,
395 const UnicodeString& description,
396 UErrorCode& status)
397 : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
398
399 virtual int64_t transformNumber(int64_t number) const { return number; }
400 virtual double transformNumber(double number) const { return uprv_floor(number); }
401 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
402 virtual double calcUpperBound(double /*oldUpperBound*/) const { return DBL_MAX; }
403 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
404private:
405 static const char fgClassID;
406
407public:
408 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
409 virtual UClassID getDynamicClassID(void) const;
410};
411
412class FractionalPartSubstitution : public NFSubstitution {
413 UBool byDigits;
414 UBool useSpaces;
415 enum { kMaxDecimalDigits = 8 };
416public:
417 FractionalPartSubstitution(int32_t pos,
418 const NFRuleSet* ruleSet,
419 const RuleBasedNumberFormat* formatter,
420 const UnicodeString& description,
421 UErrorCode& status);
422
423 virtual UBool operator==(const NFSubstitution& rhs) const;
424
425 virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
426 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
427 virtual int64_t transformNumber(int64_t /*number*/) const { return 0; }
428 virtual double transformNumber(double number) const { return number - uprv_floor(number); }
429
430 virtual UBool doParse(const UnicodeString& text,
431 ParsePosition& parsePosition,
432 double baseValue,
433 double upperBound,
434 UBool lenientParse,
435 Formattable& result) const;
436
437 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
438 virtual double calcUpperBound(double /*oldUpperBound*/) const { return 0.0; }
439 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>'
440private:
441 static const char fgClassID;
442
443public:
444 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
445 virtual UClassID getDynamicClassID(void) const;
446};
447
448class AbsoluteValueSubstitution : public NFSubstitution {
449public:
450 AbsoluteValueSubstitution(int32_t _pos,
451 const NFRuleSet* _ruleSet,
452 const RuleBasedNumberFormat* formatter,
453 const UnicodeString& description,
454 UErrorCode& status)
455 : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
456
457 virtual int64_t transformNumber(int64_t number) const { return number >= 0 ? number : -number; }
458 virtual double transformNumber(double number) const { return uprv_fabs(number); }
459 virtual double composeRuleValue(double newRuleValue, double /*oldRuleValue*/) const { return -newRuleValue; }
460 virtual double calcUpperBound(double /*oldUpperBound*/) const { return DBL_MAX; }
461 virtual UChar tokenChar() const { return (UChar)0x003e; } // '>'
462private:
463 static const char fgClassID;
464
465public:
466 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
467 virtual UClassID getDynamicClassID(void) const;
468};
469
470class NumeratorSubstitution : public NFSubstitution {
471 double denominator;
472 int64_t ldenominator;
473public:
474 NumeratorSubstitution(int32_t _pos,
475 double _denominator,
476 const NFRuleSet* _ruleSet,
477 const RuleBasedNumberFormat* formatter,
478 const UnicodeString& description,
479 UErrorCode& status)
480 : NFSubstitution(_pos, _ruleSet, formatter, description, status), denominator(_denominator)
481 {
482 ldenominator = util64_fromDouble(denominator);
483 }
484
485 virtual UBool operator==(const NFSubstitution& rhs) const;
486
487 virtual int64_t transformNumber(int64_t number) const { return number * ldenominator; }
488 virtual double transformNumber(double number) const { return uprv_round(number * denominator); }
489
490 virtual UBool doParse(const UnicodeString& text,
491 ParsePosition& parsePosition,
492 double baseValue,
493 double upperBound,
494 UBool /*lenientParse*/,
495 Formattable& result) const
496 {
497 // we don't have to do anything special to do the parsing here,
498 // but we have to turn lenient parsing off-- if we leave it on,
499 // it SERIOUSLY messes up the algorithm
500 return NFSubstitution::doParse(text, parsePosition, baseValue, upperBound, FALSE, result);
501 }
502 virtual double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue / oldRuleValue; }
503 virtual double calcUpperBound(double /*oldUpperBound*/) const { return denominator; }
504 virtual UChar tokenChar() const { return (UChar)0x003c; } // '<'
505private:
506 static const char fgClassID;
507
508public:
509 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
510 virtual UClassID getDynamicClassID(void) const;
511};
512
513class NullSubstitution : public NFSubstitution {
514public:
515 NullSubstitution(int32_t _pos,
516 const NFRuleSet* _ruleSet,
517 const RuleBasedNumberFormat* formatter,
518 const UnicodeString& description,
519 UErrorCode& status)
520 : NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
521
522 virtual void toString(UnicodeString& /*result*/) const {}
523 virtual void doSubstitution(double /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
524 virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/) const {}
525 virtual int64_t transformNumber(int64_t /*number*/) const { return 0; }
526 virtual double transformNumber(double /*number*/) const { return 0; }
527 virtual UBool doParse(const UnicodeString& /*text*/,
528 ParsePosition& /*parsePosition*/,
529 double baseValue,
530 double /*upperBound*/,
531 UBool /*lenientParse*/,
532 Formattable& result) const
533 { result.setDouble(baseValue); return TRUE; }
534 virtual double composeRuleValue(double /*newRuleValue*/, double /*oldRuleValue*/) const { return 0.0; } // never called
535 virtual double calcUpperBound(double /*oldUpperBound*/) const { return 0; } // never called
536 virtual UBool isNullSubstitution() const { return TRUE; }
537 virtual UChar tokenChar() const { return (UChar)0x0020; } // ' ' never called
538private:
539 static const char fgClassID;
540
541public:
542 static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
543 virtual UClassID getDynamicClassID(void) const;
544};
545
546U_NAMESPACE_END
547
548/* U_HAVE_RBNF */
549#endif
550
551// NFSUBS_H
552#endif