Coverage Report

Created: 2025-06-24 06:43

/src/icu/source/i18n/number_formatimpl.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_FORMATIMPL_H__
8
#define __NUMBER_FORMATIMPL_H__
9
10
#include "number_types.h"
11
#include "formatted_string_builder.h"
12
#include "number_patternstring.h"
13
#include "number_usageprefs.h"
14
#include "number_utils.h"
15
#include "number_patternmodifier.h"
16
#include "number_longnames.h"
17
#include "number_compact.h"
18
#include "number_microprops.h"
19
#include "number_utypes.h"
20
21
U_NAMESPACE_BEGIN namespace number {
22
namespace impl {
23
24
/**
25
 * This is the "brain" of the number formatting pipeline. It ties all the pieces together, taking in a MacroProps and a
26
 * DecimalQuantity and outputting a properly formatted number string.
27
 */
28
class NumberFormatterImpl : public UMemory {
29
  public:
30
    /**
31
     * Builds a "safe" MicroPropsGenerator, which is thread-safe and can be used repeatedly.
32
     * The caller owns the returned NumberFormatterImpl.
33
     */
34
    NumberFormatterImpl(const MacroProps &macros, UErrorCode &status);
35
36
    /**
37
     * Default constructor; leaves the NumberFormatterImpl in an undefined state.
38
     * Takes an error code to prevent the method from being called accidentally.
39
     */
40
0
    NumberFormatterImpl(UErrorCode &) {}
41
42
    /**
43
     * Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper but can be used only once.
44
     */
45
    static int32_t formatStatic(const MacroProps &macros, UFormattedNumberData *results,
46
                                UErrorCode &status);
47
48
    /**
49
     * Prints only the prefix and suffix; used for DecimalFormat getters.
50
     *
51
     * @return The index into the output at which the prefix ends and the suffix starts; in other words,
52
     *         the prefix length.
53
     */
54
    static int32_t getPrefixSuffixStatic(const MacroProps& macros, Signum signum,
55
                                         StandardPlural::Form plural, FormattedStringBuilder& outString,
56
                                         UErrorCode& status);
57
58
    /**
59
     * Evaluates the "safe" MicroPropsGenerator created by "fromMacros".
60
     */
61
    int32_t format(UFormattedNumberData *results, UErrorCode &status) const;
62
63
    /**
64
     * Like format(), but saves the result into an output MicroProps without additional processing.
65
     */
66
    void preProcess(DecimalQuantity& inValue, MicroProps& microsOut, UErrorCode& status) const;
67
68
    /**
69
     * Like getPrefixSuffixStatic() but uses the safe compiled object.
70
     */
71
    int32_t getPrefixSuffix(Signum signum, StandardPlural::Form plural, FormattedStringBuilder& outString,
72
                            UErrorCode& status) const;
73
74
0
    const MicroProps& getRawMicroProps() const {
75
0
        return fMicros;
76
0
    }
77
78
    /**
79
     * Synthesizes the output string from a MicroProps and DecimalQuantity.
80
     * This method formats only the main number, not affixes.
81
     */
82
    static int32_t writeNumber(const MicroProps& micros, DecimalQuantity& quantity,
83
                               FormattedStringBuilder& string, int32_t index, UErrorCode& status);
84
85
    /**
86
     * Adds the affixes.  Intended to be called immediately after formatNumber.
87
     */
88
    static int32_t writeAffixes(const MicroProps& micros, FormattedStringBuilder& string, int32_t start,
89
                                int32_t end, UErrorCode& status);
90
91
  private:
92
    // Head of the MicroPropsGenerator linked list. Subclasses' processQuantity
93
    // methods process this list in a parent-first order, such that the last
94
    // item added, which this points to, typically has its logic executed last.
95
    const MicroPropsGenerator *fMicroPropsGenerator = nullptr;
96
97
    // Tail of the list:
98
    MicroProps fMicros;
99
100
    // Other fields possibly used by the number formatting pipeline:
101
    // TODO: Convert more of these LocalPointers to value objects to reduce the number of news?
102
    LocalPointer<const UsagePrefsHandler> fUsagePrefsHandler;
103
    LocalPointer<const UnitConversionHandler> fUnitConversionHandler;
104
    LocalPointer<const DecimalFormatSymbols> fSymbols;
105
    LocalPointer<const PluralRules> fRules;
106
    LocalPointer<const ParsedPatternInfo> fPatternInfo;
107
    LocalPointer<const ScientificHandler> fScientificHandler;
108
    LocalPointer<MutablePatternModifier> fPatternModifier;
109
    LocalPointer<ImmutablePatternModifier> fImmutablePatternModifier;
110
    LocalPointer<LongNameHandler> fLongNameHandler;
111
    // TODO: use a common base class that enables fLongNameHandler,
112
    // fLongNameMultiplexer, and fMixedUnitLongNameHandler to be merged into one
113
    // member?
114
    LocalPointer<MixedUnitLongNameHandler> fMixedUnitLongNameHandler;
115
    LocalPointer<const LongNameMultiplexer> fLongNameMultiplexer;
116
    LocalPointer<const CompactHandler> fCompactHandler;
117
118
    // Value objects possibly used by the number formatting pipeline:
119
    struct Warehouse {
120
        CurrencySymbols fCurrencySymbols;
121
    } fWarehouse;
122
123
124
    NumberFormatterImpl(const MacroProps &macros, bool safe, UErrorCode &status);
125
126
    MicroProps& preProcessUnsafe(DecimalQuantity &inValue, UErrorCode &status);
127
128
    int32_t getPrefixSuffixUnsafe(Signum signum, StandardPlural::Form plural,
129
                                  FormattedStringBuilder& outString, UErrorCode& status);
130
131
    /**
132
     * If rulesPtr is non-null, return it.  Otherwise, return a PluralRules owned by this object for the
133
     * specified locale, creating it if necessary.
134
     */
135
    const PluralRules *
136
    resolvePluralRules(const PluralRules *rulesPtr, const Locale &locale, UErrorCode &status);
137
138
    /**
139
     * Synthesizes the MacroProps into a MicroPropsGenerator. All information, including the locale, is encoded into the
140
     * MicroPropsGenerator, except for the quantity itself, which is left abstract and must be provided to the returned
141
     * MicroPropsGenerator instance.
142
     *
143
     * @see MicroPropsGenerator
144
     * @param macros
145
     *            The {@link MacroProps} to consume. This method does not mutate the MacroProps instance.
146
     * @param safe
147
     *            If true, the returned MicroPropsGenerator will be thread-safe. If false, the returned value will
148
     *            <em>not</em> be thread-safe, intended for a single "one-shot" use only. Building the thread-safe
149
     *            object is more expensive.
150
     */
151
    const MicroPropsGenerator *
152
    macrosToMicroGenerator(const MacroProps &macros, bool safe, UErrorCode &status);
153
154
    static int32_t
155
    writeIntegerDigits(const MicroProps &micros, DecimalQuantity &quantity, FormattedStringBuilder &string,
156
                       int32_t index, UErrorCode &status);
157
158
    static int32_t
159
    writeFractionDigits(const MicroProps &micros, DecimalQuantity &quantity, FormattedStringBuilder &string,
160
                        int32_t index, UErrorCode &status);
161
};
162
163
}  // namespace impl
164
}  // namespace number
165
U_NAMESPACE_END
166
167
168
#endif //__NUMBER_FORMATIMPL_H__
169
170
#endif /* #if !UCONFIG_NO_FORMATTING */