6 #include <forward_list>
11 #include <type_traits>
12 #include <unordered_map>
16 #include <nlohmann/detail/exceptions.hpp>
17 #include <nlohmann/detail/macro_scope.hpp>
18 #include <nlohmann/detail/meta/cpp_future.hpp>
19 #include <nlohmann/detail/meta/type_traits.hpp>
20 #include <nlohmann/detail/value_t.hpp>
26 template<
typename BasicJsonType>
27 void from_json(
const BasicJsonType& j,
typename std::nullptr_t& n)
29 if (JSON_HEDLEY_UNLIKELY(not j.is_null()))
31 JSON_THROW(type_error::create(302,
"type must be null, but is " + std::string(j.type_name())));
37 template<
typename BasicJsonType,
typename ArithmeticType,
38 enable_if_t<std::is_arithmetic<ArithmeticType>::value and
39 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
41 void 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*>());
62 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
66 template<
typename BasicJsonType>
67 void from_json(
const BasicJsonType& j,
typename BasicJsonType::boolean_t& b)
69 if (JSON_HEDLEY_UNLIKELY(not j.is_boolean()))
71 JSON_THROW(type_error::create(302,
"type must be boolean, but is " + std::string(j.type_name())));
73 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
76 template<
typename BasicJsonType>
77 void from_json(
const BasicJsonType& j,
typename BasicJsonType::string_t& s)
79 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
81 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
83 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
87 typename BasicJsonType,
typename ConstructibleStringType,
90 not std::is_same<
typename BasicJsonType::string_t,
91 ConstructibleStringType>::value,
93 void from_json(
const BasicJsonType& j, ConstructibleStringType& s)
95 if (JSON_HEDLEY_UNLIKELY(not j.is_string()))
97 JSON_THROW(type_error::create(302,
"type must be string, but is " + std::string(j.type_name())));
100 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
103 template<
typename BasicJsonType>
104 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_float_t& val)
106 get_arithmetic_value(j, val);
109 template<
typename BasicJsonType>
110 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_unsigned_t& val)
112 get_arithmetic_value(j, val);
115 template<
typename BasicJsonType>
116 void from_json(
const BasicJsonType& j,
typename BasicJsonType::number_integer_t& val)
118 get_arithmetic_value(j, val);
121 template<
typename BasicJsonType,
typename EnumType,
122 enable_if_t<std::is_enum<EnumType>::value,
int> = 0>
123 void from_json(
const BasicJsonType& j, EnumType& e)
125 typename std::underlying_type<EnumType>::type val;
126 get_arithmetic_value(j, val);
127 e =
static_cast<EnumType
>(val);
131 template<
typename BasicJsonType,
typename T,
typename Allocator,
132 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
133 void from_json(
const BasicJsonType& j, std::forward_list<T, Allocator>& l)
135 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
137 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
140 std::transform(j.rbegin(), j.rend(),
141 std::front_inserter(l), [](
const BasicJsonType & i)
143 return i.template get<T>();
148 template<
typename BasicJsonType,
typename T,
149 enable_if_t<std::is_convertible<BasicJsonType, T>::value,
int> = 0>
150 void from_json(
const BasicJsonType& j, std::valarray<T>& l)
152 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
154 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
157 std::copy(j.begin(), j.end(), std::begin(l));
160 template <
typename BasicJsonType,
typename T, std::
size_t N>
161 auto from_json(
const BasicJsonType& j, T (&arr)[N])
162 -> decltype(j.template get<T>(),
void())
164 for (std::size_t i = 0; i < N; ++i)
166 arr[i] = j.at(i).template get<T>();
170 template<
typename BasicJsonType>
171 void from_json_array_impl(
const BasicJsonType& j,
typename BasicJsonType::array_t& arr,
priority_tag<3> )
173 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
176 template <
typename BasicJsonType,
typename T, std::
size_t N>
177 auto from_json_array_impl(
const BasicJsonType& j, std::array<T, N>& arr,
179 -> decltype(j.template get<T>(),
void())
181 for (std::size_t i = 0; i < N; ++i)
183 arr[i] = j.at(i).template get<T>();
187 template<
typename BasicJsonType,
typename ConstructibleArrayType>
188 auto from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
priority_tag<1> )
190 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
191 j.template get<typename ConstructibleArrayType::value_type>(),
196 ConstructibleArrayType ret;
197 ret.reserve(j.size());
198 std::transform(j.begin(), j.end(),
199 std::inserter(ret, end(ret)), [](
const BasicJsonType & i)
203 return i.template get<typename ConstructibleArrayType::value_type>();
205 arr = std::move(ret);
208 template <
typename BasicJsonType,
typename ConstructibleArrayType>
209 void from_json_array_impl(
const BasicJsonType& j, ConstructibleArrayType& arr,
214 ConstructibleArrayType ret;
216 j.begin(), j.end(), std::inserter(ret, end(ret)),
217 [](
const BasicJsonType & i)
221 return i.template get<typename ConstructibleArrayType::value_type>();
223 arr = std::move(ret);
226 template <
typename BasicJsonType,
typename ConstructibleArrayType,
234 auto from_json(
const BasicJsonType& j, ConstructibleArrayType& arr)
236 j.template get<typename ConstructibleArrayType::value_type>(),
239 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
241 JSON_THROW(type_error::create(302,
"type must be array, but is " +
242 std::string(j.type_name())));
248 template<
typename BasicJsonType,
typename ConstructibleObjectType,
249 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value,
int> = 0>
250 void from_json(
const BasicJsonType& j, ConstructibleObjectType& obj)
252 if (JSON_HEDLEY_UNLIKELY(not j.is_object()))
254 JSON_THROW(type_error::create(302,
"type must be object, but is " + std::string(j.type_name())));
257 ConstructibleObjectType ret;
258 auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
259 using value_type =
typename ConstructibleObjectType::value_type;
261 inner_object->begin(), inner_object->end(),
262 std::inserter(ret, ret.begin()),
263 [](
typename BasicJsonType::object_t::value_type
const & p)
265 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
267 obj = std::move(ret);
274 template<
typename BasicJsonType,
typename ArithmeticType,
276 std::is_arithmetic<ArithmeticType>::value and
277 not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value and
278 not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value and
279 not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value and
280 not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
282 void from_json(
const BasicJsonType& j, ArithmeticType& val)
284 switch (
static_cast<value_t>(j))
288 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
293 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
298 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
303 val =
static_cast<ArithmeticType
>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
308 JSON_THROW(type_error::create(302,
"type must be number, but is " + std::string(j.type_name())));
312 template<
typename BasicJsonType,
typename A1,
typename A2>
313 void from_json(
const BasicJsonType& j, std::pair<A1, A2>& p)
315 p = {j.at(0).template get<A1>(), j.at(1).template get<A2>()};
318 template<
typename BasicJsonType,
typename Tuple, std::size_t... Idx>
321 t = std::make_tuple(j.at(Idx).template get<
typename std::tuple_element<Idx, Tuple>::type>()...);
324 template<
typename BasicJsonType,
typename... Args>
325 void from_json(
const BasicJsonType& j, std::tuple<Args...>& t)
330 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Compare,
typename Allocator,
331 typename = enable_if_t<not std::is_constructible<
332 typename BasicJsonType::string_t, Key>::value>>
333 void from_json(
const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
335 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
337 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
340 for (
const auto& p : j)
342 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
344 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
346 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
350 template <
typename BasicJsonType,
typename Key,
typename Value,
typename Hash,
typename KeyEqual,
typename Allocator,
351 typename = enable_if_t<not std::is_constructible<
352 typename BasicJsonType::string_t, Key>::value>>
353 void from_json(
const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
355 if (JSON_HEDLEY_UNLIKELY(not j.is_array()))
357 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(j.type_name())));
360 for (
const auto& p : j)
362 if (JSON_HEDLEY_UNLIKELY(not p.is_array()))
364 JSON_THROW(type_error::create(302,
"type must be array, but is " + std::string(p.type_name())));
366 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
372 template<
typename BasicJsonType,
typename T>
373 auto operator()(
const BasicJsonType& j, T& val)
const
374 noexcept(noexcept(from_json(j, val)))
375 -> decltype(from_json(j, val),
void())
377 return from_json(j, val);
value_t
the JSON type enumeration
Definition: value_t.hpp:42
@ 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:371
Definition: cpp_future.hpp:22
Definition: type_traits.hpp:39
Definition: type_traits.hpp:316
Definition: type_traits.hpp:213
Definition: type_traits.hpp:250
Definition: cpp_future.hpp:41
Definition: cpp_future.hpp:51
Definition: cpp_future.hpp:50
Definition: cpp_future.hpp:56