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