simdjson 5.0.2
Ridiculously Fast JSON
Loading...
Searching...
No Matches
object.h
1#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H
2
3#ifndef SIMDJSON_CONDITIONAL_INCLUDE
4#define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H
5#include "simdjson/generic/ondemand/base.h"
6#include "simdjson/generic/implementation_simdjson_result_base.h"
7#include "simdjson/generic/ondemand/value_iterator.h"
8#include "simdjson/generic/ondemand/key_selector.h"
9#include <vector>
10#if SIMDJSON_STATIC_REFLECTION && SIMDJSON_SUPPORTS_CONCEPTS
11#include "simdjson/generic/ondemand/json_string_builder.h" // for constevalutil::fixed_string
12#endif
13#endif // SIMDJSON_CONDITIONAL_INCLUDE
14
15namespace simdjson {
16namespace SIMDJSON_IMPLEMENTATION {
17namespace ondemand {
18
19#if SIMDJSON_SUPPORTS_CONCEPTS
39struct [[nodiscard]] for_each_result {
40 error_code error{SUCCESS};
41 std::size_t matched_count{0};
42 constexpr operator error_code() const noexcept { return error; }
43};
44
45namespace key_selector_for_each_detail {
56template <typename H>
57concept field_handler =
58 std::is_invocable_v<std::remove_reference_t<H>&, value> ||
59 ::simdjson::deserializable<std::remove_cvref_t<H>, value>;
60
67template <typename H>
68inline constexpr bool nothrow_field_handler_v =
69 std::is_invocable_v<std::remove_reference_t<H>&, value>
70 ? std::is_nothrow_invocable_v<std::remove_reference_t<H>&, value>
71 : ::simdjson::nothrow_deserializable<std::remove_cvref_t<H>, value>;
72
83template <typename... Handlers>
84inline constexpr bool nothrow_field_handlers_v =
85 (nothrow_field_handler_v<Handlers> && ...);
86} // namespace key_selector_for_each_detail
87#endif
88
115 simdjson_inline object_position() noexcept = default;
116
117private:
118 token_position position{};
119 depth_t depth{};
120
121 simdjson_inline object_position(token_position position_, depth_t depth_) noexcept
122 : position(position_), depth(depth_) {}
123
124 friend class object;
125};
126
130class object {
131public:
137 simdjson_inline object() noexcept = default;
138
150 simdjson_inline simdjson_result<object_iterator> begin() & noexcept;
157 simdjson_inline simdjson_result<object_iterator> begin() && noexcept;
158 simdjson_inline simdjson_result<object_iterator> end() noexcept;
198 simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept;
200 simdjson_inline simdjson_result<value> find_field(std::string_view key) && noexcept;
201
238 simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept;
240 simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) && noexcept;
242 simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
244 simdjson_inline simdjson_result<value> operator[](std::string_view key) && noexcept;
245
246#if SIMDJSON_SUPPORTS_CONCEPTS
288 template <typename Selector, typename Func>
289 requires key_selector_type<Selector> &&
290 std::is_invocable_v<Func&, std::size_t, value>
291 simdjson_inline for_each_result for_each(Func&& on_match)
292 noexcept(std::is_nothrow_invocable_v<Func&, std::size_t, value>);
293
318 template <typename Selector, typename... Handlers>
319 requires key_selector_type<Selector> &&
320 (sizeof...(Handlers) == Selector::size()) &&
321 (key_selector_for_each_detail::field_handler<Handlers> && ...)
322 simdjson_inline for_each_result for_each(Handlers&&... on_match)
323 noexcept(key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
324
332 template <constevalutil::fixed_string... Keys, typename... Handlers>
333 requires (sizeof...(Handlers) == sizeof...(Keys)) &&
334 (sizeof...(Keys) >= 1) && (sizeof...(Keys) <= 255) &&
335 (key_selector_for_each_detail::field_handler<Handlers> && ...)
336 simdjson_inline for_each_result for_each(Handlers&&... on_match)
337 noexcept(key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
338#endif
339
374 inline simdjson_result<value> at_pointer(std::string_view json_pointer) noexcept;
375
387 inline simdjson_result<value> at_path(std::string_view json_path) noexcept;
388
398#if SIMDJSON_SUPPORTS_CONCEPTS
399 template <typename Func>
400 requires std::invocable<Func, value>
401#else
402 template <typename Func>
403#endif
404 inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
405
415 inline simdjson_result<bool> reset() & noexcept;
431 simdjson_inline object_position get_current_position() const noexcept;
443 simdjson_inline error_code revert_position(object_position position) noexcept;
453 inline simdjson_result<bool> is_empty() & noexcept;
471 simdjson_inline simdjson_result<size_t> count_fields() & noexcept;
477 simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
478
479#if SIMDJSON_SUPPORTS_CONCEPTS
487 template <typename T>
488 simdjson_warn_unused simdjson_inline error_code get(T &out)
489 noexcept(nothrow_gettable<T, object>) {
490 static_assert(custom_deserializable<T, object>);
491 return deserialize(*this, out);
492 }
499 template <typename T>
500 simdjson_inline simdjson_result<T> get()
501 noexcept(nothrow_gettable<T, object>)
502 {
503 static_assert(std::is_default_constructible<T>::value, "The specified type is not default constructible.");
504 T out{};
505 SIMDJSON_TRY(get<T>(out));
506 return out;
507 }
508
509#if SIMDJSON_STATIC_REFLECTION
534 template<constevalutil::fixed_string... FieldNames, typename T>
535 requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
536 simdjson_warn_unused simdjson_inline error_code extract_into(T& out) & noexcept;
537#endif // SIMDJSON_STATIC_REFLECTION
538#endif // SIMDJSON_SUPPORTS_CONCEPTS
539protected:
543 simdjson_warn_unused simdjson_inline error_code consume() noexcept;
544 static simdjson_inline simdjson_result<object> start(value_iterator &iter) noexcept;
545 static simdjson_inline simdjson_result<object> start_root(value_iterator &iter) noexcept;
546 static simdjson_inline simdjson_result<object> started(value_iterator &iter) noexcept;
547 static simdjson_inline object resume(const value_iterator &iter) noexcept;
548 simdjson_inline object(const value_iterator &iter) noexcept;
549
550 simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept;
551
552 value_iterator iter{};
553#if SIMDJSON_DEVELOPMENT_CHECKS
554 bool locked{false};
555 simdjson_inline void set_locked(bool _locked) noexcept;
556#endif
557
558 friend class value;
559 friend class document;
560 friend struct simdjson_result<object>;
561#if SIMDJSON_DEVELOPMENT_CHECKS
562 friend class object_iterator;
563 friend struct simdjson_result<object_iterator>;
564#endif
565};
566
567} // namespace ondemand
568} // namespace SIMDJSON_IMPLEMENTATION
569} // namespace simdjson
570
571namespace simdjson {
572
573template<>
574struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object> {
575public:
576 simdjson_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::object &&value) noexcept;
577 simdjson_inline simdjson_result(error_code error) noexcept;
578 simdjson_inline simdjson_result() noexcept = default;
579
583 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(std::string_view key) & noexcept;
584 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(std::string_view key) && noexcept;
585 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
586 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) && noexcept;
587 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
588 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) && noexcept;
589 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
590 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
591#if SIMDJSON_SUPPORTS_CONCEPTS
592 template <typename Func>
593 requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
594#else
595 template <typename Func>
596#endif
597 simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
598 inline simdjson_result<bool> reset() noexcept;
599 inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_position> get_current_position() noexcept;
600 inline error_code revert_position(SIMDJSON_IMPLEMENTATION::ondemand::object_position position) noexcept;
601 inline simdjson_result<bool> is_empty() noexcept;
602 inline simdjson_result<size_t> count_fields() & noexcept;
603 inline simdjson_result<std::string_view> raw_json() noexcept;
604 #if SIMDJSON_SUPPORTS_CONCEPTS
605 // TODO: move this code into object-inl.h
606
607 template<typename T>
608 simdjson_inline simdjson_result<T> get() noexcept(nothrow_gettable<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
609 if (error()) { return error(); }
610 if constexpr (std::is_same_v<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
611 return first;
612 }
613 return first.get<T>();
614 }
615 template<typename T>
616 simdjson_warn_unused simdjson_inline error_code get(T& out) noexcept(nothrow_gettable<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
617 if (error()) { return error(); }
618 if constexpr (std::is_same_v<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
619 out = first;
620 } else {
621 SIMDJSON_TRY( first.get<T>(out) );
622 }
623 return SUCCESS;
624 }
625
633 template <typename Selector, typename Func>
634 requires SIMDJSON_IMPLEMENTATION::ondemand::key_selector_type<Selector> &&
635 std::is_invocable_v<Func&, std::size_t, SIMDJSON_IMPLEMENTATION::ondemand::value>
636 simdjson_inline SIMDJSON_IMPLEMENTATION::ondemand::for_each_result for_each(Func&& on_match)
637 noexcept(std::is_nothrow_invocable_v<Func&, std::size_t, SIMDJSON_IMPLEMENTATION::ondemand::value>);
638
642 template <typename Selector, typename... Handlers>
643 requires SIMDJSON_IMPLEMENTATION::ondemand::key_selector_type<Selector> &&
644 (sizeof...(Handlers) == Selector::size()) &&
645 (SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::field_handler<Handlers> && ...)
646 simdjson_inline SIMDJSON_IMPLEMENTATION::ondemand::for_each_result for_each(Handlers&&... on_match)
647 noexcept(SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
648
652 template <constevalutil::fixed_string... Keys, typename... Handlers>
653 requires (sizeof...(Handlers) == sizeof...(Keys)) &&
654 (sizeof...(Keys) >= 1) && (sizeof...(Keys) <= 255) &&
655 (SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::field_handler<Handlers> && ...)
656 simdjson_inline SIMDJSON_IMPLEMENTATION::ondemand::for_each_result for_each(Handlers&&... on_match)
657 noexcept(SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
658
659#if SIMDJSON_STATIC_REFLECTION
660 // TODO: move this code into object-inl.h
661 template<constevalutil::fixed_string... FieldNames, typename T>
662 requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
663 simdjson_warn_unused simdjson_inline error_code extract_into(T& out) noexcept {
664 if (error()) { return error(); }
665 return first.extract_into<FieldNames...>(out);
666 }
667#endif // SIMDJSON_STATIC_REFLECTION
668#endif // SIMDJSON_SUPPORTS_CONCEPTS
669};
670
671} // namespace simdjson
672
673#endif // SIMDJSON_GENERIC_ONDEMAND_OBJECT_H
A forward-only JSON object field iterator.
Definition object.h:130
simdjson_inline object() noexcept=default
Create a new invalid object.
error_code for_each_at_path_with_wildcard(std::string_view json_path, Func &&callback) noexcept
Call the provided callback for each value matching the given JSONPath expression with wildcard suppor...
Definition object-inl.h:357
simdjson_inline object_position get_current_position() const noexcept
Get an opaque token representing the object's current scanning position.
Definition object-inl.h:422
simdjson_inline simdjson_result< value > find_field_unordered(std::string_view key) &noexcept
Look up a field by name on an object, without regard to key order.
Definition object-inl.h:27
simdjson_inline simdjson_result< std::string_view > raw_json() noexcept
Consumes the object and returns a string_view instance corresponding to the object as represented in ...
Definition object-inl.h:260
simdjson_warn_unused simdjson_inline error_code consume() noexcept
Go to the end of the object, no matter where you are right now.
Definition object-inl.h:234
simdjson_inline simdjson_result< object_iterator > begin() &noexcept
Get an iterator to the start of the object.
Definition object-inl.h:285
simdjson_inline simdjson_result< value > find_field(std::string_view key) &noexcept
Look up a field by name on an object (order-sensitive).
Definition object-inl.h:57
simdjson_result< bool > is_empty() &noexcept
This method scans the beginning of the object and checks whether the object is empty.
Definition object-inl.h:405
simdjson_result< bool > reset() &noexcept
Reset the iterator so that we are pointing back at the beginning of the object.
Definition object-inl.h:415
simdjson_result< value > at_path(std::string_view json_path) noexcept
Get the value associated with the given JSONPath expression.
Definition object-inl.h:343
simdjson_result< value > at_pointer(std::string_view json_pointer) noexcept
Get the value associated with the given JSON pointer.
Definition object-inl.h:303
simdjson_inline error_code revert_position(object_position position) noexcept
Return the object's scanning position to a snapshot previously obtained from get_current_position().
Definition object-inl.h:426
simdjson_inline simdjson_result< size_t > count_fields() &noexcept
This method scans the object and counts the number of key-value pairs.
Definition object-inl.h:393
An ephemeral JSON value returned during iteration.
Definition value.h:22
int32_t depth_t
Represents the depth of a JSON value (number of nested arrays/objects).
Definition base.h:18
The top level simdjson namespace, containing everything the library provides.
Definition base.h:8
error_code
All possible errors returned by simdjson.
Definition error.h:19
@ SUCCESS
No error.
Definition error.h:20
An opaque snapshot of an object's scanning position, obtained from object::get_current_position() and...
Definition object.h:110
simdjson_inline object_position() noexcept=default
Default-constructed so a variable can be declared and assigned later, matching e.g.
The result of a simdjson operation that could fail.
Definition error.h:281
simdjson_inline error_code error() const noexcept
The error.
Definition error-inl.h:168
simdjson_warn_unused simdjson_inline error_code get(T &value) &&noexcept
Move the value to the provided variable.
Definition error-inl.h:163