• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2022 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #ifndef __FORMATTEDNUMBER_H__
5 #define __FORMATTEDNUMBER_H__
6 
7 #include "unicode/utypes.h"
8 
9 #if U_SHOW_CPLUSPLUS_API
10 
11 #if !UCONFIG_NO_FORMATTING
12 
13 #include "unicode/uobject.h"
14 #include "unicode/formattedvalue.h"
15 #include "unicode/measunit.h"
16 #include "unicode/udisplayoptions.h"
17 
18 /**
19  * \file
20  * \brief C API: Formatted number result from various number formatting functions.
21  *
22  * See also {@link icu::FormattedValue} for additional things you can do with a FormattedNumber.
23  */
24 
25 U_NAMESPACE_BEGIN
26 
27 class FieldPositionIteratorHandler;
28 
29 namespace number {  // icu::number
30 
31 namespace impl {
32 class DecimalQuantity;
33 class UFormattedNumberData;
34 struct UFormattedNumberImpl;
35 }  // icu::number::impl
36 
37 
38 
39 /**
40  * The result of a number formatting operation. This class allows the result to be exported in several data types,
41  * including a UnicodeString and a FieldPositionIterator.
42  *
43  * Instances of this class are immutable and thread-safe.
44  *
45  * @stable ICU 60
46  */
47 class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
48   public:
49 
50     /**
51      * Default constructor; makes an empty FormattedNumber.
52      * @stable ICU 64
53      */
FormattedNumber()54     FormattedNumber()
55         : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
56 
57     /**
58      * Move constructor: Leaves the source FormattedNumber in an undefined state.
59      * @stable ICU 62
60      */
61     FormattedNumber(FormattedNumber&& src) noexcept;
62 
63     /**
64      * Destruct an instance of FormattedNumber.
65      * @stable ICU 60
66      */
67     virtual ~FormattedNumber() override;
68 
69     /** Copying not supported; use move constructor instead. */
70     FormattedNumber(const FormattedNumber&) = delete;
71 
72     /** Copying not supported; use move assignment instead. */
73     FormattedNumber& operator=(const FormattedNumber&) = delete;
74 
75     /**
76      * Move assignment: Leaves the source FormattedNumber in an undefined state.
77      * @stable ICU 62
78      */
79     FormattedNumber& operator=(FormattedNumber&& src) noexcept;
80 
81     // Copybrief: this method is older than the parent method
82     /**
83      * @copybrief FormattedValue::toString()
84      *
85      * For more information, see FormattedValue::toString()
86      *
87      * @stable ICU 62
88      */
89     UnicodeString toString(UErrorCode& status) const override;
90 
91     // Copydoc: this method is new in ICU 64
92     /** @copydoc FormattedValue::toTempString() */
93     UnicodeString toTempString(UErrorCode& status) const override;
94 
95     // Copybrief: this method is older than the parent method
96     /**
97      * @copybrief FormattedValue::appendTo()
98      *
99      * For more information, see FormattedValue::appendTo()
100      *
101      * @stable ICU 62
102      */
103     Appendable &appendTo(Appendable& appendable, UErrorCode& status) const override;
104 
105     // Copydoc: this method is new in ICU 64
106     /** @copydoc FormattedValue::nextPosition() */
107     UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const override;
108 
109     /**
110      * Export the formatted number as a "numeric string" conforming to the
111      * syntax defined in the Decimal Arithmetic Specification, available at
112      * http://speleotrove.com/decimal
113      *
114      * This endpoint is useful for obtaining the exact number being printed
115      * after scaling and rounding have been applied by the number formatter.
116      *
117      * Example call site:
118      *
119      *     auto decimalNumber = fn.toDecimalNumber<std::string>(status);
120      *
121      * @tparam StringClass A string class compatible with StringByteSink;
122      *         for example, std::string.
123      * @param status Set if an error occurs.
124      * @return A StringClass containing the numeric string.
125      * @stable ICU 65
126      */
127     template<typename StringClass>
128     inline StringClass toDecimalNumber(UErrorCode& status) const;
129 
130 	/**
131      * Gets the resolved output unit.
132      *
133      * The output unit is dependent upon the localized preferences for the usage
134      * specified via NumberFormatterSettings::usage(), and may be a unit with
135      * UMEASURE_UNIT_MIXED unit complexity (MeasureUnit::getComplexity()), such
136      * as "foot-and-inch" or "hour-and-minute-and-second".
137      *
138      * @return `MeasureUnit`.
139      * @stable ICU 68
140      */
141     MeasureUnit getOutputUnit(UErrorCode& status) const;
142 
143 #ifndef U_HIDE_DRAFT_API
144 
145     /**
146      * Gets the noun class of the formatted output. Returns `UNDEFINED` when the noun class
147      * is not supported yet.
148      *
149      * @return UDisplayOptionsNounClass
150      * @draft ICU 72
151      */
152     UDisplayOptionsNounClass getNounClass(UErrorCode &status) const;
153 
154 #endif // U_HIDE_DRAFT_API
155 
156 #ifndef U_HIDE_INTERNAL_API
157 
158     /**
159      *  Gets the raw DecimalQuantity for plural rule selection.
160      *  @internal
161      */
162     void getDecimalQuantity(impl::DecimalQuantity& output, UErrorCode& status) const;
163 
164     /**
165      * Populates the mutable builder type FieldPositionIteratorHandler.
166      * @internal
167      */
168     void getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, UErrorCode& status) const;
169 
170 #endif  /* U_HIDE_INTERNAL_API */
171 
172   private:
173     // Can't use LocalPointer because UFormattedNumberData is forward-declared
174     impl::UFormattedNumberData *fData;
175 
176     // Error code for the terminal methods
177     UErrorCode fErrorCode;
178 
179     /**
180      * Internal constructor from data type. Adopts the data pointer.
181      * @internal (private)
182      */
FormattedNumber(impl::UFormattedNumberData * results)183     explicit FormattedNumber(impl::UFormattedNumberData *results)
184         : fData(results), fErrorCode(U_ZERO_ERROR) {}
185 
FormattedNumber(UErrorCode errorCode)186     explicit FormattedNumber(UErrorCode errorCode)
187         : fData(nullptr), fErrorCode(errorCode) {}
188 
189     void toDecimalNumber(ByteSink& sink, UErrorCode& status) const;
190 
191     // To give LocalizedNumberFormatter format methods access to this class's constructor:
192     friend class LocalizedNumberFormatter;
193     friend class SimpleNumberFormatter;
194 
195     // To give C API access to internals
196     friend struct impl::UFormattedNumberImpl;
197 };
198 
199 template<typename StringClass>
toDecimalNumber(UErrorCode & status)200 StringClass FormattedNumber::toDecimalNumber(UErrorCode& status) const {
201     StringClass result;
202     StringByteSink<StringClass> sink(&result);
203     toDecimalNumber(sink, status);
204     return result;
205 }
206 
207 }  // namespace number
208 U_NAMESPACE_END
209 
210 #endif /* #if !UCONFIG_NO_FORMATTING */
211 
212 #endif /* U_SHOW_CPLUSPLUS_API */
213 
214 #endif // __FORMATTEDNUMBER_H__
215 
216