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