100.00% Lines (46/46)
100.00% Functions (10/10)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | Code | |||
| 1 | // | 1 | // | |||||
| 2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | 2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | |||||
| 3 | // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) | 3 | // Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com) | |||||
| 4 | // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com) | 4 | // Copyright (c) 2022 Dmitry Arkhipov (grisumbras@gmail.com) | |||||
| 5 | // | 5 | // | |||||
| 6 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 6 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |||||
| 7 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 7 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||||
| 8 | // | 8 | // | |||||
| 9 | // Official repository: https://github.com/boostorg/json | 9 | // Official repository: https://github.com/boostorg/json | |||||
| 10 | // | 10 | // | |||||
| 11 | 11 | |||||||
| 12 | #ifndef BOOST_JSON_DETAIL_VALUE_FROM_HPP | 12 | #ifndef BOOST_JSON_DETAIL_VALUE_FROM_HPP | |||||
| 13 | #define BOOST_JSON_DETAIL_VALUE_FROM_HPP | 13 | #define BOOST_JSON_DETAIL_VALUE_FROM_HPP | |||||
| 14 | 14 | |||||||
| 15 | #include <boost/json/value.hpp> | 15 | #include <boost/json/value.hpp> | |||||
| 16 | #include <boost/json/conversion.hpp> | 16 | #include <boost/json/conversion.hpp> | |||||
| 17 | #include <boost/describe/enum_to_string.hpp> | 17 | #include <boost/describe/enum_to_string.hpp> | |||||
| 18 | #include <boost/mp11/algorithm.hpp> | 18 | #include <boost/mp11/algorithm.hpp> | |||||
| 19 | 19 | |||||||
| 20 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL | 20 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL | |||||
| 21 | # include <optional> | 21 | # include <optional> | |||||
| 22 | #endif | 22 | #endif | |||||
| 23 | 23 | |||||||
| 24 | namespace boost { | 24 | namespace boost { | |||||
| 25 | namespace json { | 25 | namespace json { | |||||
| 26 | 26 | |||||||
| 27 | namespace detail { | 27 | namespace detail { | |||||
| 28 | 28 | |||||||
| 29 | template< class Ctx, class T > | 29 | template< class Ctx, class T > | |||||
| 30 | struct append_tuple_element { | 30 | struct append_tuple_element { | |||||
| 31 | array& arr; | 31 | array& arr; | |||||
| 32 | Ctx const& ctx; | 32 | Ctx const& ctx; | |||||
| 33 | T&& t; | 33 | T&& t; | |||||
| 34 | 34 | |||||||
| 35 | template<std::size_t I> | 35 | template<std::size_t I> | |||||
| 36 | void | 36 | void | |||||
| HITCBC | 37 | 295 | operator()(mp11::mp_size_t<I>) const | 37 | 295 | operator()(mp11::mp_size_t<I>) const | ||
| 38 | { | 38 | { | |||||
| 39 | using std::get; | 39 | using std::get; | |||||
| HITCBC | 40 | 590 | arr.emplace_back(value_from( | 40 | 590 | arr.emplace_back(value_from( | ||
| HITCBC | 41 | 600 | get<I>(std::forward<T>(t)), ctx, arr.storage() )); | 41 | 600 | get<I>(std::forward<T>(t)), ctx, arr.storage() )); | ||
| HITCBC | 42 | 295 | } | 42 | 295 | } | ||
| 43 | }; | 43 | }; | |||||
| 44 | 44 | |||||||
| 45 | //---------------------------------------------------------- | 45 | //---------------------------------------------------------- | |||||
| 46 | // User-provided conversion | 46 | // User-provided conversion | |||||
| 47 | 47 | |||||||
| 48 | template< class T, class Ctx > | 48 | template< class T, class Ctx > | |||||
| 49 | void | 49 | void | |||||
| HITCBC | 50 | - | 35 | value_from_impl( user_conversion_tag, value& jv, T&& from, Ctx const& ) | 50 | + | 35 | value_from_impl( user_category, value& jv, T&& from, Ctx const& ) |
| 51 | { | 51 | { | |||||
| HITCBC | 52 | 35 | tag_invoke( value_from_tag(), jv, static_cast<T&&>(from) ); | 52 | 35 | tag_invoke( value_from_tag(), jv, static_cast<T&&>(from) ); | ||
| HITCBC | 53 | 35 | } | 53 | 35 | } | ||
| 54 | 54 | |||||||
| 55 | template< class T, class Ctx > | 55 | template< class T, class Ctx > | |||||
| 56 | void | 56 | void | |||||
| HITCBC | 57 | - | 26 | value_from_impl( context_conversion_tag, value& jv, T&& from, Ctx const& ctx) | 57 | + | 26 | value_from_impl( user_context_category, value& jv, T&& from, Ctx const& ctx) |
| 58 | { | 58 | { | |||||
| 59 | using Sup = supported_context<Ctx, T, value_from_conversion>; | 59 | using Sup = supported_context<Ctx, T, value_from_conversion>; | |||||
| HITCBC | 60 | 26 | tag_invoke( value_from_tag(), jv, static_cast<T&&>(from), Sup::get(ctx) ); | 60 | 26 | tag_invoke( value_from_tag(), jv, static_cast<T&&>(from), Sup::get(ctx) ); | ||
| HITCBC | 61 | 26 | } | 61 | 26 | } | ||
| 62 | 62 | |||||||
| 63 | template< class T, class Ctx > | 63 | template< class T, class Ctx > | |||||
| 64 | void | 64 | void | |||||
| HITCBC | 65 | 2 | value_from_impl( | 65 | 2 | value_from_impl( | ||
| 66 | - | full_context_conversion_tag, value& jv, T&& from, Ctx const& ctx) | 66 | + | user_full_context_category, value& jv, T&& from, Ctx const& ctx) | |||
| 67 | { | 67 | { | |||||
| 68 | using Sup = supported_context<Ctx, T, value_from_conversion>; | 68 | using Sup = supported_context<Ctx, T, value_from_conversion>; | |||||
| HITCBC | 69 | 2 | tag_invoke( | 69 | 2 | tag_invoke( | ||
| HITCBC | 70 | 2 | value_from_tag(), jv, static_cast<T&&>(from), Sup::get(ctx), ctx ); | 70 | 2 | value_from_tag(), jv, static_cast<T&&>(from), Sup::get(ctx), ctx ); | ||
| HITCBC | 71 | 2 | } | 71 | 2 | } | ||
| 72 | 72 | |||||||
| 73 | //---------------------------------------------------------- | 73 | //---------------------------------------------------------- | |||||
| 74 | // Native conversion | 74 | // Native conversion | |||||
| 75 | 75 | |||||||
| 76 | - | template< class T, class Ctx > | 76 | + | template< class Cat, class T, class Ctx > | |||
| 77 | void | 77 | void | |||||
| HITCBC | 78 | - | 6622 | value_from_impl( native_conversion_tag, value& jv, T&& from, Ctx const& ) | 78 | + | 6622 | value_from_impl( |
| 79 | + | Cat, | ||||||
| 80 | + | value& jv, | ||||||
| 81 | + | T&& from, | ||||||
| 82 | + | Ctx const&, | ||||||
| 83 | + | typename std::enable_if<is_native_conversion<Cat>::value>* = nullptr) | ||||||
| 79 | { | 84 | { | |||||
| HITCBC | 80 | 6622 | jv = std::forward<T>(from); | 85 | 6622 | jv = std::forward<T>(from); | ||
| HITCBC | 81 | 6622 | } | 86 | 6622 | } | ||
| 82 | 87 | |||||||
| 83 | // null-like types | 88 | // null-like types | |||||
| 84 | template< class T, class Ctx > | 89 | template< class T, class Ctx > | |||||
| 85 | void | 90 | void | |||||
| HITCBC | 86 | - | 11 | value_from_impl( null_like_conversion_tag, value& jv, T&&, Ctx const& ) | 91 | + | 11 | value_from_impl( null_category, value& jv, T&&, Ctx const& ) |
| 87 | { | 92 | { | |||||
| 88 | // do nothing | 93 | // do nothing | |||||
| HITCBC | 89 | 11 | BOOST_ASSERT(jv.is_null()); | 94 | 11 | BOOST_ASSERT(jv.is_null()); | ||
| 90 | (void)jv; | 95 | (void)jv; | |||||
| HITCBC | 91 | 11 | } | 96 | 11 | } | ||
| 92 | 97 | |||||||
| 93 | // string-like types | 98 | // string-like types | |||||
| 94 | template< class T, class Ctx > | 99 | template< class T, class Ctx > | |||||
| 95 | void | 100 | void | |||||
| HITCBC | 96 | - | 75 | value_from_impl( string_like_conversion_tag, value& jv, T&& from, Ctx const& ) | 101 | + | 75 | value_from_impl( string_category, value& jv, T&& from, Ctx const& ) |
| 97 | { | 102 | { | |||||
| HITCBC | 98 | 75 | auto sv = static_cast<string_view>(from); | 103 | 75 | auto sv = static_cast<string_view>(from); | ||
| HITCBC | 99 | 75 | jv.emplace_string().assign(sv); | 104 | 75 | jv.emplace_string().assign(sv); | ||
| HITCBC | 100 | 75 | } | 105 | 75 | } | ||
| 101 | 106 | |||||||
| 102 | // map-like types | 107 | // map-like types | |||||
| 103 | template< class T, class Ctx > | 108 | template< class T, class Ctx > | |||||
| 104 | void | 109 | void | |||||
| HITCBC | 105 | - | 46 | value_from_impl( map_like_conversion_tag, value& jv, T&& from, Ctx const& ctx ) | 110 | + | 46 | value_from_impl( map_category, value& jv, T&& from, Ctx const& ctx ) |
| 106 | { | 111 | { | |||||
| 107 | using std::get; | 112 | using std::get; | |||||
| HITCBC | 108 | 46 | object& obj = jv.emplace_object(); | 113 | 46 | object& obj = jv.emplace_object(); | ||
| HITCBC | 109 | 46 | obj.reserve(detail::try_size(from, size_implementation<T>())); | 114 | 46 | obj.reserve(detail::try_size(from, size_implementation<T>())); | ||
| HITCBC | 110 | 145 | for (auto&& elem : from) | 115 | 145 | for (auto&& elem : from) | ||
| HITCBC | 111 | 297 | obj.emplace( | 116 | 297 | obj.emplace( | ||
| HITCBC | 112 | 99 | get<0>(elem), | 117 | 99 | get<0>(elem), | ||
| HITCBC | 113 | 99 | value_from( get<1>(elem), ctx, obj.storage() )); | 118 | 99 | value_from( get<1>(elem), ctx, obj.storage() )); | ||
| HITCBC | 114 | 46 | } | 119 | 46 | } | ||
| 115 | 120 | |||||||
| 116 | // ranges | 121 | // ranges | |||||
| 117 | template< class T, class Ctx > | 122 | template< class T, class Ctx > | |||||
| 118 | void | 123 | void | |||||
| HITCBC | 119 | - | 100 | value_from_impl( sequence_conversion_tag, value& jv, T&& from, Ctx const& ctx ) | 124 | + | 100 | value_from_impl( sequence_category, value& jv, T&& from, Ctx const& ctx ) |
| 120 | { | 125 | { | |||||
| HITCBC | 121 | 100 | array& result = jv.emplace_array(); | 126 | 100 | array& result = jv.emplace_array(); | ||
| HITCBC | 122 | 100 | result.reserve(detail::try_size(from, size_implementation<T>())); | 127 | 100 | result.reserve(detail::try_size(from, size_implementation<T>())); | ||
| 123 | using ForwardedValue = forwarded_value<T&&>; | 128 | using ForwardedValue = forwarded_value<T&&>; | |||||
| HITCBC | 124 | 6355 | for (auto&& elem : from) | 129 | 6355 | for (auto&& elem : from) | ||
| HITCBC | 125 | 6445 | result.emplace_back( | 130 | 6445 | result.emplace_back( | ||
| 126 | value_from( | 131 | value_from( | |||||
| 127 | // not a static_cast in order to appease clang < 4.0 | 132 | // not a static_cast in order to appease clang < 4.0 | |||||
| HITCBC | 128 | 190 | ForwardedValue(elem), | 133 | 190 | ForwardedValue(elem), | ||
| 129 | ctx, | 134 | ctx, | |||||
| 130 | result.storage() )); | 135 | result.storage() )); | |||||
| HITCBC | 131 | 100 | } | 136 | 100 | } | ||
| 132 | 137 | |||||||
| 133 | // tuple-like types | 138 | // tuple-like types | |||||
| 134 | template< class T, class Ctx > | 139 | template< class T, class Ctx > | |||||
| 135 | void | 140 | void | |||||
| HITCBC | 136 | - | 139 | value_from_impl( tuple_conversion_tag, value& jv, T&& from, Ctx const& ctx ) | 141 | + | 139 | value_from_impl( tuple_category, value& jv, T&& from, Ctx const& ctx ) |
| 137 | { | 142 | { | |||||
| HITCBC | 138 | 139 | constexpr std::size_t n = | 143 | 139 | constexpr std::size_t n = | ||
| 139 | std::tuple_size<remove_cvref<T>>::value; | 144 | std::tuple_size<remove_cvref<T>>::value; | |||||
| HITCBC | 140 | 139 | array& arr = jv.emplace_array(); | 145 | 139 | array& arr = jv.emplace_array(); | ||
| HITCBC | 141 | 139 | arr.reserve(n); | 146 | 139 | arr.reserve(n); | ||
| HITCBC | 142 | 139 | mp11::mp_for_each<mp11::mp_iota_c<n>>( | 147 | 139 | mp11::mp_for_each<mp11::mp_iota_c<n>>( | ||
| HITCBC | 143 | 139 | append_tuple_element< Ctx, T >{ arr, ctx, std::forward<T>(from) }); | 148 | 139 | append_tuple_element< Ctx, T >{ arr, ctx, std::forward<T>(from) }); | ||
| HITCBC | 144 | 139 | } | 149 | 139 | } | ||
| 145 | 150 | |||||||
| 146 | // no suitable conversion implementation | 151 | // no suitable conversion implementation | |||||
| 147 | template< class T, class Ctx > | 152 | template< class T, class Ctx > | |||||
| 148 | void | 153 | void | |||||
| 149 | - | value_from_impl( no_conversion_tag, value&, T&&, Ctx const& ) | 154 | + | value_from_impl( unknown_category, value&, T&&, Ctx const& ) | |||
| 150 | { | 155 | { | |||||
| 151 | static_assert( | 156 | static_assert( | |||||
| 152 | !std::is_same<T, T>::value, | 157 | !std::is_same<T, T>::value, | |||||
| 153 | "No suitable tag_invoke overload found for the type"); | 158 | "No suitable tag_invoke overload found for the type"); | |||||
| 154 | } | 159 | } | |||||
| 155 | 160 | |||||||
| 156 | template< class Ctx, class T > | 161 | template< class Ctx, class T > | |||||
| 157 | struct from_described_member | 162 | struct from_described_member | |||||
| 158 | { | 163 | { | |||||
| 159 | static_assert( | 164 | static_assert( | |||||
| 160 | uniquely_named_members< remove_cvref<T> >::value, | 165 | uniquely_named_members< remove_cvref<T> >::value, | |||||
| 161 | "The type has several described members with the same name."); | 166 | "The type has several described members with the same name."); | |||||
| 162 | 167 | |||||||
| 163 | using Ds = described_members< remove_cvref<T> >; | 168 | using Ds = described_members< remove_cvref<T> >; | |||||
| 164 | 169 | |||||||
| 165 | object& obj; | 170 | object& obj; | |||||
| 166 | Ctx const& ctx; | 171 | Ctx const& ctx; | |||||
| 167 | T&& from; | 172 | T&& from; | |||||
| 168 | 173 | |||||||
| 169 | template< class I > | 174 | template< class I > | |||||
| 170 | void | 175 | void | |||||
| 171 | operator()(I) const | 176 | operator()(I) const | |||||
| 172 | { | 177 | { | |||||
| 173 | using D = mp11::mp_at<Ds, I>; | 178 | using D = mp11::mp_at<Ds, I>; | |||||
| 174 | obj.emplace( | 179 | obj.emplace( | |||||
| 175 | D::name, | 180 | D::name, | |||||
| 176 | value_from( | 181 | value_from( | |||||
| 177 | static_cast<T&&>(from).* D::pointer, | 182 | static_cast<T&&>(from).* D::pointer, | |||||
| 178 | ctx, | 183 | ctx, | |||||
| 179 | obj.storage())); | 184 | obj.storage())); | |||||
| 180 | } | 185 | } | |||||
| 181 | }; | 186 | }; | |||||
| 182 | 187 | |||||||
| 183 | // described classes | 188 | // described classes | |||||
| 184 | template< class T, class Ctx > | 189 | template< class T, class Ctx > | |||||
| 185 | void | 190 | void | |||||
| 186 | value_from_impl( | 191 | value_from_impl( | |||||
| 187 | - | described_class_conversion_tag, value& jv, T&& from, Ctx const& ctx ) | 192 | + | described_class_category, value& jv, T&& from, Ctx const& ctx ) | |||
| 188 | { | 193 | { | |||||
| 189 | object& obj = jv.emplace_object(); | 194 | object& obj = jv.emplace_object(); | |||||
| 190 | from_described_member<Ctx, T> member_converter{ | 195 | from_described_member<Ctx, T> member_converter{ | |||||
| 191 | obj, ctx, static_cast<T&&>(from)}; | 196 | obj, ctx, static_cast<T&&>(from)}; | |||||
| 192 | 197 | |||||||
| 193 | using Ds = typename decltype(member_converter)::Ds; | 198 | using Ds = typename decltype(member_converter)::Ds; | |||||
| 194 | constexpr std::size_t N = mp11::mp_size<Ds>::value; | 199 | constexpr std::size_t N = mp11::mp_size<Ds>::value; | |||||
| 195 | obj.reserve(N); | 200 | obj.reserve(N); | |||||
| 196 | mp11::mp_for_each< mp11::mp_iota_c<N> >(member_converter); | 201 | mp11::mp_for_each< mp11::mp_iota_c<N> >(member_converter); | |||||
| 197 | } | 202 | } | |||||
| 198 | 203 | |||||||
| 199 | // described enums | 204 | // described enums | |||||
| 200 | template< class T, class Ctx > | 205 | template< class T, class Ctx > | |||||
| 201 | void | 206 | void | |||||
| 202 | - | value_from_impl( | 207 | + | value_from_impl( described_enum_category, value& jv, T from, Ctx const& ) | |||
| 203 | - | described_enum_conversion_tag, value& jv, T from, Ctx const& ) | ||||||
| 204 | { | 208 | { | |||||
| 205 | (void)jv; | 209 | (void)jv; | |||||
| 206 | (void)from; | 210 | (void)from; | |||||
| 207 | #ifdef BOOST_DESCRIBE_CXX14 | 211 | #ifdef BOOST_DESCRIBE_CXX14 | |||||
| 208 | char const* const name = describe::enum_to_string(from, nullptr); | 212 | char const* const name = describe::enum_to_string(from, nullptr); | |||||
| 209 | if( name ) | 213 | if( name ) | |||||
| 210 | { | 214 | { | |||||
| 211 | string& str = jv.emplace_string(); | 215 | string& str = jv.emplace_string(); | |||||
| 212 | str.assign(name); | 216 | str.assign(name); | |||||
| 213 | } | 217 | } | |||||
| 214 | else | 218 | else | |||||
| 215 | { | 219 | { | |||||
| 216 | using Integer = typename std::underlying_type< remove_cvref<T> >::type; | 220 | using Integer = typename std::underlying_type< remove_cvref<T> >::type; | |||||
| 217 | jv = static_cast<Integer>(from); | 221 | jv = static_cast<Integer>(from); | |||||
| 218 | } | 222 | } | |||||
| 219 | #endif | 223 | #endif | |||||
| 220 | } | 224 | } | |||||
| 221 | 225 | |||||||
| 222 | // optionals | 226 | // optionals | |||||
| 223 | template< class T, class Ctx > | 227 | template< class T, class Ctx > | |||||
| 224 | void | 228 | void | |||||
| 225 | - | value_from_impl( | 229 | + | value_from_impl( optional_category, value& jv, T&& from, Ctx const& ctx ) | |||
| 226 | - | optional_conversion_tag, value& jv, T&& from, Ctx const& ctx ) | ||||||
| 227 | { | 230 | { | |||||
| 228 | if( from ) | 231 | if( from ) | |||||
| 229 | value_from( *from, ctx, jv ); | 232 | value_from( *from, ctx, jv ); | |||||
| 230 | else | 233 | else | |||||
| 231 | jv = nullptr; | 234 | jv = nullptr; | |||||
| 232 | } | 235 | } | |||||
| 233 | 236 | |||||||
| 234 | // variants | 237 | // variants | |||||
| 235 | template< class Ctx > | 238 | template< class Ctx > | |||||
| 236 | struct value_from_visitor | 239 | struct value_from_visitor | |||||
| 237 | { | 240 | { | |||||
| 238 | value& jv; | 241 | value& jv; | |||||
| 239 | Ctx const& ctx; | 242 | Ctx const& ctx; | |||||
| 240 | 243 | |||||||
| 241 | template<class T> | 244 | template<class T> | |||||
| 242 | void | 245 | void | |||||
| 243 | operator()(T&& t) | 246 | operator()(T&& t) | |||||
| 244 | { | 247 | { | |||||
| 245 | value_from( static_cast<T&&>(t), ctx, jv ); | 248 | value_from( static_cast<T&&>(t), ctx, jv ); | |||||
| 246 | } | 249 | } | |||||
| 247 | }; | 250 | }; | |||||
| 248 | 251 | |||||||
| 249 | template< class Ctx, class T > | 252 | template< class Ctx, class T > | |||||
| 250 | void | 253 | void | |||||
| 251 | - | value_from_impl( variant_conversion_tag, value& jv, T&& from, Ctx const& ctx ) | 254 | + | value_from_impl( variant_category, value& jv, T&& from, Ctx const& ctx ) | |||
| 252 | { | 255 | { | |||||
| 253 | visit( value_from_visitor<Ctx>{ jv, ctx }, static_cast<T&&>(from) ); | 256 | visit( value_from_visitor<Ctx>{ jv, ctx }, static_cast<T&&>(from) ); | |||||
| 254 | } | 257 | } | |||||
| 255 | 258 | |||||||
| 256 | template< class Ctx, class T > | 259 | template< class Ctx, class T > | |||||
| 257 | void | 260 | void | |||||
| 258 | - | value_from_impl( path_conversion_tag, value& jv, T&& from, Ctx const& ) | 261 | + | value_from_impl( path_category, value& jv, T&& from, Ctx const& ) | |||
| 259 | { | 262 | { | |||||
| 260 | std::string s = from.generic_string(); | 263 | std::string s = from.generic_string(); | |||||
| 261 | string_view sv = s; | 264 | string_view sv = s; | |||||
| 262 | jv.emplace_string().assign(sv); | 265 | jv.emplace_string().assign(sv); | |||||
| 263 | } | 266 | } | |||||
| 264 | 267 | |||||||
| 265 | //---------------------------------------------------------- | 268 | //---------------------------------------------------------- | |||||
| 266 | // Contextual conversions | 269 | // Contextual conversions | |||||
| 267 | 270 | |||||||
| 268 | template< class Ctx, class T > | 271 | template< class Ctx, class T > | |||||
| 269 | - | using value_from_category = conversion_category< | 272 | + | using value_from_category = extended_conversion_category< | |||
| 270 | Ctx, T, value_from_conversion >; | 273 | Ctx, T, value_from_conversion >; | |||||
| 271 | 274 | |||||||
| 272 | } // detail | 275 | } // detail | |||||
| 273 | 276 | |||||||
| 274 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL | 277 | #ifndef BOOST_NO_CXX17_HDR_OPTIONAL | |||||
| 275 | inline | 278 | inline | |||||
| 276 | void | 279 | void | |||||
| 277 | tag_invoke( | 280 | tag_invoke( | |||||
| 278 | value_from_tag, | 281 | value_from_tag, | |||||
| 279 | value& jv, | 282 | value& jv, | |||||
| 280 | std::nullopt_t) | 283 | std::nullopt_t) | |||||
| 281 | { | 284 | { | |||||
| 282 | // do nothing | 285 | // do nothing | |||||
| 283 | BOOST_ASSERT(jv.is_null()); | 286 | BOOST_ASSERT(jv.is_null()); | |||||
| 284 | (void)jv; | 287 | (void)jv; | |||||
| 285 | } | 288 | } | |||||
| 286 | #endif | 289 | #endif | |||||
| 287 | 290 | |||||||
| 288 | } // namespace json | 291 | } // namespace json | |||||
| 289 | } // namespace boost | 292 | } // namespace boost | |||||
| 290 | 293 | |||||||
| 291 | #endif | 294 | #endif | |||||