5 #include <forward_list>
10 #include <type_traits>
11 #include <unordered_map>
15 #include <nlohmann/detail/exceptions.hpp>
16 #include <nlohmann/detail/macro_scope.hpp>
17 #include <nlohmann/detail/meta/cpp_future.hpp>
18 #include <nlohmann/detail/meta/type_traits.hpp>
19 #include <nlohmann/detail/value_t.hpp>
25 template<
typename BasicJsonType>
26 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
28 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
30 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name())));
36 template <
typename BasicJsonType,
typename ArithmeticType,
37 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
38 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
40 void get_arithmetic_value(
const BasicJsonType& j, ArithmeticType& val)
42 switch (
static_cast<value_t>(j))
46 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
51 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
56 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
61 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
65 template<
typename BasicJsonType>
66 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
68 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
70 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
72 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
75 template<
typename BasicJsonType>
76 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
78 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
80 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
82 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
86 typename BasicJsonType,
typename ConstructibleStringType,
89 !std::is_same<
typename BasicJsonType::string_t,
90 ConstructibleStringType>::value,
92 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
94 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
96 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
99 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
102 template<
typename BasicJsonType>
103 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
105 get_arithmetic_value(j, val);
108 template<
typename BasicJsonType>
109 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
111 get_arithmetic_value(j, val);
114 template<
typename BasicJsonType>
115 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
117 get_arithmetic_value(j, val);
120 template<
typename BasicJsonType,
typename EnumType,
121 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
122 void from_json(
const BasicJsonType& j, EnumType& e)
124 typename std::underlying_type<EnumType>::type val;
125 get_arithmetic_value(j, val);
126 e =
static_cast<EnumType
>(val);
130 template<
typename BasicJsonType,
typename T,
typename Allocator,
131 enable_if_t<is_getable<BasicJsonType, T>::value,
int> = 0>
132 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
134 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
136 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
139 std::transform(j.rbegin(), j.rend(),
140 std::front_inserter(l), [](
const BasicJsonType & i)
142 return i.template get<T>();
147 template<
typename BasicJsonType,
typename T,
148 enable_if_t<is_getable<BasicJsonType, T>::value,
int> = 0>
149 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
151 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
153 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
156 std::transform(j.begin(), j.end(), std::begin(l),
157 [](
const BasicJsonType & elem)
159 return elem.template get<T>();
163 template<
typename BasicJsonType,
typename T, std::
size_t N>
164 auto from_json(
const BasicJsonType& j, T (&arr)[N])
165 -> decltype(j.template get<T>(),
void())
167 for (std::size_t i = 0; i < N; ++i)
169 arr[i] = j.at(i).template get<T>();
173 template<
typename BasicJsonType>
174 void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr,
priority_tag<3> )
176 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
179 template<
typename BasicJsonType,
typename T, std::
size_t N>
180 auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
182 -> decltype(j.template get<T>(),
void())
184 for (std::size_t i = 0; i < N; ++i)
186 arr[i] = j.at(i).template get<T>();
190 template<
typename BasicJsonType,
typename ConstructibleArrayType>
191 auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<1> )
193 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
194 j.template get<typename ConstructibleArrayType::value_type>(),
199 ConstructibleArrayType ret;
200 ret.reserve(j.size());
201 std::transform(j.begin(), j.end(),
202 std::inserter(ret, end(ret)), [](
const BasicJsonType & i)
206 return i.template get<typename ConstructibleArrayType::value_type>();
208 arr = std::move(ret);
211 template<
typename BasicJsonType,
typename ConstructibleArrayType>
212 void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
217 ConstructibleArrayType ret;
219 j.begin(), j.end(), std::inserter(ret, end(ret)),
220 [](
const BasicJsonType & i)
224 return i.template get<typename ConstructibleArrayType::value_type>();
226 arr = std::move(ret);
229 template <
typename BasicJsonType,
typename ConstructibleArrayType,
234 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
237 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
239 j.template get<typename ConstructibleArrayType::value_type>(),
242 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
244 JSON_THROW(type_error::create(302,
"type must be array, but is " +
245 std::string(j.type_name())));
251 template<
typename BasicJsonType>
252 void from_json(
const BasicJsonType& j,
typename BasicJsonType::binary_t& bin)
254 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
256 JSON_THROW(type_error::create(302,
"type must be binary, but is " + std::string(j.type_name())));
259 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
262 template<
typename BasicJsonType,
typename ConstructibleObjectType,
263 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
264 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
266 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
268 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
271 ConstructibleObjectType ret;
272 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
273 using value_type =
typename ConstructibleObjectType::value_type;
275 inner_object->begin(), inner_object->end(),
276 std::inserter(ret, ret.begin()),
277 [](
typename BasicJsonType::object_t::value_type
const & p)
279 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
281 obj = std::move(ret);
288 template <
typename BasicJsonType,
typename ArithmeticType,
290 std::is_arithmetic<ArithmeticType>::value&&
291 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
292 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
293 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
294 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
296 void from_json(
const BasicJsonType& j, ArithmeticType& val)
298 switch (
static_cast<value_t>(j))
302 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
307 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
312 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
317 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
322 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
326 template<
typename BasicJsonType,
typename A1,
typename A2>
327 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
329 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
332 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
335 t = std::make_tuple(j.at(Idx).template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
338 template<
typename BasicJsonType,
typename... Args>
339 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
344 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
345 typename = enable_if_t < !std::is_constructible <
346 typename BasicJsonType::string_t, Key >::value >>
347 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
349 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
351 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
354 for (
const auto& p : j)
356 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
358 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
360 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
364 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
365 typename = enable_if_t < !std::is_constructible <
366 typename BasicJsonType::string_t, Key >::value >>
367 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
369 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
371 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
374 for (
const auto& p : j)
376 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
378 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
380 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
386 template<
typename BasicJsonType,
typename T>
387 auto operator()(
const BasicJsonType& j, T& val)
const
388 noexcept(noexcept(from_json(j, val)))
389 -> decltype(from_json(j, val),
void())
391 return from_json(j, val);
value_t
the JSON type enumeration
Definition: value_t.hpp:41
@ number_integer
number value (signed integer)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
Definition: from_json.hpp:385
Definition: cpp_future.hpp:21
Definition: type_traits.hpp:38
Definition: type_traits.hpp:338
Definition: type_traits.hpp:235
Definition: type_traits.hpp:272
Definition: cpp_future.hpp:40
Definition: cpp_future.hpp:50
Definition: cpp_future.hpp:49
Definition: cpp_future.hpp:55