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"
20 U_NAMESPACE_BEGIN
namespace number
{
23 // Typedef several enums for brevity and for easier comparison to Java.
25 typedef UNumberFormatFields Field
;
27 typedef UNumberFormatRoundingMode RoundingMode
;
29 typedef UNumberFormatPadPosition PadPosition
;
31 typedef UNumberCompactStyle CompactStyle
;
33 // ICU4J Equivalent: RoundingUtils.MAX_INT_FRAC_SIG
34 static constexpr int32_t kMaxIntFracSig
= 999;
36 // ICU4J Equivalent: RoundingUtils.DEFAULT_ROUNDING_MODE
37 static constexpr RoundingMode kDefaultMode
= RoundingMode::UNUM_FOUND_HALFEVEN
;
39 // ICU4J Equivalent: Padder.FALLBACK_PADDING_STRING
40 static constexpr char16_t kFallbackPaddingString
[] = u
" ";
42 // Forward declarations:
45 class MutablePatternModifier
;
46 class DecimalQuantity
;
47 class NumberStringBuilder
;
51 enum AffixPatternType
{
52 // Represents a literal character; the value is stored in the code point field.
55 // Represents a minus sign symbol '-'.
58 // Represents a plus sign symbol '+'.
61 // Represents a percent sign symbol '%'.
64 // Represents a permille sign symbol '‰'.
67 // Represents a single currency symbol '¤'.
68 TYPE_CURRENCY_SINGLE
= -5,
70 // Represents a double currency symbol '¤¤'.
71 TYPE_CURRENCY_DOUBLE
= -6,
73 // Represents a triple currency symbol '¤¤¤'.
74 TYPE_CURRENCY_TRIPLE
= -7,
76 // Represents a quadruple currency symbol '¤¤¤¤'.
77 TYPE_CURRENCY_QUAD
= -8,
79 // Represents a quintuple currency symbol '¤¤¤¤¤'.
80 TYPE_CURRENCY_QUINT
= -9,
82 // Represents a sequence of six or more currency symbols.
83 TYPE_CURRENCY_OVERFLOW
= -15
87 TYPE_DECIMAL
, TYPE_CURRENCY
91 class U_I18N_API AffixPatternProvider
{
93 static const int32_t AFFIX_PLURAL_MASK
= 0xff;
94 static const int32_t AFFIX_PREFIX
= 0x100;
95 static const int32_t AFFIX_NEGATIVE_SUBPATTERN
= 0x200;
96 static const int32_t AFFIX_PADDING
= 0x400;
98 // Convenience compound flags
99 static const int32_t AFFIX_POS_PREFIX
= AFFIX_PREFIX
;
100 static const int32_t AFFIX_POS_SUFFIX
= 0;
101 static const int32_t AFFIX_NEG_PREFIX
= AFFIX_PREFIX
| AFFIX_NEGATIVE_SUBPATTERN
;
102 static const int32_t AFFIX_NEG_SUFFIX
= AFFIX_NEGATIVE_SUBPATTERN
;
104 virtual ~AffixPatternProvider();
106 virtual char16_t charAt(int flags
, int i
) const = 0;
108 virtual int length(int flags
) const = 0;
110 virtual UnicodeString
getString(int flags
) const = 0;
112 virtual bool hasCurrencySign() const = 0;
114 virtual bool positiveHasPlusSign() const = 0;
116 virtual bool hasNegativeSubpattern() const = 0;
118 virtual bool negativeHasMinusSign() const = 0;
120 virtual bool containsSymbolType(AffixPatternType
, UErrorCode
&) const = 0;
123 * True if the pattern has a number placeholder like "0" or "#,##0.00"; false if the pattern does not
124 * have one. This is used in cases like compact notation, where the pattern replaces the entire
125 * number instead of rendering the number.
127 virtual bool hasBody() const = 0;
131 * A Modifier is an object that can be passed through the formatting pipeline until it is finally applied to the string
132 * builder. A Modifier usually contains a prefix and a suffix that are applied, but it could contain something else,
133 * like a {@link com.ibm.icu.text.SimpleFormatter} pattern.
135 * A Modifier is usually immutable, except in cases such as {@link MurkyModifier}, which are mutable for performance
138 * Exported as U_I18N_API because it is a base class for other exported types
140 class U_I18N_API Modifier
{
145 * Apply this Modifier to the string builder.
148 * The string builder to which to apply this modifier.
150 * The left index of the string within the builder. Equal to 0 when only one number is being formatted.
152 * The right index of the string within the string builder. Equal to length when only one number is being
154 * @return The number of characters (UTF-16 code units) that were added to the string builder.
156 virtual int32_t apply(NumberStringBuilder
& output
, int leftIndex
, int rightIndex
,
157 UErrorCode
& status
) const = 0;
160 * Gets the length of the prefix. This information can be used in combination with {@link #apply} to extract the
161 * prefix and suffix strings.
163 * @return The number of characters (UTF-16 code units) in the prefix.
165 virtual int32_t getPrefixLength(UErrorCode
& status
) const = 0;
168 * Returns the number of code points in the modifier, prefix plus suffix.
170 virtual int32_t getCodePointCount(UErrorCode
& status
) const = 0;
173 * Whether this modifier is strong. If a modifier is strong, it should always be applied immediately and not allowed
174 * to bubble up. With regard to padding, strong modifiers are considered to be on the inside of the prefix and
177 * @return Whether the modifier is strong.
179 virtual bool isStrong() const = 0;
183 * This interface is used when all number formatting settings, including the locale, are known, except for the quantity
184 * itself. The {@link #processQuantity} method performs the final step in the number processing pipeline: it uses the
185 * quantity to generate a finalized {@link MicroProps}, which can be used to render the number to output.
188 * In other words, this interface is used for the parts of number processing that are <em>quantity-dependent</em>.
191 * In order to allow for multiple different objects to all mutate the same MicroProps, a "chain" of MicroPropsGenerators
192 * are linked together, and each one is responsible for manipulating a certain quantity-dependent part of the
193 * MicroProps. At the tail of the linked list is a base instance of {@link MicroProps} with properties that are not
194 * quantity-dependent. Each element in the linked list calls {@link #processQuantity} on its "parent", then does its
195 * work, and then returns the result.
197 * Exported as U_I18N_API because it is a base class for other exported types
200 class U_I18N_API MicroPropsGenerator
{
202 virtual ~MicroPropsGenerator();
205 * Considers the given {@link DecimalQuantity}, optionally mutates it, and returns a {@link MicroProps}.
208 * The quantity for consideration and optional mutation.
210 * The MicroProps instance to populate.
211 * @return A MicroProps instance resolved for the quantity.
213 virtual void processQuantity(DecimalQuantity
& quantity
, MicroProps
& micros
,
214 UErrorCode
& status
) const = 0;
218 * An interface used by compact notation and scientific notation to choose a multiplier while rounding.
220 class MultiplierProducer
{
222 virtual ~MultiplierProducer();
225 * Maps a magnitude to a multiplier in powers of ten. For example, in compact notation in English, a magnitude of 5
226 * (e.g., 100,000) should return a multiplier of -3, since the number is displayed in thousands.
229 * The power of ten of the input number.
230 * @return The shift in powers of ten.
232 virtual int32_t getMultiplier(int32_t magnitude
) const = 0;
235 // Exported as U_I18N_API because it is a public member field of exported DecimalFormatProperties
237 class U_I18N_API NullableValue
{
242 NullableValue(const NullableValue
<T
>& other
) = default;
244 explicit NullableValue(const T
& other
) {
249 NullableValue
<T
>& operator=(const NullableValue
<T
>& other
) {
252 fValue
= other
.fValue
;
257 NullableValue
<T
>& operator=(const T
& other
) {
263 bool operator==(const NullableValue
& other
) const {
264 // "fValue == other.fValue" returns UBool, not bool (causes compiler warnings)
265 return fNull
? other
.fNull
: (other
.fNull
? false : static_cast<bool>(fValue
== other
.fValue
));
269 // TODO: It might be nice to call the destructor here.
273 bool isNull() const {
277 T
get(UErrorCode
& status
) const {
279 status
= U_UNDEFINED_VARIABLE
;
284 T
getNoError() const {
288 T
getOrDefault(T defaultValue
) const {
289 return fNull
? defaultValue
: fValue
;
298 } // namespace number
301 #endif //__NUMBER_TYPES_H__
303 #endif /* #if !UCONFIG_NO_FORMATTING */