1// Copyright (C) 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/*
4*******************************************************************************
5* Copyright (C) 2015, International Business Machines Corporation and         *
6* others. All Rights Reserved.                                                *
7*******************************************************************************
8*/
9
10#ifndef VALUEFORMATTER_H
11#define VALUEFORMATTER_H
12
13#if !UCONFIG_NO_FORMATTING
14
15#include "unicode/uobject.h"
16#include "unicode/utypes.h"
17
18
19
20U_NAMESPACE_BEGIN
21
22class UnicodeString;
23class DigitList;
24class FieldPositionHandler;
25class DigitGrouping;
26class PluralRules;
27class FixedPrecision;
28class DigitFormatter;
29class DigitFormatterOptions;
30class ScientificPrecision;
31class SciFormatterOptions;
32class FixedDecimal;
33class VisibleDigitsWithExponent;
34
35
36/**
37 * A closure around rounding and formatting a value. As these instances are
38 * designed to be short lived (they only exist while formatting a value), they
39 * do not own their own attributes. Rather the caller maintains ownership of
40 * all attributes. A caller first calls a prepareXXX method on an instance
41 * to share its data before using that instance. Using an
42 * instance without first calling a prepareXXX method results in an
43 * assertion error and a program crash.
44 */
45class U_I18N_API ValueFormatter : public UObject {
46public:
47    ValueFormatter() : fType(kFormatTypeCount) {
48    }
49
50    virtual ~ValueFormatter();
51
52    /**
53     * This function is here only to support the protected round() method
54     * in DecimalFormat. It serves no ther purpose than that.
55     *
56     * @param value this value is rounded in place.
57     * @param status any error returned here.
58     */
59    DigitList &round(DigitList &value, UErrorCode &status) const;
60
61    /**
62     * Returns TRUE if the absolute value of value can be fast formatted
63     * using ValueFormatter::formatInt32.
64     */
65    UBool isFastFormattable(int32_t value) const;
66
67    /**
68     * Converts value to a VisibleDigitsWithExponent.
69     * Result may be fixed point or scientific.
70     */
71    VisibleDigitsWithExponent &toVisibleDigitsWithExponent(
72            int64_t value,
73            VisibleDigitsWithExponent &digits,
74            UErrorCode &status) const;
75
76    /**
77     * Converts value to a VisibleDigitsWithExponent.
78     * Result may be fixed point or scientific.
79     */
80    VisibleDigitsWithExponent &toVisibleDigitsWithExponent(
81            DigitList &value,
82            VisibleDigitsWithExponent &digits,
83            UErrorCode &status) const;
84
85    /**
86     * formats positiveValue and appends to appendTo. Returns appendTo.
87     * @param positiveValue If negative, no negative sign is formatted.
88     * @param handler stores the field positions
89     * @param appendTo formatted value appended here.
90     */
91    UnicodeString &format(
92        const VisibleDigitsWithExponent &positiveValue,
93        FieldPositionHandler &handler,
94        UnicodeString &appendTo) const;
95
96
97    /**
98     * formats positiveValue and appends to appendTo. Returns appendTo.
99     * value must be positive. Calling formatInt32 to format a value when
100     * isFastFormattable indicates that the value cannot be fast formatted
101     * results in undefined behavior.
102     */
103    UnicodeString &formatInt32(
104        int32_t positiveValue,
105        FieldPositionHandler &handler,
106        UnicodeString &appendTo) const;
107
108    /**
109     * Returns the number of code points needed to format.
110     * @param positiveValue if negative, the negative sign is not included
111     *   in count.
112     */
113    int32_t countChar32(
114            const VisibleDigitsWithExponent &positiveValue) const;
115
116    /**
117     * Prepares this instance for fixed decimal formatting.
118     */
119    void prepareFixedDecimalFormatting(
120        const DigitFormatter &formatter,
121        const DigitGrouping &grouping,
122        const FixedPrecision &precision,
123        const DigitFormatterOptions &options);
124
125    /**
126     * Prepares this instance for scientific formatting.
127     */
128    void prepareScientificFormatting(
129        const DigitFormatter &formatter,
130        const ScientificPrecision &precision,
131        const SciFormatterOptions &options);
132
133private:
134    ValueFormatter(const ValueFormatter &);
135    ValueFormatter &operator=(const ValueFormatter &);
136    enum FormatType {
137        kFixedDecimal,
138        kScientificNotation,
139        kFormatTypeCount
140    };
141
142    FormatType fType;
143
144    // for fixed decimal and scientific formatting
145    const DigitFormatter *fDigitFormatter;
146
147    // for fixed decimal formatting
148    const FixedPrecision *fFixedPrecision;
149    const DigitFormatterOptions *fFixedOptions;
150    const DigitGrouping *fGrouping;
151
152    // for scientific formatting
153    const ScientificPrecision *fScientificPrecision;
154    const SciFormatterOptions *fScientificOptions;
155};
156
157U_NAMESPACE_END
158
159#endif /* !UCONFIG_NO_FORMATTING */
160
161#endif /* VALUEFORMATTER_H */
162