1// © 2018 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3
4#ifndef __FORMATTEDVALUE_H__
5#define __FORMATTEDVALUE_H__
6
7#include "unicode/utypes.h"
8
9#if U_SHOW_CPLUSPLUS_API
10
11#if !UCONFIG_NO_FORMATTING
12
13#include "unicode/appendable.h"
14#include "unicode/fpositer.h"
15#include "unicode/unistr.h"
16#include "unicode/uformattedvalue.h"
17
18U_NAMESPACE_BEGIN
19
20/**
21 * \file
22 * \brief C++ API: Abstract operations for localized strings.
23 *
24 * This file contains declarations for classes that deal with formatted strings. A number
25 * of APIs throughout ICU use these classes for expressing their localized output.
26 */
27
28
29// The following cannot have #ifndef U_HIDE_DRAFT_API because
30// class FormattedValue depends on it, and FormattedValue cannot be
31// hidden becauseclass FormattedNumber (stable ICU 60) depends on it.
32#ifndef U_FORCE_HIDE_DRAFT_API
33/**
34 * Represents a span of a string containing a given field.
35 *
36 * This class differs from FieldPosition in the following ways:
37 *
38 * 1. It has information on the field category.
39 * 2. It allows you to set constraints to use when iterating over field positions.
40 * 3. It is used for the newer FormattedValue APIs.
41 *
42 * This class is not intended for public subclassing.
43 *
44 * @draft ICU 64
45 */
46class U_I18N_API ConstrainedFieldPosition : public UMemory {
47 public:
48
49 /**
50 * Initializes a ConstrainedFieldPosition.
51 *
52 * By default, the ConstrainedFieldPosition has no iteration constraints.
53 *
54 * @draft ICU 64
55 */
56 ConstrainedFieldPosition();
57
58 /** @draft ICU 64 */
59 ~ConstrainedFieldPosition();
60
61#ifndef U_HIDE_DRAFT_API
62 /**
63 * Resets this ConstrainedFieldPosition to its initial state, as if it were newly created:
64 *
65 * - Removes any constraints that may have been set on the instance.
66 * - Resets the iteration position.
67 *
68 * @draft ICU 64
69 */
70 void reset();
71
72 /**
73 * Sets a constraint on the field category.
74 *
75 * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition,
76 * positions are skipped unless they have the given category.
77 *
78 * Any previously set constraints are cleared.
79 *
80 * For example, to loop over only the number-related fields:
81 *
82 * ConstrainedFieldPosition cfpos;
83 * cfpos.constrainCategory(UFIELDCATEGORY_NUMBER_FORMAT);
84 * while (fmtval.nextPosition(cfpos, status)) {
85 * // handle the number-related field position
86 * }
87 *
88 * Changing the constraint while in the middle of iterating over a FormattedValue
89 * does not generally have well-defined behavior.
90 *
91 * @param category The field category to fix when iterating.
92 * @draft ICU 64
93 */
94 void constrainCategory(int32_t category);
95
96 /**
97 * Sets a constraint on the category and field.
98 *
99 * When this instance of ConstrainedFieldPosition is passed to FormattedValue#nextPosition,
100 * positions are skipped unless they have the given category and field.
101 *
102 * Any previously set constraints are cleared.
103 *
104 * For example, to loop over all grouping separators:
105 *
106 * ConstrainedFieldPosition cfpos;
107 * cfpos.constrainField(UFIELDCATEGORY_NUMBER_FORMAT, UNUM_GROUPING_SEPARATOR_FIELD);
108 * while (fmtval.nextPosition(cfpos, status)) {
109 * // handle the grouping separator position
110 * }
111 *
112 * Changing the constraint while in the middle of iterating over a FormattedValue
113 * does not generally have well-defined behavior.
114 *
115 * @param category The field category to fix when iterating.
116 * @param field The field to fix when iterating.
117 * @draft ICU 64
118 */
119 void constrainField(int32_t category, int32_t field);
120
121 /**
122 * Gets the field category for the current position.
123 *
124 * The return value is well-defined only after
125 * FormattedValue#nextPosition returns TRUE.
126 *
127 * @return The field category saved in the instance.
128 * @draft ICU 64
129 */
130 inline int32_t getCategory() const {
131 return fCategory;
132 }
133
134 /**
135 * Gets the field for the current position.
136 *
137 * The return value is well-defined only after
138 * FormattedValue#nextPosition returns TRUE.
139 *
140 * @return The field saved in the instance.
141 * @draft ICU 64
142 */
143 inline int32_t getField() const {
144 return fField;
145 }
146
147 /**
148 * Gets the INCLUSIVE start index for the current position.
149 *
150 * The return value is well-defined only after FormattedValue#nextPosition returns TRUE.
151 *
152 * @return The start index saved in the instance.
153 * @draft ICU 64
154 */
155 inline int32_t getStart() const {
156 return fStart;
157 }
158
159 /**
160 * Gets the EXCLUSIVE end index stored for the current position.
161 *
162 * The return value is well-defined only after FormattedValue#nextPosition returns TRUE.
163 *
164 * @return The end index saved in the instance.
165 * @draft ICU 64
166 */
167 inline int32_t getLimit() const {
168 return fLimit;
169 }
170
171 ////////////////////////////////////////////////////////////////////
172 //// The following methods are for FormattedValue implementers; ////
173 //// most users can ignore them. ////
174 ////////////////////////////////////////////////////////////////////
175
176 /**
177 * Gets an int64 that FormattedValue implementations may use for storage.
178 *
179 * The initial value is zero.
180 *
181 * Users of FormattedValue should not need to call this method.
182 *
183 * @return The current iteration context from {@link #setInt64IterationContext}.
184 * @draft ICU 64
185 */
186 inline int64_t getInt64IterationContext() const {
187 return fContext;
188 }
189
190 /**
191 * Sets an int64 that FormattedValue implementations may use for storage.
192 *
193 * Intended to be used by FormattedValue implementations.
194 *
195 * @param context The new iteration context.
196 * @draft ICU 64
197 */
198 void setInt64IterationContext(int64_t context);
199
200 /**
201 * Determines whether a given field should be included given the
202 * constraints.
203 *
204 * Intended to be used by FormattedValue implementations.
205 *
206 * @param category The category to test.
207 * @param field The field to test.
208 * @draft ICU 64
209 */
210 UBool matchesField(int32_t category, int32_t field) const;
211
212 /**
213 * Sets new values for the primary public getters.
214 *
215 * Intended to be used by FormattedValue implementations.
216 *
217 * It is up to the implementation to ensure that the user-requested
218 * constraints are satisfied. This method does not check!
219 *
220 * @param category The new field category.
221 * @param field The new field.
222 * @param start The new inclusive start index.
223 * @param limit The new exclusive end index.
224 * @draft ICU 64
225 */
226 void setState(
227 int32_t category,
228 int32_t field,
229 int32_t start,
230 int32_t limit);
231#endif /* U_HIDE_DRAFT_API */
232
233 private:
234 int64_t fContext = 0LL;
235 int32_t fField = 0;
236 int32_t fStart = 0;
237 int32_t fLimit = 0;
238#ifndef U_HIDE_DRAFT_API
239 int32_t fCategory = UFIELD_CATEGORY_UNDEFINED;
240#else /* U_HIDE_DRAFT_API */
241 int32_t fCategory = 0;
242#endif /* U_HIDE_DRAFT_API */
243 int8_t fConstraint = 0;
244};
245
246// The following cannot have #ifndef U_HIDE_DRAFT_API because
247// class FormattedNumber (stable ICU 60) depends on it.
248/**
249 * An abstract formatted value: a string with associated field attributes.
250 * Many formatters format to classes implementing FormattedValue.
251 *
252 * @draft ICU 64
253 */
254class U_I18N_API FormattedValue /* not : public UObject because this is an interface/mixin class */ {
255 public:
256 /** @draft ICU 64 */
257 virtual ~FormattedValue();
258
259 /**
260 * Returns the formatted string as a self-contained UnicodeString.
261 *
262 * If you need the string within the current scope only, consider #toTempString.
263 *
264 * @param status Set if an error occurs.
265 * @return a UnicodeString containing the formatted string.
266 *
267 * @draft ICU 64
268 */
269 virtual UnicodeString toString(UErrorCode& status) const = 0;
270
271 /**
272 * Returns the formatted string as a read-only alias to memory owned by the FormattedValue.
273 *
274 * The return value is valid only as long as this FormattedValue is present and unchanged in
275 * memory. If you need the string outside the current scope, consider #toString.
276 *
277 * The buffer returned by calling UnicodeString#getBuffer() on the return value is
278 * guaranteed to be NUL-terminated.
279 *
280 * @param status Set if an error occurs.
281 * @return a temporary UnicodeString containing the formatted string.
282 *
283 * @draft ICU 64
284 */
285 virtual UnicodeString toTempString(UErrorCode& status) const = 0;
286
287 /**
288 * Appends the formatted string to an Appendable.
289 *
290 * @param appendable
291 * The Appendable to which to append the string output.
292 * @param status Set if an error occurs.
293 * @return The same Appendable, for chaining.
294 *
295 * @draft ICU 64
296 * @see Appendable
297 */
298 virtual Appendable& appendTo(Appendable& appendable, UErrorCode& status) const = 0;
299
300 /**
301 * Iterates over field positions in the FormattedValue. This lets you determine the position
302 * of specific types of substrings, like a month or a decimal separator.
303 *
304 * To loop over all field positions:
305 *
306 * ConstrainedFieldPosition cfpos;
307 * while (fmtval.nextPosition(cfpos, status)) {
308 * // handle the field position; get information from cfpos
309 * }
310 *
311 * @param cfpos
312 * The object used for iteration state. This can provide constraints to iterate over
313 * only one specific category or field;
314 * see ConstrainedFieldPosition#constrainCategory
315 * and ConstrainedFieldPosition#constrainField.
316 * @param status Set if an error occurs.
317 * @return TRUE if a new occurrence of the field was found;
318 * FALSE otherwise or if an error was set.
319 *
320 * @draft ICU 64
321 */
322 virtual UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const = 0;
323};
324#endif // U_FORCE_HIDE_DRAFT_API
325
326U_NAMESPACE_END
327
328#endif /* #if !UCONFIG_NO_FORMATTING */
329
330#endif /* U_SHOW_CPLUSPLUS_API */
331
332#endif // __FORMATTEDVALUE_H__
333