2
2
3
3
#include < algorithm> // transform
4
4
#include < array> // array
5
- #include < ciso646> // and, not
6
5
#include < forward_list> // forward_list
7
6
#include < iterator> // inserter, front_inserter, end
8
7
#include < map> // map
@@ -26,18 +25,18 @@ namespace detail
26
25
template <typename BasicJsonType>
27
26
void from_json (const BasicJsonType& j, typename std::nullptr_t & n)
28
27
{
29
- if (JSON_UNLIKELY ( not j.is_null ()))
28
+ if (JSON_HEDLEY_UNLIKELY (! j.is_null ()))
30
29
{
31
30
JSON_THROW (type_error::create (302 , " type must be null, but is " + std::string (j.type_name ())));
32
31
}
33
32
n = nullptr ;
34
33
}
35
34
36
35
// overloads for basic_json template parameters
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,
40
- int > = 0 >
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,
39
+ int > = 0 >
41
40
void get_arithmetic_value (const BasicJsonType& j, ArithmeticType& val)
42
41
{
43
42
switch (static_cast <value_t >(j))
@@ -66,7 +65,7 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
66
65
template <typename BasicJsonType>
67
66
void from_json (const BasicJsonType& j, typename BasicJsonType::boolean_t & b)
68
67
{
69
- if (JSON_UNLIKELY ( not j.is_boolean ()))
68
+ if (JSON_HEDLEY_UNLIKELY (! j.is_boolean ()))
70
69
{
71
70
JSON_THROW (type_error::create (302 , " type must be boolean, but is " + std::string (j.type_name ())));
72
71
}
@@ -76,7 +75,7 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
76
75
template <typename BasicJsonType>
77
76
void from_json (const BasicJsonType& j, typename BasicJsonType::string_t & s)
78
77
{
79
- if (JSON_UNLIKELY ( not j.is_string ()))
78
+ if (JSON_HEDLEY_UNLIKELY (! j.is_string ()))
80
79
{
81
80
JSON_THROW (type_error::create (302 , " type must be string, but is " + std::string (j.type_name ())));
82
81
}
@@ -86,13 +85,13 @@ void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
86
85
template <
87
86
typename BasicJsonType, typename ConstructibleStringType,
88
87
enable_if_t <
89
- is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value and
90
- not std::is_same<typename BasicJsonType::string_t ,
91
- ConstructibleStringType>::value,
88
+ is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
89
+ ! std::is_same<typename BasicJsonType::string_t ,
90
+ ConstructibleStringType>::value,
92
91
int > = 0 >
93
92
void from_json (const BasicJsonType& j, ConstructibleStringType& s)
94
93
{
95
- if (JSON_UNLIKELY ( not j.is_string ()))
94
+ if (JSON_HEDLEY_UNLIKELY (! j.is_string ()))
96
95
{
97
96
JSON_THROW (type_error::create (302 , " type must be string, but is " + std::string (j.type_name ())));
98
97
}
@@ -129,13 +128,14 @@ void from_json(const BasicJsonType& j, EnumType& e)
129
128
130
129
// forward_list doesn't have an insert method
131
130
template <typename BasicJsonType, typename T, typename Allocator,
132
- enable_if_t <std::is_convertible <BasicJsonType, T>::value, int > = 0 >
131
+ enable_if_t <is_getable <BasicJsonType, T>::value, int > = 0 >
133
132
void from_json (const BasicJsonType& j, std::forward_list<T, Allocator>& l)
134
133
{
135
- if (JSON_UNLIKELY ( not j.is_array ()))
134
+ if (JSON_HEDLEY_UNLIKELY (! j.is_array ()))
136
135
{
137
136
JSON_THROW (type_error::create (302 , " type must be array, but is " + std::string (j.type_name ())));
138
137
}
138
+ l.clear ();
139
139
std::transform (j.rbegin (), j.rend (),
140
140
std::front_inserter (l), [](const BasicJsonType & i)
141
141
{
@@ -145,15 +145,29 @@ void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
145
145
146
146
// valarray doesn't have an insert method
147
147
template <typename BasicJsonType, typename T,
148
- enable_if_t <std::is_convertible <BasicJsonType, T>::value, int > = 0 >
148
+ enable_if_t <is_getable <BasicJsonType, T>::value, int > = 0 >
149
149
void from_json (const BasicJsonType& j, std::valarray<T>& l)
150
150
{
151
- if (JSON_UNLIKELY ( not j.is_array ()))
151
+ if (JSON_HEDLEY_UNLIKELY (! j.is_array ()))
152
152
{
153
153
JSON_THROW (type_error::create (302 , " type must be array, but is " + std::string (j.type_name ())));
154
154
}
155
155
l.resize (j.size ());
156
- std::copy (j.m_value .array ->begin (), j.m_value .array ->end (), std::begin (l));
156
+ std::transform (j.begin (), j.end (), std::begin (l),
157
+ [](const BasicJsonType & elem)
158
+ {
159
+ return elem.template get <T>();
160
+ });
161
+ }
162
+
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())
166
+ {
167
+ for (std::size_t i = 0 ; i < N; ++i)
168
+ {
169
+ arr[i] = j.at (i).template get <T>();
170
+ }
157
171
}
158
172
159
173
template <typename BasicJsonType>
@@ -162,7 +176,7 @@ void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_
162
176
arr = *j.template get_ptr <const typename BasicJsonType::array_t *>();
163
177
}
164
178
165
- template <typename BasicJsonType, typename T, std::size_t N>
179
+ template <typename BasicJsonType, typename T, std::size_t N>
166
180
auto from_json_array_impl (const BasicJsonType& j, std::array<T, N>& arr,
167
181
priority_tag<2 > /* unused*/ )
168
182
-> decltype(j.template get<T>(), void())
@@ -182,46 +196,50 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
182
196
{
183
197
using std::end;
184
198
185
- arr.reserve (j.size ());
199
+ ConstructibleArrayType ret;
200
+ ret.reserve (j.size ());
186
201
std::transform (j.begin (), j.end (),
187
- std::inserter (arr , end (arr )), [](const BasicJsonType & i)
202
+ std::inserter (ret , end (ret )), [](const BasicJsonType & i)
188
203
{
189
204
// get<BasicJsonType>() returns *this, this won't call a from_json
190
205
// method when value_type is BasicJsonType
191
206
return i.template get <typename ConstructibleArrayType::value_type>();
192
207
});
208
+ arr = std::move (ret);
193
209
}
194
210
195
- template <typename BasicJsonType, typename ConstructibleArrayType>
211
+ template <typename BasicJsonType, typename ConstructibleArrayType>
196
212
void from_json_array_impl (const BasicJsonType& j, ConstructibleArrayType& arr,
197
213
priority_tag<0 > /* unused*/ )
198
214
{
199
215
using std::end;
200
216
217
+ ConstructibleArrayType ret;
201
218
std::transform (
202
- j.begin (), j.end (), std::inserter (arr , end (arr )),
219
+ j.begin (), j.end (), std::inserter (ret , end (ret )),
203
220
[](const BasicJsonType & i)
204
221
{
205
222
// get<BasicJsonType>() returns *this, this won't call a from_json
206
223
// method when value_type is BasicJsonType
207
224
return i.template get <typename ConstructibleArrayType::value_type>();
208
225
});
226
+ arr = std::move (ret);
209
227
}
210
228
211
- template <typename BasicJsonType, typename ConstructibleArrayType,
212
- enable_if_t <
213
- is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value and
214
- not is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value and
215
- not is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value and
216
- not is_basic_json <ConstructibleArrayType>::value,
217
- int > = 0 >
218
-
229
+ template < typename BasicJsonType, typename ConstructibleArrayType,
230
+ enable_if_t <
231
+ is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
232
+ ! is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
233
+ ! is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
234
+ !std::is_same <ConstructibleArrayType, typename BasicJsonType:: binary_t >::value&&
235
+ !is_basic_json<ConstructibleArrayType>::value,
236
+ int > = 0 >
219
237
auto from_json (const BasicJsonType& j, ConstructibleArrayType& arr)
220
238
-> decltype(from_json_array_impl(j, arr, priority_tag<3 > {}),
221
239
j.template get<typename ConstructibleArrayType::value_type>(),
222
240
void())
223
241
{
224
- if (JSON_UNLIKELY ( not j.is_array ()))
242
+ if (JSON_HEDLEY_UNLIKELY (! j.is_array ()))
225
243
{
226
244
JSON_THROW (type_error::create (302 , " type must be array, but is " +
227
245
std::string (j.type_name ())));
@@ -230,38 +248,51 @@ void())
230
248
from_json_array_impl (j, arr, priority_tag<3 > {});
231
249
}
232
250
251
+ template <typename BasicJsonType>
252
+ void from_json (const BasicJsonType& j, typename BasicJsonType::binary_t & bin)
253
+ {
254
+ if (JSON_HEDLEY_UNLIKELY (!j.is_binary ()))
255
+ {
256
+ JSON_THROW (type_error::create (302 , " type must be binary, but is " + std::string (j.type_name ())));
257
+ }
258
+
259
+ bin = *j.template get_ptr <const typename BasicJsonType::binary_t *>();
260
+ }
261
+
233
262
template <typename BasicJsonType, typename ConstructibleObjectType,
234
263
enable_if_t <is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int > = 0 >
235
264
void from_json (const BasicJsonType& j, ConstructibleObjectType& obj)
236
265
{
237
- if (JSON_UNLIKELY ( not j.is_object ()))
266
+ if (JSON_HEDLEY_UNLIKELY (! j.is_object ()))
238
267
{
239
268
JSON_THROW (type_error::create (302 , " type must be object, but is " + std::string (j.type_name ())));
240
269
}
241
270
271
+ ConstructibleObjectType ret;
242
272
auto inner_object = j.template get_ptr <const typename BasicJsonType::object_t *>();
243
273
using value_type = typename ConstructibleObjectType::value_type;
244
274
std::transform (
245
275
inner_object->begin (), inner_object->end (),
246
- std::inserter (obj, obj .begin ()),
276
+ std::inserter (ret, ret .begin ()),
247
277
[](typename BasicJsonType::object_t ::value_type const & p)
248
278
{
249
279
return value_type (p.first , p.second .template get <typename ConstructibleObjectType::mapped_type>());
250
280
});
281
+ obj = std::move (ret);
251
282
}
252
283
253
284
// overload for arithmetic types, not chosen for basic_json template arguments
254
285
// (BooleanType, etc..); note: Is it really necessary to provide explicit
255
286
// overloads for boolean_t etc. in case of a custom BooleanType which is not
256
287
// an arithmetic type?
257
- template < typename BasicJsonType, typename ArithmeticType,
258
- enable_if_t <
259
- std::is_arithmetic<ArithmeticType>::value and
260
- not std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t >::value and
261
- not std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t >::value and
262
- not std::is_same<ArithmeticType, typename BasicJsonType::number_float_t >::value and
263
- not std::is_same<ArithmeticType, typename BasicJsonType::boolean_t >::value,
264
- int > = 0 >
288
+ template < typename BasicJsonType, typename ArithmeticType,
289
+ enable_if_t <
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,
295
+ int > = 0 >
265
296
void from_json (const BasicJsonType& j, ArithmeticType& val)
266
297
{
267
298
switch (static_cast <value_t >(j))
@@ -310,37 +341,39 @@ void from_json(const BasicJsonType& j, std::tuple<Args...>& t)
310
341
from_json_tuple_impl (j, t, index_sequence_for<Args...> {});
311
342
}
312
343
313
- template <typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
314
- typename = enable_if_t < not std::is_constructible<
315
- typename BasicJsonType::string_t , Key>::value>>
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 >>
316
347
void from_json (const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
317
348
{
318
- if (JSON_UNLIKELY ( not j.is_array ()))
349
+ if (JSON_HEDLEY_UNLIKELY (! j.is_array ()))
319
350
{
320
351
JSON_THROW (type_error::create (302 , " type must be array, but is " + std::string (j.type_name ())));
321
352
}
353
+ m.clear ();
322
354
for (const auto & p : j)
323
355
{
324
- if (JSON_UNLIKELY ( not p.is_array ()))
356
+ if (JSON_HEDLEY_UNLIKELY (! p.is_array ()))
325
357
{
326
358
JSON_THROW (type_error::create (302 , " type must be array, but is " + std::string (p.type_name ())));
327
359
}
328
360
m.emplace (p.at (0 ).template get <Key>(), p.at (1 ).template get <Value>());
329
361
}
330
362
}
331
363
332
- template <typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
333
- typename = enable_if_t < not std::is_constructible<
334
- typename BasicJsonType::string_t , Key>::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 >>
335
367
void from_json (const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
336
368
{
337
- if (JSON_UNLIKELY ( not j.is_array ()))
369
+ if (JSON_HEDLEY_UNLIKELY (! j.is_array ()))
338
370
{
339
371
JSON_THROW (type_error::create (302 , " type must be array, but is " + std::string (j.type_name ())));
340
372
}
373
+ m.clear ();
341
374
for (const auto & p : j)
342
375
{
343
- if (JSON_UNLIKELY ( not p.is_array ()))
376
+ if (JSON_HEDLEY_UNLIKELY (! p.is_array ()))
344
377
{
345
378
JSON_THROW (type_error::create (302 , " type must be array, but is " + std::string (p.type_name ())));
346
379
}
@@ -367,4 +400,4 @@ namespace
367
400
{
368
401
constexpr const auto & from_json = detail::static_const<detail::from_json_fn>::value;
369
402
} // namespace
370
- } // namespace nlohmann
403
+ } // namespace nlohmann
0 commit comments