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