1 // © 2017 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 #include "unicode/utypes.h"
6 #if !UCONFIG_NO_FORMATTING
7 #ifndef __NUMBER_TYPES_H__
8 #define __NUMBER_TYPES_H__
11 #include "unicode/decimfmt.h"
12 #include "unicode/unum.h"
13 #include "unicode/numsys.h"
14 #include "unicode/numberformatter.h"
15 #include "unicode/utf16.h"
17 #include "unicode/platform.h"
18 #include "unicode/uniset.h"
19 #include "standardplural.h"
21 U_NAMESPACE_BEGIN
namespace number
{
24 // Typedef several enums for brevity and for easier comparison to Java.
26 // Convention: bottom 4 bits for field, top 4 bits for field category.
27 // Field category 0 implies the number category so that the number field
28 // literals can be directly passed as a Field type.
29 // See the helper functions in "NumFieldUtils" in number_utils.h
30 typedef uint8_t Field
;
32 typedef UNumberFormatRoundingMode RoundingMode
;
34 typedef UNumberFormatPadPosition PadPosition
;
36 typedef UNumberCompactStyle CompactStyle
;
38 // ICU4J Equivalent: RoundingUtils.MAX_INT_FRAC_SIG
39 static constexpr int32_t kMaxIntFracSig
= 999;
41 // ICU4J Equivalent: RoundingUtils.DEFAULT_ROUNDING_MODE
42 static constexpr RoundingMode kDefaultMode
= RoundingMode::UNUM_FOUND_HALFEVEN
;
44 // ICU4J Equivalent: Padder.FALLBACK_PADDING_STRING
45 static constexpr char16_t kFallbackPaddingString
[] = u
" ";
47 // Forward declarations:
50 class MutablePatternModifier
;
51 class DecimalQuantity
;
52 class NumberStringBuilder
;
57 enum AffixPatternType
{
58 // Represents a literal character; the value is stored in the code point field.
61 // Represents a minus sign symbol '-'.
64 // Represents a plus sign symbol '+'.
67 // Represents a percent sign symbol '%'.
70 // Represents a permille sign symbol '‰'.
73 // Represents a single currency symbol '¤'.
74 TYPE_CURRENCY_SINGLE
= -5,
76 // Represents a double currency symbol '¤¤'.
77 TYPE_CURRENCY_DOUBLE
= -6,
79 // Represents a triple currency symbol '¤¤¤'.
80 TYPE_CURRENCY_TRIPLE
= -7,
82 // Represents a quadruple currency symbol '¤¤¤¤'.
83 TYPE_CURRENCY_QUAD
= -8,
85 // Represents a quintuple currency symbol '¤¤¤¤¤'.
86 TYPE_CURRENCY_QUINT
= -9,
88 // Represents a sequence of six or more currency symbols.
89 TYPE_CURRENCY_OVERFLOW
= -15
93 TYPE_DECIMAL
, TYPE_CURRENCY
97 class U_I18N_API AffixPatternProvider
{
99 static const int32_t AFFIX_PLURAL_MASK
= 0xff;
100 static const int32_t AFFIX_PREFIX
= 0x100;
101 static const int32_t AFFIX_NEGATIVE_SUBPATTERN
= 0x200;
102 static const int32_t AFFIX_PADDING
= 0x400;
104 // Convenience compound flags
105 static const int32_t AFFIX_POS_PREFIX
= AFFIX_PREFIX
;
106 static const int32_t AFFIX_POS_SUFFIX
= 0;
107 static const int32_t AFFIX_NEG_PREFIX
= AFFIX_PREFIX
| AFFIX_NEGATIVE_SUBPATTERN
;
108 static const int32_t AFFIX_NEG_SUFFIX
= AFFIX_NEGATIVE_SUBPATTERN
;
110 virtual ~AffixPatternProvider();
112 virtual char16_t charAt(int flags
, int i
) const = 0;
114 virtual int length(int flags
) const = 0;
116 virtual UnicodeString
getString(int flags
) const = 0;
118 virtual bool hasCurrencySign() const = 0;
120 virtual bool positiveHasPlusSign() const = 0;
122 virtual bool hasNegativeSubpattern() const = 0;
124 virtual bool negativeHasMinusSign() const = 0;
126 virtual bool containsSymbolType(AffixPatternType
, UErrorCode
&) const = 0;
129 * True if the pattern has a number placeholder like "0" or "#,##0.00"; false if the pattern does not
130 * have one. This is used in cases like compact notation, where the pattern replaces the entire
131 * number instead of rendering the number.
133 virtual bool hasBody() const = 0;
138 * A Modifier is an object that can be passed through the formatting pipeline until it is finally applied to the string
139 * builder. A Modifier usually contains a prefix and a suffix that are applied, but it could contain something else,
140 * like a {@link com.ibm.icu.text.SimpleFormatter} pattern.
142 * A Modifier is usually immutable, except in cases such as {@link MutablePatternModifier}, which are mutable for performance
145 * Exported as U_I18N_API because it is a base class for other exported types
147 class U_I18N_API Modifier
{
152 * Apply this Modifier to the string builder.
155 * The string builder to which to apply this modifier.
157 * The left index of the string within the builder. Equal to 0 when only one number is being formatted.
159 * The right index of the string within the string builder. Equal to length when only one number is being
161 * @return The number of characters (UTF-16 code units) that were added to the string builder.
163 virtual int32_t apply(NumberStringBuilder
& output
, int leftIndex
, int rightIndex
,
164 UErrorCode
& status
) const = 0;
167 * Gets the length of the prefix. This information can be used in combination with {@link #apply} to extract the
168 * prefix and suffix strings.
170 * @return The number of characters (UTF-16 code units) in the prefix.
172 virtual int32_t getPrefixLength() const = 0;
175 * Returns the number of code points in the modifier, prefix plus suffix.
177 virtual int32_t getCodePointCount() const = 0;
180 * Whether this modifier is strong. If a modifier is strong, it should always be applied immediately and not allowed
181 * to bubble up. With regard to padding, strong modifiers are considered to be on the inside of the prefix and
184 * @return Whether the modifier is strong.
186 virtual bool isStrong() const = 0;
189 * Whether the modifier contains at least one occurrence of the given field.
191 virtual bool containsField(UNumberFormatFields field
) const = 0;
194 * A fill-in for getParameters(). obj will always be set; if non-null, the other
195 * two fields are also safe to read.
197 struct U_I18N_API Parameters
{
198 const ModifierStore
* obj
= nullptr;
200 StandardPlural::Form plural
;
203 Parameters(const ModifierStore
* _obj
, int8_t _signum
, StandardPlural::Form _plural
);
207 * Gets a set of "parameters" for this Modifier.
209 * TODO: Make this return a `const Parameters*` more like Java?
211 virtual void getParameters(Parameters
& output
) const = 0;
214 * Returns whether this Modifier is *semantically equivalent* to the other Modifier;
215 * in many cases, this is the same as equal, but parameters should be ignored.
217 virtual bool semanticallyEquivalent(const Modifier
& other
) const = 0;
222 * This is *not* a modifier; rather, it is an object that can return modifiers
223 * based on given parameters.
225 * Exported as U_I18N_API because it is a base class for other exported types.
227 class U_I18N_API ModifierStore
{
229 virtual ~ModifierStore();
232 * Returns a Modifier with the given parameters (best-effort).
234 virtual const Modifier
* getModifier(int8_t signum
, StandardPlural::Form plural
) const = 0;
239 * This interface is used when all number formatting settings, including the locale, are known, except for the quantity
240 * itself. The {@link #processQuantity} method performs the final step in the number processing pipeline: it uses the
241 * quantity to generate a finalized {@link MicroProps}, which can be used to render the number to output.
244 * In other words, this interface is used for the parts of number processing that are <em>quantity-dependent</em>.
247 * In order to allow for multiple different objects to all mutate the same MicroProps, a "chain" of MicroPropsGenerators
248 * are linked together, and each one is responsible for manipulating a certain quantity-dependent part of the
249 * MicroProps. At the tail of the linked list is a base instance of {@link MicroProps} with properties that are not
250 * quantity-dependent. Each element in the linked list calls {@link #processQuantity} on its "parent", then does its
251 * work, and then returns the result.
253 * Exported as U_I18N_API because it is a base class for other exported types
256 class U_I18N_API MicroPropsGenerator
{
258 virtual ~MicroPropsGenerator();
261 * Considers the given {@link DecimalQuantity}, optionally mutates it, and returns a {@link MicroProps}.
264 * The quantity for consideration and optional mutation.
266 * The MicroProps instance to populate.
267 * @return A MicroProps instance resolved for the quantity.
269 virtual void processQuantity(DecimalQuantity
& quantity
, MicroProps
& micros
,
270 UErrorCode
& status
) const = 0;
274 * An interface used by compact notation and scientific notation to choose a multiplier while rounding.
276 class MultiplierProducer
{
278 virtual ~MultiplierProducer();
281 * Maps a magnitude to a multiplier in powers of ten. For example, in compact notation in English, a magnitude of 5
282 * (e.g., 100,000) should return a multiplier of -3, since the number is displayed in thousands.
285 * The power of ten of the input number.
286 * @return The shift in powers of ten.
288 virtual int32_t getMultiplier(int32_t magnitude
) const = 0;
291 // Exported as U_I18N_API because it is a public member field of exported DecimalFormatProperties
293 class U_I18N_API NullableValue
{
298 NullableValue(const NullableValue
<T
>& other
) = default;
300 explicit NullableValue(const T
& other
) {
305 NullableValue
<T
>& operator=(const NullableValue
<T
>& other
) {
308 fValue
= other
.fValue
;
313 NullableValue
<T
>& operator=(const T
& other
) {
319 bool operator==(const NullableValue
& other
) const {
320 // "fValue == other.fValue" returns UBool, not bool (causes compiler warnings)
321 return fNull
? other
.fNull
: (other
.fNull
? false : static_cast<bool>(fValue
== other
.fValue
));
325 // TODO: It might be nice to call the destructor here.
329 bool isNull() const {
333 T
get(UErrorCode
& status
) const {
335 status
= U_UNDEFINED_VARIABLE
;
340 T
getNoError() const {
344 T
getOrDefault(T defaultValue
) const {
345 return fNull
? defaultValue
: fValue
;
355 } // namespace number
358 #endif //__NUMBER_TYPES_H__
360 #endif /* #if !UCONFIG_NO_FORMATTING */