45template<
typename BasicJsonType>
46inline void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
48 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
50 JSON_THROW(type_error::create(302, concat(
"type must be null, but is ", j.type_name()), &j));
56template<
typename BasicJsonType,
typename T>
57void from_json(
const BasicJsonType& j, std::optional<T>& opt)
65 opt.emplace(j.template get<T>());
71template <
typename BasicJsonType,
typename ArithmeticType,
72 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
73 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
75void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
77 switch (
static_cast<value_t>(j))
81 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
86 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
91 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
103 JSON_THROW(type_error::create(302, concat(
"type must be number, but is ", j.type_name()), &j));
107template<
typename BasicJsonType>
108inline void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
110 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
112 JSON_THROW(type_error::create(302, concat(
"type must be boolean, but is ", j.type_name()), &j));
114 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
117template<
typename BasicJsonType>
118inline void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
120 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
122 JSON_THROW(type_error::create(302, concat(
"type must be string, but is ", j.type_name()), &j));
124 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
128 typename BasicJsonType,
typename StringType,
130 std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
131 && is_detected_exact<typename BasicJsonType::string_t::value_type, value_type_t, StringType>::value
132 && !std::is_same<typename BasicJsonType::string_t, StringType>::value
134inline void from_json(
const BasicJsonType& j, StringType& s)
136 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
138 JSON_THROW(type_error::create(302, concat(
"type must be string, but is ", j.type_name()), &j));
141 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
144template<
typename BasicJsonType>
145inline void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
147 get_arithmetic_value(j, val);
150template<
typename BasicJsonType>
151inline void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
153 get_arithmetic_value(j, val);
156template<
typename BasicJsonType>
157inline void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
159 get_arithmetic_value(j, val);
162#if !JSON_DISABLE_ENUM_SERIALIZATION
163template<
typename BasicJsonType,
typename EnumType,
164 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
165inline void from_json(
const BasicJsonType& j, EnumType& e)
167 typename std::underlying_type<EnumType>::type val;
168 get_arithmetic_value(j, val);
169 e =
static_cast<EnumType
>(val);
174template<
typename BasicJsonType,
typename T,
typename Allocator,
175 enable_if_t<is_getable<BasicJsonType, T>::value,
int> = 0>
176inline void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
178 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
180 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
183 std::transform(j.rbegin(), j.rend(),
184 std::front_inserter(l), [](
const BasicJsonType & i)
186 return i.template get<T>();
191template<
typename BasicJsonType,
typename T,
192 enable_if_t<is_getable<BasicJsonType, T>::value,
int> = 0>
193inline void from_json(
const BasicJsonType& j, std::valarray<T>& l)
195 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
197 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
200 std::transform(j.begin(), j.end(), std::begin(l),
201 [](
const BasicJsonType & elem)
203 return elem.template get<T>();
207template<
typename BasicJsonType,
typename T, std::
size_t N>
208auto from_json(
const BasicJsonType& j, T (&arr)[N])
209->
decltype(j.template get<T>(), void())
211 for (std::size_t i = 0; i < N; ++i)
213 arr[i] = j.at(i).template get<T>();
217template<
typename BasicJsonType,
typename T, std::
size_t N1, std::
size_t N2>
218auto from_json(
const BasicJsonType& j, T (&arr)[N1][N2])
219->
decltype(j.template get<T>(), void())
221 for (std::size_t i1 = 0; i1 < N1; ++i1)
223 for (std::size_t i2 = 0; i2 < N2; ++i2)
225 arr[i1][i2] = j.at(i1).at(i2).template get<T>();
230template<
typename BasicJsonType,
typename T, std::
size_t N1, std::
size_t N2, std::
size_t N3>
231auto from_json(
const BasicJsonType& j, T (&arr)[N1][N2][N3])
232->
decltype(j.template get<T>(), void())
234 for (std::size_t i1 = 0; i1 < N1; ++i1)
236 for (std::size_t i2 = 0; i2 < N2; ++i2)
238 for (std::size_t i3 = 0; i3 < N3; ++i3)
240 arr[i1][i2][i3] = j.at(i1).at(i2).at(i3).template get<T>();
246template<
typename BasicJsonType,
typename T, std::
size_t N1, std::
size_t N2, std::
size_t N3, std::
size_t N4>
247auto from_json(
const BasicJsonType& j, T (&arr)[N1][N2][N3][N4])
248->
decltype(j.template get<T>(), void())
250 for (std::size_t i1 = 0; i1 < N1; ++i1)
252 for (std::size_t i2 = 0; i2 < N2; ++i2)
254 for (std::size_t i3 = 0; i3 < N3; ++i3)
256 for (std::size_t i4 = 0; i4 < N4; ++i4)
258 arr[i1][i2][i3][i4] = j.at(i1).at(i2).at(i3).at(i4).template get<T>();
265template<
typename BasicJsonType>
266inline void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr,
priority_tag<3> )
268 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
271template<
typename BasicJsonType,
typename T, std::
size_t N>
272auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
274->
decltype(j.template get<T>(), void())
276 for (std::size_t i = 0; i < N; ++i)
278 arr[i] = j.at(i).template get<T>();
282template<
typename BasicJsonType,
typename ConstructibleArrayType,
284 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
286auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<1> )
288 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
289 j.template get<typename ConstructibleArrayType::value_type>(),
294 ConstructibleArrayType ret;
295 ret.reserve(j.size());
296 std::transform(j.begin(), j.end(),
297 std::inserter(ret, end(ret)), [](
const BasicJsonType & i)
301 return i.template get<typename ConstructibleArrayType::value_type>();
303 arr = std::move(ret);
306template<
typename BasicJsonType,
typename ConstructibleArrayType,
308 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
310inline void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
315 ConstructibleArrayType ret;
317 j.begin(), j.end(), std::inserter(ret, end(ret)),
318 [](
const BasicJsonType & i)
322 return i.template get<typename ConstructibleArrayType::value_type>();
324 arr = std::move(ret);
327template <
typename BasicJsonType,
typename ConstructibleArrayType,
331 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
332 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
335auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
337j.template get<typename ConstructibleArrayType::value_type>(),
340 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
342 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
348template <
typename BasicJsonType,
typename T, std::size_t... Idx >
349std::array<T,
sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
350 identity_tag<std::array<T,
sizeof...(Idx)>> , index_sequence<Idx...> )
352 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
355template <
typename BasicJsonType,
typename T, std::
size_t N >
356auto from_json(BasicJsonType&& j,
identity_tag<std::array<T, N>> tag)
357->
decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
359 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
361 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
364 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
367template<
typename BasicJsonType>
368inline void from_json(
const BasicJsonType& j,
typename BasicJsonType::binary_t& bin)
370 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
372 JSON_THROW(type_error::create(302, concat(
"type must be binary, but is ", j.type_name()), &j));
375 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
378template<
typename BasicJsonType,
typename ConstructibleObjectType,
379 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
380inline void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
382 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
384 JSON_THROW(type_error::create(302, concat(
"type must be object, but is ", j.type_name()), &j));
387 ConstructibleObjectType ret;
388 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
389 using value_type =
typename ConstructibleObjectType::value_type;
391 inner_object->begin(), inner_object->end(),
392 std::inserter(ret, ret.begin()),
393 [](
typename BasicJsonType::object_t::value_type
const & p)
395 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
397 obj = std::move(ret);
404template <
typename BasicJsonType,
typename ArithmeticType,
406 std::is_arithmetic<ArithmeticType>::value&&
407 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
408 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
409 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
410 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
412inline void from_json(
const BasicJsonType& j, ArithmeticType& val)
414 switch (
static_cast<value_t>(j))
418 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
423 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
428 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
433 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
444 JSON_THROW(type_error::create(302, concat(
"type must be number, but is ", j.type_name()), &j));
448template<
typename BasicJsonType,
typename... Args, std::size_t... Idx>
449std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> )
451 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).
template get<Args>()...);
454template<
typename BasicJsonType>
455std::tuple<> from_json_tuple_impl_base(BasicJsonType& , index_sequence<> )
460template <
typename BasicJsonType,
class A1,
class A2 >
463 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
464 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
467template<
typename BasicJsonType,
typename A1,
typename A2>
468inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p,
priority_tag<1> )
473template<
typename BasicJsonType,
typename... Args>
476 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
479template<
typename BasicJsonType,
typename... Args>
480inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t,
priority_tag<3> )
482 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
485template<
typename BasicJsonType,
typename TupleRelated>
486auto from_json(BasicJsonType&& j, TupleRelated&& t)
487->
decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t),
priority_tag<3> {}))
489 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
491 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
494 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t),
priority_tag<3> {});
497template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
498 typename = enable_if_t < !std::is_constructible <
499 typename BasicJsonType::string_t, Key >::value >>
500inline void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
502 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
504 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
507 for (
const auto& p : j)
509 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
511 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", p.type_name()), &j));
513 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
517template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
518 typename = enable_if_t < !std::is_constructible <
519 typename BasicJsonType::string_t, Key >::value >>
520inline void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
522 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
524 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", j.type_name()), &j));
527 for (
const auto& p : j)
529 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
531 JSON_THROW(type_error::create(302, concat(
"type must be array, but is ", p.type_name()), &j));
533 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
537#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
538template<
typename BasicJsonType>
539inline void from_json(
const BasicJsonType& j, std_fs::path& p)
541 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
543 JSON_THROW(type_error::create(302, concat(
"type must be string, but is ", j.type_name()), &j));
545 const auto& s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
549#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
550 p = std_fs::path(std::u8string_view(
reinterpret_cast<const char8_t*
>(s.data()), s.size()));
552 p = std_fs::u8path(s);
559 template<
typename BasicJsonType,
typename T>
560 auto operator()(
const BasicJsonType& j, T&& val)
const
561 noexcept(
noexcept(from_json(j, std::forward<T>(val))))
562 ->
decltype(from_json(j, std::forward<T>(val)))
564 return from_json(j, std::forward<T>(val));