]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
2ca993e8 A |
3 | /* |
4 | ******************************************************************************** | |
5 | * Copyright (C) 2015, International Business Machines | |
6 | * Corporation and others. All Rights Reserved. | |
7 | ******************************************************************************** | |
8 | * | |
9 | * File decimfmtimpl.h | |
10 | ******************************************************************************** | |
11 | */ | |
12 | ||
13 | #ifndef DECIMFMTIMPL_H | |
14 | #define DECIMFMTIMPL_H | |
15 | ||
16 | #include "unicode/utypes.h" | |
17 | ||
18 | #if !UCONFIG_NO_FORMATTING | |
19 | ||
20 | #include "unicode/decimfmt.h" | |
21 | #include "unicode/uobject.h" | |
22 | #include "affixpatternparser.h" | |
23 | #include "digitaffixesandpadding.h" | |
24 | #include "digitformatter.h" | |
25 | #include "digitgrouping.h" | |
26 | #include "precision.h" | |
27 | ||
28 | U_NAMESPACE_BEGIN | |
29 | ||
30 | class UnicodeString; | |
31 | class FieldPosition; | |
32 | class ValueFormatter; | |
33 | class FieldPositionHandler; | |
34 | class FixedDecimal; | |
35 | ||
36 | /** | |
37 | * DecimalFormatImpl is the glue code between the legacy DecimalFormat class | |
38 | * and the new decimal formatting classes. DecimalFormat still handles | |
39 | * parsing directly. However, DecimalFormat uses attributes of this class | |
40 | * for parsing when possible. | |
41 | * | |
42 | * The public API of this class closely mirrors the legacy API of the | |
43 | * legacy DecimalFormat deviating only when the legacy API does not make | |
44 | * sense. For example, although DecimalFormat has a | |
45 | * getPadCharacterString() method, DecimalFormatImpl has a getPadCharacter() | |
46 | * method because formatting uses only a single pad character for padding. | |
47 | * | |
48 | * Each legacy DecimalFormat instance heap allocates its own instance of | |
49 | * this class. Most DecimalFormat methods that deal with formatting simply | |
50 | * delegate to the DecimalFormat's DecimalFormatImpl method. | |
51 | * | |
52 | * Because DecimalFormat extends NumberFormat, Each instance of this class | |
53 | * "borrows" a pointer to the NumberFormat part of its enclosing DecimalFormat | |
54 | * instance. This way each DecimalFormatImpl instance can read or even modify | |
55 | * the NumberFormat portion of its enclosing DecimalFormat instance. | |
56 | * | |
57 | * Directed acyclic graph (DAG): | |
58 | * | |
59 | * This class can be represented as a directed acyclic graph (DAG) where each | |
60 | * vertex is an attribute, and each directed edge indicates that the value | |
61 | * of the destination attribute is calculated from the value of the source | |
62 | * attribute. Attributes with setter methods reside at the bottom of the | |
63 | * DAG. That is, no edges point to them. We call these independent attributes | |
64 | * because their values can be set independently of one another. The rest of | |
65 | * the attributes are derived attributes because their values depend on the | |
66 | * independent attributes. DecimalFormatImpl often uses the derived | |
67 | * attributes, not the independent attributes, when formatting numbers. | |
68 | * | |
69 | * The independent attributes at the bottom of the DAG correspond to the legacy | |
70 | * attributes of DecimalFormat while the attributes at the top of the DAG | |
71 | * correspond to the attributes of the new code. The edges of the DAG | |
72 | * correspond to the code that handles the complex interaction among all the | |
73 | * legacy attributes of the DecimalFormat API. | |
74 | * | |
75 | * We use a DAG for three reasons. | |
76 | * | |
77 | * First, the DAG preserves backward compatibility. Clients of the legacy | |
78 | * DecimalFormat expect existing getters and setters of each attribute to be | |
79 | * consistent. That means if a client sets a particular attribute to a new | |
80 | * value, the attribute should retain that value until the client sets it to | |
81 | * a new value. The DAG allows these attributes to remain consistent even | |
82 | * though the new code may not use them when formatting. | |
83 | * | |
84 | * Second, the DAG obviates the need to recalculate derived attributes with | |
85 | * each format. Instead, the DAG "remembers" the values of all derived | |
86 | * attributes. Only setting an independent attribute requires a recalculation. | |
87 | * Moreover, setting an independent attribute recalculates only the affected | |
88 | * dependent attributes rather than all dependent attributes. | |
89 | * | |
90 | * Third, the DAG abstracts away the complex interaction among the legacy | |
91 | * attributes of the DecimalFormat API. | |
92 | * | |
93 | * Only the independent attributes of the DAG have setters and getters. | |
94 | * Derived attributes have no setters (and often no getters either). | |
95 | * | |
96 | * Copy and assign: | |
97 | * | |
98 | * For copy and assign, DecimalFormatImpl copies and assigns every attribute | |
99 | * regardless of whether or not it is independent. We do this for simplicity. | |
100 | * | |
101 | * Implementation of the DAG: | |
102 | * | |
103 | * The DAG consists of three smaller DAGs: | |
104 | * 1. Grouping attributes | |
105 | * 2. Precision attributes | |
106 | * 3. Formatting attributes. | |
107 | * | |
108 | * The first two DAGs are simple in that setting any independent attribute | |
109 | * in the DAG recalculates all the dependent attributes in that DAG. | |
110 | * The updateGrouping() and updatePrecision() perform the respective | |
111 | * recalculations. | |
112 | * | |
113 | * Because some of the derived formatting attributes are expensive to | |
114 | * calculate, the formatting attributes DAG is more complex. The | |
115 | * updateFormatting() method is composed of many updateFormattingXXX() | |
116 | * methods, each of which recalculates a single derived attribute. The | |
117 | * updateFormatting() method accepts a bitfield of recently changed | |
118 | * attributes and passes this bitfield by reference to each of the | |
119 | * updateFormattingXXX() methods. Each updateFormattingXXX() method checks | |
120 | * the bitfield to see if any of the attributes it uses to compute the XXX | |
121 | * attribute changed. If none of them changed, it exists immediately. However, | |
122 | * if at least one of them changed, it recalculates the XXX attribute and | |
123 | * sets the corresponding bit in the bitfield. In this way, each | |
124 | * updateFormattingXXX() method encodes the directed edges in the formatting | |
125 | * DAG that point to the attribute its calculating. | |
126 | * | |
127 | * Maintenance of the updateFormatting() method. | |
128 | * | |
129 | * Use care when changing the updateFormatting() method. | |
130 | * The updateFormatting() method must call each updateFormattingXXX() in the | |
131 | * same partial order that the formatting DAG prescribes. That is, the | |
132 | * attributes near the bottom of the DAG must be calculated before attributes | |
133 | * further up. As we mentioned in the prvious paragraph, the directed edges of | |
134 | * the formatting DAG are encoded within each updateFormattingXXX() method. | |
135 | * Finally, adding new attributes may involve adding to the bitmap that the | |
136 | * updateFormatting() method uses. The top most attributes in the DAG, | |
137 | * those that do not point to any attributes but only have attributes | |
138 | * pointing to it, need not have a slot in the bitmap. | |
139 | * | |
140 | * Keep in mind that most of the code that makes the legacy DecimalFormat API | |
141 | * work the way it always has before can be found in these various updateXXX() | |
142 | * methods. For example the updatePrecisionForScientific() method | |
143 | * handles the complex interactions amoung the various precision attributes | |
144 | * when formatting in scientific notation. Changing the way attributes | |
145 | * interract, often means changing one of these updateXXX() methods. | |
146 | * | |
147 | * Conclusion: | |
148 | * | |
149 | * The DecimFmtImpl class is the glue code between the legacy and new | |
150 | * number formatting code. It uses a direct acyclic graph (DAG) to | |
151 | * maintain backward compatibility, to make the code efficient, and to | |
152 | * abstract away the complex interraction among legacy attributs. | |
153 | */ | |
154 | ||
155 | ||
156 | class DecimalFormatImpl : public UObject { | |
157 | public: | |
158 | ||
159 | DecimalFormatImpl( | |
160 | NumberFormat *super, | |
161 | const Locale &locale, | |
162 | const UnicodeString &pattern, | |
163 | UErrorCode &status); | |
164 | DecimalFormatImpl( | |
165 | NumberFormat *super, | |
166 | const UnicodeString &pattern, | |
167 | DecimalFormatSymbols *symbolsToAdopt, | |
168 | UParseError &parseError, | |
169 | UErrorCode &status); | |
170 | DecimalFormatImpl( | |
171 | NumberFormat *super, | |
172 | const DecimalFormatImpl &other, | |
173 | UErrorCode &status); | |
174 | DecimalFormatImpl &assign( | |
175 | const DecimalFormatImpl &other, UErrorCode &status); | |
176 | virtual ~DecimalFormatImpl(); | |
177 | void adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt); | |
178 | const DecimalFormatSymbols &getDecimalFormatSymbols() const { | |
179 | return *fSymbols; | |
180 | } | |
181 | UnicodeString &format( | |
182 | int32_t number, | |
183 | UnicodeString &appendTo, | |
184 | FieldPosition &pos, | |
185 | UErrorCode &status) const; | |
186 | UnicodeString &format( | |
187 | int32_t number, | |
188 | UnicodeString &appendTo, | |
189 | FieldPositionIterator *posIter, | |
190 | UErrorCode &status) const; | |
191 | UnicodeString &format( | |
192 | int64_t number, | |
193 | UnicodeString &appendTo, | |
194 | FieldPosition &pos, | |
195 | UErrorCode &status) const; | |
196 | UnicodeString &format( | |
197 | double number, | |
198 | UnicodeString &appendTo, | |
199 | FieldPosition &pos, | |
200 | UErrorCode &status) const; | |
201 | UnicodeString &format( | |
202 | const DigitList &number, | |
203 | UnicodeString &appendTo, | |
204 | FieldPosition &pos, | |
205 | UErrorCode &status) const; | |
206 | UnicodeString &format( | |
207 | int64_t number, | |
208 | UnicodeString &appendTo, | |
209 | FieldPositionIterator *posIter, | |
210 | UErrorCode &status) const; | |
211 | UnicodeString &format( | |
212 | double number, | |
213 | UnicodeString &appendTo, | |
214 | FieldPositionIterator *posIter, | |
215 | UErrorCode &status) const; | |
216 | UnicodeString &format( | |
217 | const DigitList &number, | |
218 | UnicodeString &appendTo, | |
219 | FieldPositionIterator *posIter, | |
220 | UErrorCode &status) const; | |
221 | UnicodeString &format( | |
f3c0d7a5 | 222 | StringPiece number, |
2ca993e8 A |
223 | UnicodeString &appendTo, |
224 | FieldPositionIterator *posIter, | |
225 | UErrorCode &status) const; | |
226 | UnicodeString &format( | |
227 | const VisibleDigitsWithExponent &digits, | |
228 | UnicodeString &appendTo, | |
229 | FieldPosition &pos, | |
230 | UErrorCode &status) const; | |
231 | UnicodeString &format( | |
232 | const VisibleDigitsWithExponent &digits, | |
233 | UnicodeString &appendTo, | |
234 | FieldPositionIterator *posIter, | |
235 | UErrorCode &status) const; | |
236 | ||
237 | UBool operator==(const DecimalFormatImpl &) const; | |
238 | ||
239 | UBool operator!=(const DecimalFormatImpl &other) const { | |
240 | return !(*this == other); | |
241 | } | |
242 | ||
243 | void setRoundingMode(DecimalFormat::ERoundingMode mode) { | |
244 | fRoundingMode = mode; | |
245 | fEffPrecision.fMantissa.fExactOnly = (fRoundingMode == DecimalFormat::kRoundUnnecessary); | |
246 | fEffPrecision.fMantissa.fRoundingMode = mode; | |
247 | } | |
248 | DecimalFormat::ERoundingMode getRoundingMode() const { | |
249 | return fRoundingMode; | |
250 | } | |
251 | void setFailIfMoreThanMaxDigits(UBool b) { | |
252 | fEffPrecision.fMantissa.fFailIfOverMax = b; | |
253 | } | |
254 | UBool isFailIfMoreThanMaxDigits() const { return fEffPrecision.fMantissa.fFailIfOverMax; } | |
255 | void setMinimumSignificantDigits(int32_t newValue); | |
256 | void setMaximumSignificantDigits(int32_t newValue); | |
257 | void setMinMaxSignificantDigits(int32_t min, int32_t max); | |
258 | void setScientificNotation(UBool newValue); | |
259 | void setSignificantDigitsUsed(UBool newValue); | |
260 | ||
261 | int32_t getMinimumSignificantDigits() const { | |
262 | return fMinSigDigits; } | |
263 | int32_t getMaximumSignificantDigits() const { | |
264 | return fMaxSigDigits; } | |
265 | UBool isScientificNotation() const { return fUseScientific; } | |
266 | UBool areSignificantDigitsUsed() const { return fUseSigDigits; } | |
267 | void setGroupingSize(int32_t newValue); | |
268 | void setSecondaryGroupingSize(int32_t newValue); | |
269 | void setMinimumGroupingDigits(int32_t newValue); | |
270 | int32_t getGroupingSize() const { return fGrouping.fGrouping; } | |
271 | int32_t getSecondaryGroupingSize() const { return fGrouping.fGrouping2; } | |
272 | int32_t getMinimumGroupingDigits() const { return fGrouping.fMinGrouping; } | |
273 | void applyPattern(const UnicodeString &pattern, UErrorCode &status); | |
274 | void applyPatternFavorCurrencyPrecision( | |
275 | const UnicodeString &pattern, UErrorCode &status); | |
276 | void applyPattern( | |
277 | const UnicodeString &pattern, UParseError &perror, UErrorCode &status); | |
278 | void applyLocalizedPattern(const UnicodeString &pattern, UErrorCode &status); | |
279 | void applyLocalizedPattern( | |
280 | const UnicodeString &pattern, UParseError &perror, UErrorCode &status); | |
281 | void setCurrencyUsage(UCurrencyUsage usage, UErrorCode &status); | |
282 | UCurrencyUsage getCurrencyUsage() const { return fCurrencyUsage; } | |
283 | void setRoundingIncrement(double d); | |
284 | double getRoundingIncrement() const; | |
285 | int32_t getMultiplier() const; | |
286 | void setMultiplier(int32_t m); | |
287 | UChar32 getPadCharacter() const { return fAffixes.fPadChar; } | |
288 | void setPadCharacter(UChar32 c) { fAffixes.fPadChar = c; } | |
289 | int32_t getFormatWidth() const { return fAffixes.fWidth; } | |
290 | void setFormatWidth(int32_t x) { fAffixes.fWidth = x; } | |
291 | DigitAffixesAndPadding::EPadPosition getPadPosition() const { | |
292 | return fAffixes.fPadPosition; | |
293 | } | |
294 | void setPadPosition(DigitAffixesAndPadding::EPadPosition x) { | |
295 | fAffixes.fPadPosition = x; | |
296 | } | |
297 | int32_t getMinimumExponentDigits() const { | |
298 | return fEffPrecision.fMinExponentDigits; | |
299 | } | |
300 | void setMinimumExponentDigits(int32_t x) { | |
301 | fEffPrecision.fMinExponentDigits = x; | |
302 | } | |
303 | UBool isExponentSignAlwaysShown() const { | |
304 | return fOptions.fExponent.fAlwaysShowSign; | |
305 | } | |
306 | void setExponentSignAlwaysShown(UBool x) { | |
307 | fOptions.fExponent.fAlwaysShowSign = x; | |
308 | } | |
309 | UBool isDecimalSeparatorAlwaysShown() const { | |
310 | return fOptions.fMantissa.fAlwaysShowDecimal; | |
311 | } | |
312 | void setDecimalSeparatorAlwaysShown(UBool x) { | |
313 | fOptions.fMantissa.fAlwaysShowDecimal = x; | |
314 | } | |
315 | UnicodeString &getPositivePrefix(UnicodeString &result) const; | |
316 | UnicodeString &getPositiveSuffix(UnicodeString &result) const; | |
317 | UnicodeString &getNegativePrefix(UnicodeString &result) const; | |
318 | UnicodeString &getNegativeSuffix(UnicodeString &result) const; | |
319 | void setPositivePrefix(const UnicodeString &str); | |
320 | void setPositiveSuffix(const UnicodeString &str); | |
321 | void setNegativePrefix(const UnicodeString &str); | |
322 | void setNegativeSuffix(const UnicodeString &str); | |
323 | UnicodeString &toPattern(UnicodeString& result) const; | |
324 | FixedDecimal &getFixedDecimal(double value, FixedDecimal &result, UErrorCode &status) const; | |
325 | FixedDecimal &getFixedDecimal(DigitList &number, FixedDecimal &result, UErrorCode &status) const; | |
326 | DigitList &round(DigitList &number, UErrorCode &status) const; | |
327 | ||
328 | VisibleDigitsWithExponent & | |
329 | initVisibleDigitsWithExponent( | |
330 | int64_t number, | |
331 | VisibleDigitsWithExponent &digits, | |
332 | UErrorCode &status) const; | |
333 | VisibleDigitsWithExponent & | |
334 | initVisibleDigitsWithExponent( | |
335 | double number, | |
336 | VisibleDigitsWithExponent &digits, | |
337 | UErrorCode &status) const; | |
338 | VisibleDigitsWithExponent & | |
339 | initVisibleDigitsWithExponent( | |
340 | DigitList &number, | |
341 | VisibleDigitsWithExponent &digits, | |
342 | UErrorCode &status) const; | |
343 | ||
344 | void updatePrecision(); | |
345 | void updateGrouping(); | |
346 | void updateCurrency(UErrorCode &status); | |
347 | ||
0f5d89e8 A |
348 | // Apple-specific |
349 | UBool getFormatFullPrecision() const { return fFormatFullPrecision; } | |
350 | void setFormatFullPrecision(UBool formatFullPrecision) { fFormatFullPrecision = formatFullPrecision; } | |
2ca993e8 A |
351 | |
352 | private: | |
353 | // Disallow copy and assign | |
354 | DecimalFormatImpl(const DecimalFormatImpl &other); | |
355 | DecimalFormatImpl &operator=(const DecimalFormatImpl &other); | |
356 | NumberFormat *fSuper; | |
357 | DigitList fMultiplier; | |
358 | int32_t fScale; | |
359 | ||
360 | DecimalFormat::ERoundingMode fRoundingMode; | |
361 | ||
362 | // These fields include what the user can see and set. | |
363 | // When the user updates these fields, it triggers automatic updates of | |
364 | // other fields that may be invisible to user | |
365 | ||
366 | // Updating any of the following fields triggers an update to | |
367 | // fEffPrecision.fMantissa.fMin, | |
368 | // fEffPrecision.fMantissa.fMax, | |
369 | // fEffPrecision.fMantissa.fSignificant fields | |
370 | // We have this two phase update because of backward compatibility. | |
371 | // DecimalFormat has to remember all settings even if those settings are | |
372 | // invalid or disabled. | |
373 | int32_t fMinSigDigits; | |
374 | int32_t fMaxSigDigits; | |
375 | UBool fUseScientific; | |
376 | UBool fUseSigDigits; | |
377 | // In addition to these listed above, changes to min/max int digits and | |
378 | // min/max frac digits from fSuper also trigger an update. | |
379 | ||
380 | // Updating any of the following fields triggers an update to | |
381 | // fEffGrouping field Again we do it this way because original | |
382 | // grouping settings have to be retained if grouping is turned off. | |
383 | DigitGrouping fGrouping; | |
384 | // In addition to these listed above, changes to isGroupingUsed in | |
385 | // fSuper also triggers an update to fEffGrouping. | |
386 | ||
387 | // Updating any of the following fields triggers updates on the following: | |
388 | // fMonetary, fRules, fAffixParser, fCurrencyAffixInfo, | |
389 | // fFormatter, fAffixes.fPositivePrefiix, fAffixes.fPositiveSuffix, | |
390 | // fAffixes.fNegativePrefiix, fAffixes.fNegativeSuffix | |
391 | // We do this two phase update because localizing the affix patterns | |
392 | // and formatters can be expensive. Better to do it once with the setters | |
393 | // than each time within format. | |
394 | AffixPattern fPositivePrefixPattern; | |
395 | AffixPattern fNegativePrefixPattern; | |
396 | AffixPattern fPositiveSuffixPattern; | |
397 | AffixPattern fNegativeSuffixPattern; | |
398 | DecimalFormatSymbols *fSymbols; | |
399 | UCurrencyUsage fCurrencyUsage; | |
400 | // In addition to these listed above, changes to getCurrency() in | |
401 | // fSuper also triggers an update. | |
402 | ||
403 | // Optional may be NULL | |
404 | PluralRules *fRules; | |
405 | ||
406 | // These fields are totally hidden from user and are used to derive the affixes | |
407 | // in fAffixes below from the four affix patterns above. | |
408 | UBool fMonetary; | |
409 | AffixPatternParser fAffixParser; | |
410 | CurrencyAffixInfo fCurrencyAffixInfo; | |
411 | ||
412 | // The actual precision used when formatting | |
413 | ScientificPrecision fEffPrecision; | |
414 | ||
415 | // The actual grouping used when formatting | |
416 | DigitGrouping fEffGrouping; | |
417 | SciFormatterOptions fOptions; // Encapsulates fixed precision options | |
418 | DigitFormatter fFormatter; | |
419 | DigitAffixesAndPadding fAffixes; | |
420 | ||
0f5d89e8 A |
421 | // Flag to cap double conversion precision at DBL_DIG digits (Apple specific) |
422 | UBool fFormatFullPrecision; | |
423 | ||
2ca993e8 A |
424 | UnicodeString &formatInt32( |
425 | int32_t number, | |
426 | UnicodeString &appendTo, | |
427 | FieldPositionHandler &handler, | |
428 | UErrorCode &status) const; | |
429 | ||
430 | UnicodeString &formatInt64( | |
431 | int64_t number, | |
432 | UnicodeString &appendTo, | |
433 | FieldPositionHandler &handler, | |
434 | UErrorCode &status) const; | |
435 | ||
436 | UnicodeString &formatDouble( | |
437 | double number, | |
438 | UnicodeString &appendTo, | |
439 | FieldPositionHandler &handler, | |
440 | UErrorCode &status) const; | |
441 | ||
442 | // Scales for precent or permille symbols | |
443 | UnicodeString &formatDigitList( | |
444 | DigitList &number, | |
445 | UnicodeString &appendTo, | |
446 | FieldPositionHandler &handler, | |
447 | UErrorCode &status) const; | |
448 | ||
449 | // Does not scale for precent or permille symbols | |
450 | UnicodeString &formatAdjustedDigitList( | |
451 | DigitList &number, | |
452 | UnicodeString &appendTo, | |
453 | FieldPositionHandler &handler, | |
454 | UErrorCode &status) const; | |
455 | ||
456 | UnicodeString &formatVisibleDigitsWithExponent( | |
457 | const VisibleDigitsWithExponent &number, | |
458 | UnicodeString &appendTo, | |
459 | FieldPositionHandler &handler, | |
460 | UErrorCode &status) const; | |
461 | ||
462 | VisibleDigitsWithExponent & | |
463 | initVisibleDigitsFromAdjusted( | |
464 | DigitList &number, | |
465 | VisibleDigitsWithExponent &digits, | |
466 | UErrorCode &status) const; | |
467 | ||
468 | template<class T> | |
469 | UBool maybeFormatWithDigitList( | |
470 | T number, | |
471 | UnicodeString &appendTo, | |
472 | FieldPositionHandler &handler, | |
473 | UErrorCode &status) const; | |
474 | ||
475 | template<class T> | |
476 | UBool maybeInitVisibleDigitsFromDigitList( | |
477 | T number, | |
478 | VisibleDigitsWithExponent &digits, | |
479 | UErrorCode &status) const; | |
480 | ||
481 | DigitList &adjustDigitList(DigitList &number, UErrorCode &status) const; | |
482 | ||
483 | void applyPattern( | |
484 | const UnicodeString &pattern, | |
485 | UBool localized, UParseError &perror, UErrorCode &status); | |
486 | ||
487 | ValueFormatter &prepareValueFormatter(ValueFormatter &vf) const; | |
488 | void setMultiplierScale(int32_t s); | |
489 | int32_t getPatternScale() const; | |
490 | void setScale(int32_t s) { fScale = s; } | |
491 | int32_t getScale() const { return fScale; } | |
492 | ||
493 | // Updates everything | |
494 | void updateAll(UErrorCode &status); | |
495 | void updateAll( | |
496 | int32_t formattingFlags, | |
497 | UBool updatePrecisionBasedOnCurrency, | |
498 | UErrorCode &status); | |
499 | ||
500 | // Updates from formatting pattern changes | |
501 | void updateForApplyPattern(UErrorCode &status); | |
502 | void updateForApplyPatternFavorCurrencyPrecision(UErrorCode &status); | |
503 | ||
504 | // Updates from changes to third group of attributes | |
505 | void updateFormatting(int32_t changedFormattingFields, UErrorCode &status); | |
506 | void updateFormatting( | |
507 | int32_t changedFormattingFields, | |
508 | UBool updatePrecisionBasedOnCurrency, | |
509 | UErrorCode &status); | |
510 | ||
511 | // Helper functions for updatePrecision | |
512 | void updatePrecisionForScientific(); | |
513 | void updatePrecisionForFixed(); | |
514 | void extractMinMaxDigits(DigitInterval &min, DigitInterval &max) const; | |
515 | void extractSigDigits(SignificantDigitInterval &sig) const; | |
516 | ||
517 | // Helper functions for updateFormatting | |
518 | void updateFormattingUsesCurrency(int32_t &changedFormattingFields); | |
519 | void updateFormattingPluralRules( | |
520 | int32_t &changedFormattingFields, UErrorCode &status); | |
521 | void updateFormattingAffixParser(int32_t &changedFormattingFields); | |
522 | void updateFormattingCurrencyAffixInfo( | |
523 | int32_t &changedFormattingFields, | |
524 | UBool updatePrecisionBasedOnCurrency, | |
525 | UErrorCode &status); | |
526 | void updateFormattingFixedPointFormatter( | |
527 | int32_t &changedFormattingFields); | |
528 | void updateFormattingLocalizedPositivePrefix( | |
529 | int32_t &changedFormattingFields, UErrorCode &status); | |
530 | void updateFormattingLocalizedPositiveSuffix( | |
531 | int32_t &changedFormattingFields, UErrorCode &status); | |
532 | void updateFormattingLocalizedNegativePrefix( | |
533 | int32_t &changedFormattingFields, UErrorCode &status); | |
534 | void updateFormattingLocalizedNegativeSuffix( | |
535 | int32_t &changedFormattingFields, UErrorCode &status); | |
536 | ||
537 | int32_t computeExponentPatternLength() const; | |
538 | int32_t countFractionDigitAndDecimalPatternLength(int32_t fracDigitCount) const; | |
539 | UnicodeString &toNumberPattern( | |
540 | UBool hasPadding, int32_t minimumLength, UnicodeString& result) const; | |
541 | ||
542 | int32_t getOldFormatWidth() const; | |
543 | const UnicodeString &getConstSymbol( | |
544 | DecimalFormatSymbols::ENumberFormatSymbol symbol) const; | |
545 | UBool isParseFastpath() const; | |
546 | ||
547 | friend class DecimalFormat; | |
548 | ||
549 | }; | |
550 | ||
551 | ||
552 | U_NAMESPACE_END | |
553 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
554 | #endif // DECIMFMTIMPL_H | |
555 | //eof |