summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/i18n/unicode/formattedvalue.h
blob: 5febea066180a01978cdbab135d22d1d62073f74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#ifndef __FORMATTEDVALUE_H__
#define __FORMATTEDVALUE_H__

#include "unicode/utypes.h"

#if U_SHOW_CPLUSPLUS_API

#if !UCONFIG_NO_FORMATTING

#include "unicode/appendable.h"
#include "unicode/fpositer.h"
#include "unicode/unistr.h"
#include "unicode/uformattedvalue.h"

U_NAMESPACE_BEGIN

/**
 * \file
 * \brief C++ API: Abstract operations for localized strings.
 * 
 * This file contains declarations for classes that deal with formatted strings. A number
 * of APIs throughout ICU use these classes for expressing their localized output.
 */

/**
 * Represents a span of a string containing a given field.
 *
 * This class differs from FieldPosition in the following ways:
 *
 *   1. It has information on the field category.
 *   2. It allows you to set constraints to use when iterating over field positions.
 *   3. It is used for the newer FormattedValue APIs.
 *
 * This class is not intended for public subclassing.
 *
 * @stable ICU 64
 */
class U_I18N_API ConstrainedFieldPosition : public UMemory {
  public:

    /**
     * Initializes a ConstrainedFieldPosition.
     *
     * By default, the ConstrainedFieldPosition has no iteration constraints.
     *
     * @stable ICU 64
     */
    ConstrainedFieldPosition();

    /** @stable ICU 64 */
    ~ConstrainedFieldPosition();

    /**
     * Resets this ConstrainedFieldPosition to its initial state, as if it were newly created:
     *
     * - Removes any constraints that may have been set on the instance.
     * - Resets the iteration position.
     *
     * @stable ICU 64
     */
    void reset();

    /**
     * Sets a constraint on the field category.
     * 
     * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition,
     * positions are skipped unless they have the given category.
     *
     * Any previously set constraints are cleared.
     *
     * For example, to loop over only the number-related fields:
     *
     *     ConstrainedFieldPosition cfpos;
     *     cfpos.constrainCategory(UFIELDCATEGORY_NUMBER_FORMAT);
     *     while (fmtval.nextPosition(cfpos, status)) {
     *         // handle the number-related field position
     *     }
     *
     * Changing the constraint while in the middle of iterating over a FormattedValue
     * does not generally have well-defined behavior.
     *
     * @param category The field category to fix when iterating.
     * @stable ICU 64
     */
    void constrainCategory(int32_t category);

    /**
     * Sets a constraint on the category and field.
     * 
     * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition,
     * positions are skipped unless they have the given category and field.
     *
     * Any previously set constraints are cleared.
     *
     * For example, to loop over all grouping separators:
     *
     *     ConstrainedFieldPosition cfpos;
     *     cfpos.constrainField(UFIELDCATEGORY_NUMBER_FORMAT, UNUM_GROUPING_SEPARATOR_FIELD);
     *     while (fmtval.nextPosition(cfpos, status)) {
     *         // handle the grouping separator position
     *     }
     *
     * Changing the constraint while in the middle of iterating over a FormattedValue
     * does not generally have well-defined behavior.
     *
     * @param category The field category to fix when iterating.
     * @param field The field to fix when iterating.
     * @stable ICU 64
     */
    void constrainField(int32_t category, int32_t field);

    /**
     * Gets the field category for the current position.
     *
     * The return value is well-defined only after
     * FormattedValue#nextPosition returns true.
     *
     * @return The field category saved in the instance.
     * @stable ICU 64
     */
    inline int32_t getCategory() const {
        return fCategory;
    }

    /**
     * Gets the field for the current position.
     *
     * The return value is well-defined only after
     * FormattedValue#nextPosition returns true.
     *
     * @return The field saved in the instance.
     * @stable ICU 64
     */
    inline int32_t getField() const {
        return fField;
    }

    /**
     * Gets the INCLUSIVE start index for the current position.
     *
     * The return value is well-defined only after FormattedValue#nextPosition returns true.
     *
     * @return The start index saved in the instance.
     * @stable ICU 64
     */
    inline int32_t getStart() const {
        return fStart;
    }

    /**
     * Gets the EXCLUSIVE end index stored for the current position.
     *
     * The return value is well-defined only after FormattedValue#nextPosition returns true.
     *
     * @return The end index saved in the instance.
     * @stable ICU 64
     */
    inline int32_t getLimit() const {
        return fLimit;
    }

    ////////////////////////////////////////////////////////////////////
    //// The following methods are for FormattedValue implementers; ////
    //// most users can ignore them.                                ////
    ////////////////////////////////////////////////////////////////////

    /**
     * Gets an int64 that FormattedValue implementations may use for storage.
     *
     * The initial value is zero.
     *
     * Users of FormattedValue should not need to call this method.
     *
     * @return The current iteration context from {@link #setInt64IterationContext}.
     * @stable ICU 64
     */
    inline int64_t getInt64IterationContext() const {
        return fContext;
    }

    /**
     * Sets an int64 that FormattedValue implementations may use for storage.
     *
     * Intended to be used by FormattedValue implementations.
     *
     * @param context The new iteration context.
     * @stable ICU 64
     */
    void setInt64IterationContext(int64_t context);

    /**
     * Determines whether a given field should be included given the
     * constraints.
     *
     * Intended to be used by FormattedValue implementations.
     *
     * @param category The category to test.
     * @param field The field to test.
     * @stable ICU 64
     */
    UBool matchesField(int32_t category, int32_t field) const;

    /**
     * Sets new values for the primary public getters.
     *
     * Intended to be used by FormattedValue implementations.
     *
     * It is up to the implementation to ensure that the user-requested
     * constraints are satisfied. This method does not check!
     *
     * @param category The new field category.
     * @param field The new field.
     * @param start The new inclusive start index.
     * @param limit The new exclusive end index.
     * @stable ICU 64
     */
    void setState(
        int32_t category,
        int32_t field,
        int32_t start,
        int32_t limit);

  private:
    int64_t fContext = 0LL;
    int32_t fField = 0;
    int32_t fStart = 0;
    int32_t fLimit = 0;
    int32_t fCategory = UFIELD_CATEGORY_UNDEFINED;
    int8_t fConstraint = 0;
};

/**
 * An abstract formatted value: a string with associated field attributes.
 * Many formatters format to classes implementing FormattedValue.
 *
 * @stable ICU 64
 */
class U_I18N_API FormattedValue /* not : public UObject because this is an interface/mixin class */ {
  public:
    /** @stable ICU 64 */
    virtual ~FormattedValue();

    /**
     * Returns the formatted string as a self-contained UnicodeString.
     *
     * If you need the string within the current scope only, consider #toTempString.
     *
     * @param status Set if an error occurs.
     * @return a UnicodeString containing the formatted string.
     *
     * @stable ICU 64
     */
    virtual UnicodeString toString(UErrorCode& status) const = 0;

    /**
     * Returns the formatted string as a read-only alias to memory owned by the FormattedValue.
     *
     * The return value is valid only as long as this FormattedValue is present and unchanged in
     * memory. If you need the string outside the current scope, consider #toString.
     *
     * The buffer returned by calling UnicodeString#getBuffer() on the return value is
     * guaranteed to be NUL-terminated.
     *
     * @param status Set if an error occurs.
     * @return a temporary UnicodeString containing the formatted string.
     *
     * @stable ICU 64
     */
    virtual UnicodeString toTempString(UErrorCode& status) const = 0;

    /**
     * Appends the formatted string to an Appendable.
     *
     * @param appendable
     *         The Appendable to which to append the string output.
     * @param status Set if an error occurs.
     * @return The same Appendable, for chaining.
     *
     * @stable ICU 64
     * @see Appendable
     */
    virtual Appendable& appendTo(Appendable& appendable, UErrorCode& status) const = 0;

    /**
     * Iterates over field positions in the FormattedValue. This lets you determine the position
     * of specific types of substrings, like a month or a decimal separator.
     *
     * To loop over all field positions:
     *
     *     ConstrainedFieldPosition cfpos;
     *     while (fmtval.nextPosition(cfpos, status)) {
     *         // handle the field position; get information from cfpos
     *     }
     *
     * @param cfpos
     *         The object used for iteration state. This can provide constraints to iterate over
     *         only one specific category or field;
     *         see ConstrainedFieldPosition#constrainCategory
     *         and ConstrainedFieldPosition#constrainField.
     * @param status Set if an error occurs.
     * @return true if a new occurrence of the field was found;
     *         false otherwise or if an error was set.
     *
     * @stable ICU 64
     */
    virtual UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const = 0;
};

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif /* U_SHOW_CPLUSPLUS_API */

#endif // __FORMATTEDVALUE_H__