@@ -191,6 +191,8 @@ template<typename CharType> struct basic_json
191
191
192
192
struct iterator
193
193
{
194
+ constexpr iterator () noexcept = default;
195
+
194
196
constexpr explicit iterator (const basic_json &value, std::size_t index = 0 ) noexcept
195
197
: parent_value_(&value), index_{ index }
196
198
{}
@@ -289,6 +291,8 @@ template<typename CharType> struct basic_json
289
291
290
292
[[nodiscard]] constexpr std::size_t size () const noexcept { return size_; }
291
293
294
+ [[nodiscard]] constexpr bool empty () const noexcept { return size_ == 0 ; }
295
+
292
296
[[nodiscard]] static constexpr std::size_t size (const basic_json &obj) noexcept
293
297
{
294
298
if (obj.is_null ()) { return 0 ; }
@@ -308,16 +312,7 @@ template<typename CharType> struct basic_json
308
312
}
309
313
}
310
314
311
- [[nodiscard]] constexpr iterator find (const std::basic_string_view<CharType> key) const noexcept
312
- {
313
- for (auto itr = begin (); itr != end (); ++itr) {
314
- if (itr.key () == key) { return itr; }
315
- }
316
-
317
- return end ();
318
- }
319
-
320
- [[nodiscard]] constexpr const basic_json &operator [](const std::basic_string_view<CharType> key) const
315
+ [[nodiscard]] constexpr const basic_json &at (const std::basic_string_view<CharType> key) const
321
316
{
322
317
const auto &children = object_data ();
323
318
@@ -343,6 +338,33 @@ template<typename CharType> struct basic_json
343
338
}
344
339
}
345
340
341
+ template <typename Key>[[nodiscard]] constexpr std::size_t count (const Key &key) const noexcept
342
+ {
343
+ if (is_object ()) {
344
+ const auto found = find (key);
345
+ if (found == end ()) {
346
+ return 0 ;
347
+ } else {
348
+ return 1 ;
349
+ }
350
+ }
351
+ return 0 ;
352
+ }
353
+
354
+ [[nodiscard]] constexpr iterator find (const std::basic_string_view<CharType> key) const noexcept
355
+ {
356
+ for (auto itr = begin (); itr != end (); ++itr) {
357
+ if (itr.key () == key) { return itr; }
358
+ }
359
+
360
+ return end ();
361
+ }
362
+
363
+ [[nodiscard]] constexpr const basic_json &operator [](const std::basic_string_view<CharType> key) const
364
+ {
365
+ return at (key);
366
+ }
367
+
346
368
constexpr const auto &array_data () const
347
369
{
348
370
if (const auto *result = data.get_if_array (); result != nullptr ) {
@@ -364,38 +386,35 @@ template<typename CharType> struct basic_json
364
386
constexpr static basic_json object () { return basic_json{ data_t { basic_object_t <CharType>{} } }; }
365
387
constexpr static basic_json array () { return basic_json{ data_t { basic_array_t <CharType>{} } }; }
366
388
367
- template <typename Type>[[nodiscard]] constexpr Type get () const
389
+ template <typename Type>[[nodiscard]] constexpr auto get () const
368
390
{
369
- bool error = false ;
370
- if constexpr (std::is_same_v<Type, std::uint64_t > || std::is_same_v<Type, std::int64_t >) {
391
+ if constexpr (std::is_same_v<Type, std::uint64_t > || std::is_same_v<Type, std::int64_t > || std::is_same_v<Type, double >) {
371
392
if (const auto *uint_value = data.get_if_uinteger (); uint_value != nullptr ) {
372
393
return Type (*uint_value);
373
394
} else if (const auto *value = data.get_if_integer (); value != nullptr ) {
374
395
return Type (*value);
396
+ } else if (const auto *fpvalue = data.get_if_floating_point (); fpvalue != nullptr ) {
397
+ return Type (*fpvalue);
398
+ } else {
399
+ // std::stringstream ss;
400
+ // ss << is_string() << is_object() << is_array() << is_string() << is_boolean() << is_structured() << is_number() << is_null() << is_binary() << is_primitive();
401
+ throw std::runtime_error (" Unexpected type: number requested" );// + ss.str() );
375
402
}
376
- error = true ;
377
- } else if constexpr (std::is_same_v<Type, double >) {
378
- if (const auto *value = data.get_if_floating_point (); value != nullptr ) { return *value; }
379
- error = true ;
380
403
} else if constexpr (std::is_same_v<Type,
381
404
std::basic_string_view<CharType>> || std::is_same_v<Type, std::basic_string<CharType>>) {
382
405
if (const auto *value = data.get_if_string (); value != nullptr ) { return *value; }
383
- error = true ;
406
+ else {
407
+ throw std::runtime_error (" Unexpected type: string-like requested" );
408
+ }
384
409
} else if constexpr (std::is_same_v<Type, bool >) {
385
410
if (const auto *value = data.get_if_boolean (); value != nullptr ) { return *value; }
386
- error = true ;
411
+ else {
412
+ throw std::runtime_error (" Unexpected type: bool requested" );
413
+ }
387
414
} else {
388
415
throw std::runtime_error (" Unexpected type for get()" );
389
416
}
390
417
391
- if (error) {
392
- // we have this boolean only because of a broken gcc implementation
393
- // that incorrect says this is not a constexpr function
394
- throw std::runtime_error (" Type mismatch in get()" );
395
- } else {
396
- // this code is terrible and it makes me sad
397
- return Type{};
398
- }
399
418
}
400
419
401
420
[[nodiscard]] constexpr bool is_object () const noexcept { return data.selected == data_t ::selected_type::object; }
@@ -430,7 +449,7 @@ template<typename CharType> struct basic_json
430
449
431
450
432
451
data_t data;
433
- std::size_t size_{ size (*this ) };
452
+ std::size_t size_{ basic_json:: size (*this ) };
434
453
};
435
454
436
455
using json = basic_json<char >;
0 commit comments