/src/mozilla-central/intl/icu/source/i18n/number_fluent.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // © 2017 and later: Unicode, Inc. and others. |
2 | | // License & terms of use: http://www.unicode.org/copyright.html |
3 | | |
4 | | #include "unicode/utypes.h" |
5 | | |
6 | | #if !UCONFIG_NO_FORMATTING |
7 | | |
8 | | #include "uassert.h" |
9 | | #include "unicode/numberformatter.h" |
10 | | #include "number_decimalquantity.h" |
11 | | #include "number_formatimpl.h" |
12 | | #include "umutex.h" |
13 | | #include "number_asformat.h" |
14 | | #include "number_skeletons.h" |
15 | | #include "number_utils.h" |
16 | | #include "number_utypes.h" |
17 | | #include "util.h" |
18 | | #include "fphdlimp.h" |
19 | | |
20 | | using namespace icu; |
21 | | using namespace icu::number; |
22 | | using namespace icu::number::impl; |
23 | | |
24 | | template<typename Derived> |
25 | 0 | Derived NumberFormatterSettings<Derived>::notation(const Notation& notation) const& { |
26 | 0 | Derived copy(*this); |
27 | 0 | // NOTE: Slicing is OK. |
28 | 0 | copy.fMacros.notation = notation; |
29 | 0 | return copy; |
30 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::notation(icu_62::number::Notation const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::notation(icu_62::number::Notation const&) const & |
31 | | |
32 | | template<typename Derived> |
33 | 0 | Derived NumberFormatterSettings<Derived>::notation(const Notation& notation)&& { |
34 | 0 | Derived move(std::move(*this)); |
35 | 0 | // NOTE: Slicing is OK. |
36 | 0 | move.fMacros.notation = notation; |
37 | 0 | return move; |
38 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::notation(icu_62::number::Notation const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::notation(icu_62::number::Notation const&) && |
39 | | |
40 | | template<typename Derived> |
41 | 0 | Derived NumberFormatterSettings<Derived>::unit(const icu::MeasureUnit& unit) const& { |
42 | 0 | Derived copy(*this); |
43 | 0 | // NOTE: Slicing occurs here. However, CurrencyUnit can be restored from MeasureUnit. |
44 | 0 | // TimeUnit may be affected, but TimeUnit is not as relevant to number formatting. |
45 | 0 | copy.fMacros.unit = unit; |
46 | 0 | return copy; |
47 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::unit(icu_62::MeasureUnit const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::unit(icu_62::MeasureUnit const&) const & |
48 | | |
49 | | template<typename Derived> |
50 | 0 | Derived NumberFormatterSettings<Derived>::unit(const icu::MeasureUnit& unit)&& { |
51 | 0 | Derived move(std::move(*this)); |
52 | 0 | // See comments above about slicing. |
53 | 0 | move.fMacros.unit = unit; |
54 | 0 | return move; |
55 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::unit(icu_62::MeasureUnit const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::unit(icu_62::MeasureUnit const&) && |
56 | | |
57 | | template<typename Derived> |
58 | 0 | Derived NumberFormatterSettings<Derived>::adoptUnit(icu::MeasureUnit* unit) const& { |
59 | 0 | Derived copy(*this); |
60 | 0 | // Just move the unit into the MacroProps by value, and delete it since we have ownership. |
61 | 0 | // NOTE: Slicing occurs here. However, CurrencyUnit can be restored from MeasureUnit. |
62 | 0 | // TimeUnit may be affected, but TimeUnit is not as relevant to number formatting. |
63 | 0 | if (unit != nullptr) { |
64 | 0 | // TODO: On nullptr, reset to default value? |
65 | 0 | copy.fMacros.unit = std::move(*unit); |
66 | 0 | delete unit; |
67 | 0 | } |
68 | 0 | return copy; |
69 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::adoptUnit(icu_62::MeasureUnit*) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::adoptUnit(icu_62::MeasureUnit*) const & |
70 | | |
71 | | template<typename Derived> |
72 | 0 | Derived NumberFormatterSettings<Derived>::adoptUnit(icu::MeasureUnit* unit)&& { |
73 | 0 | Derived move(std::move(*this)); |
74 | 0 | // See comments above about slicing and ownership. |
75 | 0 | if (unit != nullptr) { |
76 | 0 | // TODO: On nullptr, reset to default value? |
77 | 0 | move.fMacros.unit = std::move(*unit); |
78 | 0 | delete unit; |
79 | 0 | } |
80 | 0 | return move; |
81 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::adoptUnit(icu_62::MeasureUnit*) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::adoptUnit(icu_62::MeasureUnit*) && |
82 | | |
83 | | template<typename Derived> |
84 | 0 | Derived NumberFormatterSettings<Derived>::perUnit(const icu::MeasureUnit& perUnit) const& { |
85 | 0 | Derived copy(*this); |
86 | 0 | // See comments above about slicing. |
87 | 0 | copy.fMacros.perUnit = perUnit; |
88 | 0 | return copy; |
89 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::perUnit(icu_62::MeasureUnit const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::perUnit(icu_62::MeasureUnit const&) const & |
90 | | |
91 | | template<typename Derived> |
92 | 0 | Derived NumberFormatterSettings<Derived>::perUnit(const icu::MeasureUnit& perUnit)&& { |
93 | 0 | Derived move(std::move(*this)); |
94 | 0 | // See comments above about slicing. |
95 | 0 | move.fMacros.perUnit = perUnit; |
96 | 0 | return move; |
97 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::perUnit(icu_62::MeasureUnit const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::perUnit(icu_62::MeasureUnit const&) && |
98 | | |
99 | | template<typename Derived> |
100 | 0 | Derived NumberFormatterSettings<Derived>::adoptPerUnit(icu::MeasureUnit* perUnit) const& { |
101 | 0 | Derived copy(*this); |
102 | 0 | // See comments above about slicing and ownership. |
103 | 0 | if (perUnit != nullptr) { |
104 | 0 | // TODO: On nullptr, reset to default value? |
105 | 0 | copy.fMacros.perUnit = std::move(*perUnit); |
106 | 0 | delete perUnit; |
107 | 0 | } |
108 | 0 | return copy; |
109 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::adoptPerUnit(icu_62::MeasureUnit*) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::adoptPerUnit(icu_62::MeasureUnit*) const & |
110 | | |
111 | | template<typename Derived> |
112 | 0 | Derived NumberFormatterSettings<Derived>::adoptPerUnit(icu::MeasureUnit* perUnit)&& { |
113 | 0 | Derived move(std::move(*this)); |
114 | 0 | // See comments above about slicing and ownership. |
115 | 0 | if (perUnit != nullptr) { |
116 | 0 | // TODO: On nullptr, reset to default value? |
117 | 0 | move.fMacros.perUnit = std::move(*perUnit); |
118 | 0 | delete perUnit; |
119 | 0 | } |
120 | 0 | return move; |
121 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::adoptPerUnit(icu_62::MeasureUnit*) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::adoptPerUnit(icu_62::MeasureUnit*) && |
122 | | |
123 | | template<typename Derived> |
124 | 0 | Derived NumberFormatterSettings<Derived>::precision(const Precision& precision) const& { |
125 | 0 | Derived copy(*this); |
126 | 0 | // NOTE: Slicing is OK. |
127 | 0 | copy.fMacros.precision = precision; |
128 | 0 | return copy; |
129 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::precision(icu_62::number::Precision const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::precision(icu_62::number::Precision const&) const & |
130 | | |
131 | | template<typename Derived> |
132 | 0 | Derived NumberFormatterSettings<Derived>::precision(const Precision& precision)&& { |
133 | 0 | Derived move(std::move(*this)); |
134 | 0 | // NOTE: Slicing is OK. |
135 | 0 | move.fMacros.precision = precision; |
136 | 0 | return move; |
137 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::precision(icu_62::number::Precision const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::precision(icu_62::number::Precision const&) && |
138 | | |
139 | | template<typename Derived> |
140 | 0 | Derived NumberFormatterSettings<Derived>::roundingMode(UNumberFormatRoundingMode roundingMode) const& { |
141 | 0 | Derived copy(*this); |
142 | 0 | copy.fMacros.roundingMode = roundingMode; |
143 | 0 | return copy; |
144 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::roundingMode(UNumberFormatRoundingMode) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::roundingMode(UNumberFormatRoundingMode) const & |
145 | | |
146 | | template<typename Derived> |
147 | 0 | Derived NumberFormatterSettings<Derived>::roundingMode(UNumberFormatRoundingMode roundingMode)&& { |
148 | 0 | Derived move(std::move(*this)); |
149 | 0 | move.fMacros.roundingMode = roundingMode; |
150 | 0 | return move; |
151 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::roundingMode(UNumberFormatRoundingMode) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::roundingMode(UNumberFormatRoundingMode) && |
152 | | |
153 | | template<typename Derived> |
154 | 0 | Derived NumberFormatterSettings<Derived>::grouping(UGroupingStrategy strategy) const& { |
155 | 0 | Derived copy(*this); |
156 | 0 | // NOTE: This is slightly different than how the setting is stored in Java |
157 | 0 | // because we want to put it on the stack. |
158 | 0 | copy.fMacros.grouper = Grouper::forStrategy(strategy); |
159 | 0 | return copy; |
160 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::grouping(UGroupingStrategy) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::grouping(UGroupingStrategy) const & |
161 | | |
162 | | template<typename Derived> |
163 | 0 | Derived NumberFormatterSettings<Derived>::grouping(UGroupingStrategy strategy)&& { |
164 | 0 | Derived move(std::move(*this)); |
165 | 0 | move.fMacros.grouper = Grouper::forStrategy(strategy); |
166 | 0 | return move; |
167 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::grouping(UGroupingStrategy) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::grouping(UGroupingStrategy) && |
168 | | |
169 | | template<typename Derived> |
170 | 0 | Derived NumberFormatterSettings<Derived>::integerWidth(const IntegerWidth& style) const& { |
171 | 0 | Derived copy(*this); |
172 | 0 | copy.fMacros.integerWidth = style; |
173 | 0 | return copy; |
174 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::integerWidth(icu_62::number::IntegerWidth const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::integerWidth(icu_62::number::IntegerWidth const&) const & |
175 | | |
176 | | template<typename Derived> |
177 | 0 | Derived NumberFormatterSettings<Derived>::integerWidth(const IntegerWidth& style)&& { |
178 | 0 | Derived move(std::move(*this)); |
179 | 0 | move.fMacros.integerWidth = style; |
180 | 0 | return move; |
181 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::integerWidth(icu_62::number::IntegerWidth const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::integerWidth(icu_62::number::IntegerWidth const&) && |
182 | | |
183 | | template<typename Derived> |
184 | 0 | Derived NumberFormatterSettings<Derived>::symbols(const DecimalFormatSymbols& symbols) const& { |
185 | 0 | Derived copy(*this); |
186 | 0 | copy.fMacros.symbols.setTo(symbols); |
187 | 0 | return copy; |
188 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::symbols(icu_62::DecimalFormatSymbols const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::symbols(icu_62::DecimalFormatSymbols const&) const & |
189 | | |
190 | | template<typename Derived> |
191 | 0 | Derived NumberFormatterSettings<Derived>::symbols(const DecimalFormatSymbols& symbols)&& { |
192 | 0 | Derived move(std::move(*this)); |
193 | 0 | move.fMacros.symbols.setTo(symbols); |
194 | 0 | return move; |
195 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::symbols(icu_62::DecimalFormatSymbols const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::symbols(icu_62::DecimalFormatSymbols const&) && |
196 | | |
197 | | template<typename Derived> |
198 | 0 | Derived NumberFormatterSettings<Derived>::adoptSymbols(NumberingSystem* ns) const& { |
199 | 0 | Derived copy(*this); |
200 | 0 | copy.fMacros.symbols.setTo(ns); |
201 | 0 | return copy; |
202 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::adoptSymbols(icu_62::NumberingSystem*) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::adoptSymbols(icu_62::NumberingSystem*) const & |
203 | | |
204 | | template<typename Derived> |
205 | 0 | Derived NumberFormatterSettings<Derived>::adoptSymbols(NumberingSystem* ns)&& { |
206 | 0 | Derived move(std::move(*this)); |
207 | 0 | move.fMacros.symbols.setTo(ns); |
208 | 0 | return move; |
209 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::adoptSymbols(icu_62::NumberingSystem*) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::adoptSymbols(icu_62::NumberingSystem*) && |
210 | | |
211 | | template<typename Derived> |
212 | 0 | Derived NumberFormatterSettings<Derived>::unitWidth(UNumberUnitWidth width) const& { |
213 | 0 | Derived copy(*this); |
214 | 0 | copy.fMacros.unitWidth = width; |
215 | 0 | return copy; |
216 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::unitWidth(UNumberUnitWidth) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::unitWidth(UNumberUnitWidth) const & |
217 | | |
218 | | template<typename Derived> |
219 | 0 | Derived NumberFormatterSettings<Derived>::unitWidth(UNumberUnitWidth width)&& { |
220 | 0 | Derived move(std::move(*this)); |
221 | 0 | move.fMacros.unitWidth = width; |
222 | 0 | return move; |
223 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::unitWidth(UNumberUnitWidth) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::unitWidth(UNumberUnitWidth) && |
224 | | |
225 | | template<typename Derived> |
226 | 0 | Derived NumberFormatterSettings<Derived>::sign(UNumberSignDisplay style) const& { |
227 | 0 | Derived copy(*this); |
228 | 0 | copy.fMacros.sign = style; |
229 | 0 | return copy; |
230 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::sign(UNumberSignDisplay) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::sign(UNumberSignDisplay) const & |
231 | | |
232 | | template<typename Derived> |
233 | 0 | Derived NumberFormatterSettings<Derived>::sign(UNumberSignDisplay style)&& { |
234 | 0 | Derived move(std::move(*this)); |
235 | 0 | move.fMacros.sign = style; |
236 | 0 | return move; |
237 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::sign(UNumberSignDisplay) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::sign(UNumberSignDisplay) && |
238 | | |
239 | | template<typename Derived> |
240 | 0 | Derived NumberFormatterSettings<Derived>::decimal(UNumberDecimalSeparatorDisplay style) const& { |
241 | 0 | Derived copy(*this); |
242 | 0 | copy.fMacros.decimal = style; |
243 | 0 | return copy; |
244 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::decimal(UNumberDecimalSeparatorDisplay) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::decimal(UNumberDecimalSeparatorDisplay) const & |
245 | | |
246 | | template<typename Derived> |
247 | 0 | Derived NumberFormatterSettings<Derived>::decimal(UNumberDecimalSeparatorDisplay style)&& { |
248 | 0 | Derived move(std::move(*this)); |
249 | 0 | move.fMacros.decimal = style; |
250 | 0 | return move; |
251 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::decimal(UNumberDecimalSeparatorDisplay) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::decimal(UNumberDecimalSeparatorDisplay) && |
252 | | |
253 | | template<typename Derived> |
254 | 0 | Derived NumberFormatterSettings<Derived>::scale(const Scale& scale) const& { |
255 | 0 | Derived copy(*this); |
256 | 0 | copy.fMacros.scale = scale; |
257 | 0 | return copy; |
258 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::scale(icu_62::number::Scale const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::scale(icu_62::number::Scale const&) const & |
259 | | |
260 | | template<typename Derived> |
261 | 0 | Derived NumberFormatterSettings<Derived>::scale(const Scale& scale)&& { |
262 | 0 | Derived move(std::move(*this)); |
263 | 0 | move.fMacros.scale = scale; |
264 | 0 | return move; |
265 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::scale(icu_62::number::Scale const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::scale(icu_62::number::Scale const&) && |
266 | | |
267 | | template<typename Derived> |
268 | 0 | Derived NumberFormatterSettings<Derived>::padding(const Padder& padder) const& { |
269 | 0 | Derived copy(*this); |
270 | 0 | copy.fMacros.padder = padder; |
271 | 0 | return copy; |
272 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::padding(icu_62::number::impl::Padder const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::padding(icu_62::number::impl::Padder const&) const & |
273 | | |
274 | | template<typename Derived> |
275 | 0 | Derived NumberFormatterSettings<Derived>::padding(const Padder& padder)&& { |
276 | 0 | Derived move(std::move(*this)); |
277 | 0 | move.fMacros.padder = padder; |
278 | 0 | return move; |
279 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::padding(icu_62::number::impl::Padder const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::padding(icu_62::number::impl::Padder const&) && |
280 | | |
281 | | template<typename Derived> |
282 | 0 | Derived NumberFormatterSettings<Derived>::threshold(int32_t threshold) const& { |
283 | 0 | Derived copy(*this); |
284 | 0 | copy.fMacros.threshold = threshold; |
285 | 0 | return copy; |
286 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::threshold(int) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::threshold(int) const & |
287 | | |
288 | | template<typename Derived> |
289 | 0 | Derived NumberFormatterSettings<Derived>::threshold(int32_t threshold)&& { |
290 | 0 | Derived move(std::move(*this)); |
291 | 0 | move.fMacros.threshold = threshold; |
292 | 0 | return move; |
293 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::threshold(int) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::threshold(int) && |
294 | | |
295 | | template<typename Derived> |
296 | 0 | Derived NumberFormatterSettings<Derived>::macros(const impl::MacroProps& macros) const& { |
297 | 0 | Derived copy(*this); |
298 | 0 | copy.fMacros = macros; |
299 | 0 | return copy; |
300 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps const&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps const&) const & |
301 | | |
302 | | template<typename Derived> |
303 | 0 | Derived NumberFormatterSettings<Derived>::macros(const impl::MacroProps& macros)&& { |
304 | 0 | Derived move(std::move(*this)); |
305 | 0 | move.fMacros = macros; |
306 | 0 | return move; |
307 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps const&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps const&) && |
308 | | |
309 | | template<typename Derived> |
310 | 0 | Derived NumberFormatterSettings<Derived>::macros(impl::MacroProps&& macros) const& { |
311 | 0 | Derived copy(*this); |
312 | 0 | copy.fMacros = std::move(macros); |
313 | 0 | return copy; |
314 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps&&) const & Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps&&) const & |
315 | | |
316 | | template<typename Derived> |
317 | 0 | Derived NumberFormatterSettings<Derived>::macros(impl::MacroProps&& macros)&& { |
318 | 0 | Derived move(std::move(*this)); |
319 | 0 | move.fMacros = std::move(macros); |
320 | 0 | return move; |
321 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps&&) && Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::macros(icu_62::number::impl::MacroProps&&) && |
322 | | |
323 | | template<typename Derived> |
324 | 0 | UnicodeString NumberFormatterSettings<Derived>::toSkeleton(UErrorCode& status) const { |
325 | 0 | if (fMacros.copyErrorTo(status)) { |
326 | 0 | return ICU_Utility::makeBogusString(); |
327 | 0 | } |
328 | 0 | return skeleton::generate(fMacros, status); |
329 | 0 | } Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::UnlocalizedNumberFormatter>::toSkeleton(UErrorCode&) const Unexecuted instantiation: icu_62::number::NumberFormatterSettings<icu_62::number::LocalizedNumberFormatter>::toSkeleton(UErrorCode&) const |
330 | | |
331 | | // Declare all classes that implement NumberFormatterSettings |
332 | | // See https://stackoverflow.com/a/495056/1407170 |
333 | | template |
334 | | class icu::number::NumberFormatterSettings<icu::number::UnlocalizedNumberFormatter>; |
335 | | template |
336 | | class icu::number::NumberFormatterSettings<icu::number::LocalizedNumberFormatter>; |
337 | | |
338 | | |
339 | 0 | UnlocalizedNumberFormatter NumberFormatter::with() { |
340 | 0 | UnlocalizedNumberFormatter result; |
341 | 0 | return result; |
342 | 0 | } |
343 | | |
344 | 0 | LocalizedNumberFormatter NumberFormatter::withLocale(const Locale& locale) { |
345 | 0 | return with().locale(locale); |
346 | 0 | } |
347 | | |
348 | | UnlocalizedNumberFormatter |
349 | 0 | NumberFormatter::forSkeleton(const UnicodeString& skeleton, UErrorCode& status) { |
350 | 0 | return skeleton::create(skeleton, status); |
351 | 0 | } |
352 | | |
353 | | |
354 | | template<typename T> using NFS = NumberFormatterSettings<T>; |
355 | | using LNF = LocalizedNumberFormatter; |
356 | | using UNF = UnlocalizedNumberFormatter; |
357 | | |
358 | | UnlocalizedNumberFormatter::UnlocalizedNumberFormatter(const UNF& other) |
359 | 0 | : UNF(static_cast<const NFS<UNF>&>(other)) {} |
360 | | |
361 | | UnlocalizedNumberFormatter::UnlocalizedNumberFormatter(const NFS<UNF>& other) |
362 | 0 | : NFS<UNF>(other) { |
363 | 0 | // No additional fields to assign |
364 | 0 | } |
365 | | |
366 | | UnlocalizedNumberFormatter::UnlocalizedNumberFormatter(UNF&& src) U_NOEXCEPT |
367 | 0 | : UNF(static_cast<NFS<UNF>&&>(src)) {} |
368 | | |
369 | | UnlocalizedNumberFormatter::UnlocalizedNumberFormatter(NFS<UNF>&& src) U_NOEXCEPT |
370 | 0 | : NFS<UNF>(std::move(src)) { |
371 | 0 | // No additional fields to assign |
372 | 0 | } |
373 | | |
374 | 0 | UnlocalizedNumberFormatter& UnlocalizedNumberFormatter::operator=(const UNF& other) { |
375 | 0 | NFS<UNF>::operator=(static_cast<const NFS<UNF>&>(other)); |
376 | 0 | // No additional fields to assign |
377 | 0 | return *this; |
378 | 0 | } |
379 | | |
380 | 0 | UnlocalizedNumberFormatter& UnlocalizedNumberFormatter::operator=(UNF&& src) U_NOEXCEPT { |
381 | 0 | NFS<UNF>::operator=(static_cast<NFS<UNF>&&>(src)); |
382 | 0 | // No additional fields to assign |
383 | 0 | return *this; |
384 | 0 | } |
385 | | |
386 | | LocalizedNumberFormatter::LocalizedNumberFormatter(const LNF& other) |
387 | 0 | : LNF(static_cast<const NFS<LNF>&>(other)) {} |
388 | | |
389 | | LocalizedNumberFormatter::LocalizedNumberFormatter(const NFS<LNF>& other) |
390 | 0 | : NFS<LNF>(other) { |
391 | 0 | // No additional fields to assign (let call count and compiled formatter reset to defaults) |
392 | 0 | } |
393 | | |
394 | | LocalizedNumberFormatter::LocalizedNumberFormatter(LocalizedNumberFormatter&& src) U_NOEXCEPT |
395 | 0 | : LNF(static_cast<NFS<LNF>&&>(src)) {} |
396 | | |
397 | | LocalizedNumberFormatter::LocalizedNumberFormatter(NFS<LNF>&& src) U_NOEXCEPT |
398 | 0 | : NFS<LNF>(std::move(src)) { |
399 | 0 | // For the move operators, copy over the compiled formatter. |
400 | 0 | // Note: if the formatter is not compiled, call count information is lost. |
401 | 0 | if (static_cast<LNF&&>(src).fCompiled != nullptr) { |
402 | 0 | lnfMoveHelper(static_cast<LNF&&>(src)); |
403 | 0 | } |
404 | 0 | } |
405 | | |
406 | 0 | LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(const LNF& other) { |
407 | 0 | NFS<LNF>::operator=(static_cast<const NFS<LNF>&>(other)); |
408 | 0 | // No additional fields to assign (let call count and compiled formatter reset to defaults) |
409 | 0 | return *this; |
410 | 0 | } |
411 | | |
412 | 0 | LocalizedNumberFormatter& LocalizedNumberFormatter::operator=(LNF&& src) U_NOEXCEPT { |
413 | 0 | NFS<LNF>::operator=(static_cast<NFS<LNF>&&>(src)); |
414 | 0 | // For the move operators, copy over the compiled formatter. |
415 | 0 | // Note: if the formatter is not compiled, call count information is lost. |
416 | 0 | if (static_cast<LNF&&>(src).fCompiled != nullptr) { |
417 | 0 | // Formatter is compiled |
418 | 0 | lnfMoveHelper(static_cast<LNF&&>(src)); |
419 | 0 | } else { |
420 | 0 | // Reset to default values. |
421 | 0 | auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount); |
422 | 0 | umtx_storeRelease(*callCount, 0); |
423 | 0 | fCompiled = nullptr; |
424 | 0 | } |
425 | 0 | return *this; |
426 | 0 | } |
427 | | |
428 | 0 | void LocalizedNumberFormatter::lnfMoveHelper(LNF&& src) { |
429 | 0 | // Copy over the compiled formatter and set call count to INT32_MIN as in computeCompiled(). |
430 | 0 | // Don't copy the call count directly because doing so requires a loadAcquire/storeRelease. |
431 | 0 | // The bits themselves appear to be platform-dependent, so copying them might not be safe. |
432 | 0 | auto* callCount = reinterpret_cast<u_atomic_int32_t*>(fUnsafeCallCount); |
433 | 0 | umtx_storeRelease(*callCount, INT32_MIN); |
434 | 0 | fCompiled = src.fCompiled; |
435 | 0 | // Reset the source object to leave it in a safe state. |
436 | 0 | auto* srcCallCount = reinterpret_cast<u_atomic_int32_t*>(src.fUnsafeCallCount); |
437 | 0 | umtx_storeRelease(*srcCallCount, 0); |
438 | 0 | src.fCompiled = nullptr; |
439 | 0 | } |
440 | | |
441 | | |
442 | 0 | LocalizedNumberFormatter::~LocalizedNumberFormatter() { |
443 | 0 | delete fCompiled; |
444 | 0 | } |
445 | | |
446 | 0 | LocalizedNumberFormatter::LocalizedNumberFormatter(const MacroProps& macros, const Locale& locale) { |
447 | 0 | fMacros = macros; |
448 | 0 | fMacros.locale = locale; |
449 | 0 | } |
450 | | |
451 | 0 | LocalizedNumberFormatter::LocalizedNumberFormatter(MacroProps&& macros, const Locale& locale) { |
452 | 0 | fMacros = std::move(macros); |
453 | 0 | fMacros.locale = locale; |
454 | 0 | } |
455 | | |
456 | 0 | LocalizedNumberFormatter UnlocalizedNumberFormatter::locale(const Locale& locale) const& { |
457 | 0 | return LocalizedNumberFormatter(fMacros, locale); |
458 | 0 | } |
459 | | |
460 | 0 | LocalizedNumberFormatter UnlocalizedNumberFormatter::locale(const Locale& locale)&& { |
461 | 0 | return LocalizedNumberFormatter(std::move(fMacros), locale); |
462 | 0 | } |
463 | | |
464 | 0 | SymbolsWrapper::SymbolsWrapper(const SymbolsWrapper& other) { |
465 | 0 | doCopyFrom(other); |
466 | 0 | } |
467 | | |
468 | 0 | SymbolsWrapper::SymbolsWrapper(SymbolsWrapper&& src) U_NOEXCEPT { |
469 | 0 | doMoveFrom(std::move(src)); |
470 | 0 | } |
471 | | |
472 | 0 | SymbolsWrapper& SymbolsWrapper::operator=(const SymbolsWrapper& other) { |
473 | 0 | if (this == &other) { |
474 | 0 | return *this; |
475 | 0 | } |
476 | 0 | doCleanup(); |
477 | 0 | doCopyFrom(other); |
478 | 0 | return *this; |
479 | 0 | } |
480 | | |
481 | 0 | SymbolsWrapper& SymbolsWrapper::operator=(SymbolsWrapper&& src) U_NOEXCEPT { |
482 | 0 | if (this == &src) { |
483 | 0 | return *this; |
484 | 0 | } |
485 | 0 | doCleanup(); |
486 | 0 | doMoveFrom(std::move(src)); |
487 | 0 | return *this; |
488 | 0 | } |
489 | | |
490 | 0 | SymbolsWrapper::~SymbolsWrapper() { |
491 | 0 | doCleanup(); |
492 | 0 | } |
493 | | |
494 | 0 | void SymbolsWrapper::setTo(const DecimalFormatSymbols& dfs) { |
495 | 0 | doCleanup(); |
496 | 0 | fType = SYMPTR_DFS; |
497 | 0 | fPtr.dfs = new DecimalFormatSymbols(dfs); |
498 | 0 | } |
499 | | |
500 | 0 | void SymbolsWrapper::setTo(const NumberingSystem* ns) { |
501 | 0 | doCleanup(); |
502 | 0 | fType = SYMPTR_NS; |
503 | 0 | fPtr.ns = ns; |
504 | 0 | } |
505 | | |
506 | 0 | void SymbolsWrapper::doCopyFrom(const SymbolsWrapper& other) { |
507 | 0 | fType = other.fType; |
508 | 0 | switch (fType) { |
509 | 0 | case SYMPTR_NONE: |
510 | 0 | // No action necessary |
511 | 0 | break; |
512 | 0 | case SYMPTR_DFS: |
513 | 0 | // Memory allocation failures are exposed in copyErrorTo() |
514 | 0 | if (other.fPtr.dfs != nullptr) { |
515 | 0 | fPtr.dfs = new DecimalFormatSymbols(*other.fPtr.dfs); |
516 | 0 | } else { |
517 | 0 | fPtr.dfs = nullptr; |
518 | 0 | } |
519 | 0 | break; |
520 | 0 | case SYMPTR_NS: |
521 | 0 | // Memory allocation failures are exposed in copyErrorTo() |
522 | 0 | if (other.fPtr.ns != nullptr) { |
523 | 0 | fPtr.ns = new NumberingSystem(*other.fPtr.ns); |
524 | 0 | } else { |
525 | 0 | fPtr.ns = nullptr; |
526 | 0 | } |
527 | 0 | break; |
528 | 0 | } |
529 | 0 | } |
530 | | |
531 | | void SymbolsWrapper::doMoveFrom(SymbolsWrapper&& src) { |
532 | | fType = src.fType; |
533 | | switch (fType) { |
534 | | case SYMPTR_NONE: |
535 | | // No action necessary |
536 | | break; |
537 | | case SYMPTR_DFS: |
538 | | fPtr.dfs = src.fPtr.dfs; |
539 | | src.fPtr.dfs = nullptr; |
540 | | break; |
541 | | case SYMPTR_NS: |
542 | | fPtr.ns = src.fPtr.ns; |
543 | | src.fPtr.ns = nullptr; |
544 | | break; |
545 | | } |
546 | | } |
547 | | |
548 | | void SymbolsWrapper::doCleanup() { |
549 | | switch (fType) { |
550 | | case SYMPTR_NONE: |
551 | | // No action necessary |
552 | | break; |
553 | | case SYMPTR_DFS: |
554 | | delete fPtr.dfs; |
555 | | break; |
556 | | case SYMPTR_NS: |
557 | | delete fPtr.ns; |
558 | | break; |
559 | | } |
560 | | } |
561 | | |
562 | 0 | bool SymbolsWrapper::isDecimalFormatSymbols() const { |
563 | 0 | return fType == SYMPTR_DFS; |
564 | 0 | } |
565 | | |
566 | 0 | bool SymbolsWrapper::isNumberingSystem() const { |
567 | 0 | return fType == SYMPTR_NS; |
568 | 0 | } |
569 | | |
570 | 0 | const DecimalFormatSymbols* SymbolsWrapper::getDecimalFormatSymbols() const { |
571 | 0 | U_ASSERT(fType == SYMPTR_DFS); |
572 | 0 | return fPtr.dfs; |
573 | 0 | } |
574 | | |
575 | 0 | const NumberingSystem* SymbolsWrapper::getNumberingSystem() const { |
576 | 0 | U_ASSERT(fType == SYMPTR_NS); |
577 | 0 | return fPtr.ns; |
578 | 0 | } |
579 | | |
580 | | |
581 | 0 | FormattedNumber LocalizedNumberFormatter::formatInt(int64_t value, UErrorCode& status) const { |
582 | 0 | if (U_FAILURE(status)) { return FormattedNumber(U_ILLEGAL_ARGUMENT_ERROR); } |
583 | 0 | auto results = new UFormattedNumberData(); |
584 | 0 | if (results == nullptr) { |
585 | 0 | status = U_MEMORY_ALLOCATION_ERROR; |
586 | 0 | return FormattedNumber(status); |
587 | 0 | } |
588 | 0 | results->quantity.setToLong(value); |
589 | 0 | formatImpl(results, status); |
590 | 0 |
|
591 | 0 | // Do not save the results object if we encountered a failure. |
592 | 0 | if (U_SUCCESS(status)) { |
593 | 0 | return FormattedNumber(results); |
594 | 0 | } else { |
595 | 0 | delete results; |
596 | 0 | return FormattedNumber(status); |
597 | 0 | } |
598 | 0 | } |
599 | | |
600 | 0 | FormattedNumber LocalizedNumberFormatter::formatDouble(double value, UErrorCode& status) const { |
601 | 0 | if (U_FAILURE(status)) { return FormattedNumber(U_ILLEGAL_ARGUMENT_ERROR); } |
602 | 0 | auto results = new UFormattedNumberData(); |
603 | 0 | if (results == nullptr) { |
604 | 0 | status = U_MEMORY_ALLOCATION_ERROR; |
605 | 0 | return FormattedNumber(status); |
606 | 0 | } |
607 | 0 | results->quantity.setToDouble(value); |
608 | 0 | formatImpl(results, status); |
609 | 0 |
|
610 | 0 | // Do not save the results object if we encountered a failure. |
611 | 0 | if (U_SUCCESS(status)) { |
612 | 0 | return FormattedNumber(results); |
613 | 0 | } else { |
614 | 0 | delete results; |
615 | 0 | return FormattedNumber(status); |
616 | 0 | } |
617 | 0 | } |
618 | | |
619 | 0 | FormattedNumber LocalizedNumberFormatter::formatDecimal(StringPiece value, UErrorCode& status) const { |
620 | 0 | if (U_FAILURE(status)) { return FormattedNumber(U_ILLEGAL_ARGUMENT_ERROR); } |
621 | 0 | auto results = new UFormattedNumberData(); |
622 | 0 | if (results == nullptr) { |
623 | 0 | status = U_MEMORY_ALLOCATION_ERROR; |
624 | 0 | return FormattedNumber(status); |
625 | 0 | } |
626 | 0 | results->quantity.setToDecNumber(value, status); |
627 | 0 | formatImpl(results, status); |
628 | 0 |
|
629 | 0 | // Do not save the results object if we encountered a failure. |
630 | 0 | if (U_SUCCESS(status)) { |
631 | 0 | return FormattedNumber(results); |
632 | 0 | } else { |
633 | 0 | delete results; |
634 | 0 | return FormattedNumber(status); |
635 | 0 | } |
636 | 0 | } |
637 | | |
638 | | FormattedNumber |
639 | 0 | LocalizedNumberFormatter::formatDecimalQuantity(const DecimalQuantity& dq, UErrorCode& status) const { |
640 | 0 | if (U_FAILURE(status)) { return FormattedNumber(U_ILLEGAL_ARGUMENT_ERROR); } |
641 | 0 | auto results = new UFormattedNumberData(); |
642 | 0 | if (results == nullptr) { |
643 | 0 | status = U_MEMORY_ALLOCATION_ERROR; |
644 | 0 | return FormattedNumber(status); |
645 | 0 | } |
646 | 0 | results->quantity = dq; |
647 | 0 | formatImpl(results, status); |
648 | 0 |
|
649 | 0 | // Do not save the results object if we encountered a failure. |
650 | 0 | if (U_SUCCESS(status)) { |
651 | 0 | return FormattedNumber(results); |
652 | 0 | } else { |
653 | 0 | delete results; |
654 | 0 | return FormattedNumber(status); |
655 | 0 | } |
656 | 0 | } |
657 | | |
658 | 0 | void LocalizedNumberFormatter::formatImpl(impl::UFormattedNumberData* results, UErrorCode& status) const { |
659 | 0 | if (computeCompiled(status)) { |
660 | 0 | fCompiled->apply(results->quantity, results->string, status); |
661 | 0 | } else { |
662 | 0 | NumberFormatterImpl::applyStatic(fMacros, results->quantity, results->string, status); |
663 | 0 | } |
664 | 0 | } |
665 | | |
666 | | void LocalizedNumberFormatter::getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, |
667 | 0 | UErrorCode& status) const { |
668 | 0 | NumberStringBuilder string; |
669 | 0 | auto signum = static_cast<int8_t>(isNegative ? -1 : 1); |
670 | 0 | // Always return affixes for plural form OTHER. |
671 | 0 | static const StandardPlural::Form plural = StandardPlural::OTHER; |
672 | 0 | int32_t prefixLength; |
673 | 0 | if (computeCompiled(status)) { |
674 | 0 | prefixLength = fCompiled->getPrefixSuffix(signum, plural, string, status); |
675 | 0 | } else { |
676 | 0 | prefixLength = NumberFormatterImpl::getPrefixSuffixStatic(fMacros, signum, plural, string, status); |
677 | 0 | } |
678 | 0 | result.remove(); |
679 | 0 | if (isPrefix) { |
680 | 0 | result.append(string.toTempUnicodeString().tempSubStringBetween(0, prefixLength)); |
681 | 0 | } else { |
682 | 0 | result.append(string.toTempUnicodeString().tempSubStringBetween(prefixLength, string.length())); |
683 | 0 | } |
684 | 0 | } |
685 | | |
686 | 0 | bool LocalizedNumberFormatter::computeCompiled(UErrorCode& status) const { |
687 | 0 | // fUnsafeCallCount contains memory to be interpreted as an atomic int, most commonly |
688 | 0 | // std::atomic<int32_t>. Since the type of atomic int is platform-dependent, we cast the |
689 | 0 | // bytes in fUnsafeCallCount to u_atomic_int32_t, a typedef for the platform-dependent |
690 | 0 | // atomic int type defined in umutex.h. |
691 | 0 | static_assert( |
692 | 0 | sizeof(u_atomic_int32_t) <= sizeof(fUnsafeCallCount), |
693 | 0 | "Atomic integer size on this platform exceeds the size allocated by fUnsafeCallCount"); |
694 | 0 | auto* callCount = reinterpret_cast<u_atomic_int32_t*>( |
695 | 0 | const_cast<LocalizedNumberFormatter*>(this)->fUnsafeCallCount); |
696 | 0 |
|
697 | 0 | // A positive value in the atomic int indicates that the data structure is not yet ready; |
698 | 0 | // a negative value indicates that it is ready. If, after the increment, the atomic int |
699 | 0 | // is exactly threshold, then it is the current thread's job to build the data structure. |
700 | 0 | // Note: We set the callCount to INT32_MIN so that if another thread proceeds to increment |
701 | 0 | // the atomic int, the value remains below zero. |
702 | 0 | int32_t currentCount = umtx_loadAcquire(*callCount); |
703 | 0 | if (0 <= currentCount && currentCount <= fMacros.threshold && fMacros.threshold > 0) { |
704 | 0 | currentCount = umtx_atomic_inc(callCount); |
705 | 0 | } |
706 | 0 |
|
707 | 0 | if (currentCount == fMacros.threshold && fMacros.threshold > 0) { |
708 | 0 | // Build the data structure and then use it (slow to fast path). |
709 | 0 | const NumberFormatterImpl* compiled = NumberFormatterImpl::fromMacros(fMacros, status); |
710 | 0 | U_ASSERT(fCompiled == nullptr); |
711 | 0 | const_cast<LocalizedNumberFormatter*>(this)->fCompiled = compiled; |
712 | 0 | umtx_storeRelease(*callCount, INT32_MIN); |
713 | 0 | return true; |
714 | 0 | } else if (currentCount < 0) { |
715 | 0 | // The data structure is already built; use it (fast path). |
716 | 0 | U_ASSERT(fCompiled != nullptr); |
717 | 0 | return true; |
718 | 0 | } else { |
719 | 0 | // Format the number without building the data structure (slow path). |
720 | 0 | return false; |
721 | 0 | } |
722 | 0 | } |
723 | | |
724 | 0 | const impl::NumberFormatterImpl* LocalizedNumberFormatter::getCompiled() const { |
725 | 0 | return fCompiled; |
726 | 0 | } |
727 | | |
728 | 0 | int32_t LocalizedNumberFormatter::getCallCount() const { |
729 | 0 | auto* callCount = reinterpret_cast<u_atomic_int32_t*>( |
730 | 0 | const_cast<LocalizedNumberFormatter*>(this)->fUnsafeCallCount); |
731 | 0 | return umtx_loadAcquire(*callCount); |
732 | 0 | } |
733 | | |
734 | 0 | Format* LocalizedNumberFormatter::toFormat(UErrorCode& status) const { |
735 | 0 | LocalPointer<LocalizedNumberFormatterAsFormat> retval( |
736 | 0 | new LocalizedNumberFormatterAsFormat(*this, fMacros.locale), status); |
737 | 0 | return retval.orphan(); |
738 | 0 | } |
739 | | |
740 | | |
741 | | FormattedNumber::FormattedNumber(FormattedNumber&& src) U_NOEXCEPT |
742 | 0 | : fResults(src.fResults), fErrorCode(src.fErrorCode) { |
743 | 0 | // Disown src.fResults to prevent double-deletion |
744 | 0 | src.fResults = nullptr; |
745 | 0 | src.fErrorCode = U_INVALID_STATE_ERROR; |
746 | 0 | } |
747 | | |
748 | 0 | FormattedNumber& FormattedNumber::operator=(FormattedNumber&& src) U_NOEXCEPT { |
749 | 0 | delete fResults; |
750 | 0 | fResults = src.fResults; |
751 | 0 | fErrorCode = src.fErrorCode; |
752 | 0 | // Disown src.fResults to prevent double-deletion |
753 | 0 | src.fResults = nullptr; |
754 | 0 | src.fErrorCode = U_INVALID_STATE_ERROR; |
755 | 0 | return *this; |
756 | 0 | } |
757 | | |
758 | 0 | UnicodeString FormattedNumber::toString() const { |
759 | 0 | UErrorCode localStatus = U_ZERO_ERROR; |
760 | 0 | return toString(localStatus); |
761 | 0 | } |
762 | | |
763 | 0 | UnicodeString FormattedNumber::toString(UErrorCode& status) const { |
764 | 0 | if (U_FAILURE(status)) { |
765 | 0 | return ICU_Utility::makeBogusString(); |
766 | 0 | } |
767 | 0 | if (fResults == nullptr) { |
768 | 0 | status = fErrorCode; |
769 | 0 | return ICU_Utility::makeBogusString(); |
770 | 0 | } |
771 | 0 | return fResults->string.toUnicodeString(); |
772 | 0 | } |
773 | | |
774 | 0 | Appendable& FormattedNumber::appendTo(Appendable& appendable) { |
775 | 0 | UErrorCode localStatus = U_ZERO_ERROR; |
776 | 0 | return appendTo(appendable, localStatus); |
777 | 0 | } |
778 | | |
779 | 0 | Appendable& FormattedNumber::appendTo(Appendable& appendable, UErrorCode& status) { |
780 | 0 | if (U_FAILURE(status)) { |
781 | 0 | return appendable; |
782 | 0 | } |
783 | 0 | if (fResults == nullptr) { |
784 | 0 | status = fErrorCode; |
785 | 0 | return appendable; |
786 | 0 | } |
787 | 0 | appendable.appendString(fResults->string.chars(), fResults->string.length()); |
788 | 0 | return appendable; |
789 | 0 | } |
790 | | |
791 | 0 | void FormattedNumber::populateFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) { |
792 | 0 | if (U_FAILURE(status)) { |
793 | 0 | return; |
794 | 0 | } |
795 | 0 | if (fResults == nullptr) { |
796 | 0 | status = fErrorCode; |
797 | 0 | return; |
798 | 0 | } |
799 | 0 | // in case any users were depending on the old behavior: |
800 | 0 | fieldPosition.setBeginIndex(0); |
801 | 0 | fieldPosition.setEndIndex(0); |
802 | 0 | fResults->string.nextFieldPosition(fieldPosition, status); |
803 | 0 | } |
804 | | |
805 | 0 | UBool FormattedNumber::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const { |
806 | 0 | if (U_FAILURE(status)) { |
807 | 0 | return FALSE; |
808 | 0 | } |
809 | 0 | if (fResults == nullptr) { |
810 | 0 | status = fErrorCode; |
811 | 0 | return FALSE; |
812 | 0 | } |
813 | 0 | // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool |
814 | 0 | return fResults->string.nextFieldPosition(fieldPosition, status) ? TRUE : FALSE; |
815 | 0 | } |
816 | | |
817 | 0 | void FormattedNumber::populateFieldPositionIterator(FieldPositionIterator& iterator, UErrorCode& status) { |
818 | 0 | getAllFieldPositions(iterator, status); |
819 | 0 | } |
820 | | |
821 | 0 | void FormattedNumber::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const { |
822 | 0 | FieldPositionIteratorHandler fpih(&iterator, status); |
823 | 0 | getAllFieldPositionsImpl(fpih, status); |
824 | 0 | } |
825 | | |
826 | | void FormattedNumber::getAllFieldPositionsImpl(FieldPositionIteratorHandler& fpih, |
827 | 0 | UErrorCode& status) const { |
828 | 0 | if (U_FAILURE(status)) { |
829 | 0 | return; |
830 | 0 | } |
831 | 0 | if (fResults == nullptr) { |
832 | 0 | status = fErrorCode; |
833 | 0 | return; |
834 | 0 | } |
835 | 0 | fResults->string.getAllFieldPositions(fpih, status); |
836 | 0 | } |
837 | | |
838 | 0 | void FormattedNumber::getDecimalQuantity(DecimalQuantity& output, UErrorCode& status) const { |
839 | 0 | if (U_FAILURE(status)) { |
840 | 0 | return; |
841 | 0 | } |
842 | 0 | if (fResults == nullptr) { |
843 | 0 | status = fErrorCode; |
844 | 0 | return; |
845 | 0 | } |
846 | 0 | output = fResults->quantity; |
847 | 0 | } |
848 | | |
849 | 0 | FormattedNumber::~FormattedNumber() { |
850 | 0 | delete fResults; |
851 | 0 | } |
852 | | |
853 | | #endif /* #if !UCONFIG_NO_FORMATTING */ |