tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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