1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 **********************************************************************
5 * Copyright (c) 2014-2016, International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 **********************************************************************
8 */
9 #ifndef SCINUMBERFORMATTER_H
10 #define SCINUMBERFORMATTER_H
11 
12 #include "unicode/utypes.h"
13 
14 #if U_SHOW_CPLUSPLUS_API
15 
16 #if !UCONFIG_NO_FORMATTING
17 
18 
19 #include "unicode/unistr.h"
20 
21 /**
22  * \file
23  * \brief C++ API: Formats in scientific notation.
24  */
25 
26 U_NAMESPACE_BEGIN
27 
28 class FieldPositionIterator;
29 class DecimalFormatSymbols;
30 class DecimalFormat;
31 class Formattable;
32 
33 /**
34  * A formatter that formats numbers in user-friendly scientific notation.
35  *
36  * Sample code:
37  * <pre>
38  * UErrorCode status = U_ZERO_ERROR;
39  * LocalPointer<ScientificNumberFormatter> fmt(
40  *         ScientificNumberFormatter::createMarkupInstance(
41  *                 "en", "<sup>", "</sup>", status));
42  * if (U_FAILURE(status)) {
43  *     return;
44  * }
45  * UnicodeString appendTo;
46  * // appendTo = "1.23456x10<sup>-78</sup>"
47  * fmt->format(1.23456e-78, appendTo, status);
48  * </pre>
49  *
50  * @stable ICU 55
51  */
52 class U_I18N_API ScientificNumberFormatter : public UObject {
53 public:
54 
55     /**
56      * Creates a ScientificNumberFormatter instance that uses
57      * superscript characters for exponents.
58      * @param fmtToAdopt The DecimalFormat which must be configured for
59      *   scientific notation.
60      * @param status error returned here.
61      * @return The new ScientificNumberFormatter instance.
62      *
63      * @stable ICU 55
64      */
65     static ScientificNumberFormatter *createSuperscriptInstance(
66             DecimalFormat *fmtToAdopt, UErrorCode &status);
67 
68     /**
69      * Creates a ScientificNumberFormatter instance that uses
70      * superscript characters for exponents for this locale.
71      * @param locale The locale
72      * @param status error returned here.
73      * @return The ScientificNumberFormatter instance.
74      *
75      * @stable ICU 55
76      */
77     static ScientificNumberFormatter *createSuperscriptInstance(
78             const Locale &locale, UErrorCode &status);
79 
80 
81     /**
82      * Creates a ScientificNumberFormatter instance that uses
83      * markup for exponents.
84      * @param fmtToAdopt The DecimalFormat which must be configured for
85      *   scientific notation.
86      * @param beginMarkup the markup to start superscript.
87      * @param endMarkup the markup to end superscript.
88      * @param status error returned here.
89      * @return The new ScientificNumberFormatter instance.
90      *
91      * @stable ICU 55
92      */
93     static ScientificNumberFormatter *createMarkupInstance(
94             DecimalFormat *fmtToAdopt,
95             const UnicodeString &beginMarkup,
96             const UnicodeString &endMarkup,
97             UErrorCode &status);
98 
99     /**
100      * Creates a ScientificNumberFormatter instance that uses
101      * markup for exponents for this locale.
102      * @param locale The locale
103      * @param beginMarkup the markup to start superscript.
104      * @param endMarkup the markup to end superscript.
105      * @param status error returned here.
106      * @return The ScientificNumberFormatter instance.
107      *
108      * @stable ICU 55
109      */
110     static ScientificNumberFormatter *createMarkupInstance(
111             const Locale &locale,
112             const UnicodeString &beginMarkup,
113             const UnicodeString &endMarkup,
114             UErrorCode &status);
115 
116 
117     /**
118      * Returns a copy of this object. Caller must free returned copy.
119      * @stable ICU 55
120      */
clone()121     ScientificNumberFormatter *clone() const {
122         return new ScientificNumberFormatter(*this);
123     }
124 
125     /**
126      * Destructor.
127      * @stable ICU 55
128      */
129     virtual ~ScientificNumberFormatter();
130 
131     /**
132      * Formats a number into user friendly scientific notation.
133      *
134      * @param number the number to format.
135      * @param appendTo formatted string appended here.
136      * @param status any error returned here.
137      * @return appendTo
138      *
139      * @stable ICU 55
140      */
141     UnicodeString &format(
142             const Formattable &number,
143             UnicodeString &appendTo,
144             UErrorCode &status) const;
145  private:
146     class U_I18N_API Style : public UObject {
147     public:
148         virtual Style *clone() const = 0;
149     protected:
150         virtual UnicodeString &format(
151                 const UnicodeString &original,
152                 FieldPositionIterator &fpi,
153                 const UnicodeString &preExponent,
154                 UnicodeString &appendTo,
155                 UErrorCode &status) const = 0;
156     private:
157         friend class ScientificNumberFormatter;
158     };
159 
160     class U_I18N_API SuperscriptStyle : public Style {
161     public:
162         virtual SuperscriptStyle *clone() const;
163     protected:
164         virtual UnicodeString &format(
165                 const UnicodeString &original,
166                 FieldPositionIterator &fpi,
167                 const UnicodeString &preExponent,
168                 UnicodeString &appendTo,
169                 UErrorCode &status) const;
170     };
171 
172     class U_I18N_API MarkupStyle : public Style {
173     public:
MarkupStyle(const UnicodeString & beginMarkup,const UnicodeString & endMarkup)174         MarkupStyle(
175                 const UnicodeString &beginMarkup,
176                 const UnicodeString &endMarkup)
177                 : Style(),
178                   fBeginMarkup(beginMarkup),
179                   fEndMarkup(endMarkup) { }
180         virtual MarkupStyle *clone() const;
181     protected:
182         virtual UnicodeString &format(
183                 const UnicodeString &original,
184                 FieldPositionIterator &fpi,
185                 const UnicodeString &preExponent,
186                 UnicodeString &appendTo,
187                 UErrorCode &status) const;
188     private:
189         UnicodeString fBeginMarkup;
190         UnicodeString fEndMarkup;
191     };
192 
193     ScientificNumberFormatter(
194             DecimalFormat *fmtToAdopt,
195             Style *styleToAdopt,
196             UErrorCode &status);
197 
198     ScientificNumberFormatter(const ScientificNumberFormatter &other);
199     ScientificNumberFormatter &operator=(const ScientificNumberFormatter &);
200 
201     static void getPreExponent(
202             const DecimalFormatSymbols &dfs, UnicodeString &preExponent);
203 
204     static ScientificNumberFormatter *createInstance(
205             DecimalFormat *fmtToAdopt,
206             Style *styleToAdopt,
207             UErrorCode &status);
208 
209     UnicodeString fPreExponent;
210     DecimalFormat *fDecimalFormat;
211     Style *fStyle;
212 
213 };
214 
215 U_NAMESPACE_END
216 
217 
218 #endif /* !UCONFIG_NO_FORMATTING */
219 
220 #endif /* U_SHOW_CPLUSPLUS_API */
221 
222 #endif
223