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
45#if defined(U_REAL_MSVC)
46#pragma warning(push)
47// Ignore warning 4251 as these templates are instantiated later in this file,
48// after the classes used to instantiate them have been defined.
49#pragma warning(disable: 4251)
50#endif
51
52namespace message2 {
53 class Checker;
54 class MFDataModel;
55 class MessageFormatter;
56 class Parser;
57 class Serializer;
58
59
60 namespace data_model {
61 class Binding;
62 class Literal;
63 class Operator;
64
76 class U_I18N_API Reserved : public UMemory {
77 public:
97 const Literal& getPart(int32_t i) const;
98
108 class U_I18N_API Builder : public UMemory {
109 private:
110 UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
111
112 public:
136 Reserved build(UErrorCode& status) const noexcept;
153 virtual ~Builder();
154 Builder(const Builder&) = delete;
155 Builder& operator=(const Builder&) = delete;
156 Builder(Builder&&) = delete;
157 Builder& operator=(Builder&&) = delete;
158 }; // class Reserved::Builder
167 friend inline void swap(Reserved& r1, Reserved& r2) noexcept {
168 using std::swap;
169
170 swap(r1.bogus, r2.bogus);
171 swap(r1.parts, r2.parts);
172 swap(r1.len, r2.len);
173 }
202 virtual ~Reserved();
203 private:
204 friend class Builder;
205 friend class Operator;
206
207 // True if a copy failed; this has to be distinguished
208 // from a valid `Reserved` with empty parts
209 bool bogus = false;
210
211 // Possibly-empty list of parts
212 // `literal` reserved as a quoted literal; `reserved-char` / `reserved-escape`
213 // strings represented as unquoted literals
214 /* const */ LocalArray<Literal> parts;
215 int32_t len = 0;
216
217 Reserved(const UVector& parts, UErrorCode& status) noexcept;
218 // Helper
219 static void initLiterals(Reserved&, const Reserved&);
220 };
221
233 class U_I18N_API Literal : public UObject {
234 public:
252 const UnicodeString& unquoted() const;
262 UBool isQuoted() const { return thisIsQuoted; }
274 Literal(UBool q, const UnicodeString& s) : thisIsQuoted(q), contents(s) {}
281 Literal(const Literal& other) : thisIsQuoted(other.thisIsQuoted), contents(other.contents) {}
290 friend inline void swap(Literal& l1, Literal& l2) noexcept {
291 using std::swap;
292
293 swap(l1.thisIsQuoted, l2.thisIsQuoted);
294 swap(l1.contents, l2.contents);
295 }
310 Literal() = default;
326 bool operator<(const Literal& other) const;
342 bool operator==(const Literal& other) const;
349 virtual ~Literal();
350
351 private:
352 friend class Reserved::Builder;
353
354 /* const */ bool thisIsQuoted = false;
355 /* const */ UnicodeString contents;
356 };
357 } // namespace data_model
358} // namespace message2
359
361// Export an explicit template instantiation of the LocalPointer that is used as a
362// data member of various MFDataModel classes.
363// (When building DLLs for Windows this is required.)
364// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
365// for similar examples.)
366#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
369#endif
370#if defined(U_REAL_MSVC)
371#pragma warning(pop)
372#endif
374
376
378// Export an explicit template instantiation of the std::variants and std::optionals
379// that are used as a data member of various MFDataModel classes.
380// (When building DLLs for Windows this is required.)
381// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
382// for similar examples.)
383#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
384#if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION)
385struct U_I18N_API std::_Nontrivial_dummy_type;
386template class U_I18N_API std::_Variant_storage_<false, icu::UnicodeString, icu::message2::data_model::Literal>;
387#endif
388template class U_I18N_API std::variant<icu::UnicodeString, icu::message2::data_model::Literal>;
389template class U_I18N_API std::optional<std::variant<icu::UnicodeString, icu::message2::data_model::Literal>>;
390template class U_I18N_API std::optional<icu::message2::data_model::Literal>;
391#endif
393
395
396namespace message2 {
397 namespace data_model {
398
413 class U_I18N_API Operand : public UObject {
414 public:
423 UBool isVariable() const;
432 UBool isLiteral() const;
441 virtual UBool isNull() const;
451 const UnicodeString& asVariable() const;
461 const Literal& asLiteral() const;
469 Operand() : contents(std::nullopt) {}
479 explicit Operand(const UnicodeString& v) : contents(VariableName(v)) {}
489 explicit Operand(const Literal& l) : contents(l) {}
498 friend inline void swap(Operand& o1, Operand& o2) noexcept {
499 using std::swap;
500 (void) o1;
501 (void) o2;
502 swap(o1.contents, o2.contents);
503 }
510 virtual Operand& operator=(Operand) noexcept;
517 Operand(const Operand&);
524 virtual ~Operand();
525 private:
526 std::optional<std::variant<VariableName, Literal>> contents;
527 }; // class Operand
528
544 class U_I18N_API Key : public UObject {
545 public:
554 UBool isWildcard() const { return !contents.has_value(); }
564 const Literal& asLiteral() const;
571 Key(const Key& other) : contents(other.contents) {}
579 Key() : contents(std::nullopt) {}
589 explicit Key(const Literal& lit) : contents(lit) {}
598 friend inline void swap(Key& k1, Key& k2) noexcept {
599 using std::swap;
600
601 swap(k1.contents, k2.contents);
602 }
609 Key& operator=(Key) noexcept;
623 bool operator<(const Key& other) const;
637 bool operator==(const Key& other) const;
644 virtual ~Key();
645 private:
646 /* const */ std::optional<Literal> contents;
647 }; // class Key
648 } // namespace data_model
649} // namespace message2
650
652// Export an explicit template instantiation of the LocalPointer that is used as a
653// data member of various MFDataModel classes.
654// (When building DLLs for Windows this is required.)
655// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
656// for similar examples.)
657#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
658template class U_I18N_API LocalPointerBase<message2::data_model::Key>;
659template class U_I18N_API LocalArray<message2::data_model::Key>;
660#endif
662
663namespace message2 {
664 namespace data_model {
675 class U_I18N_API SelectorKeys : public UObject {
676 public:
687 std::vector<Key> getKeys() const {
688 return toStdVector<Key>(keys.getAlias(), len);
689 }
699 class U_I18N_API Builder : public UMemory {
700 private:
701 friend class SelectorKeys;
702 UVector* keys; // This is a raw pointer and not a LocalPointer<UVector> to avoid undefined behavior warnings,
703 // since UVector is forward-declared
704 // The vector owns its elements
705 public:
716 Builder& add(Key&& key, UErrorCode& status) noexcept;
729 SelectorKeys build(UErrorCode& status) const;
746 virtual ~Builder();
747 Builder(const Builder&) = delete;
748 Builder& operator=(const Builder&) = delete;
749 Builder(Builder&&) = delete;
750 Builder& operator=(Builder&&) = delete;
751 }; // class SelectorKeys::Builder
766 bool operator<(const SelectorKeys& other) const;
774 SelectorKeys() : len(0) {}
783 friend inline void swap(SelectorKeys& s1, SelectorKeys& s2) noexcept {
784 using std::swap;
785
786 swap(s1.len, s2.len);
787 swap(s1.keys, s2.keys);
788 }
795 SelectorKeys(const SelectorKeys& other);
802 SelectorKeys& operator=(SelectorKeys other) noexcept;
809 virtual ~SelectorKeys();
810 private:
811 friend class Builder;
812 friend class message2::Checker;
813 friend class message2::MessageFormatter;
814 friend class message2::Serializer;
815
816 /* const */ LocalArray<Key> keys;
817 /* const */ int32_t len;
818
819 const Key* getKeysInternal() const;
820 SelectorKeys(const UVector& ks, UErrorCode& status);
821 }; // class SelectorKeys
822
823
824 } // namespace data_model
825
826
827 namespace data_model {
828 class Operator;
829
838 class U_I18N_API Option : public UObject {
839 public:
848 const Operand& getValue() const { return rand; }
857 const UnicodeString& getName() const { return name; }
868 Option(const UnicodeString& n, Operand&& r) : name(n), rand(std::move(r)) {}
885 friend inline void swap(Option& o1, Option& o2) noexcept {
886 using std::swap;
887
888 swap(o1.name, o2.name);
889 swap(o1.rand, o2.rand);
890 }
911 virtual ~Option();
912 private:
913 /* const */ UnicodeString name;
914 /* const */ Operand rand;
915 }; // class Option
916 } // namespace data_model
917} // namespace message2
918
920// Export an explicit template instantiation of the LocalPointer that is used as a
921// data member of various MFDataModel classes.
922// (When building DLLs for Windows this is required.)
923// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
924// for similar examples.)
925#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
928#endif
930
931namespace message2 {
932 namespace data_model {
933 // Internal only
934 #ifndef U_IN_DOXYGEN
935 // Options
936 // This is a wrapper class around a vector of options that provides lookup operations
937 class U_I18N_API OptionMap : public UObject {
938 public:
939 int32_t size() const;
940 // Needs to take an error code b/c an earlier copy might have failed
941 const Option& getOption(int32_t, UErrorCode&) const;
942 friend inline void swap(OptionMap& m1, OptionMap& m2) noexcept {
943 using std::swap;
944
945 swap(m1.bogus, m2.bogus);
946 swap(m1.options, m2.options);
947 swap(m1.len, m2.len);
948 }
949 OptionMap() : len(0) {}
950 OptionMap(const OptionMap&);
951 OptionMap& operator=(OptionMap);
952 std::vector<Option> getOptions() const {
953 return toStdVector<Option>(options.getAlias(), len);
954 }
955 OptionMap(const UVector&, UErrorCode&);
956 OptionMap(Option*, int32_t);
957 virtual ~OptionMap();
958
959 class U_I18N_API Builder : public UObject {
960 private:
961 UVector* options;
962 bool checkDuplicates = true;
963 public:
964 Builder& add(Option&& opt, UErrorCode&);
965 Builder(UErrorCode&);
966 static Builder attributes(UErrorCode&);
967 // As this class is private, build() is destructive
968 OptionMap build(UErrorCode&);
969 friend inline void swap(Builder& m1, Builder& m2) noexcept {
970 using std::swap;
971
972 swap(m1.options, m2.options);
973 swap(m1.checkDuplicates, m2.checkDuplicates);
974 }
975 Builder(Builder&&);
976 Builder(const Builder&) = delete;
977 Builder& operator=(Builder) noexcept;
978 virtual ~Builder();
979 }; // class OptionMap::Builder
980 private:
981 friend class message2::Serializer;
982
983 bool bogus = false;
984 LocalArray<Option> options;
985 int32_t len;
986 }; // class OptionMap
987 #endif
988
989 // Internal use only
990 #ifndef U_IN_DOXYGEN
991 class U_I18N_API Callable : public UObject {
992 public:
993 friend inline void swap(Callable& c1, Callable& c2) noexcept {
994 using std::swap;
995
996 swap(c1.name, c2.name);
997 swap(c1.options, c2.options);
998 }
999 const FunctionName& getName() const { return name; }
1000 const OptionMap& getOptions() const { return options; }
1001 Callable(const FunctionName& f, const OptionMap& opts) : name(f), options(opts) {}
1002 Callable& operator=(Callable) noexcept;
1003 Callable(const Callable&);
1004 Callable() = default;
1005 virtual ~Callable();
1006 private:
1007 /* const */ FunctionName name;
1008 /* const */ OptionMap options;
1009 };
1010 #endif
1011 } // namespace data_model
1012} // namespace message2
1013
1014U_NAMESPACE_END
1015
1017// Export an explicit template instantiation of the std::variant that is used as a
1018// data member of various MFDataModel classes.
1019// (When building DLLs for Windows this is required.)
1020// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1021// for similar examples.)
1022#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1023#if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION)
1024template class U_I18N_API std::_Variant_storage_<false, icu::message2::data_model::Reserved,icu::message2::data_model::Callable>;
1025#endif
1026template class U_I18N_API std::variant<icu::message2::data_model::Reserved,icu::message2::data_model::Callable>;
1027#endif
1029
1030U_NAMESPACE_BEGIN
1031
1032namespace message2 {
1033 namespace data_model {
1049 class U_I18N_API Operator : public UObject {
1050 public:
1059 UBool isReserved() const { return std::holds_alternative<Reserved>(contents); }
1069 const FunctionName& getFunctionName() const;
1079 const Reserved& asReserved() const;
1089 std::vector<Option> getOptions() const {
1090 const Callable* f = std::get_if<Callable>(&contents);
1091 // This case should never happen, as the precondition is !isReserved()
1092 if (f == nullptr) { return {}; }
1093 const OptionMap& opts = f->getOptions();
1094 return opts.getOptions();
1095 }
1105 class U_I18N_API Builder : public UMemory {
1106 private:
1107 friend class Operator;
1108 bool isReservedSequence = false;
1109 bool hasFunctionName = false;
1110 bool hasOptions = false;
1111 Reserved asReserved;
1112 FunctionName functionName;
1113 OptionMap::Builder options;
1114 public:
1153 Builder& addOption(const UnicodeString &key, Operand&& value, UErrorCode& status) noexcept;
1188 virtual ~Builder();
1189 Builder(const Builder&) = delete;
1190 Builder& operator=(const Builder&) = delete;
1191 Builder(Builder&&) = delete;
1192 Builder& operator=(Builder&&) = delete;
1193 }; // class Operator::Builder
1200 Operator(const Operator& other) noexcept;
1209 friend inline void swap(Operator& o1, Operator& o2) noexcept {
1210 using std::swap;
1211
1212 swap(o1.contents, o2.contents);
1213 }
1220 Operator& operator=(Operator) noexcept;
1228 Operator() : contents(Reserved()) {}
1235 virtual ~Operator();
1236 private:
1237 friend class Binding;
1238 friend class Builder;
1239 friend class message2::Checker;
1240 friend class message2::MessageFormatter;
1241 friend class message2::Serializer;
1242
1243 // Function call constructor
1244 Operator(const FunctionName& f, const UVector& options, UErrorCode&);
1245 // Reserved sequence constructor
1246 Operator(const Reserved& r) : contents(r) {}
1247
1248 const OptionMap& getOptionsInternal() const;
1249 Operator(const FunctionName&, const OptionMap&);
1250 /* const */ std::variant<Reserved, Callable> contents;
1251 }; // class Operator
1252 } // namespace data_model
1253} // namespace message2
1254
1255U_NAMESPACE_END
1256
1258// Export an explicit template instantiation of the std::optional that is used as a
1259// data member of various MFDataModel classes.
1260// (When building DLLs for Windows this is required.)
1261// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1262// for similar examples.)
1263#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1264template class U_I18N_API std::optional<icu::message2::data_model::Operator>;
1265template class U_I18N_API std::optional<icu::message2::data_model::Reserved>;
1266#endif
1268
1269U_NAMESPACE_BEGIN
1270
1271namespace message2 {
1272 namespace data_model {
1273 // Internal only
1274 typedef enum UMarkupType {
1275 UMARKUP_OPEN = 0,
1276 UMARKUP_CLOSE,
1277 UMARKUP_STANDALONE,
1278 UMARKUP_COUNT
1279 } UMarkupType;
1280
1291 class U_I18N_API Markup : public UObject {
1292 public:
1301 UBool isOpen() const { return (type == UMARKUP_OPEN); }
1310 UBool isClose() const { return (type == UMARKUP_CLOSE); }
1319 UBool isStandalone() const { return (type == UMARKUP_STANDALONE); }
1328 const UnicodeString& getName() const { return name; }
1337 std::vector<Option> getOptions() const { return options.getOptions(); }
1346 std::vector<Option> getAttributes() const { return attributes.getOptions(); }
1361 virtual ~Markup();
1371 class U_I18N_API Builder : public UMemory {
1372 private:
1373 friend class Markup;
1374
1375 UnicodeString name;
1376 OptionMap::Builder options;
1377 OptionMap::Builder attributes;
1378 UMarkupType type = UMARKUP_COUNT;
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; }
1475 virtual ~Builder();
1476 Builder(const Builder&) = delete;
1477 Builder& operator=(const Builder&) = delete;
1478 Builder(Builder&&) = delete;
1479 Builder& operator=(Builder&&) = delete;
1480 }; // class Markup::Builder
1481
1482 private:
1483 friend class Builder;
1484 friend class message2::Serializer;
1485
1486 UMarkupType type;
1487 UnicodeString name;
1488 OptionMap options;
1489 OptionMap attributes;
1490 const OptionMap& getOptionsInternal() const { return options; }
1491 const OptionMap& getAttributesInternal() const { return attributes; }
1492 Markup(UMarkupType, UnicodeString, OptionMap&&, OptionMap&&);
1493 }; // class Markup
1494
1509 public:
1557 const Operator* getOperator(UErrorCode& status) const;
1567 const Operand& getOperand() const;
1576 std::vector<Option> getAttributes() const { return attributes.getOptions(); }
1586 class U_I18N_API Builder : public UMemory {
1587 private:
1588 friend class Expression;
1589
1590 bool hasOperand = false;
1591 bool hasOperator = false;
1592 Operand rand;
1593 Operator rator;
1594 OptionMap::Builder attributes;
1595 public:
1662 virtual ~Builder();
1663 Builder(const Builder&) = delete;
1664 Builder& operator=(const Builder&) = delete;
1665 Builder(Builder&&) = delete;
1666 Builder& operator=(Builder&&) = delete;
1667 }; // class Expression::Builder
1676 friend inline void swap(Expression& e1, Expression& e2) noexcept {
1677 using std::swap;
1678
1679 swap(e1.rator, e2.rator);
1680 swap(e1.rand, e2.rand);
1681 swap(e1.attributes, e2.attributes);
1682 }
1711 virtual ~Expression();
1712 private:
1713 friend class message2::Serializer;
1714
1715 /*
1716 Internally, an expression is represented as the application of an optional operator to an operand.
1717 The operand is always present; for function calls with no operand, it's represented
1718 as an operand for which `isNull()` is true.
1719
1720 Operator | Operand
1721 --------------------------------
1722 { |42| :fun opt=value } => (FunctionName=fun, | Literal(quoted=true, contents="42")
1723 options={opt: value})
1724 { abcd } => null | Literal(quoted=false, contents="abcd")
1725 { : fun opt=value } => (FunctionName=fun,
1726 options={opt: value}) | NullOperand()
1727 */
1728
1729 Expression(const Operator &rAtor, const Operand &rAnd, const OptionMap& attrs) : rator(rAtor), rand(rAnd), attributes(attrs) {}
1730 Expression(const Operand &rAnd, const OptionMap& attrs) : rator(std::nullopt), rand(Operand(rAnd)), attributes(attrs) {}
1731 Expression(const Operator &rAtor, const OptionMap& attrs) : rator(rAtor), rand(), attributes(attrs) {}
1732 /* const */ std::optional<Operator> rator;
1733 /* const */ Operand rand;
1734 /* const */ OptionMap attributes;
1735 const OptionMap& getAttributesInternal() const { return attributes; }
1736 }; // class Expression
1737 } // namespace data_model
1738} // namespace message2
1739
1741// Export an explicit template instantiation of the LocalPointer that is used as a
1742// data member of various MFDataModel classes.
1743// (When building DLLs for Windows this is required.)
1744// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
1745// for similar examples.)
1746#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
1747template class U_I18N_API LocalPointerBase<message2::data_model::Expression>;
1748template class U_I18N_API LocalArray<message2::data_model::Expression>;
1749#endif
1751
1752namespace message2 {
1753 namespace data_model {
1768 public:
1777 const UnicodeString& getKeyword() const { return keyword; }
1798 std::vector<Expression> getExpressions() const {
1799 if (expressionsLen <= 0 || !expressions.isValid()) {
1800 // This case should never happen, but we can't use an assertion here
1801 return {};
1802 }
1803 return toStdVector<Expression>(expressions.getAlias(), expressionsLen);
1804 }
1814 class U_I18N_API Builder : public UMemory {
1815 private:
1816 friend class UnsupportedStatement;
1817 friend class message2::Parser;
1818
1819 UnicodeString keyword;
1820 std::optional<Reserved> body;
1821 UVector* expressions; // Vector of expressions;
1822 // not a LocalPointer for
1823 // the same reason as in `SelectorKeys::builder`
1824 public:
1888 virtual ~Builder();
1889 Builder(const Builder&) = delete;
1890 Builder& operator=(const Builder&) = delete;
1891 Builder(Builder&&) = delete;
1892 Builder& operator=(Builder&&) = delete;
1893 }; // class UnsupportedStatement::Builder
1902 friend inline void swap(UnsupportedStatement& s1, UnsupportedStatement& s2) noexcept {
1903 using std::swap;
1904
1905 swap(s1.keyword, s2.keyword);
1906 swap(s1.body, s2.body);
1907 swap(s1.expressions, s2.expressions);
1908 swap(s1.expressionsLen, s2.expressionsLen);
1909 }
1939 private:
1940 friend class message2::Serializer;
1941
1942 /* const */ UnicodeString keyword;
1943 /* const */ std::optional<Reserved> body;
1944 /* const */ LocalArray<Expression> expressions;
1945 /* const */ int32_t expressionsLen = 0;
1946
1947 const Expression* getExpressionsInternal() const { return expressions.getAlias(); }
1948
1949 UnsupportedStatement(const UnicodeString&, const std::optional<Reserved>&, const UVector&, UErrorCode&);
1950 }; // class UnsupportedStatement
1951
1952 class Pattern;
1953
1954 // Despite the comments, `PatternPart` is internal-only
1965 class PatternPart : public UObject {
1966 public:
1975 UBool isText() const { return std::holds_alternative<UnicodeString>(piece); }
1984 UBool isMarkup() const { return std::holds_alternative<Markup>(piece); }
1993 UBool isExpression() const { return std::holds_alternative<Expression>(piece); }
2003 const Expression& contents() const;
2013 const Markup& asMarkup() const;
2023 const UnicodeString& asText() const;
2032 friend inline void swap(PatternPart& p1, PatternPart& p2) noexcept {
2033 using std::swap;
2034
2035 swap(p1.piece, p2.piece);
2036 }
2057 virtual ~PatternPart();
2067 explicit PatternPart(const UnicodeString& t) : piece(t) {}
2077 explicit PatternPart(Expression&& e) : piece(e) {}
2087 explicit PatternPart(Markup&& m) : piece(m) {}
2095 PatternPart() = default;
2096 private:
2097 friend class Pattern;
2098
2099 std::variant<UnicodeString, Expression, Markup> piece;
2100 }; // class PatternPart
2101 } // namespace data_model
2102} // namespace message2
2103
2105// Export an explicit template instantiation of the LocalPointer that is used as a
2106// data member of various MFDataModel classes.
2107// (When building DLLs for Windows this is required.)
2108// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2109// for similar examples.)
2110#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2115#endif
2117
2118namespace message2 {
2119 namespace data_model {
2130 class U_I18N_API Pattern : public UObject {
2131 private:
2132 friend class PatternPart;
2133
2134 public:
2135 struct Iterator;
2145 Iterator begin() const {
2146 return Iterator(this, 0);
2147 }
2157 Iterator end() const {
2158 return Iterator(this, len);
2159 }
2169 class U_I18N_API Builder : public UMemory {
2170 private:
2171 friend class Pattern;
2172
2173 UVector* parts; // Not a LocalPointer for the same reason as in `SelectorKeys::Builder`
2174
2175 public:
2221 Pattern build(UErrorCode& status) const noexcept;
2238 virtual ~Builder();
2239 Builder(const Builder&) = delete;
2240 Builder& operator=(const Builder&) = delete;
2241 Builder(Builder&&) = delete;
2242 Builder& operator=(Builder&&) = delete;
2243 }; // class Pattern::Builder
2244
2252 Pattern() : parts(LocalArray<PatternPart>()) {}
2261 friend inline void swap(Pattern& p1, Pattern& p2) noexcept {
2262 using std::swap;
2263
2264 swap(p1.bogus, p2.bogus);
2265 swap(p1.len, p2.len);
2266 swap(p1.parts, p2.parts);
2267 }
2274 Pattern(const Pattern& other);
2281 Pattern& operator=(Pattern) noexcept;
2288 virtual ~Pattern();
2289
2300 private:
2301 using iterator_category = std::forward_iterator_tag;
2302 using difference_type = std::ptrdiff_t;
2303 using value_type = std::variant<UnicodeString, Expression, Markup>;
2304 using pointer = value_type*;
2305 using reference = const value_type&;
2306
2307 friend class Pattern;
2308 Iterator(const Pattern* p, int32_t i) : pos(i), pat(p) {}
2309 friend bool operator== (const Iterator& a, const Iterator& b) { return (a.pat == b.pat && a.pos == b.pos); }
2310
2311 int32_t pos;
2312 const Pattern* pat;
2313
2314 public:
2321 reference operator*() const {
2322 const PatternPart& part = pat->parts[pos];
2323 return patternContents(part);
2324 }
2331 Iterator operator++() { pos++; return *this; }
2338 friend bool operator!= (const Iterator& a, const Iterator& b) { return !(a == b); }
2339 }; // struct Iterator
2340
2341 private:
2342 friend class Builder;
2343 friend class message2::MessageFormatter;
2344 friend class message2::Serializer;
2345
2346 // Set to true if a copy constructor fails;
2347 // needed in order to distinguish an uninitialized
2348 // Pattern from a 0-length pattern
2349 bool bogus = false;
2350
2351 // Possibly-empty array of parts
2352 int32_t len = 0;
2354
2355 Pattern(const UVector& parts, UErrorCode& status);
2356 // Helper
2357 static void initParts(Pattern&, const Pattern&);
2358
2367 int32_t numParts() const;
2378 const PatternPart& getPart(int32_t i) const;
2379
2380 // Gets around not being able to declare Pattern::Iterator as a friend
2381 // in PatternPart
2382 static const std::variant<UnicodeString, Expression, Markup>&
2383 patternContents(const PatternPart& p) { return p.piece; }
2384 }; // class Pattern
2385
2396 class U_I18N_API Variant : public UObject {
2397 public:
2406 const Pattern& getPattern() const { return p; }
2415 const SelectorKeys& getKeys() const { return k; }
2427 Variant(const SelectorKeys& keys, Pattern&& pattern) : k(keys), p(std::move(pattern)) {}
2436 friend inline void swap(Variant& v1, Variant& v2) noexcept {
2437 using std::swap;
2438
2439 swap(v1.k, v2.k);
2440 swap(v1.p, v2.p);
2441 }
2448 Variant& operator=(Variant other) noexcept;
2456 Variant() = default;
2463 Variant(const Variant&);
2470 virtual ~Variant();
2471 private:
2472 /* const */ SelectorKeys k;
2473 /* const */ Pattern p;
2474 }; // class Variant
2475 } // namespace data_model
2476
2477 namespace data_model {
2488 class U_I18N_API Binding : public UObject {
2489 public:
2498 const Expression& getValue() const;
2507 const VariableName& getVariable() const { return var; }
2522 static Binding input(UnicodeString&& variableName, Expression&& rhs, UErrorCode& errorCode);
2530 UBool isLocal() const { return local; }
2540 Binding(const VariableName& v, Expression&& e) : var(v), expr(std::move(e)), local(true), annotation(nullptr) {}
2549 friend inline void swap(Binding& b1, Binding& b2) noexcept {
2550 using std::swap;
2551
2552 swap(b1.var, b2.var);
2553 swap(b1.expr, b2.expr);
2554 swap(b1.local, b2.local);
2555 b1.updateAnnotation();
2556 b2.updateAnnotation();
2557 }
2564 Binding(const Binding& other);
2571 Binding& operator=(Binding) noexcept;
2579 Binding() : local(true) {}
2586 virtual ~Binding();
2587 private:
2588 friend class message2::Checker;
2589 friend class message2::MessageFormatter;
2590 friend class message2::Parser;
2591 friend class message2::Serializer;
2592
2593 /* const */ VariableName var;
2594 /* const */ Expression expr;
2595 /* const */ bool local;
2596
2597 // The following field is always nullptr for a local
2598 // declaration, and possibly nullptr for an .input declaration
2599 // If non-null, the referent is a member of `expr` so
2600 // its lifetime is the same as the lifetime of the enclosing Binding
2601 // (as long as there's no mutation)
2602 const Callable* annotation = nullptr;
2603
2604 const OptionMap& getOptionsInternal() const;
2605
2606 bool hasAnnotation() const { return !local && (annotation != nullptr); }
2607 void updateAnnotation();
2608 }; // class Binding
2609 } // namespace data_model
2610} // namespace message2
2611
2613// Export an explicit template instantiation of the LocalPointer that is used as a
2614// data member of various MFDataModel classes.
2615// (When building DLLs for Windows this is required.)
2616// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2617// for similar examples.)
2618#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2619template class U_I18N_API LocalPointerBase<message2::data_model::Variant>;
2620template class U_I18N_API LocalPointerBase<message2::data_model::Binding>;
2621template class U_I18N_API LocalArray<message2::data_model::Variant>;
2622template class U_I18N_API LocalArray<message2::data_model::Binding>;
2623#endif
2625
2626namespace message2 {
2627 using namespace data_model;
2628
2629
2630 // Internal only
2631
2632 class MFDataModel;
2633
2634 #ifndef U_IN_DOXYGEN
2635 class Matcher : public UObject {
2636 public:
2637 Matcher& operator=(Matcher);
2638 Matcher(const Matcher&);
2647 friend inline void swap(Matcher& m1, Matcher& m2) noexcept {
2648 using std::swap;
2649
2650 if (m1.bogus) {
2651 m2.bogus = true;
2652 return;
2653 }
2654 if (m2.bogus) {
2655 m1.bogus = true;
2656 return;
2657 }
2658 swap(m1.selectors, m2.selectors);
2659 swap(m1.numSelectors, m2.numSelectors);
2660 swap(m1.variants, m2.variants);
2661 swap(m1.numVariants, m2.numVariants);
2662 }
2663 virtual ~Matcher();
2664 private:
2665
2666 friend class MFDataModel;
2667
2668 Matcher(Expression* ss, int32_t ns, Variant* vs, int32_t nv);
2669 Matcher() {}
2670
2671 // A Matcher may have numSelectors=0 and numVariants=0
2672 // (this is a data model error, but it's representable).
2673 // So we have to keep a separate flag to track failed copies.
2674 bool bogus = false;
2675
2676 // The expressions that are being matched on.
2677 LocalArray<Expression> selectors;
2678 // The number of selectors
2679 int32_t numSelectors = 0;
2680 // The list of `when` clauses (case arms).
2681 LocalArray<Variant> variants;
2682 // The number of variants
2683 int32_t numVariants = 0;
2684 }; // class Matcher
2685 #endif
2686} // namespace message2
2687
2688U_NAMESPACE_END
2689
2691// Export an explicit template instantiation of the std::variant that is used as a
2692// data member of various MFDataModel classes.
2693// (When building DLLs for Windows this is required.)
2694// (See measunit_impl.h, datefmt.h, collationiterator.h, erarules.h and others
2695// for similar examples.)
2696#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
2697#if defined(U_REAL_MSVC) && defined(_MSVC_STL_VERSION)
2698template class U_I18N_API std::_Variant_storage_<false, icu::message2::Matcher,icu::message2::data_model::Pattern>;
2699#endif
2700template class U_I18N_API std::variant<icu::message2::Matcher,icu::message2::data_model::Pattern>;
2701#endif
2703
2704U_NAMESPACE_BEGIN
2705
2706namespace message2 {
2707 // -----------------------------------------------------------------------
2708 // Public MFDataModel class
2709
2726 class U_I18N_API MFDataModel : public UMemory {
2727 /*
2728 Classes that represent nodes in the data model are nested inside the
2729 `MFDataModel` class.
2730
2731 Classes such as `Expression`, `Pattern` and `VariantMap` are immutable and
2732 are constructed using the builder pattern.
2733
2734 Most classes representing nodes have copy constructors. This is because builders
2735 contain immutable data that must be copied when calling `build()`, since the builder
2736 could go out of scope before the immutable result of the builder does. Copying is
2737 also necessary to prevent unexpected mutation if intermediate builders are saved
2738 and mutated again after calling `build()`.
2739
2740 The copy constructors perform a deep copy, for example by copying the entire
2741 list of options for an `Operator` (and copying the entire underlying vector.)
2742 Some internal fields should be `const`, but are declared as non-`const` to make
2743 the copy constructor simpler to implement. (These are noted throughout.) In
2744 other words, those fields are `const` except during the execution of a copy
2745 constructor.
2746
2747 On the other hand, intermediate `Builder` methods that return a `Builder&`
2748 mutate the state of the builder, so in code like:
2749
2750 Expression::Builder& exprBuilder = Expression::builder()-> setOperand(foo);
2751 Expression::Builder& exprBuilder2 = exprBuilder.setOperator(bar);
2752
2753 the call to `setOperator()` would mutate `exprBuilder`, since `exprBuilder`
2754 and `exprBuilder2` are references to the same object.
2755
2756 An alternate choice would be to make `build()` destructive, so that copying would
2757 be unnecessary. Or, both copying and moving variants of `build()` could be
2758 provided. Copying variants of the intermediate `Builder` methods could be
2759 provided as well, if this proved useful.
2760 */
2761 public:
2770 std::vector<Binding> getLocalVariables() const {
2771 std::vector<Binding> result;
2772 if (!bogus) {
2773 return toStdVector<Binding>(bindings.getAlias(), bindingsLen);
2774 }
2775 return {};
2776 }
2785 const std::vector<Expression> getSelectors() const {
2786 if (std::holds_alternative<Pattern>(body)) {
2787 return {};
2788 }
2789 const Matcher* match = std::get_if<Matcher>(&body);
2790 // match must be non-null, given the previous check
2791 return toStdVector<Expression>(match->selectors.getAlias(), match->numSelectors);
2792 }
2801 std::vector<Variant> getVariants() const {
2802 // Return empty vector if no variants
2803 if (std::holds_alternative<Pattern>(body)) {
2804 return {};
2805 }
2806 const Matcher* match = std::get_if<Matcher>(&body);
2807 // match must be non-null, given the previous check
2808 return toStdVector<Variant>(match->variants.getAlias(), match->numVariants);
2809 return {};
2810 }
2819 std::vector<UnsupportedStatement> getUnsupportedStatements() const {
2820 std::vector<UnsupportedStatement> result;
2821 if (!bogus) {
2822 return toStdVector<UnsupportedStatement>(unsupportedStatements.getAlias(), unsupportedStatementsLen);
2823 }
2824 return {};
2825 }
2835 const Pattern& getPattern() const;
2836
2844 class U_I18N_API Builder;
2845
2853 MFDataModel();
2862 friend inline void swap(MFDataModel& m1, MFDataModel& m2) noexcept {
2863 using std::swap;
2864
2865 if (m1.bogus) {
2866 m2.bogus = true;
2867 return;
2868 }
2869 if (m2.bogus) {
2870 m1.bogus = true;
2871 return;
2872 }
2873 swap(m1.body, m2.body);
2874 swap(m1.bindings, m2.bindings);
2875 swap(m1.bindingsLen, m2.bindingsLen);
2876 swap(m1.unsupportedStatements, m2.unsupportedStatements);
2877 swap(m1.unsupportedStatementsLen, m2.unsupportedStatementsLen);
2878 }
2885 MFDataModel& operator=(MFDataModel) noexcept;
2892 MFDataModel(const MFDataModel& other);
2899 virtual ~MFDataModel();
2900
2908 class U_I18N_API Builder : public UMemory {
2909 private:
2910 friend class MFDataModel;
2911
2912 void checkDuplicate(const VariableName&, UErrorCode&) const;
2913 void buildSelectorsMessage(UErrorCode&);
2914 bool hasPattern = true;
2915 bool hasSelectors = false;
2916 Pattern pattern;
2917 // The following members are not LocalPointers for the same reason as in SelectorKeys::Builder
2918 UVector* selectors = nullptr;
2919 UVector* variants = nullptr;
2920 UVector* bindings = nullptr;
2921 UVector* unsupportedStatements = nullptr;
2922 public:
2971 Builder& addVariant(SelectorKeys&& keys, Pattern&& pattern, UErrorCode& errorCode) noexcept;
2983 Builder& setPattern(Pattern&& pattern);
3003 MFDataModel build(UErrorCode& status) const noexcept;
3023 virtual ~Builder();
3024 Builder(const Builder&) = delete;
3025 Builder& operator=(const Builder&) = delete;
3026 Builder(Builder&&) = delete;
3027 Builder& operator=(Builder&&) = delete;
3028 }; // class Builder
3029
3030 private:
3031 friend class Checker;
3032 friend class MessageFormatter;
3033 friend class Serializer;
3034
3035 Pattern empty; // Provided so that `getPattern()` can return a result
3036 // if called on a selectors message
3037 bool hasPattern() const { return std::holds_alternative<Pattern>(body); }
3038
3039 bool bogus = false; // Set if a copy constructor fails
3040
3041 // A message body is either a matcher (selector list and variant list),
3042 // or a single pattern
3043 std::variant<Matcher, Pattern> body;
3044
3045 // Bindings for local variables
3046 /* const */ LocalArray<Binding> bindings;
3047 int32_t bindingsLen = 0;
3048
3049 // Unsupported statements
3050 // (Treated as a type of `declaration` in the data model spec;
3051 // stored separately for convenience)
3052 /* const */ LocalArray<UnsupportedStatement> unsupportedStatements;
3053 int32_t unsupportedStatementsLen = 0;
3054
3055 const Binding* getLocalVariablesInternal() const;
3056 const Expression* getSelectorsInternal() const;
3057 const Variant* getVariantsInternal() const;
3058 const UnsupportedStatement* getUnsupportedStatementsInternal() const;
3059
3060 int32_t numSelectors() const {
3061 const Matcher* matcher = std::get_if<Matcher>(&body);
3062 return (matcher == nullptr ? 0 : matcher->numSelectors);
3063 }
3064 int32_t numVariants() const {
3065 const Matcher* matcher = std::get_if<Matcher>(&body);
3066 return (matcher == nullptr ? 0 : matcher->numVariants);
3067 }
3068
3069 // Helper
3070 void initBindings(const Binding*);
3071
3072 MFDataModel(const Builder& builder, UErrorCode&) noexcept;
3073 }; // class MFDataModel
3074
3075} // namespace message2
3076
3077U_NAMESPACE_END
3078
3079#endif // U_HIDE_DEPRECATED_API
3080
3081#endif /* #if !UCONFIG_NO_MF2 */
3082
3083#endif /* #if !UCONFIG_NO_FORMATTING */
3084
3085#endif /* U_SHOW_CPLUSPLUS_API */
3086
3087#endif // MESSAGEFORMAT_DATA_MODEL_H
3088
3089// eof
3090
"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 & addOption(const UnicodeString &key, Operand &&value, UErrorCode &status)
Adds a single option.
Builder(UErrorCode &status)
Default constructor.
Builder & addAttribute(const UnicodeString &key, Operand &&value, UErrorCode &status)
Adds a single attribute.
Builder & setClose()
Sets this to be an closing markup.
Builder & setName(const UnicodeString &n)
Sets the name of this markup.
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