messageformat2_formattable.h (40310B)
1 // © 2024 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 #ifndef MESSAGEFORMAT2_FORMATTABLE_H 7 #define MESSAGEFORMAT2_FORMATTABLE_H 8 9 #if U_SHOW_CPLUSPLUS_API 10 11 #if !UCONFIG_NO_NORMALIZATION 12 13 #if !UCONFIG_NO_FORMATTING 14 15 #if !UCONFIG_NO_MF2 16 17 #include "unicode/chariter.h" 18 #include "unicode/numberformatter.h" 19 #include "unicode/messageformat2_data_model_names.h" 20 #include "unicode/smpdtfmt.h" 21 22 #ifndef U_HIDE_DEPRECATED_API 23 24 #include <map> 25 #include <variant> 26 27 U_NAMESPACE_BEGIN 28 29 class Hashtable; 30 class UVector; 31 32 namespace message2 { 33 34 class Formatter; 35 class MessageContext; 36 class Selector; 37 38 // Formattable 39 // ---------- 40 41 /** 42 * `FormattableObject` is an abstract class that can be implemented in order to define 43 * an arbitrary class that can be passed to a custom formatter or selector function. 44 * To be passed in such a way, it must be wrapped in a `Formattable` object. 45 * 46 * @internal ICU 75 technology preview 47 * @deprecated This API is for technology preview only. 48 */ 49 class U_I18N_API FormattableObject : public UObject { 50 public: 51 /** 52 * Returns an arbitrary string representing the type of this object. 53 * It's up to the implementor of this class, as well as the implementors 54 * of any custom functions that rely on particular values of this tag 55 * corresponding to particular classes that the object contents can be 56 * downcast to, to ensure that the type tags are used soundly. 57 * @internal ICU 75 technology preview 58 * @deprecated This API is for technology preview only. 59 */ 60 virtual const UnicodeString& tag() const = 0; 61 /** 62 * Destructor. 63 * 64 * @internal ICU 75 technology preview 65 * @deprecated This API is for technology preview only. 66 */ 67 virtual ~FormattableObject(); 68 }; // class FormattableObject 69 70 /** 71 * The `DateInfo` struct represents all the information needed to 72 * format a date with a time zone. It includes an absolute date and a time zone name, 73 * as well as a calendar name. The calendar name is not currently used. 74 * 75 * @internal ICU 78 technology preview 76 * @deprecated This API is for technology preview only. 77 */ 78 struct U_I18N_API DateInfo { 79 /** 80 * Date in UTC 81 * 82 * @internal ICU 78 technology preview 83 * @deprecated This API is for technology preview only. 84 */ 85 UDate date; 86 /** 87 * IANA time zone name; "UTC" if UTC; empty string if value is floating 88 * The time zone is required in order to format the date/time value 89 * (its offset is added to/subtracted from the datestamp in order to 90 * produce the formatted date). 91 * 92 * @internal ICU 78 technology preview 93 * @deprecated This API is for technology preview only. 94 */ 95 UnicodeString zoneId; 96 }; 97 98 /** 99 * The `Formattable` class represents a typed value that can be formatted, 100 * originating either from a message argument or a literal in the code. 101 * ICU's Formattable class is not used in MessageFormat 2 because it's unsafe to copy an 102 * icu::Formattable value that contains an object. (See ICU-20275). 103 * 104 * `Formattable` is immutable (not deeply immutable) and 105 * is movable and copyable. 106 * (Copying does not do a deep copy when the wrapped value is an array or 107 * object. Likewise, while a pointer to a wrapped array or object is `const`, 108 * the referents of the pointers may be mutated by other code.) 109 * 110 * @internal ICU 75 technology preview 111 * @deprecated This API is for technology preview only. 112 */ 113 class U_I18N_API_CLASS Formattable : public UObject { 114 public: 115 116 /** 117 * Gets the data type of this Formattable object. 118 * @return the data type of this Formattable object. 119 * @internal ICU 75 technology preview 120 * @deprecated This API is for technology preview only. 121 */ 122 U_I18N_API UFormattableType getType() const; 123 124 /** 125 * Gets the double value of this object. If this object is not of type 126 * UFMT_DOUBLE, then the result is undefined and the error code is set. 127 * 128 * @param status Input/output error code. 129 * @return the double value of this object. 130 * @internal ICU 75 technology preview 131 * @deprecated This API is for technology preview only. 132 */ 133 U_I18N_API double getDouble(UErrorCode& status) const { 134 if (U_SUCCESS(status)) { 135 if (isDecimal() && getType() == UFMT_DOUBLE) { 136 return (std::get_if<icu::Formattable>(&contents))->getDouble(); 137 } 138 if (std::holds_alternative<double>(contents)) { 139 return *(std::get_if<double>(&contents)); 140 } 141 status = U_ILLEGAL_ARGUMENT_ERROR; 142 } 143 return 0; 144 } 145 146 /** 147 * Gets the long value of this object. If this object is not of type 148 * UFMT_LONG then the result is undefined and the error code is set. 149 * 150 * @param status Input/output error code. 151 * @return the long value of this object. 152 * @internal ICU 75 technology preview 153 * @deprecated This API is for technology preview only. 154 */ 155 U_I18N_API int32_t getLong(UErrorCode& status) const { 156 if (U_SUCCESS(status)) { 157 if (isDecimal() && getType() == UFMT_LONG) { 158 return std::get_if<icu::Formattable>(&contents)->getLong(); 159 } 160 if (std::holds_alternative<int64_t>(contents)) { 161 return static_cast<int32_t>(*(std::get_if<int64_t>(&contents))); 162 } 163 status = U_ILLEGAL_ARGUMENT_ERROR; 164 } 165 return 0; 166 } 167 168 /** 169 * Gets the int64 value of this object. If this object is not of type 170 * kInt64 then the result is undefined and the error code is set. 171 * If conversion to int64 is desired, call getInt64() 172 * 173 * @param status Input/output error code. 174 * @return the int64 value of this object. 175 * @internal ICU 75 technology preview 176 * @deprecated This API is for technology preview only. 177 */ 178 U_I18N_API int64_t getInt64Value(UErrorCode& status) const { 179 if (U_SUCCESS(status)) { 180 if (isDecimal() && getType() == UFMT_INT64) { 181 return std::get_if<icu::Formattable>(&contents)->getInt64(); 182 } 183 if (std::holds_alternative<int64_t>(contents)) { 184 return *(std::get_if<int64_t>(&contents)); 185 } 186 status = U_ILLEGAL_ARGUMENT_ERROR; 187 } 188 return 0; 189 } 190 191 /** 192 * Gets the int64 value of this object. If this object is of a numeric 193 * type and the magnitude is too large to fit in an int64, then 194 * the maximum or minimum int64 value, as appropriate, is returned 195 * and the status is set to U_INVALID_FORMAT_ERROR. If the 196 * magnitude fits in an int64, then a casting conversion is 197 * performed, with truncation of any fractional part. If this object is 198 * not a numeric type, then 0 is returned and 199 * the status is set to U_INVALID_FORMAT_ERROR. 200 * @param status the error code 201 * @return the int64 value of this object. 202 * @internal ICU 75 technology preview 203 * @deprecated This API is for technology preview only. 204 */ 205 U_I18N_API int64_t getInt64(UErrorCode& status) const; 206 /** 207 * Gets the string value of this object. If this object is not of type 208 * kString then the result is undefined and the error code is set. 209 * 210 * @param status Input/output error code. 211 * @return A reference to the string value of this object. 212 * @internal ICU 75 technology preview 213 * @deprecated This API is for technology preview only. 214 */ 215 U_I18N_API const UnicodeString& getString(UErrorCode& status) const { 216 if (U_SUCCESS(status)) { 217 if (std::holds_alternative<UnicodeString>(contents)) { 218 return *std::get_if<UnicodeString>(&contents); 219 } 220 status = U_ILLEGAL_ARGUMENT_ERROR; 221 } 222 return bogusString; 223 } 224 225 /** 226 * Gets the struct representing the date value of this object. 227 * If this object is not of type kDate then the result is 228 * undefined and the error code is set. 229 * 230 * @param status Input/output error code. 231 * @return A non-owned pointer to a DateInfo object 232 * representing the underlying date of this object. 233 * @internal ICU 75 technology preview 234 * @deprecated This API is for technology preview only. 235 */ 236 U_I18N_API const DateInfo* getDate(UErrorCode& status) const { 237 if (U_SUCCESS(status)) { 238 if (isDate()) { 239 return std::get_if<DateInfo>(&contents); 240 } 241 status = U_ILLEGAL_ARGUMENT_ERROR; 242 } 243 return nullptr; 244 } 245 246 /** 247 * Returns true if the data type of this Formattable object 248 * is kDouble 249 * @return true if this is a pure numeric object 250 * @internal ICU 75 technology preview 251 * @deprecated This API is for technology preview only. 252 */ 253 U_I18N_API UBool isNumeric() const { return (getType() == UFMT_DOUBLE || getType() == UFMT_LONG || getType() == UFMT_INT64); } 254 255 /** 256 * Gets the array value and count of this object. If this object 257 * is not of type kArray then the result is undefined and the error code is set. 258 * 259 * @param count fill-in with the count of this object. 260 * @param status Input/output error code. 261 * @return the array value of this object. 262 * @internal ICU 75 technology preview 263 * @deprecated This API is for technology preview only. 264 */ 265 U_I18N_API const Formattable* getArray(int32_t& count, UErrorCode& status) const; 266 267 /** 268 * Returns a pointer to the FormattableObject contained within this 269 * formattable, or if this object does not contain a FormattableObject, 270 * returns nullptr and sets the error code. 271 * 272 * @param status Input/output error code. 273 * @return a FormattableObject pointer, or nullptr 274 * @internal ICU 75 technology preview 275 * @deprecated This API is for technology preview only. 276 */ 277 U_I18N_API const FormattableObject* getObject(UErrorCode& status) const { 278 if (U_SUCCESS(status)) { 279 // Can't return a reference since FormattableObject 280 // is an abstract class 281 if (getType() == UFMT_OBJECT) { 282 return *std::get_if<const FormattableObject*>(&contents); 283 // TODO: should assert that if type is object, object is non-null 284 } 285 status = U_ILLEGAL_ARGUMENT_ERROR; 286 } 287 return nullptr; 288 } 289 /** 290 * Non-member swap function. 291 * @param f1 will get f2's contents 292 * @param f2 will get f1's contents 293 * 294 * @internal ICU 75 technology preview 295 * @deprecated This API is for technology preview only. 296 */ 297 U_I18N_API friend inline void swap(Formattable& f1, Formattable& f2) noexcept { 298 using std::swap; 299 300 swap(f1.contents, f2.contents); 301 } 302 /** 303 * Copy constructor. 304 * 305 * @internal ICU 75 technology preview 306 * @deprecated This API is for technology preview only. 307 */ 308 U_I18N_API Formattable(const Formattable&); 309 /** 310 * Assignment operator 311 * 312 * @internal ICU 75 technology preview 313 * @deprecated This API is for technology preview only. 314 */ 315 U_I18N_API Formattable& operator=(Formattable) noexcept; 316 /** 317 * Default constructor. Leaves the Formattable in a 318 * valid but undefined state. 319 * 320 * @internal ICU 75 technology preview 321 * @deprecated This API is for technology preview only. 322 */ 323 U_I18N_API Formattable() : contents(0.0) {} 324 /** 325 * String constructor. 326 * 327 * @param s A string to wrap as a Formattable. 328 * 329 * @internal ICU 75 technology preview 330 * @deprecated This API is for technology preview only. 331 */ 332 U_I18N_API Formattable(const UnicodeString& s) : contents(s) {} 333 /** 334 * Double constructor. 335 * 336 * @param d A double value to wrap as a Formattable. 337 * 338 * @internal ICU 75 technology preview 339 * @deprecated This API is for technology preview only. 340 */ 341 U_I18N_API Formattable(double d) : contents(d) {} 342 /** 343 * Int64 constructor. 344 * 345 * @param i An int64 value to wrap as a Formattable. 346 * 347 * @internal ICU 75 technology preview 348 * @deprecated This API is for technology preview only. 349 */ 350 U_I18N_API Formattable(int64_t i) : contents(i) {} 351 /** 352 * Date constructor. 353 * 354 * @param d A DateInfo struct representing a date, 355 * to wrap as a Formattable. 356 * Passed by move 357 * @internal ICU 75 technology preview 358 * @deprecated This API is for technology preview only. 359 */ 360 U_I18N_API Formattable(DateInfo&& d) : contents(std::move(d)) {} 361 /** 362 * Creates a Formattable object of an appropriate numeric type from a 363 * a decimal number in string form. The Formattable will retain the 364 * full precision of the input in decimal format, even when it exceeds 365 * what can be represented by a double or int64_t. 366 * 367 * @param number the unformatted (not localized) string representation 368 * of the Decimal number. 369 * @param status the error code. Possible errors include U_INVALID_FORMAT_ERROR 370 * if the format of the string does not conform to that of a 371 * decimal number. 372 * @internal ICU 75 technology preview 373 * @deprecated This API is for technology preview only. 374 */ 375 U_I18N_API static Formattable forDecimal(std::string_view number, UErrorCode& status); 376 /** 377 * Array constructor. 378 * 379 * @param arr An array of Formattables, which is adopted. 380 * @param len The length of the array. 381 * 382 * @internal ICU 75 technology preview 383 * @deprecated This API is for technology preview only. 384 */ 385 U_I18N_API Formattable(const Formattable* arr, int32_t len) : contents(std::pair(arr, len)) {} 386 /** 387 * Object constructor. 388 * 389 * @param obj A FormattableObject (not adopted). 390 * 391 * @internal ICU 75 technology preview 392 * @deprecated This API is for technology preview only. 393 */ 394 U_I18N_API Formattable(const FormattableObject* obj) : contents(obj) {} 395 /** 396 * Destructor. 397 * 398 * @internal ICU 75 technology preview 399 * @deprecated This API is for technology preview only. 400 */ 401 U_I18N_API virtual ~Formattable(); 402 /** 403 * Converts the Formattable object to an ICU Formattable object. 404 * If this has type UFMT_OBJECT or kArray, then `status` is set to 405 * U_ILLEGAL_ARGUMENT_ERROR. 406 * 407 * @param status Input/output error code. 408 * @return An icu::Formattable value with the same value as this. 409 * 410 * @internal ICU 75 technology preview 411 * @deprecated This API is for technology preview only. 412 */ 413 U_I18N_API icu::Formattable asICUFormattable(UErrorCode& status) const; 414 private: 415 416 std::variant<double, 417 int64_t, 418 UnicodeString, 419 icu::Formattable, // represents a Decimal 420 DateInfo, 421 const FormattableObject*, 422 std::pair<const Formattable*, int32_t>> contents; 423 UnicodeString bogusString; // :(((( 424 425 UBool isDecimal() const { 426 return std::holds_alternative<icu::Formattable>(contents); 427 } 428 UBool isDate() const { 429 return std::holds_alternative<DateInfo>(contents); 430 } 431 }; // class Formattable 432 433 /** 434 * Internal use only, but has to be included here as part of the implementation 435 * of the header-only `FunctionOptions::getOptions()` method 436 * 437 * A `ResolvedFunctionOption` represents the result of evaluating 438 * a single named function option. It pairs the given name with the `Formattable` 439 * value resulting from evaluating the option's value. 440 * 441 * `ResolvedFunctionOption` is immutable and is not copyable or movable. 442 * 443 * @internal ICU 75 technology preview 444 * @deprecated This API is for technology preview only. 445 */ 446 #ifndef U_IN_DOXYGEN 447 class U_I18N_API_CLASS ResolvedFunctionOption : public UObject { 448 private: 449 450 /* const */ UnicodeString name; 451 /* const */ Formattable value; 452 // True iff this option was represented in the syntax by a literal value. 453 // This is necessary in order to implement the spec for the `select` option 454 // of `:number` and `:integer`. 455 /* const */ bool sourceIsLiteral; 456 457 public: 458 U_I18N_API const UnicodeString& getName() const { return name; } 459 U_I18N_API const Formattable& getValue() const { return value; } 460 U_I18N_API bool isLiteral() const { return sourceIsLiteral; } 461 U_I18N_API ResolvedFunctionOption(const UnicodeString& n, const Formattable& f, bool s) 462 : name(n), value(f), sourceIsLiteral(s) {} 463 U_I18N_API ResolvedFunctionOption() {} 464 U_I18N_API ResolvedFunctionOption(ResolvedFunctionOption&&); 465 U_I18N_API ResolvedFunctionOption& operator=(ResolvedFunctionOption&& other) noexcept { 466 name = std::move(other.name); 467 value = std::move(other.value); 468 sourceIsLiteral = other.sourceIsLiteral; 469 return *this; 470 } 471 U_I18N_API virtual ~ResolvedFunctionOption(); 472 }; // class ResolvedFunctionOption 473 #endif 474 475 /** 476 * Mapping from option names to `message2::Formattable` objects, obtained 477 * by calling `getOptions()` on a `FunctionOptions` object. 478 * 479 * @internal ICU 75 technology preview 480 * @deprecated This API is for technology preview only. 481 */ 482 using FunctionOptionsMap = std::map<UnicodeString, message2::Formattable>; 483 484 /** 485 * Structure encapsulating named options passed to a custom selector or formatter. 486 * 487 * @internal ICU 75 technology preview 488 * @deprecated This API is for technology preview only. 489 */ 490 class U_I18N_API FunctionOptions : public UObject { 491 public: 492 /** 493 * Returns a map of all name-value pairs provided as options to this function. 494 * The syntactic order of options is not guaranteed to 495 * be preserved. 496 * 497 * This class is immutable and movable but not copyable. 498 * 499 * @return A map from strings to `message2::Formattable` objects representing 500 * the results of resolving each option value. 501 * 502 * @internal ICU 75 technology preview 503 * @deprecated This API is for technology preview only. 504 */ 505 FunctionOptionsMap getOptions() const { 506 int32_t len; 507 const ResolvedFunctionOption* resolvedOptions = getResolvedFunctionOptions(len); 508 FunctionOptionsMap result; 509 for (int32_t i = 0; i < len; i++) { 510 const ResolvedFunctionOption& opt = resolvedOptions[i]; 511 result[opt.getName()] = opt.getValue(); 512 } 513 return result; 514 } 515 /** 516 * Default constructor. 517 * Returns an empty mapping. 518 * 519 * @internal ICU 75 technology preview 520 * @deprecated This API is for technology preview only. 521 */ 522 FunctionOptions() { options = nullptr; } 523 /** 524 * Destructor. 525 * 526 * @internal ICU 75 technology preview 527 * @deprecated This API is for technology preview only. 528 */ 529 virtual ~FunctionOptions(); 530 /** 531 * Move assignment operator: 532 * The source FunctionOptions will be left in a valid but undefined state. 533 * 534 * @internal ICU 75 technology preview 535 * @deprecated This API is for technology preview only. 536 */ 537 FunctionOptions& operator=(FunctionOptions&&) noexcept; 538 /** 539 * Move constructor: 540 * The source FunctionOptions will be left in a valid but undefined state. 541 * 542 * @internal ICU 75 technology preview 543 * @deprecated This API is for technology preview only. 544 */ 545 FunctionOptions(FunctionOptions&&); 546 /** 547 * Copy constructor. 548 * 549 * @internal ICU 75 technology preview 550 * @deprecated This API is for technology preview only. 551 */ 552 FunctionOptions& operator=(const FunctionOptions&) = delete; 553 private: 554 friend class InternalValue; 555 friend class MessageFormatter; 556 friend class StandardFunctions; 557 558 explicit FunctionOptions(UVector&&, UErrorCode&); 559 560 const ResolvedFunctionOption* getResolvedFunctionOptions(int32_t& len) const; 561 UBool getFunctionOption(std::u16string_view, Formattable&) const; 562 UBool wasSetFromLiteral(const UnicodeString&) const; 563 // Returns empty string if option doesn't exist 564 UnicodeString getStringFunctionOption(std::u16string_view) const; 565 int32_t optionsCount() const { return functionOptionsLen; } 566 567 // Named options passed to functions 568 // This is not a Hashtable in order to make it possible for code in a public header file 569 // to construct a std::map from it, on-the-fly. Otherwise, it would be impossible to put 570 // that code in the header because it would have to call internal Hashtable methods. 571 ResolvedFunctionOption* options; 572 int32_t functionOptionsLen = 0; 573 574 /** 575 * The original FunctionOptions isn't usable after this call. 576 * @returns A new, merged FunctionOptions. 577 */ 578 FunctionOptions mergeOptions(FunctionOptions&& other, UErrorCode&); 579 }; // class FunctionOptions 580 581 /** 582 * A `FormattedValue` represents the result of formatting a `message2::Formattable`. 583 * It contains either a string or a formatted number. (More types could be added 584 * in the future.) 585 * 586 * `FormattedValue` is immutable and movable. It is not copyable. 587 * 588 * @internal ICU 75 technology preview 589 * @deprecated This API is for technology preview only. 590 */ 591 class U_I18N_API FormattedValue : public UObject { 592 public: 593 /** 594 * Formatted string constructor. 595 * @internal ICU 75 technology preview 596 * @deprecated This API is for technology preview only. 597 */ 598 explicit FormattedValue(const UnicodeString&); 599 /** 600 * Formatted number constructor. 601 * @internal ICU 75 technology preview 602 * @deprecated This API is for technology preview only. 603 */ 604 explicit FormattedValue(number::FormattedNumber&&); 605 /** 606 * Default constructor. Leaves the FormattedValue in 607 * a valid but undefined state. 608 * @internal ICU 75 technology preview 609 * @deprecated This API is for technology preview only. 610 */ 611 FormattedValue() : type(kString) {} 612 /** 613 * Returns true iff this is a formatted string. 614 * 615 * @return True if and only if this value is a formatted string. 616 * 617 * @internal ICU 75 technology preview 618 * @deprecated This API is for technology preview only. 619 */ 620 bool isString() const { return type == kString; } 621 /** 622 * Returns true iff this is a formatted number. 623 * 624 * @return True if and only if this value is a formatted number. 625 * 626 * @internal ICU 75 technology preview 627 * @deprecated This API is for technology preview only. 628 */ 629 bool isNumber() const { return type == kNumber; } 630 /** 631 * Gets the string contents of this value. If !isString(), then 632 * the result is undefined. 633 * @return A reference to a formatted string. 634 * @internal ICU 75 technology preview 635 * @deprecated This API is for technology preview only. 636 */ 637 const UnicodeString& getString() const { return stringOutput; } 638 /** 639 * Gets the number contents of this value. If !isNumber(), then 640 * the result is undefined. 641 * @return A reference to a formatted number. 642 * @internal ICU 75 technology preview 643 * @deprecated This API is for technology preview only. 644 */ 645 const number::FormattedNumber& getNumber() const { return numberOutput; } 646 /** 647 * Move assignment operator: 648 * The source FormattedValue will be left in a valid but undefined state. 649 * 650 * @internal ICU 75 technology preview 651 * @deprecated This API is for technology preview only. 652 */ 653 FormattedValue& operator=(FormattedValue&&) noexcept; 654 /** 655 * Move constructor: 656 * The source FormattedValue will be left in a valid but undefined state. 657 * 658 * @internal ICU 75 technology preview 659 * @deprecated This API is for technology preview only. 660 */ 661 FormattedValue(FormattedValue&& other) { *this = std::move(other); } 662 /** 663 * Destructor. 664 * 665 * @internal ICU 75 technology preview 666 * @deprecated This API is for technology preview only. 667 */ 668 virtual ~FormattedValue(); 669 private: 670 enum Type { 671 kString, 672 kNumber 673 }; 674 Type type; 675 UnicodeString stringOutput; 676 number::FormattedNumber numberOutput; 677 }; // class FormattedValue 678 679 /** 680 * A `FormattablePlaceholder` encapsulates an input value (a `message2::Formattable`) 681 * together with an optional output value (a `message2::FormattedValue`). 682 * More information, such as source line/column numbers, could be added to the class 683 * in the future. 684 * 685 * `FormattablePlaceholder` is immutable (not deeply immutable) and movable. 686 * It is not copyable. 687 * 688 * @internal ICU 75 technology preview 689 * @deprecated This API is for technology preview only. 690 */ 691 class U_I18N_API_CLASS FormattedPlaceholder : public UObject { 692 public: 693 /** 694 * Fallback constructor. Constructs a value that represents a formatting error, 695 * without recording an input `Formattable` as the source. 696 * 697 * @param s An error string. (See the MessageFormat specification for details 698 * on fallback strings.) 699 * 700 * @internal ICU 75 technology preview 701 * @deprecated This API is for technology preview only. 702 */ 703 U_I18N_API explicit FormattedPlaceholder(const UnicodeString& s) : fallback(s), type(kFallback) {} 704 /** 705 * Constructor for fully formatted placeholders. 706 * 707 * @param input A `FormattedPlaceholder` containing the fallback string and source 708 * `Formattable` used to construct the formatted value. 709 * @param output A `FormattedValue` representing the formatted output of `input`. 710 * Passed by move. 711 * 712 * @internal ICU 75 technology preview 713 * @deprecated This API is for technology preview only. 714 */ 715 U_I18N_API FormattedPlaceholder(const FormattedPlaceholder& input, FormattedValue&& output) 716 : fallback(input.fallback), source(input.source), 717 formatted(std::move(output)), previousOptions(FunctionOptions()), type(kEvaluated) {} 718 /** 719 * Constructor for fully formatted placeholders with options. 720 * 721 * @param input A `FormattedPlaceholder` containing the fallback string and source 722 * `Formattable` used to construct the formatted value. 723 * @param opts Function options that were used to construct `output`. May be the empty map. 724 * @param output A `FormattedValue` representing the formatted output of `input`. 725 * Passed by move. 726 * 727 * @internal ICU 75 technology preview 728 * @deprecated This API is for technology preview only. 729 */ 730 U_I18N_API FormattedPlaceholder(const FormattedPlaceholder& input, FunctionOptions&& opts, FormattedValue&& output) 731 : fallback(input.fallback), source(input.source), 732 formatted(std::move(output)), previousOptions(std::move(opts)), type(kEvaluated) {} 733 /** 734 * Constructor for unformatted placeholders. 735 * 736 * @param input A `Formattable` object. 737 * @param fb Fallback string to use if an error occurs while formatting the input. 738 * 739 * @internal ICU 75 technology preview 740 * @deprecated This API is for technology preview only. 741 */ 742 U_I18N_API FormattedPlaceholder(const Formattable& input, const UnicodeString& fb) 743 : fallback(fb), source(input), type(kUnevaluated) {} 744 /** 745 * Default constructor. Leaves the FormattedPlaceholder in a 746 * valid but undefined state. 747 * 748 * @internal ICU 75 technology preview 749 * @deprecated This API is for technology preview only. 750 */ 751 U_I18N_API FormattedPlaceholder() : type(kNull) {} 752 /** 753 * Returns the source `Formattable` value for this placeholder. 754 * The result is undefined if this is a null operand. 755 * 756 * @return A message2::Formattable value. 757 * 758 * @internal ICU 75 technology preview 759 * @deprecated This API is for technology preview only. 760 */ 761 U_I18N_API const message2::Formattable& asFormattable() const; 762 /** 763 * Returns true iff this is a fallback placeholder. 764 * 765 * @return True if and only if this placeholder was constructed from a fallback string, 766 * with no `Formattable` source or formatting output. 767 * 768 * @internal ICU 75 technology preview 769 * @deprecated This API is for technology preview only. 770 */ 771 U_I18N_API bool isFallback() const { return type == kFallback; } 772 /** 773 * Returns true iff this is a null placeholder. 774 * 775 * @return True if and only if this placeholder represents the absent argument to a formatter 776 * that was invoked without an argument. 777 * 778 * @internal ICU 75 technology preview 779 * @deprecated This API is for technology preview only. 780 */ 781 U_I18N_API bool isNullOperand() const { return type == kNull; } 782 /** 783 * Returns true iff this has formatting output. 784 * 785 * @return True if and only if this was constructed from both an input `Formattable` and 786 * output `FormattedValue`. 787 * 788 * @internal ICU 75 technology preview 789 * @deprecated This API is for technology preview only. 790 */ 791 U_I18N_API bool isEvaluated() const { return (type == kEvaluated); } 792 /** 793 * Returns true iff this represents a valid argument to the formatter. 794 * 795 * @return True if and only if this is neither the null argument nor a fallback placeholder. 796 * 797 * @internal ICU 75 technology preview 798 * @deprecated This API is for technology preview only. 799 */ 800 U_I18N_API bool canFormat() const { return !(isFallback() || isNullOperand()); } 801 /** 802 * Gets the fallback value of this placeholder, to be used in its place if an error occurs while 803 * formatting it. 804 * @return A reference to this placeholder's fallback string. 805 * @internal ICU 75 technology preview 806 * @deprecated This API is for technology preview only. 807 */ 808 U_I18N_API const UnicodeString& getFallback() const { return fallback; } 809 /** 810 * Returns the options of this placeholder. The result is the empty map if !isEvaluated(). 811 * @return A reference to an option map, capturing the options that were used 812 * in producing the output of this `FormattedPlaceholder` 813 * (or empty if there is no output) 814 * @internal ICU 75 technology preview 815 * @deprecated This API is for technology preview only. 816 */ 817 U_I18N_API const FunctionOptions& options() const { return previousOptions; } 818 /** 819 * Returns the formatted output of this placeholder. The result is undefined if !isEvaluated(). 820 * @return A fully formatted `FormattedPlaceholder`. 821 * @internal ICU 75 technology preview 822 * @deprecated This API is for technology preview only. 823 */ 824 U_I18N_API const FormattedValue& output() const { return formatted; } 825 /** 826 * Move assignment operator: 827 * The source FormattedPlaceholder will be left in a valid but undefined state. 828 * 829 * @internal ICU 75 technology preview 830 * @deprecated This API is for technology preview only. 831 */ 832 U_I18N_API FormattedPlaceholder& operator=(FormattedPlaceholder&&) noexcept; 833 /** 834 * Move constructor: 835 * The source FormattedPlaceholder will be left in a valid but undefined state. 836 * 837 * @internal ICU 75 technology preview 838 * @deprecated This API is for technology preview only. 839 */ 840 U_I18N_API FormattedPlaceholder(FormattedPlaceholder&& other) { *this = std::move(other); } 841 /** 842 * Formats this as a string, using defaults. If this is 843 * either the null operand or is a fallback value, the return value is the result of formatting the 844 * fallback value (which is the default fallback string if this is the null operand). 845 * If there is no formatted output and the input is object- or array-typed, 846 * then the argument is treated as a fallback value, since there is no default formatter 847 * for objects or arrays. 848 * 849 * @param locale The locale to use for formatting numbers or dates 850 * @param status Input/output error code 851 * @return The result of formatting this placeholder. 852 * 853 * @internal ICU 75 technology preview 854 * @deprecated This API is for technology preview only. 855 */ 856 U_I18N_API UnicodeString formatToString(const Locale& locale, 857 UErrorCode& status) const; 858 859 private: 860 friend class MessageFormatter; 861 862 enum Type { 863 kFallback, // Represents the result of formatting that encountered an error 864 kNull, // Represents the absence of both an output and an input (not necessarily an error) 865 kUnevaluated, // `source` should be valid, but there's no result yet 866 kEvaluated, // `formatted` exists 867 }; 868 UnicodeString fallback; 869 Formattable source; 870 FormattedValue formatted; 871 FunctionOptions previousOptions; // Ignored unless type is kEvaluated 872 Type type; 873 }; // class FormattedPlaceholder 874 875 /** 876 * Not yet implemented: The result of a message formatting operation. Based on 877 * ICU4J's FormattedMessage.java. 878 * 879 * The class will contain information allowing the result to be viewed as a string, 880 * iterator, etc. (TBD) 881 * 882 * @internal ICU 75 technology preview 883 * @deprecated This API is for technology preview only. 884 */ 885 class U_I18N_API FormattedMessage : public icu::FormattedValue { 886 public: 887 /** 888 * Not yet implemented. 889 * 890 * @internal ICU 75 technology preview 891 * @deprecated This API is for ICU internal use only. 892 */ 893 FormattedMessage(UErrorCode& status) { 894 if (U_SUCCESS(status)) { 895 status = U_UNSUPPORTED_ERROR; 896 } 897 } 898 /** 899 * Not yet implemented. 900 * 901 * @internal ICU 75 technology preview 902 * @deprecated This API is for ICU internal use only. 903 */ 904 int32_t length(UErrorCode& status) const { 905 if (U_SUCCESS(status)) { 906 status = U_UNSUPPORTED_ERROR; 907 } 908 return -1; 909 } 910 /** 911 * Not yet implemented. 912 * 913 * @internal ICU 75 technology preview 914 * @deprecated This API is for ICU internal use only. 915 */ 916 char16_t charAt(int32_t index, UErrorCode& status) const { 917 (void) index; 918 if (U_SUCCESS(status)) { 919 status = U_UNSUPPORTED_ERROR; 920 } 921 return 0; 922 } 923 /** 924 * Not yet implemented. 925 * 926 * @internal ICU 75 technology preview 927 * @deprecated This API is for ICU internal use only. 928 */ 929 StringPiece subSequence(int32_t start, int32_t end, UErrorCode& status) const { 930 (void) start; 931 (void) end; 932 if (U_SUCCESS(status)) { 933 status = U_UNSUPPORTED_ERROR; 934 } 935 return ""; 936 } 937 /** 938 * Not yet implemented. 939 * 940 * @internal ICU 75 technology preview 941 * @deprecated This API is for ICU internal use only. 942 */ 943 UnicodeString toString(UErrorCode& status) const override { 944 if (U_SUCCESS(status)) { 945 status = U_UNSUPPORTED_ERROR; 946 } 947 return {}; 948 } 949 /** 950 * Not yet implemented. 951 * 952 * @internal ICU 75 technology preview 953 * @deprecated This API is for ICU internal use only. 954 */ 955 UnicodeString toTempString(UErrorCode& status) const override { 956 if (U_SUCCESS(status)) { 957 status = U_UNSUPPORTED_ERROR; 958 } 959 return {}; 960 } 961 /** 962 * Not yet implemented. 963 * 964 * @internal ICU 75 technology preview 965 * @deprecated This API is for ICU internal use only. 966 */ 967 Appendable& appendTo(Appendable& appendable, UErrorCode& status) const override { 968 if (U_SUCCESS(status)) { 969 status = U_UNSUPPORTED_ERROR; 970 } 971 return appendable; 972 } 973 /** 974 * Not yet implemented. 975 * 976 * @internal ICU 75 technology preview 977 * @deprecated This API is for ICU internal use only. 978 */ 979 UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const override { 980 (void) cfpos; 981 if (U_SUCCESS(status)) { 982 status = U_UNSUPPORTED_ERROR; 983 } 984 return false; 985 } 986 /** 987 * Not yet implemented. 988 * 989 * @internal ICU 75 technology preview 990 * @deprecated This API is for ICU internal use only. 991 */ 992 CharacterIterator* toCharacterIterator(UErrorCode& status) { 993 if (U_SUCCESS(status)) { 994 status = U_UNSUPPORTED_ERROR; 995 } 996 return nullptr; 997 } 998 /** 999 * Destructor. 1000 * 1001 * @internal ICU 75 technology preview 1002 * @deprecated This API is for ICU internal use only. 1003 */ 1004 virtual ~FormattedMessage(); 1005 }; // class FormattedMessage 1006 1007 } // namespace message2 1008 1009 U_NAMESPACE_END 1010 1011 #endif // U_HIDE_DEPRECATED_API 1012 1013 #endif /* #if !UCONFIG_NO_MF2 */ 1014 1015 #endif /* #if !UCONFIG_NO_FORMATTING */ 1016 1017 #endif /* #if !UCONFIG_NO_NORMALIZATION */ 1018 1019 #endif /* U_SHOW_CPLUSPLUS_API */ 1020 1021 #endif // MESSAGEFORMAT2_FORMATTABLE_H 1022 1023 // eof