conversion.hpp 9.5 KB

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