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
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * digitformatter.h
9 *
10 * created on: 2015jan06
11 * created by: Travis Keep
12 */
13
14 #ifndef __DIGITFORMATTER_H__
15 #define __DIGITFORMATTER_H__
16
17 #include "unicode/uobject.h"
18
19 #if !UCONFIG_NO_FORMATTING
20
21 #include "unicode/utypes.h"
22 #include "unicode/unistr.h"
23 #include "digitaffix.h"
24
25 U_NAMESPACE_BEGIN
26
27 class DecimalFormatSymbols;
28 class DigitList;
29 class DigitGrouping;
30 class DigitInterval;
31 class UnicodeString;
32 class FieldPositionHandler;
33 class IntDigitCountRange;
34 class VisibleDigits;
35 class VisibleDigitsWithExponent;
36
37 /**
38 * Various options for formatting in fixed point.
39 */
40 class U_I18N_API DigitFormatterOptions : public UMemory {
41 public:
DigitFormatterOptions()42 DigitFormatterOptions() : fAlwaysShowDecimal(FALSE) { }
43
44 /**
45 * Returns TRUE if this object equals rhs.
46 */
equals(const DigitFormatterOptions & rhs)47 UBool equals(const DigitFormatterOptions &rhs) const {
48 return (
49 fAlwaysShowDecimal == rhs.fAlwaysShowDecimal);
50 }
51
52 /**
53 * Returns TRUE if these options allow for fast formatting of
54 * integers.
55 */
isFastFormattable()56 UBool isFastFormattable() const {
57 return (fAlwaysShowDecimal == FALSE);
58 }
59
60 /**
61 * If TRUE, show the decimal separator even when there are no fraction
62 * digits. default is FALSE.
63 */
64 UBool fAlwaysShowDecimal;
65 };
66
67 /**
68 * Various options for formatting an integer.
69 */
70 class U_I18N_API DigitFormatterIntOptions : public UMemory {
71 public:
DigitFormatterIntOptions()72 DigitFormatterIntOptions() : fAlwaysShowSign(FALSE) { }
73
74 /**
75 * Returns TRUE if this object equals rhs.
76 */
equals(const DigitFormatterIntOptions & rhs)77 UBool equals(const DigitFormatterIntOptions &rhs) const {
78 return (fAlwaysShowSign == rhs.fAlwaysShowSign);
79 }
80
81 /**
82 * If TRUE, always prefix the integer with its sign even if the number is
83 * positive. Default is FALSE.
84 */
85 UBool fAlwaysShowSign;
86 };
87
88 /**
89 * Options for formatting in scientific notation.
90 */
91 class U_I18N_API SciFormatterOptions : public UMemory {
92 public:
93
94 /**
95 * Returns TRUE if this object equals rhs.
96 */
equals(const SciFormatterOptions & rhs)97 UBool equals(const SciFormatterOptions &rhs) const {
98 return (fMantissa.equals(rhs.fMantissa) &&
99 fExponent.equals(rhs.fExponent));
100 }
101
102 /**
103 * Options for formatting the mantissa.
104 */
105 DigitFormatterOptions fMantissa;
106
107 /**
108 * Options for formatting the exponent.
109 */
110 DigitFormatterIntOptions fExponent;
111 };
112
113
114 /**
115 * Does fixed point formatting.
116 *
117 * This class only does fixed point formatting. It does no rounding before
118 * formatting.
119 */
120 class U_I18N_API DigitFormatter : public UMemory {
121 public:
122
123 /**
124 * Decimal separator is period (.), Plus sign is plus (+),
125 * minus sign is minus (-), grouping separator is comma (,), digits are 0-9.
126 */
127 DigitFormatter();
128
129 /**
130 * Let symbols determine the digits, decimal separator,
131 * plus and mius sign, grouping separator, and possibly other settings.
132 */
133 DigitFormatter(const DecimalFormatSymbols &symbols);
134
135 /**
136 * Change what this instance uses for digits, decimal separator,
137 * plus and mius sign, grouping separator, and possibly other settings
138 * according to symbols.
139 */
140 void setDecimalFormatSymbols(const DecimalFormatSymbols &symbols);
141
142 /**
143 * Change what this instance uses for digits, decimal separator,
144 * plus and mius sign, grouping separator, and possibly other settings
145 * according to symbols in the context of monetary amounts.
146 */
147 void setDecimalFormatSymbolsForMonetary(const DecimalFormatSymbols &symbols);
148
149 /**
150 * Fixed point formatting.
151 *
152 * @param positiveDigits the value to format
153 * Negative sign can be present, but it won't show.
154 * @param grouping controls how digit grouping is done
155 * @param options formatting options
156 * @param handler records field positions
157 * @param appendTo formatted value appended here.
158 * @return appendTo
159 */
160 UnicodeString &format(
161 const VisibleDigits &positiveDigits,
162 const DigitGrouping &grouping,
163 const DigitFormatterOptions &options,
164 FieldPositionHandler &handler,
165 UnicodeString &appendTo) const;
166
167 /**
168 * formats in scientifc notation.
169 * @param positiveDigits the value to format.
170 * Negative sign can be present, but it won't show.
171 * @param options formatting options
172 * @param handler records field positions.
173 * @param appendTo formatted value appended here.
174 */
175 UnicodeString &format(
176 const VisibleDigitsWithExponent &positiveDigits,
177 const SciFormatterOptions &options,
178 FieldPositionHandler &handler,
179 UnicodeString &appendTo) const;
180
181 /**
182 * Fixed point formatting of integers.
183 * Always performed with no grouping and no decimal point.
184 *
185 * @param positiveValue the value to format must be positive.
186 * @param range specifies minimum and maximum number of digits.
187 * @param handler records field positions
188 * @param appendTo formatted value appended here.
189 * @return appendTo
190 */
191 UnicodeString &formatPositiveInt32(
192 int32_t positiveValue,
193 const IntDigitCountRange &range,
194 FieldPositionHandler &handler,
195 UnicodeString &appendTo) const;
196
197 /**
198 * Counts how many code points are needed for fixed formatting.
199 * If digits is negative, the negative sign is not included in the count.
200 */
201 int32_t countChar32(
202 const VisibleDigits &digits,
203 const DigitGrouping &grouping,
204 const DigitFormatterOptions &options) const;
205
206 /**
207 * Counts how many code points are needed for scientific formatting.
208 * If digits is negative, the negative sign is not included in the count.
209 */
210 int32_t countChar32(
211 const VisibleDigitsWithExponent &digits,
212 const SciFormatterOptions &options) const;
213
214 /**
215 * Returns TRUE if this object equals rhs.
216 */
217 UBool equals(const DigitFormatter &rhs) const;
218
219 private:
220 UChar32 fLocalizedDigits[10];
221 UnicodeString fGroupingSeparator;
222 UnicodeString fDecimal;
223 UnicodeString fNegativeSign;
224 UnicodeString fPositiveSign;
225 DigitAffix fInfinity;
226 DigitAffix fNan;
227 UBool fIsStandardDigits;
228 UnicodeString fExponent;
229 UBool isStandardDigits() const;
230
231 UnicodeString &formatDigits(
232 const uint8_t *digits,
233 int32_t count,
234 const IntDigitCountRange &range,
235 int32_t intField,
236 FieldPositionHandler &handler,
237 UnicodeString &appendTo) const;
238
239 void setOtherDecimalFormatSymbols(const DecimalFormatSymbols &symbols);
240
241 int32_t countChar32(
242 const VisibleDigits &exponent,
243 const DigitInterval &mantissaInterval,
244 const SciFormatterOptions &options) const;
245
formatNaN(FieldPositionHandler & handler,UnicodeString & appendTo)246 UnicodeString &formatNaN(
247 FieldPositionHandler &handler,
248 UnicodeString &appendTo) const {
249 return fNan.format(handler, appendTo);
250 }
251
countChar32ForNaN()252 int32_t countChar32ForNaN() const {
253 return fNan.toString().countChar32();
254 }
255
formatInfinity(FieldPositionHandler & handler,UnicodeString & appendTo)256 UnicodeString &formatInfinity(
257 FieldPositionHandler &handler,
258 UnicodeString &appendTo) const {
259 return fInfinity.format(handler, appendTo);
260 }
261
countChar32ForInfinity()262 int32_t countChar32ForInfinity() const {
263 return fInfinity.toString().countChar32();
264 }
265
266 UnicodeString &formatExponent(
267 const VisibleDigits &digits,
268 const DigitFormatterIntOptions &options,
269 int32_t signField,
270 int32_t intField,
271 FieldPositionHandler &handler,
272 UnicodeString &appendTo) const;
273
274 int32_t countChar32(
275 const DigitGrouping &grouping,
276 const DigitInterval &interval,
277 const DigitFormatterOptions &options) const;
278
279 int32_t countChar32ForExponent(
280 const VisibleDigits &exponent,
281 const DigitFormatterIntOptions &options) const;
282
283 };
284
285
286 U_NAMESPACE_END
287 #endif /* #if !UCONFIG_NO_FORMATTING */
288 #endif // __DIGITFORMATTER_H__
289