1#ifndef SIMDJSON_ELEMENT_INL_H
2#define SIMDJSON_ELEMENT_INL_H
4#include "simdjson/dom/base.h"
5#include "simdjson/dom/element.h"
6#include "simdjson/dom/document.h"
7#include "simdjson/dom/object.h"
8#include "simdjson/internal/tape_type.h"
10#include "simdjson/dom/object-inl.h"
11#include "simdjson/error-inl.h"
12#include "simdjson/jsonpathutil.h"
22simdjson_inline simdjson_result<dom::element>::simdjson_result() noexcept
23 : internal::simdjson_result_base<dom::element>() {}
24simdjson_inline simdjson_result<dom::element>::simdjson_result(dom::element &&value) noexcept
25 : internal::simdjson_result_base<dom::element>(std::forward<dom::element>(value)) {}
26simdjson_inline simdjson_result<dom::element>::simdjson_result(
error_code error) noexcept
27 : internal::simdjson_result_base<dom::element>(error) {}
28inline simdjson_result<dom::element_type> simdjson_result<dom::element>::type() const noexcept {
29 if (error()) {
return error(); }
34simdjson_inline
bool simdjson_result<dom::element>::is() const noexcept {
35 return !error() && first.is<T>();
39 if (error()) {
return error(); }
40 return first.get<T>();
44 if (error()) {
return error(); }
45 return first.get<T>(value);
48simdjson_inline simdjson_result<dom::array> simdjson_result<dom::element>::get_array() const noexcept {
49 if (error()) {
return error(); }
50 return first.get_array();
52simdjson_inline simdjson_result<dom::object> simdjson_result<dom::element>::get_object() const noexcept {
53 if (error()) {
return error(); }
54 return first.get_object();
56simdjson_inline simdjson_result<const char *> simdjson_result<dom::element>::get_c_str() const noexcept {
57 if (error()) {
return error(); }
58 return first.get_c_str();
60simdjson_inline simdjson_result<size_t> simdjson_result<dom::element>::get_string_length() const noexcept {
61 if (error()) {
return error(); }
62 return first.get_string_length();
64simdjson_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_string() const noexcept {
65 if (error()) {
return error(); }
66 return first.get_string();
68simdjson_inline simdjson_result<int64_t> simdjson_result<dom::element>::get_int64() const noexcept {
69 if (error()) {
return error(); }
70 return first.get_int64();
72simdjson_inline simdjson_result<uint64_t> simdjson_result<dom::element>::get_uint64() const noexcept {
73 if (error()) {
return error(); }
74 return first.get_uint64();
76simdjson_inline simdjson_result<double> simdjson_result<dom::element>::get_double() const noexcept {
77 if (error()) {
return error(); }
78 return first.get_double();
80simdjson_inline simdjson_result<bool> simdjson_result<dom::element>::get_bool() const noexcept {
81 if (error()) {
return error(); }
82 return first.get_bool();
84simdjson_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_bigint() const noexcept {
85 if (error()) {
return error(); }
86 return first.get_bigint();
89simdjson_inline
bool simdjson_result<dom::element>::is_array() const noexcept {
90 return !error() && first.is_array();
92simdjson_inline
bool simdjson_result<dom::element>::is_object() const noexcept {
93 return !error() && first.is_object();
95simdjson_inline
bool simdjson_result<dom::element>::is_string() const noexcept {
96 return !error() && first.is_string();
98simdjson_inline
bool simdjson_result<dom::element>::is_int64() const noexcept {
99 return !error() && first.is_int64();
101simdjson_inline
bool simdjson_result<dom::element>::is_uint64() const noexcept {
102 return !error() && first.is_uint64();
104simdjson_inline
bool simdjson_result<dom::element>::is_double() const noexcept {
105 return !error() && first.is_double();
107simdjson_inline
bool simdjson_result<dom::element>::is_number() const noexcept {
108 return !error() && first.is_number();
110simdjson_inline
bool simdjson_result<dom::element>::is_bool() const noexcept {
111 return !error() && first.is_bool();
114simdjson_inline
bool simdjson_result<dom::element>::is_null() const noexcept {
115 return !error() && first.is_null();
117simdjson_inline
bool simdjson_result<dom::element>::is_bigint() const noexcept {
118 return !error() && first.is_bigint();
121simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key)
const noexcept {
122 if (error()) {
return error(); }
125simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](
const char *key)
const noexcept {
126 if (error()) {
return error(); }
129simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_pointer(
const std::string_view json_pointer)
const noexcept {
130 if (error()) {
return error(); }
131 return first.at_pointer(json_pointer);
133simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_path(
const std::string_view json_path)
const noexcept {
136 return at_pointer(json_pointer);
139simdjson_inline simdjson_result<std::vector<dom::element>> simdjson_result<dom::element>::at_path_with_wildcard(
const std::string_view json_path)
const noexcept {
140 if (error()) {
return error(); }
141 return first.at_path_with_wildcard(json_path);
144#ifndef SIMDJSON_DISABLE_DEPRECATED_API
145[[deprecated(
"For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
146simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(
const std::string_view json_pointer)
const noexcept {
147SIMDJSON_PUSH_DISABLE_WARNINGS
148SIMDJSON_DISABLE_DEPRECATED_WARNING
149 if (error()) {
return error(); }
150 return first.at(json_pointer);
151SIMDJSON_POP_DISABLE_WARNINGS
154simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(
size_t index)
const noexcept {
155 if (error()) {
return error(); }
156 return first.at(index);
158simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key(std::string_view key)
const noexcept {
159 if (error()) {
return error(); }
160 return first.at_key(key);
162simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key_case_insensitive(std::string_view key)
const noexcept {
163 if (error()) {
return error(); }
164 return first.at_key_case_insensitive(key);
167#if SIMDJSON_EXCEPTIONS
169simdjson_inline simdjson_result<dom::element>::operator bool() const noexcept(false) {
172simdjson_inline simdjson_result<dom::element>::operator
const char *()
const noexcept(
false) {
173 return get<const char *>();
175simdjson_inline simdjson_result<dom::element>::operator std::string_view() const noexcept(false) {
176 return get<std::string_view>();
178simdjson_inline simdjson_result<dom::element>::operator uint64_t() const noexcept(false) {
179 return get<uint64_t>();
181simdjson_inline simdjson_result<dom::element>::operator int64_t() const noexcept(false) {
182 return get<int64_t>();
184simdjson_inline simdjson_result<dom::element>::operator double() const noexcept(false) {
185 return get<double>();
187simdjson_inline simdjson_result<dom::element>::operator dom::array() const noexcept(false) {
188 return get<dom::array>();
190simdjson_inline simdjson_result<dom::element>::operator dom::object() const noexcept(false) {
191 return get<dom::object>();
194simdjson_inline dom::array::iterator simdjson_result<dom::element>::begin() const noexcept(false) {
195 if (error()) {
throw simdjson_error(error()); }
196 return first.begin();
198simdjson_inline dom::array::iterator simdjson_result<dom::element>::end() const noexcept(false) {
199 if (error()) {
throw simdjson_error(error()); }
211simdjson_inline
element::element(
const internal::tape_ref &_tape) noexcept : tape{_tape} { }
214 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
215 auto tape_type = tape.tape_ref_type();
220 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
223 }
else if(tape.is_false()) {
229 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
230 switch (tape.tape_ref_type()) {
231 case internal::tape_type::BIGINT:
232 return tape.get_string_view();
238 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
239 switch (tape.tape_ref_type()) {
240 case internal::tape_type::STRING: {
241 return tape.get_c_str();
248 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
249 switch (tape.tape_ref_type()) {
250 case internal::tape_type::STRING: {
251 return tape.get_string_length();
258 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
259 switch (tape.tape_ref_type()) {
260 case internal::tape_type::STRING:
261 return tape.get_string_view();
267 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
268 if(simdjson_unlikely(!tape.is_uint64())) {
269 if(tape.is_int64()) {
270 int64_t result = tape.next_tape_value<int64_t>();
274 return uint64_t(result);
278 return tape.next_tape_value<int64_t>();
281 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
282 if(simdjson_unlikely(!tape.is_int64())) {
283 if(tape.is_uint64()) {
284 uint64_t result = tape.next_tape_value<uint64_t>();
286 if (result > uint64_t((std::numeric_limits<int64_t>::max)())) {
289 return static_cast<int64_t
>(result);
293 return tape.next_tape_value<int64_t>();
296 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
306 if(simdjson_unlikely(!tape.is_double())) {
307 if(tape.is_uint64()) {
308 return double(tape.next_tape_value<uint64_t>());
309 }
else if(tape.is_int64()) {
310 return double(tape.next_tape_value<int64_t>());
315 return tape.next_tape_value<
double>();
318 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
319 switch (tape.tape_ref_type()) {
320 case internal::tape_type::START_ARRAY:
327 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
328 switch (tape.tape_ref_type()) {
329 case internal::tape_type::START_OBJECT:
338 return get<T>().get(value);
342simdjson_warn_unused simdjson_inline
error_code element::get<element>(
element &value)
const noexcept {
348 error = get<T>(value);
353 auto result = get<T>();
354 return !result.error();
359template<>
inline simdjson_result<const char *> element::get<const char *>() const noexcept {
return get_c_str(); }
360template<>
inline simdjson_result<std::string_view> element::get<std::string_view>() const noexcept {
return get_string(); }
361template<>
inline simdjson_result<int64_t> element::get<int64_t>() const noexcept {
return get_int64(); }
362template<>
inline simdjson_result<uint64_t> element::get<uint64_t>() const noexcept {
return get_uint64(); }
363template<>
inline simdjson_result<double> element::get<double>() const noexcept {
return get_double(); }
364template<>
inline simdjson_result<bool> element::get<bool>() const noexcept {
return get_bool(); }
376 return tape.is_null_on_tape();
380 return tape.tape_ref_type() == internal::tape_type::BIGINT;
383#if SIMDJSON_EXCEPTIONS
385inline element::operator bool() const noexcept(false) {
return get<bool>(); }
386inline element::operator
const char*()
const noexcept(
false) {
return get<const char *>(); }
387inline element::operator std::string_view() const noexcept(false) {
return get<std::string_view>(); }
388inline element::operator uint64_t() const noexcept(false) {
return get<uint64_t>(); }
389inline element::operator int64_t() const noexcept(false) {
return get<int64_t>(); }
390inline element::operator double() const noexcept(false) {
return get<double>(); }
391inline element::operator
array() const noexcept(false) {
return get<array>(); }
392inline element::operator
object() const noexcept(false) {
return get<object>(); }
395 return get<array>().begin();
398 return get<array>().end();
410inline bool is_pointer_well_formed(std::string_view json_pointer)
noexcept {
411 if (simdjson_unlikely(json_pointer[0] !=
'/')) {
414 size_t escape = json_pointer.find(
'~');
415 if (escape == std::string_view::npos) {
418 if (escape == json_pointer.size() - 1) {
421 if (json_pointer[escape + 1] !=
'0' && json_pointer[escape + 1] !=
'1') {
428 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
429 switch (tape.tape_ref_type()) {
430 case internal::tape_type::START_OBJECT:
432 case internal::tape_type::START_ARRAY:
435 if (!json_pointer.empty()) {
436 if (is_pointer_well_formed(json_pointer)) {
449 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
451 switch (tape.tape_ref_type()) {
452 case internal::tape_type::START_OBJECT:
454 case internal::tape_type::START_ARRAY:
457 return std::vector<element>{};
464 return at_pointer(json_pointer);
466#ifndef SIMDJSON_DISABLE_DEPRECATED_API
467[[deprecated(
"For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
470 auto std_pointer = (json_pointer.empty() ?
"" :
"/") + std::string(json_pointer.begin(), json_pointer.end());
471 return at_pointer(std_pointer);
476 return get<array>().at(index);
479 return get<object>().at_key(key);
482 return get<object>().at_key_case_insensitive(key);
485 return tape.json_index < other.tape.json_index;
488 return tape.json_index == other.tape.json_index;
491inline bool element::dump_raw_tape(std::ostream &out)
const noexcept {
492 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
493 return tape.doc->dump_raw_tape(out);
497inline std::ostream& operator<<(std::ostream& out,
element_type type) {
500 return out <<
"array";
502 return out <<
"object";
504 return out <<
"int64_t";
506 return out <<
"uint64_t";
508 return out <<
"double";
510 return out <<
"string";
512 return out <<
"bool";
514 return out <<
"null";
516 return out <<
"bigint";
518 return out <<
"unexpected content!!!";
simdjson_result< std::vector< element > > at_path_with_wildcard(std::string_view json_path) const noexcept
Adds support for JSONPath expression with wildcards '*'.
simdjson_result< element > at_pointer(std::string_view json_pointer) const noexcept
Get the value associated with the given JSON pointer.
bool is_object() const noexcept
Whether this element is a json object.
bool is_double() const noexcept
Whether this element is a json number that fits in a double.
simdjson_inline element_type type() const noexcept
The type of this element.
bool is_number() const noexcept
Whether this element is a json number.
simdjson_result< T > get() const noexcept
Get the value as the provided type (T).
simdjson_result< const char * > get_c_str() const noexcept
Cast this element to a null-terminated C string.
bool operator<(const element &other) const noexcept
operator< defines a total order for element allowing to use them in ordered C++ STL containers
simdjson_result< element > at_pointer(const std::string_view json_pointer) const noexcept
Get the value associated with the given JSON pointer.
simdjson_result< double > get_double() const noexcept
Cast this element to a double floating-point.
simdjson_inline bool is() const noexcept
Tell whether the value can be cast to provided type (T).
simdjson_result< element > at_key_case_insensitive(std::string_view key) const noexcept
Get the value associated with the given key in a case-insensitive manner.
void tie(T &value, error_code &error) &&noexcept
Get the value as the provided type (T), setting error if it's not the given type.
simdjson_result< bool > get_bool() const noexcept
Cast this element to a bool.
bool is_string() const noexcept
Whether this element is a json string.
simdjson_result< element > at_key(std::string_view key) const noexcept
Get the value associated with the given key.
simdjson_result< std::string_view > get_bigint() const noexcept
Read this element as a big integer (raw digit string).
dom::array::iterator end() const noexcept(false)
Iterate over each element in this array.
simdjson_result< array > get_array() const noexcept
Cast this element to an array.
simdjson_result< size_t > get_string_length() const noexcept
Gives the length in bytes of the string.
simdjson_inline element() noexcept
Create a new, invalid element.
simdjson_result< uint64_t > get_uint64() const noexcept
Cast this element to an unsigned integer.
dom::array::iterator begin() const noexcept(false)
Iterate over each element in this array.
simdjson_result< element > at(const std::string_view json_pointer) const noexcept
Version 0.4 of simdjson used an incorrect interpretation of the JSON Pointer standard and allowed the...
simdjson_result< int64_t > get_int64() const noexcept
Cast this element to a signed integer.
bool is_bigint() const noexcept
Whether this element is a big integer (number exceeding 64-bit range).
simdjson_result< object > get_object() const noexcept
Cast this element to an object.
bool is_uint64() const noexcept
Whether this element is a json number that fits in an unsigned 64-bit integer.
simdjson_result< element > operator[](std::string_view key) const noexcept
Get the value associated with the given key.
bool is_int64() const noexcept
Whether this element is a json number that fits in a signed 64-bit integer.
bool is_null() const noexcept
Whether this element is a json null.
simdjson_result< element > at_path(std::string_view json_path) const noexcept
Get the value associated with the given JSONPath expression.
simdjson_result< std::string_view > get_string() const noexcept
Cast this element to a string.
bool is_array() const noexcept
Whether this element is a json array.
bool operator==(const element &other) const noexcept
operator== allows to verify if two element values reference the same JSON item
bool is_bool() const noexcept
Whether this element is a json true or false.
simdjson_result< std::vector< element > > at_path_with_wildcard(std::string_view json_path) const noexcept
Adds support for JSONPath expression with wildcards '*'.
simdjson_result< element > at_pointer(std::string_view json_pointer) const noexcept
Get the value associated with the given JSON pointer.
element_type
The actual concrete type of a JSON element This is the type it is most easily cast to with get<>.
@ UINT64
uint64_t: any integer that fits in uint64_t but not int64_t
@ BIGINT
std::string_view: big integer stored as raw digit string
@ DOUBLE
double: Any number with a "." or "e" that fits in double.
The top level simdjson namespace, containing everything the library provides.
error_code
All possible errors returned by simdjson.
@ INCORRECT_TYPE
JSON element has a different type than user expected.
@ NO_SUCH_FIELD
JSON field not found in object.
@ NUMBER_OUT_OF_RANGE
JSON number does not fit in 64 bits.
@ INVALID_JSON_POINTER
Invalid JSON pointer syntax.
std::string json_path_to_pointer_conversion(std::string_view json_path)
Converts JSONPath to JSON Pointer.
The result of a simdjson operation that could fail.
simdjson_warn_unused simdjson_inline error_code get(T &value) &&noexcept
Move the value to the provided variable.