ICU 75.1 75.1
Loading...
Searching...
No Matches
messageformat2_data_model.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 MESSAGEFORMAT_DATA_MODEL_H
7#define MESSAGEFORMAT_DATA_MODEL_H
8
9#if U_SHOW_CPLUSPLUS_API
10
11#if !UCONFIG_NO_FORMATTING
12
13#if !UCONFIG_NO_MF2
14
16#include "unicode/messageformat2_data_model_names.h"
17
18#ifndef U_HIDE_DEPRECATED_API
19
20#include <algorithm>
21#include <cstddef>
22#include <iterator>
23#include <optional>
24#include <variant>
25#include <vector>
26
27U_NAMESPACE_BEGIN
28
29class UVector;
30
31// Helpers
32
33// Note: this _must_ be declared `inline` or else gcc will generate code
34// for its instantiations, which needs to be avoided because it returns
35// a std::vector
36template<typename T>
37static inline std::vector<T> toStdVector(const T* arr, int32_t len) {
38 std::vector<T> result;
39 for (int32_t i = 0; i < len; i++) {
40 result.push_back(arr[i]);
41 }
42 return result;
43}
44
45namespace message2 {
46
47 namespace data_model {
48 class Binding;
49 class Literal;
50 class Operator;
51 } // namespace data_model
52} // namespace message2
53
55// Export an explicit template instantiation of the LocalPointer that is used as a
56// data member of various MFDataModel classes.
57// (When building DLLs for Windows this is required.)
58// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
59// for similar examples.)
60#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
61#if defined(_MSC_VER)
62// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
63#pragma warning(push)
64#pragma warning(disable: 4661)
65#endif
66template class U_I18N_API LocalPointerBase<message2::data_model::Literal>;
67template class U_I18N_API LocalArray<message2::data_model::Literal>;
68#if defined(_MSC_VER)
69#pragma warning(pop)
70#endif
71#endif
73
74namespace message2 {
75 class Checker;
76 class MFDataModel;
77 class MessageFormatter;
78 class Parser;
79 class Serializer;
80
81
82 namespace data_model {
94 class U_I18N_API Reserved : public UMemory {
95 public:
115 const Literal& getPart(int32_t i) const;
116
126 class U_I18N_API Builder : public UMemory {
127 private:
128 UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
129
130 public:
154 Reserved build(UErrorCode& status) const noexcept;
171 virtual ~Builder();
172 }; // class Reserved::Builder
181 friend inline void swap(Reserved& r1, Reserved& r2) noexcept {
182 using std::swap;
183
184 swap(r1.parts, r2.parts);
185 swap(r1.len, r2.len);
186 }
215 virtual ~Reserved();
216 private:
217 friend class Builder;
218 friend class Operator;
219
220 // Possibly-empty list of parts
221 // `literal` reserved as a quoted literal; `reserved-char` / `reserved-escape`
222 // strings represented as unquoted literals
223 /* const */ LocalArray<Literal> parts;
224 int32_t len = 0;
225 Reserved(const UVector& parts, UErrorCode& status) noexcept;
226 // Helper
227 static void initLiterals(Reserved&, const Reserved&);
228 };
229
241 class U_I18N_API Literal : public UObject {
242 public:
260 const UnicodeString& unquoted() const;
270 UBool isQuoted() const { return thisIsQuoted; }
282 Literal(UBool q, const UnicodeString& s) : thisIsQuoted(q), contents(s) {}
289 Literal(const Literal& other) : thisIsQuoted(other.thisIsQuoted), contents(other.contents) {}
298 friend inline void swap(Literal& l1, Literal& l2) noexcept {
299 using std::swap;
300
301 swap(l1.thisIsQuoted, l2.thisIsQuoted);
302 swap(l1.contents, l2.contents);
303 }
318 Literal() = default;
334 bool operator<(const Literal& other) const;
350 bool operator==(const Literal& other) const;
357 virtual ~Literal();
358
359 private:
360 friend class Reserved::Builder;
361
362 /* const */ bool thisIsQuoted = false;
363 /* const */ UnicodeString contents;
364 };
365 } // namespace data_model
366} // namespace message2
367
369
371// Export an explicit template instantiation of the std::variants and std::optionals
372// that are used as a data member of various MFDataModel classes.
373// (When building DLLs for Windows this is required.)
374// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
375// for similar examples.)
376#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
377#if defined(_MSC_VER)
378struct U_I18N_API std::_Nontrivial_dummy_type;
379template class U_I18N_API std::_Variant_storage_<false, icu::UnicodeString, icu::message2::data_model::Literal>;
380#endif
381template class U_I18N_API std::variant<icu::UnicodeString, icu::message2::data_model::Literal>;
382template class U_I18N_API std::optional<std::variant<icu::UnicodeString, icu::message2::data_model::Literal>>;
383template class U_I18N_API std::optional<icu::message2::data_model::Literal>;
384#endif
386
388
389namespace message2 {
390 namespace data_model {
391
406 class U_I18N_API Operand : public UObject {
407 public:
416 UBool isVariable() const;
425 UBool isLiteral() const;
434 virtual UBool isNull() const;
444 const UnicodeString& asVariable() const;
454 const Literal& asLiteral() const;
462 Operand() : contents(std::nullopt) {}
472 explicit Operand(const UnicodeString& v) : contents(VariableName(v)) {}
482 explicit Operand(const Literal& l) : contents(l) {}
491 friend inline void swap(Operand& o1, Operand& o2) noexcept {
492 using std::swap;
493 (void) o1;
494 (void) o2;
495 swap(o1.contents, o2.contents);
496 }
503 virtual Operand& operator=(Operand) noexcept;
510 Operand(const Operand&);
517 virtual ~Operand();
518 private:
519 std::optional<std::variant<VariableName, Literal>> contents;
520 }; // class Operand
521
537 class U_I18N_API Key : public UObject {
538 public:
547 UBool isWildcard() const { return !contents.has_value(); }
557 const Literal& asLiteral() const;
564 Key(const Key& other) : contents(other.contents) {}
572 Key() : contents(std::nullopt) {}
582 explicit Key(const Literal& lit) : contents(lit) {}
591 friend inline void swap(Key& k1, Key& k2) noexcept {
592 using std::swap;
593
594 swap(k1.contents, k2.contents);
595 }
602 Key& operator=(Key) noexcept;
616 bool operator<(const Key& other) const;
630 bool operator==(const Key& other) const;
637 virtual ~Key();
638 private:
639 /* const */ std::optional<Literal> contents;
640 }; // class Key
641 } // namespace data_model
642} // namespace message2
643
645// Export an explicit template instantiation of the LocalPointer that is used as a
646// data member of various MFDataModel classes.
647// (When building DLLs for Windows this is required.)
648// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
649// for similar examples.)
650#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
651#if defined(_MSC_VER)
652// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
653#pragma warning(push)
654#pragma warning(disable: 4661)
655#endif
656template class U_I18N_API LocalPointerBase<message2::data_model::Key>;
657template class U_I18N_API LocalArray<message2::data_model::Key>;
658#if defined(_MSC_VER)
659#pragma warning(pop)
660#endif
661#endif
663
664namespace message2 {
665 namespace data_model {
676 class U_I18N_API SelectorKeys : public UObject {
677 public:
688 std::vector<Key> getKeys() const {
689 return toStdVector<Key>(keys.getAlias(), len);
690 }
700 class U_I18N_API Builder : public UMemory {
701 private:
702 friend class SelectorKeys;
703 UVector* keys; // This is a raw pointer and not a LocalPointer<UVector> to avoid undefined behavior warnings,
704 // since UVector is forward-declared
705 // The vector owns its elements
706 public:
717 Builder& add(Key&& key, UErrorCode& status) noexcept;
730 SelectorKeys build(UErrorCode& status) const;
747 virtual ~Builder();
748 }; // class SelectorKeys::Builder
763 bool operator<(const SelectorKeys& other) const;
771 SelectorKeys() : len(0) {}
780 friend inline void swap(SelectorKeys& s1, SelectorKeys& s2) noexcept {
781 using std::swap;
782
783 swap(s1.len, s2.len);
784 swap(s1.keys, s2.keys);
785 }
792 SelectorKeys(const SelectorKeys& other);
799 SelectorKeys& operator=(SelectorKeys other) noexcept;
806 virtual ~SelectorKeys();
807
808 private:
809 friend class Builder;
810 friend class message2::Checker;
811 friend class message2::MessageFormatter;
812 friend class message2::Serializer;
813
814 /* const */ LocalArray<Key> keys;
815 /* const */ int32_t len;
816
817 const Key* getKeysInternal() const;
818 SelectorKeys(const UVector& ks, UErrorCode& status);
819 }; // class SelectorKeys
820
821
822 } // namespace data_model
823
824
825 namespace data_model {
826 class Operator;
827
836 class U_I18N_API Option : public UObject {
837 public:
846 const Operand& getValue() const { return rand; }
855 const UnicodeString& getName() const { return name; }
866 Option(const UnicodeString& n, Operand&& r) : name(n), rand(std::move(r)) {}
883 friend inline void swap(Option& o1, Option& o2) noexcept {
884 using std::swap;
885
886 swap(o1.name, o2.name);
887 swap(o1.rand, o2.rand);
888 }
909 virtual ~Option();
910 private:
911 /* const */ UnicodeString name;
912 /* const */ Operand rand;
913 }; // class Option
914 } // namespace data_model
915} // namespace message2
916
918// Export an explicit template instantiation of the LocalPointer that is used as a
919// data member of various MFDataModel classes.
920// (When building DLLs for Windows this is required.)
921// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
922// for similar examples.)
923#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
924#if defined(_MSC_VER)
925// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
926#pragma warning(push)
927#pragma warning(disable: 4661)
928#endif
931#if defined(_MSC_VER)
932#pragma warning(pop)
933#endif
934#endif
936
937namespace message2 {
938 namespace data_model {
939 // Internal only
940 #ifndef U_IN_DOXYGEN
941 // Options
942 // This is a wrapper class around a vector of options that provides lookup operations
943 class U_I18N_API OptionMap : public UObject {
944 public:
945 int32_t size() const;
946 // Needs to take an error code b/c an earlier copy might have failed
947 const Option& getOption(int32_t, UErrorCode&) const;
948 friend inline void swap(OptionMap& m1, OptionMap& m2) noexcept {
949 using std::swap;
950
951 swap(m1.bogus, m2.bogus);
952 swap(m1.options, m2.options);
953 swap(m1.len, m2.len);
954 }
955 OptionMap() : len(0) {}
956 OptionMap(const OptionMap&);
957 OptionMap& operator=(OptionMap);
958 std::vector<Option> getOptions() const {
959 return toStdVector<Option>(options.getAlias(), len);
960 }
961 OptionMap(const UVector&, UErrorCode&);
962 OptionMap(Option*, int32_t);
963 virtual ~OptionMap();
964 private:
965 friend class message2::Serializer;
966
967 bool bogus = false;
968 LocalArray<Option> options;
969 int32_t len;
970 }; // class OptionMap
971 #endif
972
973 // Internal use only
974 #ifndef U_IN_DOXYGEN
975 class U_I18N_API Callable : public UObject {
976 public:
977 friend inline void swap(Callable& c1, Callable& c2) noexcept {
978 using std::swap;
979
980 swap(c1.name, c2.name);
981 swap(c1.options, c2.options);
982 }
983 const FunctionName& getName() const { return name; }
984 const OptionMap& getOptions() const { return options; }
985 Callable(const FunctionName& f, const OptionMap& opts) : name(f), options(opts) {}
986 Callable& operator=(Callable) noexcept;
987 Callable(const Callable&);
988 Callable() = default;
989 virtual ~Callable();
990 private:
991 /* const */ FunctionName name;
992 /* const */ OptionMap options;
993 };
994 #endif
995 } // namespace data_model
996} // namespace message2
997
998U_NAMESPACE_END
999
1001// Export an explicit template instantiation of the std::variant that is used as a
1002// data member of various MFDataModel classes.
1003// (When building DLLs for Windows this is required.)
1004// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1005// for similar examples.)
1006#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1007#if defined(_MSC_VER)
1008template class U_I18N_API std::_Variant_storage_<false, icu::message2::data_model::Reserved,icu::message2::data_model::Callable>;
1009#endif
1010template class U_I18N_API std::variant<icu::message2::data_model::Reserved,icu::message2::data_model::Callable>;
1011#endif
1013
1014U_NAMESPACE_BEGIN
1015
1016namespace message2 {
1017 namespace data_model {
1033 class U_I18N_API Operator : public UObject {
1034 public:
1043 UBool isReserved() const { return std::holds_alternative<Reserved>(contents); }
1053 const FunctionName& getFunctionName() const;
1063 const Reserved& asReserved() const;
1073 std::vector<Option> getOptions() const {
1074 const Callable* f = std::get_if<Callable>(&contents);
1075 // This case should never happen, as the precondition is !isReserved()
1076 if (f == nullptr) { return {}; }
1077 const OptionMap& opts = f->getOptions();
1078 return opts.getOptions();
1079 }
1089 class U_I18N_API Builder : public UMemory {
1090 private:
1091 friend class Operator;
1092 bool isReservedSequence = false;
1093 bool hasFunctionName = false;
1094 bool hasOptions = false;
1095 Reserved asReserved;
1096 FunctionName functionName;
1097 // The next field is used internally to construct Operators
1098 // and overrides the `options` vector.
1099 // This is because it's easiest to share the code
1100 // for parsing options between Operator::Builder and Markup::Builder.
1101 OptionMap optionMap;
1102 UVector* options; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
1103 Builder& setOptionMap(OptionMap&&);
1104 public:
1143 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept;
1178 virtual ~Builder();
1179 }; // class Operator::Builder
1186 Operator(const Operator& other) noexcept;
1195 friend inline void swap(Operator& o1, Operator& o2) noexcept {
1196 using std::swap;
1197
1198 swap(o1.contents, o2.contents);
1199 }
1206 Operator& operator=(Operator) noexcept;
1214 Operator() : contents(Reserved()) {}
1221 virtual ~Operator();
1222 private:
1223 friend class Binding;
1224 friend class Builder;
1225 friend class message2::Checker;
1226 friend class message2::MessageFormatter;
1227 friend class message2::Parser;
1228 friend class message2::Serializer;
1229
1230 // Function call constructor
1231 Operator(const FunctionName& f, const UVector& options, UErrorCode&);
1232 // Reserved sequence constructor
1233 Operator(const Reserved& r) : contents(r) {}
1234
1235 const OptionMap& getOptionsInternal() const;
1236 Operator(const FunctionName&, const OptionMap&);
1237 /* const */ std::variant<Reserved, Callable> contents;
1238 }; // class Operator
1239 } // namespace data_model
1240} // namespace message2
1241
1242U_NAMESPACE_END
1243
1245// Export an explicit template instantiation of the std::optional that is used as a
1246// data member of various MFDataModel classes.
1247// (When building DLLs for Windows this is required.)
1248// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1249// for similar examples.)
1250#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1251template class U_I18N_API std::optional<icu::message2::data_model::Operator>;
1252template class U_I18N_API std::optional<icu::message2::data_model::Reserved>;
1253#endif
1255
1256U_NAMESPACE_BEGIN
1257
1258namespace message2 {
1259 namespace data_model {
1260 // Internal only
1261 typedef enum UMarkupType {
1262 UMARKUP_OPEN = 0,
1263 UMARKUP_CLOSE,
1264 UMARKUP_STANDALONE,
1265 UMARKUP_COUNT
1266 } UMarkupType;
1267
1278 class U_I18N_API Markup : public UObject {
1279 public:
1288 UBool isOpen() const { return (type == UMARKUP_OPEN); }
1297 UBool isClose() const { return (type == UMARKUP_CLOSE); }
1306 UBool isStandalone() const { return (type == UMARKUP_STANDALONE); }
1315 const UnicodeString& getName() const { return name; }
1324 std::vector<Option> getOptions() const { return options.getOptions(); }
1333 std::vector<Option> getAttributes() const { return attributes.getOptions(); }
1348 virtual ~Markup();
1358 class U_I18N_API Builder : public UMemory {
1359 private:
1360 friend class Markup;
1361 friend class message2::Parser;
1362
1363 UnicodeString name;
1364 UVector* options; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
1365 UVector* attributes;
1366 // The next two fields are used internally by the parser
1367 // and override the `options` and `attributes` vectors.
1368 // This is because it's easiest to share the code
1369 // for parsing options between Operator::Builder and Markup::Builder.
1370 OptionMap optionMap;
1371 OptionMap attributeMap;
1372 UMarkupType type = UMARKUP_COUNT;
1373 Builder& setOptionMap(OptionMap&&);
1374
1375 // TODO: Would probably be best to make this method public (same for Markup)
1376 // and not make the parser a friend class.
1377 // Same for options on Operator and Markup. (addAll())
1378 Builder& setAttributeMap(OptionMap&& m);
1379 public:
1389 Builder& setName(const UnicodeString& n) { name = n; return *this; }
1398 Builder& setOpen() { type = UMARKUP_OPEN; return *this; }
1407 Builder& setClose() { type = UMARKUP_CLOSE; return *this; }
1416 Builder& setStandalone() { type = UMARKUP_STANDALONE; return *this; }
1428 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept;
1440 Builder& addAttribute(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept;
1475 virtual ~Builder();
1476 }; // class Markup::Builder
1477
1478 private:
1479 friend class Builder;
1480 friend class message2::Serializer;
1481
1482 UMarkupType type;
1483 UnicodeString name;
1484 OptionMap options;
1485 OptionMap attributes;
1486 const OptionMap& getOptionsInternal() const { return options; }
1487 const OptionMap& getAttributesInternal() const { return attributes; }
1488 Markup(UMarkupType, UnicodeString, OptionMap&&, OptionMap&&);
1489 }; // class Markup
1490
1505 public:
1553 const Operator* getOperator(UErrorCode& status) const;
1563 const Operand& getOperand() const;
1572 std::vector<Option> getAttributes() const { return attributes.getOptions(); }
1582 class U_I18N_API Builder : public UMemory {
1583 private:
1584 friend class Expression;
1585 friend class message2::Parser;
1586
1587 bool hasOperand = false;
1588 bool hasOperator = false;
1589 Operand rand;
1590 Operator rator;
1591 UVector* attributes; // Not a LocalPointer for the same reason as in `SelectorKeys::builder`
1592 // The next field is used internally by the parser
1593 // and overrides `attributes` vector.
1594 // This is because it's easiest to share the code
1595 // for parsing options between Expression::Builder and Markup::Builder.
1596 OptionMap attributeMap;
1597 // Provided as a private method so that the parser
1598 // can use the same attribute-parsing code for Expression and Markup
1599 Builder& setAttributeMap(OptionMap&& m);
1600 public:
1667 virtual ~Builder();
1668 }; // class Expression::Builder
1677 friend inline void swap(Expression& e1, Expression& e2) noexcept {
1678 using std::swap;
1679
1680 swap(e1.rator, e2.rator);
1681 swap(e1.rand, e2.rand);
1682 swap(e1.attributes, e2.attributes);
1683 }
1712 virtual ~Expression();
1713 private:
1714 friend class message2::Serializer;
1715
1716 /*
1717 Internally, an expression is represented as the application of an optional operator to an operand.
1718 The operand is always present; for function calls with no operand, it's represented
1719 as an operand for which `isNull()` is true.
1720
1721 Operator | Operand
1722 --------------------------------
1723 { |42| :fun opt=value } => (FunctionName=fun, | Literal(quoted=true, contents="42")
1724 options={opt: value})
1725 { abcd } => null | Literal(quoted=false, contents="abcd")
1726 { : fun opt=value } => (FunctionName=fun,
1727 options={opt: value}) | NullOperand()
1728 */
1729
1730 Expression(const Operator &rAtor, const Operand &rAnd, const OptionMap& attrs) : rator(rAtor), rand(rAnd), attributes(attrs) {}
1731 Expression(const Operand &rAnd, const OptionMap& attrs) : rator(std::nullopt), rand(Operand(rAnd)), attributes(attrs) {}
1732 Expression(const Operator &rAtor, const OptionMap& attrs) : rator(rAtor), rand(), attributes(attrs) {}
1733 /* const */ std::optional<Operator> rator;
1734 /* const */ Operand rand;
1735 /* const */ OptionMap attributes;
1736 const OptionMap& getAttributesInternal() const { return attributes; }
1737 }; // class Expression
1738 } // namespace data_model
1739} // namespace message2
1740
1742// Export an explicit template instantiation of the LocalPointer that is used as a
1743// data member of various MFDataModel classes.
1744// (When building DLLs for Windows this is required.)
1745// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1746// for similar examples.)
1747#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1748#if defined(_MSC_VER)
1749// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
1750#pragma warning(push)
1751#pragma warning(disable: 4661)
1752#endif
1753template class U_I18N_API LocalPointerBase<message2::data_model::Expression>;
1754template class U_I18N_API LocalArray<message2::data_model::Expression>;
1755#if defined(_MSC_VER)
1756#pragma warning(pop)
1757#endif
1758#endif
1760
1761namespace message2 {
1762 namespace data_model {
1777 public:
1786 const UnicodeString& getKeyword() const { return keyword; }
1807 std::vector<Expression> getExpressions() const {
1808 if (expressionsLen <= 0 || !expressions.isValid()) {
1809 // This case should never happen, but we can't use an assertion here
1810 return {};
1811 }
1812 return toStdVector<Expression>(expressions.getAlias(), expressionsLen);
1813 }
1823 class U_I18N_API Builder : public UMemory {
1824 private:
1825 friend class UnsupportedStatement;
1826 friend class message2::Parser;
1827
1828 UnicodeString keyword;
1829 std::optional<Reserved> body;
1830 UVector* expressions; // Vector of expressions;
1831 // not a LocalPointer for
1832 // the same reason as in `SelectorKeys::builder`
1833 public:
1897 virtual ~Builder();
1898 }; // class UnsupportedStatement::Builder
1907 friend inline void swap(UnsupportedStatement& s1, UnsupportedStatement& s2) noexcept {
1908 using std::swap;
1909
1910 swap(s1.keyword, s2.keyword);
1911 swap(s1.body, s2.body);
1912 swap(s1.expressions, s2.expressions);
1913 swap(s1.expressionsLen, s2.expressionsLen);
1914 }
1944 private:
1945 friend class message2::Serializer;
1946
1947 /* const */ UnicodeString keyword;
1948 /* const */ std::optional<Reserved> body;
1949 /* const */ LocalArray<Expression> expressions;
1950 /* const */ int32_t expressionsLen = 0;
1951
1952 const Expression* getExpressionsInternal() const { return expressions.getAlias(); }
1953
1954 UnsupportedStatement(const UnicodeString&, const std::optional<Reserved>&, const UVector&, UErrorCode&);
1955 }; // class UnsupportedStatement
1956
1957 class Pattern;
1958
1959 // Despite the comments, `PatternPart` is internal-only
1970 class PatternPart : public UObject {
1971 public:
1980 UBool isText() const { return std::holds_alternative<UnicodeString>(piece); }
1989 UBool isMarkup() const { return std::holds_alternative<Markup>(piece); }
1998 UBool isExpression() const { return std::holds_alternative<Expression>(piece); }
2008 const Expression& contents() const;
2018 const Markup& asMarkup() const;
2028 const UnicodeString& asText() const;
2037 friend inline void swap(PatternPart& p1, PatternPart& p2) noexcept {
2038 using std::swap;
2039
2040 swap(p1.piece, p2.piece);
2041 }
2062 virtual ~PatternPart();
2072 explicit PatternPart(const UnicodeString& t) : piece(t) {}
2082 explicit PatternPart(Expression&& e) : piece(e) {}
2092 explicit PatternPart(Markup&& m) : piece(m) {}
2100 PatternPart() = default;
2101 private:
2102 friend class Pattern;
2103
2104 std::variant<UnicodeString, Expression, Markup> piece;
2105 }; // class PatternPart
2106 } // namespace data_model
2107} // namespace message2
2108
2110// Export an explicit template instantiation of the LocalPointer that is used as a
2111// data member of various MFDataModel classes.
2112// (When building DLLs for Windows this is required.)
2113// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2114// for similar examples.)
2115#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2116#if defined(_MSC_VER)
2117// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
2118#pragma warning(push)
2119#pragma warning(disable: 4661)
2120#endif
2125#if defined(_MSC_VER)
2126#pragma warning(pop)
2127#endif
2128#endif
2130
2131namespace message2 {
2132 namespace data_model {
2143 class U_I18N_API Pattern : public UObject {
2144 private:
2145 friend class PatternPart;
2146
2147 public:
2148 struct Iterator;
2158 Iterator begin() const {
2159 return Iterator(this, 0);
2160 }
2170 Iterator end() const {
2171 return Iterator(this, len);
2172 }
2182 class U_I18N_API Builder : public UMemory {
2183 private:
2184 friend class Pattern;
2185
2186 UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
2187
2188 public:
2234 Pattern build(UErrorCode& status) const noexcept;
2251 virtual ~Builder();
2252 }; // class Pattern::Builder
2253
2261 Pattern() : parts(LocalArray<PatternPart>()) {}
2270 friend inline void swap(Pattern& p1, Pattern& p2) noexcept {
2271 using std::swap;
2272
2273 swap(p1.len, p2.len);
2274 swap(p1.parts, p2.parts);
2275 }
2282 Pattern(const Pattern& other) noexcept;
2289 Pattern& operator=(Pattern) noexcept;
2296 virtual ~Pattern();
2297
2308 private:
2309 using iterator_category = std::forward_iterator_tag;
2310 using difference_type = std::ptrdiff_t;
2311 using value_type = std::variant<UnicodeString, Expression, Markup>;
2312 using pointer = value_type*;
2313 using reference = const value_type&;
2314
2315 friend class Pattern;
2316 Iterator(const Pattern* p, int32_t i) : pos(i), pat(p) {}
2317 friend bool operator== (const Iterator& a, const Iterator& b) { return (a.pat == b.pat && a.pos == b.pos); }
2318
2319 int32_t pos;
2320 const Pattern* pat;
2321
2322 public:
2329 reference operator*() const {
2330 const PatternPart& part = pat->parts[pos];
2331 return patternContents(part);
2332 }
2339 Iterator operator++() { pos++; return *this; }
2346 friend bool operator!= (const Iterator& a, const Iterator& b) { return !(a == b); }
2347 }; // struct Iterator
2348
2349 private:
2350 friend class Builder;
2351 friend class message2::MessageFormatter;
2352 friend class message2::Serializer;
2353
2354 // Possibly-empty array of parts
2355 int32_t len = 0;
2357
2358 Pattern(const UVector& parts, UErrorCode& status);
2359 // Helper
2360 static void initParts(Pattern&, const Pattern&);
2361
2370 int32_t numParts() const { return len; }
2381 const PatternPart& getPart(int32_t i) const;
2382
2383 // Gets around not being able to declare Pattern::Iterator as a friend
2384 // in PatternPart
2385 static const std::variant<UnicodeString, Expression, Markup>& patternContents(const PatternPart& p) {
2386 return p.piece;
2387 }
2388
2389 }; // class Pattern
2390
2401 class U_I18N_API Variant : public UObject {
2402 public:
2411 const Pattern& getPattern() const { return p; }
2420 const SelectorKeys& getKeys() const { return k; }
2432 Variant(const SelectorKeys& keys, Pattern&& pattern) : k(keys), p(std::move(pattern)) {}
2441 friend inline void swap(Variant& v1, Variant& v2) noexcept {
2442 using std::swap;
2443
2444 swap(v1.k, v2.k);
2445 swap(v1.p, v2.p);
2446 }
2453 Variant& operator=(Variant other) noexcept;
2461 Variant() = default;
2468 Variant(const Variant&);
2475 virtual ~Variant();
2476 private:
2477 /* const */ SelectorKeys k;
2478 /* const */ Pattern p;
2479 }; // class Variant
2480 } // namespace data_model
2481
2482 namespace data_model {
2493 class U_I18N_API Binding : public UObject {
2494 public:
2503 const Expression& getValue() const;
2512 const VariableName& getVariable() const { return var; }
2527 static Binding input(UnicodeString&& variableName, Expression&& rhs, UErrorCode& errorCode);
2535 UBool isLocal() const { return local; }
2545 Binding(const VariableName& v, Expression&& e) : var(v), expr(std::move(e)), local(true), annotation(nullptr) {}
2554 friend inline void swap(Binding& b1, Binding& b2) noexcept {
2555 using std::swap;
2556
2557 swap(b1.var, b2.var);
2558 swap(b1.expr, b2.expr);
2559 swap(b1.local, b2.local);
2560 b1.updateAnnotation();
2561 b2.updateAnnotation();
2562 }
2569 Binding(const Binding& other);
2576 Binding& operator=(Binding) noexcept;
2584 Binding() : local(true) {}
2591 virtual ~Binding();
2592 private:
2593 friend class message2::Checker;
2594 friend class message2::MessageFormatter;
2595 friend class message2::Parser;
2596 friend class message2::Serializer;
2597
2598 /* const */ VariableName var;
2599 /* const */ Expression expr;
2600 /* const */ bool local;
2601
2602 // The following field is always nullptr for a local
2603 // declaration, and possibly nullptr for an .input declaration
2604 // If non-null, the referent is a member of `expr` so
2605 // its lifetime is the same as the lifetime of the enclosing Binding
2606 // (as long as there's no mutation)
2607 const Callable* annotation = nullptr;
2608
2609 const OptionMap& getOptionsInternal() const;
2610
2611 bool hasAnnotation() const { return !local && (annotation != nullptr); }
2612 void updateAnnotation();
2613 }; // class Binding
2614 } // namespace data_model
2615} // namespace message2
2616
2618// Export an explicit template instantiation of the LocalPointer that is used as a
2619// data member of various MFDataModel classes.
2620// (When building DLLs for Windows this is required.)
2621// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2622// for similar examples.)
2623#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2624#if defined(_MSC_VER)
2625// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
2626#pragma warning(push)
2627#pragma warning(disable: 4661)
2628#endif
2629template class U_I18N_API LocalPointerBase<message2::data_model::Variant>;
2630template class U_I18N_API LocalPointerBase<message2::data_model::Binding>;
2631template class U_I18N_API LocalArray<message2::data_model::Variant>;
2632template class U_I18N_API LocalArray<message2::data_model::Binding>;
2633#if defined(_MSC_VER)
2634#pragma warning(pop)
2635#endif
2636#endif
2638
2639namespace message2 {
2640 using namespace data_model;
2641
2642
2643 // Internal only
2644
2645 class MFDataModel;
2646
2647 #ifndef U_IN_DOXYGEN
2648 class Matcher {
2649 public:
2650 Matcher& operator=(Matcher);
2651 Matcher(const Matcher&);
2660 friend inline void swap(Matcher& m1, Matcher& m2) noexcept {
2661 using std::swap;
2662
2663 swap(m1.selectors, m2.selectors);
2664 swap(m1.numSelectors, m2.numSelectors);
2665 swap(m1.variants, m2.variants);
2666 swap(m1.numVariants, m2.numVariants);
2667 }
2668 private:
2669
2670 friend class MFDataModel;
2671
2672 Matcher(Expression* ss, int32_t ns, Variant* vs, int32_t nv) : selectors(ss), numSelectors(ns), variants(vs), numVariants(nv) {
2673 if (selectors == nullptr) {
2674 numSelectors = 0;
2675 }
2676 if (variants == nullptr) {
2677 numVariants = 0;
2678 }
2679 }
2680 Matcher() {}
2681 // The expressions that are being matched on.
2682 LocalArray<Expression> selectors;
2683 // The number of selectors
2684 int32_t numSelectors = 0;
2685 // The list of `when` clauses (case arms).
2686 LocalArray<Variant> variants;
2687 // The number of variants
2688 int32_t numVariants = 0;
2689 }; // class Matcher
2690 #endif
2691} // namespace message2
2692
2693U_NAMESPACE_END
2694
2696// Export an explicit template instantiation of the std::variant that is used as a
2697// data member of various MFDataModel classes.
2698// (When building DLLs for Windows this is required.)
2699// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2700// for similar examples.)
2701#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2702#if defined(_MSC_VER)
2703template class U_I18N_API std::_Variant_storage_<false, icu::message2::Matcher,icu::message2::data_model::Pattern>;
2704#endif
2705template class U_I18N_API std::variant<icu::message2::Matcher,icu::message2::data_model::Pattern>;
2706#endif
2708
2709U_NAMESPACE_BEGIN
2710
2711namespace message2 {
2712 // -----------------------------------------------------------------------
2713 // Public MFDataModel class
2714
2731 class U_I18N_API MFDataModel : public UMemory {
2732 /*
2733 Classes that represent nodes in the data model are nested inside the
2734 `MFDataModel` class.
2735
2736 Classes such as `Expression`, `Pattern` and `VariantMap` are immutable and
2737 are constructed using the builder pattern.
2738
2739 Most classes representing nodes have copy constructors. This is because builders
2740 contain immutable data that must be copied when calling `build()`, since the builder
2741 could go out of scope before the immutable result of the builder does. Copying is
2742 also necessary to prevent unexpected mutation if intermediate builders are saved
2743 and mutated again after calling `build()`.
2744
2745 The copy constructors perform a deep copy, for example by copying the entire
2746 list of options for an `Operator` (and copying the entire underlying vector.)
2747 Some internal fields should be `const`, but are declared as non-`const` to make
2748 the copy constructor simpler to implement. (These are noted throughout.) In
2749 other words, those fields are `const` except during the execution of a copy
2750 constructor.
2751
2752 On the other hand, intermediate `Builder` methods that return a `Builder&`
2753 mutate the state of the builder, so in code like:
2754
2755 Expression::Builder& exprBuilder = Expression::builder()-> setOperand(foo);
2756 Expression::Builder& exprBuilder2 = exprBuilder.setOperator(bar);
2757
2758 the call to `setOperator()` would mutate `exprBuilder`, since `exprBuilder`
2759 and `exprBuilder2` are references to the same object.
2760
2761 An alternate choice would be to make `build()` destructive, so that copying would
2762 be unnecessary. Or, both copying and moving variants of `build()` could be
2763 provided. Copying variants of the intermediate `Builder` methods could be
2764 provided as well, if this proved useful.
2765 */
2766 public:
2775 std::vector<Binding> getLocalVariables() const {
2776 std::vector<Binding> result;
2777 if (!bogus) {
2778 return toStdVector<Binding>(bindings.getAlias(), bindingsLen);
2779 }
2780 return {};
2781 }
2790 const std::vector<Expression> getSelectors() const {
2791 if (std::holds_alternative<Pattern>(body)) {
2792 return {};
2793 }
2794 const Matcher* match = std::get_if<Matcher>(&body);
2795 // match must be non-null, given the previous check
2796 return toStdVector<Expression>(match->selectors.getAlias(), match->numSelectors);
2797 }
2806 std::vector<Variant> getVariants() const {
2807 // Return empty vector if no variants
2808 if (std::holds_alternative<Pattern>(body)) {
2809 return {};
2810 }
2811 const Matcher* match = std::get_if<Matcher>(&body);
2812 // match must be non-null, given the previous check
2813 return toStdVector<Variant>(match->variants.getAlias(), match->numVariants);
2814 return {};
2815 }
2824 std::vector<UnsupportedStatement> getUnsupportedStatements() const {
2825 std::vector<UnsupportedStatement> result;
2826 if (!bogus) {
2827 return toStdVector<UnsupportedStatement>(unsupportedStatements.getAlias(), unsupportedStatementsLen);
2828 }
2829 return {};
2830 }
2840 const Pattern& getPattern() const;
2841
2849 class U_I18N_API Builder;
2850
2858 MFDataModel();
2867 friend inline void swap(MFDataModel& m1, MFDataModel& m2) noexcept {
2868 using std::swap;
2869
2870 if (m1.bogus) {
2871 m2.bogus = true;
2872 return;
2873 }
2874 if (m2.bogus) {
2875 m1.bogus = true;
2876 return;
2877 }
2878 swap(m1.body, m2.body);
2879 swap(m1.bindings, m2.bindings);
2880 swap(m1.bindingsLen, m2.bindingsLen);
2881 swap(m1.unsupportedStatements, m2.unsupportedStatements);
2882 swap(m1.unsupportedStatementsLen, m2.unsupportedStatementsLen);
2883 }
2890 MFDataModel& operator=(MFDataModel) noexcept;
2897 MFDataModel(const MFDataModel& other);
2904 virtual ~MFDataModel();
2905
2913 class U_I18N_API Builder : public UMemory {
2914 private:
2915 friend class MFDataModel;
2916
2917 void checkDuplicate(const VariableName&, UErrorCode&) const;
2918 void buildSelectorsMessage(UErrorCode&);
2919 bool hasPattern = true;
2920 bool hasSelectors = false;
2921 Pattern pattern;
2922 // The following members are not LocalPointers for the same reason as in SelectorKeys::Builder
2923 UVector* selectors = nullptr;
2924 UVector* variants = nullptr;
2925 UVector* bindings = nullptr;
2926 UVector* unsupportedStatements = nullptr;
2927 public:
2976 Builder& addVariant(SelectorKeys&& keys, Pattern&& pattern, UErrorCode& errorCode) noexcept;
2988 Builder& setPattern(Pattern&& pattern);
3008 MFDataModel build(UErrorCode& status) const noexcept;
3028 virtual ~Builder();
3029 }; // class Builder
3030
3031 private:
3032 friend class Checker;
3033 friend class MessageFormatter;
3034 friend class Serializer;
3035
3036 Pattern empty; // Provided so that `getPattern()` can return a result
3037 // if called on a selectors message
3038 bool hasPattern() const { return std::holds_alternative<Pattern>(body); }
3039
3040 bool bogus = false; // Set if a copy constructor fails
3041
3042 // A message body is either a matcher (selector list and variant list),
3043 // or a single pattern
3044 std::variant<Matcher, Pattern> body;
3045
3046 // Bindings for local variables
3047 /* const */ LocalArray<Binding> bindings;
3048 int32_t bindingsLen = 0;
3049
3050 // Unsupported statements
3051 // (Treated as a type of `declaration` in the data model spec;
3052 // stored separately for convenience)
3053 /* const */ LocalArray<UnsupportedStatement> unsupportedStatements;
3054 int32_t unsupportedStatementsLen = 0;
3055
3056 const Binding* getLocalVariablesInternal() const;
3057 const Expression* getSelectorsInternal() const;
3058 const Variant* getVariantsInternal() const;
3059 const UnsupportedStatement* getUnsupportedStatementsInternal() const;
3060
3061 int32_t numSelectors() const {
3062 const Matcher* matcher = std::get_if<Matcher>(&body);
3063 return (matcher == nullptr ? 0 : matcher->numSelectors);
3064 }
3065 int32_t numVariants() const {
3066 const Matcher* matcher = std::get_if<Matcher>(&body);
3067 return (matcher == nullptr ? 0 : matcher->numVariants);
3068 }
3069
3070 // Helper
3071 void initBindings(const Binding*);
3072
3073 MFDataModel(const Builder& builder, UErrorCode&) noexcept;
3074 }; // class MFDataModel
3075
3076} // namespace message2
3077
3078U_NAMESPACE_END
3079
3080#endif // U_HIDE_DEPRECATED_API
3081
3082#endif /* #if !UCONFIG_NO_MF2 */
3083
3084#endif /* #if !UCONFIG_NO_FORMATTING */
3085
3086#endif /* U_SHOW_CPLUSPLUS_API */
3087
3088#endif // MESSAGEFORMAT_DATA_MODEL_H
3089
3090// eof
3091
"Smart pointer" class, deletes objects via the C++ array delete[] operator.
"Smart pointer" base class; do not use directly: use LocalPointer etc.
T * getAlias() const
Access without ownership change.
UMemory is the common ICU base class.
Definition uobject.h:115
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
The mutable MFDataModel::Builder class allows the data model to be constructed incrementally.
Builder(UErrorCode &status)
Default constructor.
Builder & addUnsupportedStatement(UnsupportedStatement &&s, UErrorCode &status)
Adds an unsupported statement.
Builder & addBinding(Binding &&b, UErrorCode &status)
Adds a binding, There must not already be a binding with the same name.
MFDataModel build(UErrorCode &status) const noexcept
Constructs a new immutable data model.
Builder & addVariant(SelectorKeys &&keys, Pattern &&pattern, UErrorCode &errorCode) noexcept
Adds a single variant.
Builder & addSelector(Expression &&selector, UErrorCode &errorCode) noexcept
Adds a selector expression.
Builder & setPattern(Pattern &&pattern)
Sets the body of the message as a pattern.
The mutable Expression::Builder class allows the operator to be constructed incrementally.
Builder & addAttribute(const UnicodeString &key, Operand &&value, UErrorCode &status)
Adds a single attribute.
Expression build(UErrorCode &status)
Constructs a new immutable Expression using the operand and operator that were previously set.
Builder & setOperand(Operand &&rAnd)
Sets the operand of this expression.
Builder & setOperator(Operator &&rAtor)
Sets the operator of this expression.
Builder(UErrorCode &status)
Default constructor.
The Expression class corresponds to the expression nonterminal in the MessageFormat 2 grammar and the...
const Operand & getOperand() const
Accesses the operand of this expression.
UBool isFunctionCall() const
Checks if this expression has a function annotation (with or without an operand).
Expression & operator=(Expression) noexcept
Assignment operator.
UBool isStandaloneAnnotation() const
Checks if this expression is an annotation with no operand.
UBool isReserved() const
Returns true if and only if this expression is annotated with a reserved sequence.
std::vector< Option > getAttributes() const
Gets the attributes of this expression.
Expression(const Expression &other)
Copy constructor.
const Operator * getOperator(UErrorCode &status) const
Accesses the function or reserved sequence annotating this expression.
friend void swap(Expression &e1, Expression &e2) noexcept
Non-member swap function.
The Literal class corresponds to the literal nonterminal in the MessageFormat 2 grammar,...
UBool isQuoted() const
Determines if this literal appeared as a quoted literal in the message.
const UnicodeString & unquoted() const
Returns the parsed string contents of this literal.
friend void swap(Literal &l1, Literal &l2) noexcept
Non-member swap function.
Literal(UBool q, const UnicodeString &s)
Literal constructor.
UnicodeString quoted() const
Returns the quoted representation of this literal (enclosed in '|' characters)
Literal()=default
Default constructor.
bool operator<(const Literal &other) const
Less than operator.
Literal(const Literal &other)
Copy constructor.
Literal & operator=(Literal) noexcept
Assignment operator.
bool operator==(const Literal &other) const
Equality operator.
The mutable Markup::Builder class allows the markup to be constructed incrementally.
Builder & setStandalone()
Sets this to be a standalone markup.
Builder(UErrorCode &status)
Default constructor.
Builder & addOption(const UnicodeString &key, Operand &&value, UErrorCode &status) noexcept
Adds a single option.
Builder & setClose()
Sets this to be an closing markup.
Builder & setName(const UnicodeString &n)
Sets the name of this markup.
Builder & addAttribute(const UnicodeString &key, Operand &&value, UErrorCode &status) noexcept
Adds a single attribute.
Markup build(UErrorCode &status)
Constructs a new immutable Markup using the name and type and (optionally) options and attributes tha...
Builder & setOpen()
Sets this to be an opening markup.
The Markup class corresponds to the markup nonterminal in the MessageFormat 2 grammar and the markup ...
std::vector< Option > getAttributes() const
Gets the attributes of this markup.
UBool isOpen() const
Checks if this markup is an opening tag.
std::vector< Option > getOptions() const
Gets the options of this markup.
UBool isClose() const
Checks if this markup is an closing tag.
virtual ~Markup()
Destructor.
const UnicodeString & getName() const
Gets the name of this markup.
UBool isStandalone() const
Checks if this markup is an standalone tag.
The mutable Operator::Builder class allows the operator to be constructed incrementally.
Builder & setFunctionName(FunctionName &&func)
Sets this operator to be a function annotation and sets its name to func.
Operator build(UErrorCode &status)
Constructs a new immutable Operator using the reserved annotation or the function name and options th...
Builder & addOption(const UnicodeString &key, Operand &&value, UErrorCode &status) noexcept
Sets this operator to be a function annotation and adds a single option.
Builder(UErrorCode &status)
Default constructor.
Builder & setReserved(Reserved &&reserved)
Sets this operator to be a reserved sequence.
An Option pairs an option name with an Operand.
Option(const Option &other)
Copy constructor.
virtual ~Option()
Destructor.
Option & operator=(Option other) noexcept
Assignment operator.
Option(const UnicodeString &n, Operand &&r)
Constructor.
const UnicodeString & getName() const
Accesses the left-hand side of the option.
const Operand & getValue() const
Accesses the right-hand side of the option.
friend void swap(Option &o1, Option &o2) noexcept
Non-member swap function.
A PatternPart is a single element (text or expression) in a Pattern.
UBool isExpression() const
Checks if the part is an expression part.
PatternPart(const UnicodeString &t)
Text part constructor.
const Expression & contents() const
Accesses the expression of the part.
PatternPart(Expression &&e)
Expression part constructor.
const UnicodeString & asText() const
Accesses the text contents of the part.
PatternPart()=default
Default constructor.
PatternPart(Markup &&m)
Markup part constructor.
UBool isMarkup() const
Checks if the part is a markup part.
UBool isText() const
Checks if the part is a text part.
const Markup & asMarkup() const
Accesses the expression of the part.
PatternPart(const PatternPart &other)
Copy constructor.
PatternPart & operator=(PatternPart) noexcept
Assignment operator.
friend void swap(PatternPart &p1, PatternPart &p2) noexcept
Non-member swap function.
The mutable Pattern::Builder class allows the pattern to be constructed one part at a time.
Builder & add(UnicodeString &&part, UErrorCode &status) noexcept
Adds a single text part to the pattern.
Builder & add(Markup &&part, UErrorCode &status) noexcept
Adds a single markup part to the pattern.
Pattern build(UErrorCode &status) const noexcept
Constructs a new immutable Pattern using the list of parts set with previous add() calls.
Builder(UErrorCode &status)
Default constructor.
Builder & add(Expression &&part, UErrorCode &status) noexcept
Adds a single expression part to the pattern.
The mutable Reserved::Builder class allows the reserved sequence to be constructed one part at a time...
Reserved build(UErrorCode &status) const noexcept
Constructs a new immutable Reserved using the list of parts set with previous add() calls.
Builder & add(Literal &&part, UErrorCode &status) noexcept
Adds a single literal to the reserved sequence.
Builder(UErrorCode &status)
Default constructor.
The Reserved class represents a reserved annotation, as in the reserved nonterminal in the MessageFor...
Reserved & operator=(Reserved) noexcept
Assignment operator.
int32_t numParts() const
A Reserved is a sequence of literals.
Reserved(const Reserved &other)
Copy constructor.
friend void swap(Reserved &r1, Reserved &r2) noexcept
Non-member swap function.
const Literal & getPart(int32_t i) const
Indexes into the sequence.
The mutable SelectorKeys::Builder class allows the key list to be constructed one key at a time.
Builder & add(Key &&key, UErrorCode &status) noexcept
Adds a single key to the list.
Builder(UErrorCode &status)
Default constructor.
SelectorKeys build(UErrorCode &status) const
Constructs a new immutable SelectorKeys using the list of keys set with previous add() calls.
The mutable UnsupportedStatement::Builder class allows the statement to be constructed incrementally.
Builder & setKeyword(const UnicodeString &k)
Sets the keyword of this statement.
Builder(UErrorCode &status)
Default constructor.
Builder & addExpression(Expression &&e, UErrorCode &status)
Adds an expression to this statement.
UnsupportedStatement build(UErrorCode &status) const
Constructs a new immutable UnsupportedStatement using the keyword, body and (if applicable) expressio...
Builder & setBody(Reserved &&r)
Sets the body of this statement.
The UnsupportedStatement class corresponds to the reserved-statement nonterminal in the MessageFormat...
UnsupportedStatement & operator=(UnsupportedStatement) noexcept
Assignment operator.
const UnicodeString & getKeyword() const
Accesses the keyword of this statement.
const Reserved * getBody(UErrorCode &status) const
Accesses the reserved-body of this statement.
std::vector< Expression > getExpressions() const
Accesses the expressions of this statement.
friend void swap(UnsupportedStatement &s1, UnsupportedStatement &s2) noexcept
Non-member swap function.
UnsupportedStatement(const UnsupportedStatement &other)
Copy constructor.
C++ API: "Smart pointers" for use with and in ICU4C C++ code.
U_EXPORT UBool operator==(const StringPiece &x, const StringPiece &y)
Global operator == for StringPiece.
The Pattern::Iterator class provides an iterator over the formattable parts of a pattern.
reference operator*() const
Dereference operator (gets the element at the current iterator position)
Iterator operator++()
Increment operator (advances to the next iterator position)
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
#define U_I18N_API
Set to export library symbols from inside the i18n library, and to import them from outside.
Definition utypes.h:301