26template<
typename BasicJsonType>
27void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
29 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
31 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name()), j));
37template <
typename BasicJsonType,
typename ArithmeticType,
38 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
39 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
41void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
43 switch (
static_cast<value_t>(j))
47 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
52 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
57 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
69 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name()), j));
73template<
typename BasicJsonType>
74void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
76 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
78 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name()), j));
80 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
83template<
typename BasicJsonType>
84void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
86 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
88 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name()), j));
90 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
94 typename BasicJsonType,
typename ConstructibleStringType,
97 !std::is_same<
typename BasicJsonType::string_t,
98 ConstructibleStringType>
::value,
100void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
102 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
104 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name()), j));
107 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
110template<
typename BasicJsonType>
111void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
113 get_arithmetic_value(j, val);
116template<
typename BasicJsonType>
117void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
119 get_arithmetic_value(j, val);
122template<
typename BasicJsonType>
123void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
125 get_arithmetic_value(j, val);
128template<
typename BasicJsonType,
typename EnumType,
129 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
130void from_json(
const BasicJsonType& j, EnumType& e)
132 typename std::underlying_type<EnumType>::type val;
133 get_arithmetic_value(j, val);
134 e =
static_cast<EnumType
>(val);
138template<
typename BasicJsonType,
typename T,
typename Allocator,
139 enable_if_t<is_getable<BasicJsonType, T>::value,
int> = 0>
140void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
142 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
144 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
147 std::transform(j.rbegin(), j.rend(),
148 std::front_inserter(l), [](
const BasicJsonType & i)
150 return i.template get<T>();
155template<
typename BasicJsonType,
typename T,
156 enable_if_t<is_getable<BasicJsonType, T>::value,
int> = 0>
157void from_json(
const BasicJsonType& j, std::valarray<T>& l)
159 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
161 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
164 std::transform(j.begin(), j.end(), std::begin(l),
165 [](
const BasicJsonType & elem)
167 return elem.template get<T>();
171template<
typename BasicJsonType,
typename T, std::
size_t N>
172auto from_json(
const BasicJsonType& j, T (&arr)[N])
173->
decltype(j.template get<T>(), void())
175 for (std::size_t i = 0; i < N; ++i)
177 arr[i] = j.at(i).template get<T>();
181template<
typename BasicJsonType>
182void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr,
priority_tag<3> )
184 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
187template<
typename BasicJsonType,
typename T, std::
size_t N>
188auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
190->
decltype(j.template get<T>(), void())
192 for (std::size_t i = 0; i < N; ++i)
194 arr[i] = j.at(i).template get<T>();
198template<
typename BasicJsonType,
typename ConstructibleArrayType,
200 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
202auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<1> )
204 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
205 j.template get<typename ConstructibleArrayType::value_type>(),
210 ConstructibleArrayType ret;
211 ret.reserve(j.size());
212 std::transform(j.begin(), j.end(),
213 std::inserter(ret, end(ret)), [](
const BasicJsonType & i)
217 return i.template get<typename ConstructibleArrayType::value_type>();
219 arr = std::move(ret);
222template<
typename BasicJsonType,
typename ConstructibleArrayType,
224 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
226void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
231 ConstructibleArrayType ret;
233 j.begin(), j.end(), std::inserter(ret, end(ret)),
234 [](
const BasicJsonType & i)
238 return i.template get<typename ConstructibleArrayType::value_type>();
240 arr = std::move(ret);
243template <
typename BasicJsonType,
typename ConstructibleArrayType,
248 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
251auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
253j.template get<typename ConstructibleArrayType::value_type>(),
256 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
258 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
264template <
typename BasicJsonType,
typename T, std::size_t... Idx >
265std::array<T,
sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
268 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
271template <
typename BasicJsonType,
typename T, std::
size_t N >
272auto from_json(BasicJsonType&& j,
identity_tag<std::array<T, N>> tag)
273->
decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
275 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
277 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
280 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
283template<
typename BasicJsonType>
284void from_json(
const BasicJsonType& j,
typename BasicJsonType::binary_t& bin)
286 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
288 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(j.type_name()), j));
291 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
294template<
typename BasicJsonType,
typename ConstructibleObjectType,
295 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
296void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
298 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
300 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name()), j));
303 ConstructibleObjectType ret;
304 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
305 using value_type =
typename ConstructibleObjectType::value_type;
307 inner_object->begin(), inner_object->end(),
308 std::inserter(ret, ret.begin()),
309 [](
typename BasicJsonType::object_t::value_type
const & p)
311 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
313 obj = std::move(ret);
320template <
typename BasicJsonType,
typename ArithmeticType,
322 std::is_arithmetic<ArithmeticType>::value&&
323 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
324 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
325 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
326 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
328void from_json(
const BasicJsonType& j, ArithmeticType& val)
330 switch (
static_cast<value_t>(j))
334 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
339 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
344 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
349 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
360 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name()), j));
364template<
typename BasicJsonType,
typename... Args, std::size_t... Idx>
367 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).
template get<Args>()...);
370template <
typename BasicJsonType,
class A1,
class A2 >
373 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
374 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
377template<
typename BasicJsonType,
typename A1,
typename A2>
378void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p,
priority_tag<1> )
383template<
typename BasicJsonType,
typename... Args>
386 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
389template<
typename BasicJsonType,
typename... Args>
390void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t,
priority_tag<3> )
392 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
395template<
typename BasicJsonType,
typename TupleRelated>
396auto from_json(BasicJsonType&& j, TupleRelated&& t)
397->
decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t),
priority_tag<3> {}))
399 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
401 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
404 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t),
priority_tag<3> {});
407template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
408 typename = enable_if_t < !std::is_constructible <
409 typename BasicJsonType::string_t, Key >
::value >>
410void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
412 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
414 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
417 for (
const auto& p : j)
419 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
421 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name()), j));
423 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
427template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
428 typename = enable_if_t < !std::is_constructible <
429 typename BasicJsonType::string_t, Key >
::value >>
430void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
432 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
434 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name()), j));
437 for (
const auto& p : j)
439 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
441 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name()), j));
443 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
449 template<
typename BasicJsonType,
typename T>
450 auto operator()(
const BasicJsonType& j, T&& val)
const
451 noexcept(
noexcept(from_json(j, std::forward<T>(val))))
452 ->
decltype(from_json(j, std::forward<T>(val)))
454 return from_json(j, std::forward<T>(val));