ICU 75.1 75.1
Loading...
Searching...
No Matches
messageformat2_formattable.h
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_FORMATTING
12
13#if !UCONFIG_NO_MF2
14
15#include "unicode/chariter.h"
17#include "unicode/messageformat2_data_model_names.h"
18
19#ifndef U_HIDE_DEPRECATED_API
20
21#include <map>
22#include <variant>
23
24U_NAMESPACE_BEGIN
25
26class Hashtable;
27class UVector;
28
29namespace message2 {
30
31 class Formatter;
32 class MessageContext;
33 class Selector;
34
35 // Formattable
36 // ----------
37
47 public:
57 virtual const UnicodeString& tag() const = 0;
65 }; // class FormattableObject
66
67 class Formattable;
68} // namespace message2
69
71
73// Export an explicit template instantiation of the std::variant that is used
74// to represent the message2::Formattable class.
75// (When building DLLs for Windows this is required.)
76// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
77// for similar examples.)
78#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
79#if defined(_MSC_VER)
80// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
81#pragma warning(push)
82#pragma warning(disable: 4661)
83#endif
84#if defined(_MSC_VER)
85template class U_I18N_API std::_Variant_storage_<false,
86 double,
87 int64_t,
91 std::pair<const icu::message2::Formattable *,int32_t>>;
92#endif
93typedef std::pair<const icu::message2::Formattable*, int32_t> P;
94template class U_I18N_API std::variant<double,
95 int64_t,
99 P>;
100#if defined(_MSC_VER)
101#pragma warning(pop)
102#endif
103#endif
105
107
108namespace message2 {
125 public:
126
134
144 double getDouble(UErrorCode& status) const {
145 if (U_SUCCESS(status)) {
146 if (isDecimal() && getType() == UFMT_DOUBLE) {
147 return (std::get_if<icu::Formattable>(&contents))->getDouble();
148 }
149 if (std::holds_alternative<double>(contents)) {
150 return *(std::get_if<double>(&contents));
151 }
153 }
154 return 0;
155 }
156
167 if (U_SUCCESS(status)) {
168 if (isDecimal() && getType() == UFMT_LONG) {
169 return std::get_if<icu::Formattable>(&contents)->getLong();
170 }
171 if (std::holds_alternative<int64_t>(contents)) {
172 return static_cast<int32_t>(*(std::get_if<int64_t>(&contents)));
173 }
175 }
176 return 0;
177 }
178
190 if (U_SUCCESS(status)) {
191 if (isDecimal() && getType() == UFMT_INT64) {
192 return std::get_if<icu::Formattable>(&contents)->getInt64();
193 }
194 if (std::holds_alternative<int64_t>(contents)) {
195 return *(std::get_if<int64_t>(&contents));
196 }
198 }
199 return 0;
200 }
201
227 if (U_SUCCESS(status)) {
228 if (std::holds_alternative<UnicodeString>(contents)) {
229 return *std::get_if<UnicodeString>(&contents);
230 }
232 }
233 return bogusString;
234 }
235
246 if (U_SUCCESS(status)) {
247 if (isDate()) {
248 return *std::get_if<double>(&contents);
249 }
251 }
252 return 0;
253 }
254
262 UBool isNumeric() const { return (getType() == UFMT_DOUBLE || getType() == UFMT_LONG || getType() == UFMT_INT64); }
263
275
287 if (U_SUCCESS(status)) {
288 // Can't return a reference since FormattableObject
289 // is an abstract class
290 if (getType() == UFMT_OBJECT) {
291 return *std::get_if<const FormattableObject*>(&contents);
292 // TODO: should assert that if type is object, object is non-null
293 }
295 }
296 return nullptr;
297 }
306 friend inline void swap(Formattable& f1, Formattable& f2) noexcept {
307 using std::swap;
308
309 swap(f1.contents, f2.contents);
310 swap(f1.holdsDate, f2.holdsDate);
311 }
333 Formattable() : contents(0.0) {}
342 Formattable(const UnicodeString& s) : contents(s) {}
351 Formattable(double d) : contents(d) {}
360 Formattable(int64_t i) : contents(i) {}
370 f.contents = d;
371 f.holdsDate = true;
372 return f;
373 }
388 static Formattable forDecimal(std::string_view number, UErrorCode& status);
398 Formattable(const Formattable* arr, int32_t len) : contents(std::pair(arr, len)) {}
407 Formattable(const FormattableObject* obj) : contents(obj) {}
414 virtual ~Formattable();
427 private:
428
429 std::variant<double,
430 int64_t,
432 icu::Formattable, // represents a Decimal
433 const FormattableObject*,
434 std::pair<const Formattable*, int32_t>> contents;
435 bool holdsDate = false; // otherwise, we get type errors about UDate being a duplicate type
436 UnicodeString bogusString; // :((((
437
438 UBool isDecimal() const {
439 return std::holds_alternative<icu::Formattable>(contents);
440 }
441 UBool isDate() const {
442 return std::holds_alternative<double>(contents) && holdsDate;
443 }
444 }; // class Formattable
445
459#ifndef U_IN_DOXYGEN
460class U_I18N_API ResolvedFunctionOption : public UObject {
461 private:
462
463 /* const */ UnicodeString name;
464 /* const */ Formattable value;
465
466 public:
467 const UnicodeString& getName() const { return name; }
468 const Formattable& getValue() const { return value; }
469 ResolvedFunctionOption(const UnicodeString& n, const Formattable& f) : name(n), value(f) {}
470 ResolvedFunctionOption() {}
471 ResolvedFunctionOption(ResolvedFunctionOption&&);
472 ResolvedFunctionOption& operator=(ResolvedFunctionOption&& other) noexcept {
473 name = std::move(other.name);
474 value = std::move(other.value);
475 return *this;
476 }
477 virtual ~ResolvedFunctionOption();
478}; // class ResolvedFunctionOption
479#endif
480
488using FunctionOptionsMap = std::map<UnicodeString, message2::Formattable>;
489
497 public:
511 FunctionOptionsMap getOptions() const {
512 int32_t len;
513 const ResolvedFunctionOption* resolvedOptions = getResolvedFunctionOptions(len);
514 FunctionOptionsMap result;
515 for (int32_t i = 0; i < len; i++) {
517 result[opt.getName()] = opt.getValue();
518 }
519 return result;
520 }
528 FunctionOptions() { options = nullptr; }
559 private:
561 friend class StandardFunctions;
562
564
565 const ResolvedFunctionOption* getResolvedFunctionOptions(int32_t& len) const;
566 UBool getFunctionOption(const UnicodeString&, Formattable&) const;
567 // Returns empty string if option doesn't exist
568 UnicodeString getStringFunctionOption(const UnicodeString&) const;
569 int32_t optionsCount() const { return functionOptionsLen; }
570
571 // Named options passed to functions
572 // This is not a Hashtable in order to make it possible for code in a public header file
573 // to construct a std::map from it, on-the-fly. Otherwise, it would be impossible to put
574 // that code in the header because it would have to call internal Hashtable methods.
575 ResolvedFunctionOption* options;
576 int32_t functionOptionsLen = 0;
577}; // class FunctionOptions
578
579
580 // TODO doc comments
581 // Encapsulates either a formatted string or formatted number;
582 // more output types could be added in the future.
583
595 public:
614 FormattedValue() : type(kString) {}
623 bool isString() const { return type == kString; }
632 bool isNumber() const { return type == kNumber; }
640 const UnicodeString& getString() const { return stringOutput; }
648 const number::FormattedNumber& getNumber() const { return numberOutput; }
664 FormattedValue(FormattedValue&& other) { *this = std::move(other); }
672 private:
673 enum Type {
674 kString,
675 kNumber
676 };
677 Type type;
678 UnicodeString stringOutput;
679 number::FormattedNumber numberOutput;
680 }; // class FormattedValue
681
695 public:
706 explicit FormattedPlaceholder(const UnicodeString& s) : fallback(s), type(kFallback) {}
719 : fallback(input.fallback), source(input.source),
720 formatted(std::move(output)), previousOptions(FunctionOptions()), type(kEvaluated) {}
734 : fallback(input.fallback), source(input.source),
735 formatted(std::move(output)), previousOptions(std::move(opts)), type(kEvaluated) {}
746 : fallback(fb), source(input), type(kUnevaluated) {}
754 FormattedPlaceholder() : type(kNull) {}
774 bool isFallback() const { return type == kFallback; }
784 bool isNullOperand() const { return type == kNull; }
794 bool isEvaluated() const { return (type == kEvaluated); }
803 bool canFormat() const { return !(isFallback() || isNullOperand()); }
811 const UnicodeString& getFallback() const { return fallback; }
820 const FunctionOptions& options() const { return previousOptions; }
821
828 const FormattedValue& output() const { return formatted; }
861 UErrorCode& status) const;
862
863 private:
864 friend class MessageFormatter;
865
866 enum Type {
867 kFallback, // Represents the result of formatting that encountered an error
868 kNull, // Represents the absence of both an output and an input (not necessarily an error)
869 kUnevaluated, // `source` should be valid, but there's no result yet
870 kEvaluated, // `formatted` exists
871 };
872 UnicodeString fallback;
873 Formattable source;
874 FormattedValue formatted;
875 FunctionOptions previousOptions; // Ignored unless type is kEvaluated
876 Type type;
877 }; // class FormattedPlaceholder
878
890 public:
909 if (U_SUCCESS(status)) {
911 }
912 return -1;
913 }
920 char16_t charAt(int32_t index, UErrorCode& status) const {
921 (void) index;
922 if (U_SUCCESS(status)) {
924 }
925 return 0;
926 }
934 (void) start;
935 (void) end;
936 if (U_SUCCESS(status)) {
938 }
939 return "";
940 }
948 if (U_SUCCESS(status)) {
950 }
951 return {};
952 }
960 if (U_SUCCESS(status)) {
962 }
963 return {};
964 }
972 if (U_SUCCESS(status)) {
974 }
975 return appendable;
976 }
984 (void) cfpos;
985 if (U_SUCCESS(status)) {
987 }
988 return false;
989 }
997 if (U_SUCCESS(status)) {
999 }
1000 return nullptr;
1001 }
1009 }; // class FormattedMessage
1010
1011} // namespace message2
1012
1014
1015#endif // U_HIDE_DEPRECATED_API
1016
1017#endif /* #if !UCONFIG_NO_MF2 */
1018
1019#endif /* #if !UCONFIG_NO_FORMATTING */
1020
1021#endif /* U_SHOW_CPLUSPLUS_API */
1022
1023#endif // MESSAGEFORMAT2_FORMATTABLE_H
1024
1025// eof
C++ API: Character Iterator.
Base class for objects to which Unicode characters and strings can be appended.
Definition appendable.h:54
Abstract class that defines an API for iteration on text objects.
Definition chariter.h:361
Represents a span of a string containing a given field.
Formattable objects can be passed to the Format class or its subclasses for formatting.
Definition fmtable.h:63
An abstract formatted value: a string with associated field attributes.
"Smart pointer" base class; do not use directly: use LocalPointer etc.
A Locale object represents a specific geographical, political, or cultural region.
Definition locid.h:195
A string-like object that points to a sized piece of memory.
Definition stringpiece.h:60
UObject is the common ICU "boilerplate" class.
Definition uobject.h:223
UnicodeString is a string class that stores Unicode characters directly and provides similar function...
Definition unistr.h:296
FormattableObject is an abstract class that can be implemented in order to define an arbitrary class ...
virtual ~FormattableObject()
Destructor.
virtual const UnicodeString & tag() const =0
Returns an arbitrary string representing the type of this object.
The Formattable class represents a typed value that can be formatted, originating either from a messa...
Formattable(const FormattableObject *obj)
Object constructor.
Formattable(const UnicodeString &s)
String constructor.
Formattable(const Formattable *arr, int32_t len)
Array constructor.
Formattable(int64_t i)
Int64 constructor.
static Formattable forDecimal(std::string_view number, UErrorCode &status)
Creates a Formattable object of an appropriate numeric type from a a decimal number in string form.
const FormattableObject * getObject(UErrorCode &status) const
Returns a pointer to the FormattableObject contained within this formattable, or if this object does ...
double getDouble(UErrorCode &status) const
Gets the double value of this object.
icu::Formattable asICUFormattable(UErrorCode &status) const
Converts the Formattable object to an ICU Formattable object.
virtual ~Formattable()
Destructor.
int64_t getInt64(UErrorCode &status) const
Gets the int64 value of this object.
const UnicodeString & getString(UErrorCode &status) const
Gets the string value of this object.
Formattable & operator=(Formattable) noexcept
Assignment operator.
int32_t getLong(UErrorCode &status) const
Gets the long value of this object.
const Formattable * getArray(int32_t &count, UErrorCode &status) const
Gets the array value and count of this object.
int64_t getInt64Value(UErrorCode &status) const
Gets the int64 value of this object.
UBool isNumeric() const
Returns true if the data type of this Formattable object is kDouble.
static Formattable forDate(UDate d)
Date factory method.
Formattable(double d)
Double constructor.
friend void swap(Formattable &f1, Formattable &f2) noexcept
Non-member swap function.
Formattable(const Formattable &)
Copy constructor.
UFormattableType getType() const
Gets the data type of this Formattable object.
UDate getDate(UErrorCode &status) const
Gets the Date value of this object.
Not yet implemented: The result of a message formatting operation.
UBool nextPosition(ConstrainedFieldPosition &cfpos, UErrorCode &status) const override
Not yet implemented.
StringPiece subSequence(int32_t start, int32_t end, UErrorCode &status) const
Not yet implemented.
int32_t length(UErrorCode &status) const
Not yet implemented.
UnicodeString toTempString(UErrorCode &status) const override
Not yet implemented.
FormattedMessage(UErrorCode &status)
Not yet implemented.
UnicodeString toString(UErrorCode &status) const override
Not yet implemented.
virtual ~FormattedMessage()
Destructor.
CharacterIterator * toCharacterIterator(UErrorCode &status)
Not yet implemented.
char16_t charAt(int32_t index, UErrorCode &status) const
Not yet implemented.
Appendable & appendTo(Appendable &appendable, UErrorCode &status) const override
Not yet implemented.
A FormattablePlaceholder encapsulates an input value (a message2::Formattable) together with an optio...
FormattedPlaceholder(const UnicodeString &s)
Fallback constructor.
const message2::Formattable & asFormattable() const
Returns the source Formattable value for this placeholder.
UnicodeString formatToString(const Locale &locale, UErrorCode &status) const
Formats this as a string, using defaults.
FormattedPlaceholder & operator=(FormattedPlaceholder &&) noexcept
Move assignment operator: The source FormattedPlaceholder will be left in a valid but undefined state...
bool isEvaluated() const
Returns true iff this has formatting output.
bool isNullOperand() const
Returns true iff this is a null placeholder.
const UnicodeString & getFallback() const
Gets the fallback value of this placeholder, to be used in its place if an error occurs while formatt...
FormattedPlaceholder(const FormattedPlaceholder &input, FormattedValue &&output)
Constructor for fully formatted placeholders.
bool isFallback() const
Returns true iff this is a fallback placeholder.
const FunctionOptions & options() const
Returns the options of this placeholder.
FormattedPlaceholder(const Formattable &input, const UnicodeString &fb)
Constructor for unformatted placeholders.
const FormattedValue & output() const
Returns the formatted output of this placeholder.
bool canFormat() const
Returns true iff this represents a valid argument to the formatter.
FormattedPlaceholder(const FormattedPlaceholder &input, FunctionOptions &&opts, FormattedValue &&output)
Constructor for fully formatted placeholders with options.
A FormattedValue represents the result of formatting a message2::Formattable.
FormattedValue & operator=(FormattedValue &&) noexcept
Move assignment operator: The source FormattedValue will be left in a valid but undefined state.
virtual ~FormattedValue()
Destructor.
FormattedValue(number::FormattedNumber &&)
Formatted number constructor.
bool isNumber() const
Returns true iff this is a formatted number.
FormattedValue(const UnicodeString &)
Formatted string constructor.
const number::FormattedNumber & getNumber() const
Gets the number contents of this value.
const UnicodeString & getString() const
Gets the string contents of this value.
bool isString() const
Returns true iff this is a formatted string.
Structure encapsulating named options passed to a custom selector or formatter.
FunctionOptions & operator=(FunctionOptions &&) noexcept
Move assignment operator: The source FunctionOptions will be left in a valid but undefined state.
virtual ~FunctionOptions()
Destructor.
FunctionOptionsMap getOptions() const
Returns a map of all name-value pairs provided as options to this function.
The result of a number formatting operation.
C++ API: All-in-one formatter for localized numbers, currencies, and units.
UFormattableType
Enum designating the type of a UFormattable instance.
@ UFMT_LONG
ufmt_getLong() will return without conversion.
@ UFMT_OBJECT
ufmt_getObject() will return without conversion.
@ UFMT_DOUBLE
ufmt_getDouble() will return without conversion.
@ UFMT_INT64
ufmt_getInt64() will return without conversion.
int8_t UBool
The ICU boolean type, a signed-byte integer.
Definition umachine.h:247
Basic definitions for ICU, for both C and C++ APIs.
UErrorCode
Standard ICU4C error code type, a substitute for exceptions.
Definition utypes.h:415
@ U_ILLEGAL_ARGUMENT_ERROR
Start of codes indicating failure.
Definition utypes.h:452
@ U_UNSUPPORTED_ERROR
Requested operation not supported in current context.
Definition utypes.h:467
#define U_SUCCESS(x)
Does the error code indicate success?
Definition utypes.h:728
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside.
Definition utypes.h:301
double UDate
Date and Time data type.
Definition utypes.h:203