messageformat2_formattable.h 38 KB

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