@@ -191,6 +191,8 @@ template<typename CharType> struct basic_json
191191
192192 struct iterator
193193 {
194+ constexpr iterator () noexcept = default;
195+
194196 constexpr explicit iterator (const basic_json &value, std::size_t index = 0 ) noexcept
195197 : parent_value_(&value), index_{ index }
196198 {}
@@ -289,6 +291,8 @@ template<typename CharType> struct basic_json
289291
290292 [[nodiscard]] constexpr std::size_t size () const noexcept { return size_; }
291293
294+ [[nodiscard]] constexpr bool empty () const noexcept { return size_ == 0 ; }
295+
292296 [[nodiscard]] static constexpr std::size_t size (const basic_json &obj) noexcept
293297 {
294298 if (obj.is_null ()) { return 0 ; }
@@ -308,16 +312,7 @@ template<typename CharType> struct basic_json
308312 }
309313 }
310314
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
321316 {
322317 const auto &children = object_data ();
323318
@@ -343,6 +338,33 @@ template<typename CharType> struct basic_json
343338 }
344339 }
345340
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+
346368 constexpr const auto &array_data () const
347369 {
348370 if (const auto *result = data.get_if_array (); result != nullptr ) {
@@ -364,38 +386,35 @@ template<typename CharType> struct basic_json
364386 constexpr static basic_json object () { return basic_json{ data_t { basic_object_t <CharType>{} } }; }
365387 constexpr static basic_json array () { return basic_json{ data_t { basic_array_t <CharType>{} } }; }
366388
367- template <typename Type>[[nodiscard]] constexpr Type get () const
389+ template <typename Type>[[nodiscard]] constexpr auto get () const
368390 {
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 >) {
371392 if (const auto *uint_value = data.get_if_uinteger (); uint_value != nullptr ) {
372393 return Type (*uint_value);
373394 } else if (const auto *value = data.get_if_integer (); value != nullptr ) {
374395 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() );
375402 }
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 ;
380403 } else if constexpr (std::is_same_v<Type,
381404 std::basic_string_view<CharType>> || std::is_same_v<Type, std::basic_string<CharType>>) {
382405 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+ }
384409 } else if constexpr (std::is_same_v<Type, bool >) {
385410 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+ }
387414 } else {
388415 throw std::runtime_error (" Unexpected type for get()" );
389416 }
390417
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- }
399418 }
400419
401420 [[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
430449
431450
432451 data_t data;
433- std::size_t size_{ size (*this ) };
452+ std::size_t size_{ basic_json:: size (*this ) };
434453};
435454
436455using json = basic_json<char >;
0 commit comments