simdjson 5.0.1
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
146 simdjson_inline simdjson_result<object_iterator> begin() noexcept;
147 simdjson_inline simdjson_result<object_iterator> end() noexcept;
187 simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept;
189 simdjson_inline simdjson_result<value> find_field(std::string_view key) && noexcept;
190
227 simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept;
229 simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) && noexcept;
231 simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
233 simdjson_inline simdjson_result<value> operator[](std::string_view key) && noexcept;
234
235#if SIMDJSON_SUPPORTS_CONCEPTS
277 template <typename Selector, typename Func>
278 requires key_selector_type<Selector> &&
279 std::is_invocable_v<Func&, std::size_t, value>
280 simdjson_inline for_each_result for_each(Func&& on_match)
281 noexcept(std::is_nothrow_invocable_v<Func&, std::size_t, value>);
282
307 template <typename Selector, typename... Handlers>
308 requires key_selector_type<Selector> &&
309 (sizeof...(Handlers) == Selector::size()) &&
310 (key_selector_for_each_detail::field_handler<Handlers> && ...)
311 simdjson_inline for_each_result for_each(Handlers&&... on_match)
312 noexcept(key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
313
321 template <constevalutil::fixed_string... Keys, typename... Handlers>
322 requires (sizeof...(Handlers) == sizeof...(Keys)) &&
323 (sizeof...(Keys) >= 1) && (sizeof...(Keys) <= 255) &&
324 (key_selector_for_each_detail::field_handler<Handlers> && ...)
325 simdjson_inline for_each_result for_each(Handlers&&... on_match)
326 noexcept(key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
327#endif
328
363 inline simdjson_result<value> at_pointer(std::string_view json_pointer) noexcept;
364
376 inline simdjson_result<value> at_path(std::string_view json_path) noexcept;
377
387#if SIMDJSON_SUPPORTS_CONCEPTS
388 template <typename Func>
389 requires std::invocable<Func, value>
390#else
391 template <typename Func>
392#endif
393 inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
394
404 inline simdjson_result<bool> reset() & noexcept;
420 simdjson_inline object_position get_current_position() const noexcept;
432 simdjson_inline error_code revert_position(object_position position) noexcept;
442 inline simdjson_result<bool> is_empty() & noexcept;
460 simdjson_inline simdjson_result<size_t> count_fields() & noexcept;
466 simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
467
468#if SIMDJSON_SUPPORTS_CONCEPTS
476 template <typename T>
477 simdjson_warn_unused simdjson_inline error_code get(T &out)
478 noexcept(nothrow_gettable<T, object>) {
479 static_assert(custom_deserializable<T, object>);
480 return deserialize(*this, out);
481 }
488 template <typename T>
489 simdjson_inline simdjson_result<T> get()
490 noexcept(nothrow_gettable<T, object>)
491 {
492 static_assert(std::is_default_constructible<T>::value, "The specified type is not default constructible.");
493 T out{};
494 SIMDJSON_TRY(get<T>(out));
495 return out;
496 }
497
498#if SIMDJSON_STATIC_REFLECTION
523 template<constevalutil::fixed_string... FieldNames, typename T>
524 requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
525 simdjson_warn_unused simdjson_inline error_code extract_into(T& out) & noexcept;
526#endif // SIMDJSON_STATIC_REFLECTION
527#endif // SIMDJSON_SUPPORTS_CONCEPTS
528protected:
532 simdjson_warn_unused simdjson_inline error_code consume() noexcept;
533 static simdjson_inline simdjson_result<object> start(value_iterator &iter) noexcept;
534 static simdjson_inline simdjson_result<object> start_root(value_iterator &iter) noexcept;
535 static simdjson_inline simdjson_result<object> started(value_iterator &iter) noexcept;
536 static simdjson_inline object resume(const value_iterator &iter) noexcept;
537 simdjson_inline object(const value_iterator &iter) noexcept;
538
539 simdjson_warn_unused simdjson_inline error_code find_field_raw(const std::string_view key) noexcept;
540
541 value_iterator iter{};
542#if SIMDJSON_DEVELOPMENT_CHECKS
543 bool locked{false};
544 simdjson_inline void set_locked(bool _locked) noexcept;
545#endif
546
547 friend class value;
548 friend class document;
549 friend struct simdjson_result<object>;
550#if SIMDJSON_DEVELOPMENT_CHECKS
551 friend class object_iterator;
552 friend struct simdjson_result<object_iterator>;
553#endif
554};
555
556} // namespace ondemand
557} // namespace SIMDJSON_IMPLEMENTATION
558} // namespace simdjson
559
560namespace simdjson {
561
562template<>
563struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object> {
564public:
565 simdjson_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::object &&value) noexcept;
566 simdjson_inline simdjson_result(error_code error) noexcept;
567 simdjson_inline simdjson_result() noexcept = default;
568
571 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(std::string_view key) & noexcept;
572 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(std::string_view key) && noexcept;
573 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
574 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) && noexcept;
575 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
576 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) && noexcept;
577 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
578 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_path(std::string_view json_path) noexcept;
579#if SIMDJSON_SUPPORTS_CONCEPTS
580 template <typename Func>
581 requires std::invocable<Func, SIMDJSON_IMPLEMENTATION::ondemand::value>
582#else
583 template <typename Func>
584#endif
585 simdjson_inline error_code for_each_at_path_with_wildcard(std::string_view json_path, Func&& callback) noexcept;
586 inline simdjson_result<bool> reset() noexcept;
587 inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_position> get_current_position() noexcept;
588 inline error_code revert_position(SIMDJSON_IMPLEMENTATION::ondemand::object_position position) noexcept;
589 inline simdjson_result<bool> is_empty() noexcept;
590 inline simdjson_result<size_t> count_fields() & noexcept;
591 inline simdjson_result<std::string_view> raw_json() noexcept;
592 #if SIMDJSON_SUPPORTS_CONCEPTS
593 // TODO: move this code into object-inl.h
594
595 template<typename T>
596 simdjson_inline simdjson_result<T> get() noexcept(nothrow_gettable<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
597 if (error()) { return error(); }
598 if constexpr (std::is_same_v<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
599 return first;
600 }
601 return first.get<T>();
602 }
603 template<typename T>
604 simdjson_warn_unused simdjson_inline error_code get(T& out) noexcept(nothrow_gettable<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
605 if (error()) { return error(); }
606 if constexpr (std::is_same_v<T, SIMDJSON_IMPLEMENTATION::ondemand::object>) {
607 out = first;
608 } else {
609 SIMDJSON_TRY( first.get<T>(out) );
610 }
611 return SUCCESS;
612 }
613
621 template <typename Selector, typename Func>
622 requires SIMDJSON_IMPLEMENTATION::ondemand::key_selector_type<Selector> &&
623 std::is_invocable_v<Func&, std::size_t, SIMDJSON_IMPLEMENTATION::ondemand::value>
624 simdjson_inline SIMDJSON_IMPLEMENTATION::ondemand::for_each_result for_each(Func&& on_match)
625 noexcept(std::is_nothrow_invocable_v<Func&, std::size_t, SIMDJSON_IMPLEMENTATION::ondemand::value>);
626
630 template <typename Selector, typename... Handlers>
631 requires SIMDJSON_IMPLEMENTATION::ondemand::key_selector_type<Selector> &&
632 (sizeof...(Handlers) == Selector::size()) &&
633 (SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::field_handler<Handlers> && ...)
634 simdjson_inline SIMDJSON_IMPLEMENTATION::ondemand::for_each_result for_each(Handlers&&... on_match)
635 noexcept(SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
636
640 template <constevalutil::fixed_string... Keys, typename... Handlers>
641 requires (sizeof...(Handlers) == sizeof...(Keys)) &&
642 (sizeof...(Keys) >= 1) && (sizeof...(Keys) <= 255) &&
643 (SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::field_handler<Handlers> && ...)
644 simdjson_inline SIMDJSON_IMPLEMENTATION::ondemand::for_each_result for_each(Handlers&&... on_match)
645 noexcept(SIMDJSON_IMPLEMENTATION::ondemand::key_selector_for_each_detail::nothrow_field_handlers_v<Handlers...>);
646
647#if SIMDJSON_STATIC_REFLECTION
648 // TODO: move this code into object-inl.h
649 template<constevalutil::fixed_string... FieldNames, typename T>
650 requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
651 simdjson_warn_unused simdjson_inline error_code extract_into(T& out) noexcept {
652 if (error()) { return error(); }
653 return first.extract_into<FieldNames...>(out);
654 }
655#endif // SIMDJSON_STATIC_REFLECTION
656#endif // SIMDJSON_SUPPORTS_CONCEPTS
657};
658
659} // namespace simdjson
660
661#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:350
simdjson_inline object_position get_current_position() const noexcept
Get an opaque token representing the object's current scanning position.
Definition object-inl.h:415
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< 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:398
simdjson_result< bool > reset() &noexcept
Reset the iterator so that we are pointing back at the beginning of the object.
Definition object-inl.h:408
simdjson_result< value > at_path(std::string_view json_path) noexcept
Get the value associated with the given JSONPath expression.
Definition object-inl.h:336
simdjson_result< value > at_pointer(std::string_view json_pointer) noexcept
Get the value associated with the given JSON pointer.
Definition object-inl.h:296
simdjson_inline simdjson_result< object_iterator > begin() noexcept
Get an iterator to the start of the object.
Definition object-inl.h:285
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:419
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:386
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