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