Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/intl/icu/source/i18n/number_patternmodifier.h
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
#ifndef __NUMBER_PATTERNMODIFIER_H__
8
#define __NUMBER_PATTERNMODIFIER_H__
9
10
#include "standardplural.h"
11
#include "unicode/numberformatter.h"
12
#include "number_patternstring.h"
13
#include "number_types.h"
14
#include "number_modifiers.h"
15
#include "number_utils.h"
16
#include "number_currencysymbols.h"
17
18
U_NAMESPACE_BEGIN
19
20
// Export an explicit template instantiation of the LocalPointer that is used as a
21
// data member of ParameterizedModifier.
22
// (When building DLLs for Windows this is required.)
23
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
24
// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
25
#pragma warning(suppress: 4661)
26
template class U_I18N_API LocalPointerBase<number::impl::ParameterizedModifier>;
27
template class U_I18N_API LocalPointer<number::impl::ParameterizedModifier>;
28
#endif
29
30
namespace number {
31
namespace impl {
32
33
// Forward declaration
34
class MutablePatternModifier;
35
36
// Exported as U_I18N_API because it is needed for the unit test PatternModifierTest
37
class U_I18N_API ImmutablePatternModifier : public MicroPropsGenerator, public UMemory {
38
  public:
39
0
    ~ImmutablePatternModifier() U_OVERRIDE = default;
40
41
    void processQuantity(DecimalQuantity&, MicroProps& micros, UErrorCode& status) const U_OVERRIDE;
42
43
    void applyToMicros(MicroProps& micros, DecimalQuantity& quantity) const;
44
45
    const Modifier* getModifier(int8_t signum, StandardPlural::Form plural) const;
46
47
  private:
48
    ImmutablePatternModifier(ParameterizedModifier* pm, const PluralRules* rules,
49
                             const MicroPropsGenerator* parent);
50
51
    const LocalPointer<ParameterizedModifier> pm;
52
    const PluralRules* rules;
53
    const MicroPropsGenerator* parent;
54
55
    friend class MutablePatternModifier;
56
};
57
58
/**
59
 * This class is a {@link Modifier} that wraps a decimal format pattern. It applies the pattern's affixes in
60
 * {@link Modifier#apply}.
61
 *
62
 * <p>
63
 * In addition to being a Modifier, this class contains the business logic for substituting the correct locale symbols
64
 * into the affixes of the decimal format pattern.
65
 *
66
 * <p>
67
 * In order to use this class, create a new instance and call the following four setters: {@link #setPatternInfo},
68
 * {@link #setPatternAttributes}, {@link #setSymbols}, and {@link #setNumberProperties}. After calling these four
69
 * setters, the instance will be ready for use as a Modifier.
70
 *
71
 * <p>
72
 * This is a MUTABLE, NON-THREAD-SAFE class designed for performance. Do NOT save references to this or attempt to use
73
 * it from multiple threads! Instead, you can obtain a safe, immutable decimal format pattern modifier by calling
74
 * {@link MutablePatternModifier#createImmutable}, in effect treating this instance as a builder for the immutable
75
 * variant.
76
 */
77
class U_I18N_API MutablePatternModifier
78
        : public MicroPropsGenerator,
79
          public Modifier,
80
          public SymbolProvider,
81
          public UMemory {
82
  public:
83
84
0
    ~MutablePatternModifier() U_OVERRIDE = default;
85
86
    /**
87
     * @param isStrong
88
     *            Whether the modifier should be considered strong. For more information, see
89
     *            {@link Modifier#isStrong()}. Most of the time, decimal format pattern modifiers should be considered
90
     *            as non-strong.
91
     */
92
    explicit MutablePatternModifier(bool isStrong);
93
94
    /**
95
     * Sets a reference to the parsed decimal format pattern, usually obtained from
96
     * {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of {@link AffixPatternProvider} is
97
     * accepted.
98
     */
99
    void setPatternInfo(const AffixPatternProvider *patternInfo);
100
101
    /**
102
     * Sets attributes that imply changes to the literal interpretation of the pattern string affixes.
103
     *
104
     * @param signDisplay
105
     *            Whether to force a plus sign on positive numbers.
106
     * @param perMille
107
     *            Whether to substitute the percent sign in the pattern with a permille sign.
108
     */
109
    void setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille);
110
111
    /**
112
     * Sets locale-specific details that affect the symbols substituted into the pattern string affixes.
113
     *
114
     * @param symbols
115
     *            The desired instance of DecimalFormatSymbols.
116
     * @param currencySymbols
117
     *            The currency symbols to be used when substituting currency values into the affixes.
118
     * @param unitWidth
119
     *            The width used to render currencies.
120
     * @param rules
121
     *            Required if the triple currency sign, "¤¤¤", appears in the pattern, which can be determined from the
122
     *            convenience method {@link #needsPlurals()}.
123
     */
124
    void setSymbols(const DecimalFormatSymbols* symbols, const CurrencySymbols* currencySymbols,
125
                    UNumberUnitWidth unitWidth, const PluralRules* rules);
126
127
    /**
128
     * Sets attributes of the current number being processed.
129
     *
130
     * @param signum
131
     *            -1 if negative; +1 if positive; or 0 if zero.
132
     * @param plural
133
     *            The plural form of the number, required only if the pattern contains the triple
134
     *            currency sign, "¤¤¤" (and as indicated by {@link #needsPlurals()}).
135
     */
136
    void setNumberProperties(int8_t signum, StandardPlural::Form plural);
137
138
    /**
139
     * Returns true if the pattern represented by this MurkyModifier requires a plural keyword in order to localize.
140
     * This is currently true only if there is a currency long name placeholder in the pattern ("¤¤¤").
141
     */
142
    bool needsPlurals() const;
143
144
    /**
145
     * Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable
146
     * and can be saved for future use. The number properties in the current instance are mutated; all other properties
147
     * are left untouched.
148
     *
149
     * <p>
150
     * The resulting modifier cannot be used in a QuantityChain.
151
     *
152
     * <p>
153
     * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
154
     *
155
     * @return An immutable that supports both positive and negative numbers.
156
     */
157
    ImmutablePatternModifier *createImmutable(UErrorCode &status);
158
159
    /**
160
     * Creates a new quantity-dependent Modifier that behaves the same as the current instance, but which is immutable
161
     * and can be saved for future use. The number properties in the current instance are mutated; all other properties
162
     * are left untouched.
163
     *
164
     * <p>
165
     * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
166
     *
167
     * @param parent
168
     *            The QuantityChain to which to chain this immutable.
169
     * @return An immutable that supports both positive and negative numbers.
170
     */
171
    ImmutablePatternModifier *
172
    createImmutableAndChain(const MicroPropsGenerator *parent, UErrorCode &status);
173
174
    MicroPropsGenerator &addToChain(const MicroPropsGenerator *parent);
175
176
    void processQuantity(DecimalQuantity &, MicroProps &micros, UErrorCode &status) const U_OVERRIDE;
177
178
    int32_t apply(NumberStringBuilder &output, int32_t leftIndex, int32_t rightIndex,
179
                  UErrorCode &status) const U_OVERRIDE;
180
181
    int32_t getPrefixLength(UErrorCode &status) const U_OVERRIDE;
182
183
    int32_t getCodePointCount(UErrorCode &status) const U_OVERRIDE;
184
185
    bool isStrong() const U_OVERRIDE;
186
187
    /**
188
     * Returns the string that substitutes a given symbol type in a pattern.
189
     */
190
    UnicodeString getSymbol(AffixPatternType type) const U_OVERRIDE;
191
192
    UnicodeString toUnicodeString() const;
193
194
  private:
195
    // Modifier details (initialized in constructor)
196
    const bool fStrong;
197
198
    // Pattern details (initialized in setPatternInfo and setPatternAttributes)
199
    const AffixPatternProvider *patternInfo;
200
    UNumberSignDisplay signDisplay;
201
    bool perMilleReplacesPercent;
202
203
    // Symbol details (initialized in setSymbols)
204
    const DecimalFormatSymbols *symbols;
205
    UNumberUnitWidth unitWidth;
206
    const CurrencySymbols *currencySymbols;
207
    const PluralRules *rules;
208
209
    // Number details (initialized in setNumberProperties)
210
    int8_t signum;
211
    StandardPlural::Form plural;
212
213
    // QuantityChain details (initialized in addToChain)
214
    const MicroPropsGenerator *parent;
215
216
    // Transient fields for rendering
217
    UnicodeString currentAffix;
218
219
    /**
220
     * Uses the current properties to create a single {@link ConstantMultiFieldModifier} with currency spacing support
221
     * if required.
222
     *
223
     * <p>
224
     * CREATES A NEW HEAP OBJECT; THE CALLER GETS OWNERSHIP.
225
     *
226
     * @param a
227
     *            A working NumberStringBuilder object; passed from the outside to prevent the need to create many new
228
     *            instances if this method is called in a loop.
229
     * @param b
230
     *            Another working NumberStringBuilder object.
231
     * @return The constant modifier object.
232
     */
233
    ConstantMultiFieldModifier *createConstantModifier(UErrorCode &status);
234
235
    int32_t insertPrefix(NumberStringBuilder &sb, int position, UErrorCode &status);
236
237
    int32_t insertSuffix(NumberStringBuilder &sb, int position, UErrorCode &status);
238
239
    void prepareAffix(bool isPrefix);
240
};
241
242
243
}  // namespace impl
244
}  // namespace number
245
U_NAMESPACE_END
246
247
#endif //__NUMBER_PATTERNMODIFIER_H__
248
249
#endif /* #if !UCONFIG_NO_FORMATTING */