conversion.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. //
  2. // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@yandex.ru)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_CONVERSION_HPP
  10. #define BOOST_JSON_CONVERSION_HPP
  11. #include <boost/json/detail/config.hpp>
  12. #include <boost/json/fwd.hpp>
  13. #include <type_traits>
  14. namespace boost {
  15. namespace json {
  16. namespace detail {
  17. template< class Ctx, class T, class Dir >
  18. struct supported_context;
  19. } // namespace detail
  20. /** Customization point tag.
  21. This tag type is used by the function
  22. @ref value_from to select overloads
  23. of `tag_invoke`.
  24. @note This type is empty; it has no members.
  25. @see @ref value_from, @ref value_to, @ref value_to_tag,
  26. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  27. tag_invoke: A general pattern for supporting customisable functions</a>
  28. */
  29. struct value_from_tag { };
  30. /** Customization point tag type.
  31. This tag type is used by the function
  32. @ref value_to to select overloads
  33. of `tag_invoke`.
  34. @note This type is empty; it has no members.
  35. @see @ref value_from, @ref value_from_tag, @ref value_to,
  36. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  37. tag_invoke: A general pattern for supporting customisable functions</a>
  38. */
  39. template<class T>
  40. struct value_to_tag { };
  41. /** Customization point tag type.
  42. This tag type is used by the function
  43. @ref try_value_to to select overloads
  44. of `tag_invoke`.
  45. @note This type is empty; it has no members.
  46. @see @ref value_to, @ref value_to_tag
  47. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
  48. tag_invoke: A general pattern for supporting customisable functions</a>
  49. */
  50. template<class T>
  51. struct try_value_to_tag { };
  52. /** Determine if `T` can be treated like a string during conversions.
  53. Provides the member constant `value` that is equal to `true`, if `T` is
  54. convertible to @ref string_view. Otherwise, `value` is equal to `false`.
  55. <br>
  56. Users can specialize the trait for their own types if they don't want them
  57. to be treated like strings. For example:
  58. @code
  59. namespace boost {
  60. namespace json {
  61. template <>
  62. struct is_string_like<your::string> : std::false_type
  63. { };
  64. } // namespace boost
  65. } // namespace json
  66. @endcode
  67. @par Types satisfying the trait
  68. @ref string,
  69. @ref string_view,
  70. <a href="https://en.cppreference.com/w/cpp/string/basic_string"><tt>std::string</tt></a>,
  71. <a href="https://en.cppreference.com/w/cpp/string/basic_string_view"><tt>std::string_view</tt></a>.
  72. @see @ref value_from, @ref value_to
  73. */
  74. template<class T>
  75. struct is_string_like;
  76. /** Determine if `T` can be treated like a sequence during conversions.
  77. Given `t`, a glvalue of type `T`, if
  78. @li given `It`, the type denoted by `decltype(std::begin(t))`,
  79. <tt>std::iterator_traits<It>::iterator_category</tt> is well-formed and
  80. denotes a type; and
  81. @li `decltype(std::end(t))` also denotes the type `It`;
  82. then the trait provides the member constant `value` that is equal to
  83. `true`. Otherwise, `value` is equal to `false`.<br>
  84. Users can specialize the trait for their own types if they don't want them
  85. to be treated like sequences. For example:
  86. @code
  87. namespace boost {
  88. namespace json {
  89. template <>
  90. struct is_sequence_like<your::container> : std::false_type
  91. { };
  92. } // namespace boost
  93. } // namespace json
  94. @endcode
  95. @par Types satisfying the trait
  96. Any <a href="https://en.cppreference.com/w/cpp/named_req/SequenceContainer"><em>SequenceContainer</em></a>,
  97. array types.
  98. @see @ref value_from, @ref value_to
  99. */
  100. template<class T>
  101. struct is_sequence_like;
  102. /** Determine if `T` can be treated like a 1-to-1 mapping during
  103. conversions.
  104. Given `t`, a glvalue of type `T`, if
  105. @li <tt>is_sequence_like<T>::value</tt> is `true`; and
  106. @li given type `It` denoting `decltype(std::begin(t))`, and types `K`
  107. and `M`, <tt>std::iterator_traits<It>::value_type</tt> denotes
  108. `std::pair<K, M>`; and
  109. @li <tt>std::is_string_like<K>::value</tt> is `true`; and
  110. @li given `v`, a glvalue of type `V`, and `E`, the type denoted by
  111. `decltype(t.emplace(v))`,
  112. <tt>std::is_tuple_like<E>::value</tt> is `true`;
  113. then the trait provides the member constant `value`
  114. that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
  115. Users can specialize the trait for their own types if they don't want them
  116. to be treated like mappings. For example:
  117. @code
  118. namespace boost {
  119. namespace json {
  120. template <>
  121. struct is_map_like<your::map> : std::false_type
  122. { };
  123. } // namespace boost
  124. } // namespace json
  125. @endcode
  126. @note
  127. The restriction for `t.emplace()` return type ensures that the container
  128. does not accept duplicate keys.
  129. @par Types satisfying the trait
  130. <a href="https://en.cppreference.com/w/cpp/container/map"><tt>std::map</tt></a>,
  131. <a href="https://en.cppreference.com/w/cpp/container/unordered_map"><tt>std::unordered_map</tt></a>.
  132. @see @ref value_from, @ref value_to
  133. */
  134. template<class T>
  135. struct is_map_like;
  136. /** Determine if `T` can be treated like a tuple during conversions.
  137. Provides the member constant `value` that is equal to `true`, if
  138. <tt>std::tuple_size<T>::value</tt> is a positive number. Otherwise, `value`
  139. is equal to `false`.<br>
  140. Users can specialize the trait for their own types if they don't want them
  141. to be treated like tuples. For example:
  142. @code
  143. namespace boost {
  144. namespace json {
  145. template <>
  146. struct is_tuple_like<your::tuple> : std::false_type
  147. { };
  148. } // namespace boost
  149. } // namespace json
  150. @endcode
  151. @par Types satisfying the trait
  152. <a href="https://en.cppreference.com/w/cpp/utility/tuple"><tt>std::tuple</tt></a>,
  153. <a href="https://en.cppreference.com/w/cpp/utility/pair"><tt>std::pair</tt></a>.
  154. @see @ref value_from, @ref value_to
  155. */
  156. template<class T>
  157. struct is_tuple_like;
  158. /** Determine if `T` can be treated like null during conversions.
  159. Primary template instantiations provide the member constant `value` that is
  160. equal to `false`. Users can specialize the trait for their own types if
  161. they **do** want them to be treated as nulls. For example:
  162. @code
  163. namespace boost {
  164. namespace json {
  165. template <>
  166. struct is_null_like<your::null_type> : std::true_type
  167. { };
  168. } // namespace boost
  169. } // namespace json
  170. @endcode
  171. @par Types satisfying the trait
  172. <a href="https://en.cppreference.com/w/cpp/types/nullptr_t"><tt>std::nullptr_t</tt></a>.
  173. @see @ref value_from, @ref value_to
  174. */
  175. template<class T>
  176. struct is_null_like
  177. : std::false_type
  178. { };
  179. /** Determine if `T` should be treated as a described class
  180. Described classes are serialised as objects with an element for each
  181. described public data member. A described class should not have described
  182. bases or non-public members.<br>
  183. Or more formally, given `L`, a class template
  184. of the form `template<class...> struct L {};`, if
  185. @li <tt>boost::describe::has_members<T, boost::describe::mod_public>::value</tt> is `true`; and
  186. @li `boost::describe::describe_members<T, boost::describe::mod_private | boost::describe::mod_protected>` denotes `L<>`; and
  187. @li `boost::describe::describe_bases<T, boost::describe::mod_any_access>` denotes `L<>`; and
  188. @li <tt>std::is_union<T>::value</tt> is `false`;
  189. then the trait provides the member constant `value`
  190. that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
  191. Users can specialize the trait for their own types if they don't want them
  192. to be treated as described classes. For example:
  193. @code
  194. namespace boost {
  195. namespace json {
  196. template <>
  197. struct is_described_class<your::described_class> : std::false_type
  198. { };
  199. } // namespace boost
  200. } // namespace json
  201. @endcode
  202. Users can also specialize the trait for their own types _with_ described
  203. bases to enable this conversion implementation. In this case the class will
  204. be serialized in a flattened way, that is members of bases will be
  205. serialized as direct elements of the object, and no nested objects will be
  206. created for bases.
  207. @see <a href="https://www.boost.org/doc/libs/develop/libs/describe/doc/html/describe.html">Boost.Describe</a>.
  208. */
  209. template<class T>
  210. struct is_described_class;
  211. /** Determine if `T` should be treated as a described enum
  212. Described enums are serialised as strings when their value equals to a
  213. described enumerator, and as integers otherwise. The reverse operation
  214. does not convert numbers to enums values, though, and instead produces
  215. an error.<br>
  216. If <tt>boost::describe::has_describe_enumerators<T>::value</tt> is `true`,
  217. then the trait provides the member constant `value`
  218. that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
  219. Users can specialize the trait for their own enums if they don't want them
  220. to be treated as described enums. For example:
  221. @code
  222. namespace boost {
  223. namespace json {
  224. template <>
  225. struct is_described_enum<your::described_enum> : std::false_type
  226. { };
  227. } // namespace boost
  228. } // namespace json
  229. @endcode
  230. @see <a href="https://www.boost.org/doc/libs/develop/libs/describe/doc/html/describe.html">Boost.Describe</a>.
  231. */
  232. template<class T>
  233. struct is_described_enum;
  234. /** Determine if `T` should be treated as a variant
  235. Variants are serialised the same way their active alternative is
  236. serialised. The opposite conversion selects the first alternative for which
  237. conversion succeeds.<br>
  238. Given `t`, a glvalue of type ` const T`, if
  239. <tt>t.valueless_by_exception()</tt> is well-formed, then the trait provides
  240. the member constant `value` that is equal to `true`. Otherwise, `value` is
  241. equal to `false`.<br>
  242. Users can specialize the trait for their own types if they don't want them
  243. to be treated as variants. For example:
  244. @code
  245. namespace boost {
  246. namespace json {
  247. template <>
  248. struct is_variant_like<your::variant> : std::false_type
  249. { };
  250. } // namespace boost
  251. } // namespace json
  252. @endcode
  253. */
  254. template<class T>
  255. struct is_variant_like;
  256. /** Determine if `T` should be treated as an optional
  257. Optionals are serialised as `null` if empty, or as the stored type
  258. otherwise.<br>
  259. Given `t`, a glvalue of type `T`, if
  260. @li <tt>decltype( t.value() )</tt> is well-formed and isn't a void type; and
  261. @li <tt>t.reset()</tt> is well-formed;
  262. then the trait provides the member constant `value`
  263. that is equal to `true`. Otherwise, `value` is equal to `false`.<br>
  264. Users can specialize the trait for their own types if they don't want them
  265. to be treated as optionals. For example:
  266. @code
  267. namespace boost {
  268. namespace json {
  269. template <>
  270. struct is_optional_like<your::optional> : std::false_type
  271. { };
  272. } // namespace boost
  273. } // namespace json
  274. @endcode
  275. */
  276. template<class T>
  277. struct is_optional_like;
  278. } // namespace json
  279. } // namespace boost
  280. #include <boost/json/impl/conversion.hpp>
  281. #endif // BOOST_JSON_CONVERSION_HPP