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