| 1 | #ifndef SIMDJSON_INLINE_ELEMENT_H | 
|---|
| 2 | #define SIMDJSON_INLINE_ELEMENT_H | 
|---|
| 3 |  | 
|---|
| 4 | #include "simdjson/dom/array.h" | 
|---|
| 5 | #include "simdjson/dom/element.h" | 
|---|
| 6 | #include "simdjson/dom/object.h" | 
|---|
| 7 | #include <cstring> | 
|---|
| 8 | #include <utility> | 
|---|
| 9 |  | 
|---|
| 10 | namespace simdjson { | 
|---|
| 11 |  | 
|---|
| 12 | // | 
|---|
| 13 | // simdjson_result<dom::element> inline implementation | 
|---|
| 14 | // | 
|---|
| 15 | simdjson_inline simdjson_result<dom::element>::simdjson_result() noexcept | 
|---|
| 16 | : internal::simdjson_result_base<dom::element>() {} | 
|---|
| 17 | simdjson_inline simdjson_result<dom::element>::simdjson_result(dom::element &&value) noexcept | 
|---|
| 18 | : internal::simdjson_result_base<dom::element>(std::forward<dom::element>(t&: value)) {} | 
|---|
| 19 | simdjson_inline simdjson_result<dom::element>::simdjson_result(error_code error) noexcept | 
|---|
| 20 | : internal::simdjson_result_base<dom::element>(error) {} | 
|---|
| 21 | inline simdjson_result<dom::element_type> simdjson_result<dom::element>::type() const noexcept { | 
|---|
| 22 | if (error()) { return error(); } | 
|---|
| 23 | return first.type(); | 
|---|
| 24 | } | 
|---|
| 25 |  | 
|---|
| 26 | template<typename T> | 
|---|
| 27 | simdjson_inline bool simdjson_result<dom::element>::is() const noexcept { | 
|---|
| 28 | return !error() && first.is<T>(); | 
|---|
| 29 | } | 
|---|
| 30 | template<typename T> | 
|---|
| 31 | simdjson_inline simdjson_result<T> simdjson_result<dom::element>::get() const noexcept { | 
|---|
| 32 | if (error()) { return error(); } | 
|---|
| 33 | return first.get<T>(); | 
|---|
| 34 | } | 
|---|
| 35 | template<typename T> | 
|---|
| 36 | simdjson_warn_unused simdjson_inline error_code simdjson_result<dom::element>::get(T &value) const noexcept { | 
|---|
| 37 | if (error()) { return error(); } | 
|---|
| 38 | return first.get<T>(value); | 
|---|
| 39 | } | 
|---|
| 40 |  | 
|---|
| 41 | simdjson_inline simdjson_result<dom::array> simdjson_result<dom::element>::get_array() const noexcept { | 
|---|
| 42 | if (error()) { return error(); } | 
|---|
| 43 | return first.get_array(); | 
|---|
| 44 | } | 
|---|
| 45 | simdjson_inline simdjson_result<dom::object> simdjson_result<dom::element>::get_object() const noexcept { | 
|---|
| 46 | if (error()) { return error(); } | 
|---|
| 47 | return first.get_object(); | 
|---|
| 48 | } | 
|---|
| 49 | simdjson_inline simdjson_result<const char *> simdjson_result<dom::element>::get_c_str() const noexcept { | 
|---|
| 50 | if (error()) { return error(); } | 
|---|
| 51 | return first.get_c_str(); | 
|---|
| 52 | } | 
|---|
| 53 | simdjson_inline simdjson_result<size_t> simdjson_result<dom::element>::get_string_length() const noexcept { | 
|---|
| 54 | if (error()) { return error(); } | 
|---|
| 55 | return first.get_string_length(); | 
|---|
| 56 | } | 
|---|
| 57 | simdjson_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_string() const noexcept { | 
|---|
| 58 | if (error()) { return error(); } | 
|---|
| 59 | return first.get_string(); | 
|---|
| 60 | } | 
|---|
| 61 | simdjson_inline simdjson_result<int64_t> simdjson_result<dom::element>::get_int64() const noexcept { | 
|---|
| 62 | if (error()) { return error(); } | 
|---|
| 63 | return first.get_int64(); | 
|---|
| 64 | } | 
|---|
| 65 | simdjson_inline simdjson_result<uint64_t> simdjson_result<dom::element>::get_uint64() const noexcept { | 
|---|
| 66 | if (error()) { return error(); } | 
|---|
| 67 | return first.get_uint64(); | 
|---|
| 68 | } | 
|---|
| 69 | simdjson_inline simdjson_result<double> simdjson_result<dom::element>::get_double() const noexcept { | 
|---|
| 70 | if (error()) { return error(); } | 
|---|
| 71 | return first.get_double(); | 
|---|
| 72 | } | 
|---|
| 73 | simdjson_inline simdjson_result<bool> simdjson_result<dom::element>::get_bool() const noexcept { | 
|---|
| 74 | if (error()) { return error(); } | 
|---|
| 75 | return first.get_bool(); | 
|---|
| 76 | } | 
|---|
| 77 |  | 
|---|
| 78 | simdjson_inline bool simdjson_result<dom::element>::is_array() const noexcept { | 
|---|
| 79 | return !error() && first.is_array(); | 
|---|
| 80 | } | 
|---|
| 81 | simdjson_inline bool simdjson_result<dom::element>::is_object() const noexcept { | 
|---|
| 82 | return !error() && first.is_object(); | 
|---|
| 83 | } | 
|---|
| 84 | simdjson_inline bool simdjson_result<dom::element>::is_string() const noexcept { | 
|---|
| 85 | return !error() && first.is_string(); | 
|---|
| 86 | } | 
|---|
| 87 | simdjson_inline bool simdjson_result<dom::element>::is_int64() const noexcept { | 
|---|
| 88 | return !error() && first.is_int64(); | 
|---|
| 89 | } | 
|---|
| 90 | simdjson_inline bool simdjson_result<dom::element>::is_uint64() const noexcept { | 
|---|
| 91 | return !error() && first.is_uint64(); | 
|---|
| 92 | } | 
|---|
| 93 | simdjson_inline bool simdjson_result<dom::element>::is_double() const noexcept { | 
|---|
| 94 | return !error() && first.is_double(); | 
|---|
| 95 | } | 
|---|
| 96 | simdjson_inline bool simdjson_result<dom::element>::is_number() const noexcept { | 
|---|
| 97 | return !error() && first.is_number(); | 
|---|
| 98 | } | 
|---|
| 99 | simdjson_inline bool simdjson_result<dom::element>::is_bool() const noexcept { | 
|---|
| 100 | return !error() && first.is_bool(); | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|
| 103 | simdjson_inline bool simdjson_result<dom::element>::is_null() const noexcept { | 
|---|
| 104 | return !error() && first.is_null(); | 
|---|
| 105 | } | 
|---|
| 106 |  | 
|---|
| 107 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key) const noexcept { | 
|---|
| 108 | if (error()) { return error(); } | 
|---|
| 109 | return first[key]; | 
|---|
| 110 | } | 
|---|
| 111 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](const char *key) const noexcept { | 
|---|
| 112 | if (error()) { return error(); } | 
|---|
| 113 | return first[key]; | 
|---|
| 114 | } | 
|---|
| 115 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_pointer(const std::string_view json_pointer) const noexcept { | 
|---|
| 116 | if (error()) { return error(); } | 
|---|
| 117 | return first.at_pointer(json_pointer); | 
|---|
| 118 | } | 
|---|
| 119 | #ifndef SIMDJSON_DISABLE_DEPRECATED_API | 
|---|
| 120 | [[deprecated( "For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]] | 
|---|
| 121 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(const std::string_view json_pointer) const noexcept { | 
|---|
| 122 | SIMDJSON_PUSH_DISABLE_WARNINGS | 
|---|
| 123 | SIMDJSON_DISABLE_DEPRECATED_WARNING | 
|---|
| 124 | if (error()) { return error(); } | 
|---|
| 125 | return first.at(json_pointer); | 
|---|
| 126 | SIMDJSON_POP_DISABLE_WARNINGS | 
|---|
| 127 | } | 
|---|
| 128 | #endif // SIMDJSON_DISABLE_DEPRECATED_API | 
|---|
| 129 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(size_t index) const noexcept { | 
|---|
| 130 | if (error()) { return error(); } | 
|---|
| 131 | return first.at(index); | 
|---|
| 132 | } | 
|---|
| 133 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key(std::string_view key) const noexcept { | 
|---|
| 134 | if (error()) { return error(); } | 
|---|
| 135 | return first.at_key(key); | 
|---|
| 136 | } | 
|---|
| 137 | simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key_case_insensitive(std::string_view key) const noexcept { | 
|---|
| 138 | if (error()) { return error(); } | 
|---|
| 139 | return first.at_key_case_insensitive(key); | 
|---|
| 140 | } | 
|---|
| 141 |  | 
|---|
| 142 | #if SIMDJSON_EXCEPTIONS | 
|---|
| 143 |  | 
|---|
| 144 | simdjson_inline simdjson_result<dom::element>::operator bool() const noexcept(false) { | 
|---|
| 145 | return get<bool>(); | 
|---|
| 146 | } | 
|---|
| 147 | simdjson_inline simdjson_result<dom::element>::operator const char *() const noexcept(false) { | 
|---|
| 148 | return get<const char *>(); | 
|---|
| 149 | } | 
|---|
| 150 | simdjson_inline simdjson_result<dom::element>::operator std::string_view() const noexcept(false) { | 
|---|
| 151 | return get<std::string_view>(); | 
|---|
| 152 | } | 
|---|
| 153 | simdjson_inline simdjson_result<dom::element>::operator uint64_t() const noexcept(false) { | 
|---|
| 154 | return get<uint64_t>(); | 
|---|
| 155 | } | 
|---|
| 156 | simdjson_inline simdjson_result<dom::element>::operator int64_t() const noexcept(false) { | 
|---|
| 157 | return get<int64_t>(); | 
|---|
| 158 | } | 
|---|
| 159 | simdjson_inline simdjson_result<dom::element>::operator double() const noexcept(false) { | 
|---|
| 160 | return get<double>(); | 
|---|
| 161 | } | 
|---|
| 162 | simdjson_inline simdjson_result<dom::element>::operator dom::array() const noexcept(false) { | 
|---|
| 163 | return get<dom::array>(); | 
|---|
| 164 | } | 
|---|
| 165 | simdjson_inline simdjson_result<dom::element>::operator dom::object() const noexcept(false) { | 
|---|
| 166 | return get<dom::object>(); | 
|---|
| 167 | } | 
|---|
| 168 |  | 
|---|
| 169 | simdjson_inline dom::array::iterator simdjson_result<dom::element>::begin() const noexcept(false) { | 
|---|
| 170 | if (error()) { throw simdjson_error(error()); } | 
|---|
| 171 | return first.begin(); | 
|---|
| 172 | } | 
|---|
| 173 | simdjson_inline dom::array::iterator simdjson_result<dom::element>::end() const noexcept(false) { | 
|---|
| 174 | if (error()) { throw simdjson_error(error()); } | 
|---|
| 175 | return first.end(); | 
|---|
| 176 | } | 
|---|
| 177 |  | 
|---|
| 178 | #endif // SIMDJSON_EXCEPTIONS | 
|---|
| 179 |  | 
|---|
| 180 | namespace dom { | 
|---|
| 181 |  | 
|---|
| 182 | // | 
|---|
| 183 | // element inline implementation | 
|---|
| 184 | // | 
|---|
| 185 | simdjson_inline element::element() noexcept : tape{} {} | 
|---|
| 186 | simdjson_inline element::element(const internal::tape_ref &_tape) noexcept : tape{_tape} { } | 
|---|
| 187 |  | 
|---|
| 188 | inline element_type element::type() const noexcept { | 
|---|
| 189 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 190 | auto tape_type = tape.tape_ref_type(); | 
|---|
| 191 | return tape_type == internal::tape_type::FALSE_VALUE ? element_type::BOOL : static_cast<element_type>(tape_type); | 
|---|
| 192 | } | 
|---|
| 193 |  | 
|---|
| 194 | inline simdjson_result<bool> element::get_bool() const noexcept { | 
|---|
| 195 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 196 | if(tape.is_true()) { | 
|---|
| 197 | return true; | 
|---|
| 198 | } else if(tape.is_false()) { | 
|---|
| 199 | return false; | 
|---|
| 200 | } | 
|---|
| 201 | return INCORRECT_TYPE; | 
|---|
| 202 | } | 
|---|
| 203 | inline simdjson_result<const char *> element::get_c_str() const noexcept { | 
|---|
| 204 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 205 | switch (tape.tape_ref_type()) { | 
|---|
| 206 | case internal::tape_type::STRING: { | 
|---|
| 207 | return tape.get_c_str(); | 
|---|
| 208 | } | 
|---|
| 209 | default: | 
|---|
| 210 | return INCORRECT_TYPE; | 
|---|
| 211 | } | 
|---|
| 212 | } | 
|---|
| 213 | inline simdjson_result<size_t> element::get_string_length() const noexcept { | 
|---|
| 214 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 215 | switch (tape.tape_ref_type()) { | 
|---|
| 216 | case internal::tape_type::STRING: { | 
|---|
| 217 | return tape.get_string_length(); | 
|---|
| 218 | } | 
|---|
| 219 | default: | 
|---|
| 220 | return INCORRECT_TYPE; | 
|---|
| 221 | } | 
|---|
| 222 | } | 
|---|
| 223 | inline simdjson_result<std::string_view> element::get_string() const noexcept { | 
|---|
| 224 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 225 | switch (tape.tape_ref_type()) { | 
|---|
| 226 | case internal::tape_type::STRING: | 
|---|
| 227 | return tape.get_string_view(); | 
|---|
| 228 | default: | 
|---|
| 229 | return INCORRECT_TYPE; | 
|---|
| 230 | } | 
|---|
| 231 | } | 
|---|
| 232 | inline simdjson_result<uint64_t> element::get_uint64() const noexcept { | 
|---|
| 233 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 234 | if(simdjson_unlikely(!tape.is_uint64())) { // branch rarely taken | 
|---|
| 235 | if(tape.is_int64()) { | 
|---|
| 236 | int64_t result = tape.next_tape_value<int64_t>(); | 
|---|
| 237 | if (result < 0) { | 
|---|
| 238 | return NUMBER_OUT_OF_RANGE; | 
|---|
| 239 | } | 
|---|
| 240 | return uint64_t(result); | 
|---|
| 241 | } | 
|---|
| 242 | return INCORRECT_TYPE; | 
|---|
| 243 | } | 
|---|
| 244 | return tape.next_tape_value<int64_t>(); | 
|---|
| 245 | } | 
|---|
| 246 | inline simdjson_result<int64_t> element::get_int64() const noexcept { | 
|---|
| 247 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 248 | if(simdjson_unlikely(!tape.is_int64())) { // branch rarely taken | 
|---|
| 249 | if(tape.is_uint64()) { | 
|---|
| 250 | uint64_t result = tape.next_tape_value<uint64_t>(); | 
|---|
| 251 | // Wrapping max in parens to handle Windows issue: https://stackoverflow.com/questions/11544073/how-do-i-deal-with-the-max-macro-in-windows-h-colliding-with-max-in-std | 
|---|
| 252 | if (result > uint64_t((std::numeric_limits<int64_t>::max)())) { | 
|---|
| 253 | return NUMBER_OUT_OF_RANGE; | 
|---|
| 254 | } | 
|---|
| 255 | return static_cast<int64_t>(result); | 
|---|
| 256 | } | 
|---|
| 257 | return INCORRECT_TYPE; | 
|---|
| 258 | } | 
|---|
| 259 | return tape.next_tape_value<int64_t>(); | 
|---|
| 260 | } | 
|---|
| 261 | inline simdjson_result<double> element::get_double() const noexcept { | 
|---|
| 262 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 263 | // Performance considerations: | 
|---|
| 264 | // 1. Querying tape_ref_type() implies doing a shift, it is fast to just do a straight | 
|---|
| 265 | //   comparison. | 
|---|
| 266 | // 2. Using a switch-case relies on the compiler guessing what kind of code generation | 
|---|
| 267 | //    we want... But the compiler cannot know that we expect the type to be "double" | 
|---|
| 268 | //    most of the time. | 
|---|
| 269 | // We can expect get<double> to refer to a double type almost all the time. | 
|---|
| 270 | // It is important to craft the code accordingly so that the compiler can use this | 
|---|
| 271 | // information. (This could also be solved with profile-guided optimization.) | 
|---|
| 272 | if(simdjson_unlikely(!tape.is_double())) { // branch rarely taken | 
|---|
| 273 | if(tape.is_uint64()) { | 
|---|
| 274 | return double(tape.next_tape_value<uint64_t>()); | 
|---|
| 275 | } else if(tape.is_int64()) { | 
|---|
| 276 | return double(tape.next_tape_value<int64_t>()); | 
|---|
| 277 | } | 
|---|
| 278 | return INCORRECT_TYPE; | 
|---|
| 279 | } | 
|---|
| 280 | // this is common: | 
|---|
| 281 | return tape.next_tape_value<double>(); | 
|---|
| 282 | } | 
|---|
| 283 | inline simdjson_result<array> element::get_array() const noexcept { | 
|---|
| 284 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 285 | switch (tape.tape_ref_type()) { | 
|---|
| 286 | case internal::tape_type::START_ARRAY: | 
|---|
| 287 | return array(tape); | 
|---|
| 288 | default: | 
|---|
| 289 | return INCORRECT_TYPE; | 
|---|
| 290 | } | 
|---|
| 291 | } | 
|---|
| 292 | inline simdjson_result<object> element::get_object() const noexcept { | 
|---|
| 293 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 294 | switch (tape.tape_ref_type()) { | 
|---|
| 295 | case internal::tape_type::START_OBJECT: | 
|---|
| 296 | return object(tape); | 
|---|
| 297 | default: | 
|---|
| 298 | return INCORRECT_TYPE; | 
|---|
| 299 | } | 
|---|
| 300 | } | 
|---|
| 301 |  | 
|---|
| 302 | template<typename T> | 
|---|
| 303 | simdjson_warn_unused simdjson_inline error_code element::get(T &value) const noexcept { | 
|---|
| 304 | return get<T>().get(value); | 
|---|
| 305 | } | 
|---|
| 306 | // An element-specific version prevents recursion with simdjson_result::get<element>(value) | 
|---|
| 307 | template<> | 
|---|
| 308 | simdjson_warn_unused simdjson_inline error_code element::get<element>(element &value) const noexcept { | 
|---|
| 309 | value = element(tape); | 
|---|
| 310 | return SUCCESS; | 
|---|
| 311 | } | 
|---|
| 312 | template<typename T> | 
|---|
| 313 | inline void element::tie(T &value, error_code &error) && noexcept { | 
|---|
| 314 | error = get<T>(value); | 
|---|
| 315 | } | 
|---|
| 316 |  | 
|---|
| 317 | template<typename T> | 
|---|
| 318 | simdjson_inline bool element::is() const noexcept { | 
|---|
| 319 | auto result = get<T>(); | 
|---|
| 320 | return !result.error(); | 
|---|
| 321 | } | 
|---|
| 322 |  | 
|---|
| 323 | template<> inline simdjson_result<array> element::get<array>() const noexcept { return get_array(); } | 
|---|
| 324 | template<> inline simdjson_result<object> element::get<object>() const noexcept { return get_object(); } | 
|---|
| 325 | template<> inline simdjson_result<const char *> element::get<const char *>() const noexcept { return get_c_str(); } | 
|---|
| 326 | template<> inline simdjson_result<std::string_view> element::get<std::string_view>() const noexcept { return get_string(); } | 
|---|
| 327 | template<> inline simdjson_result<int64_t> element::get<int64_t>() const noexcept { return get_int64(); } | 
|---|
| 328 | template<> inline simdjson_result<uint64_t> element::get<uint64_t>() const noexcept { return get_uint64(); } | 
|---|
| 329 | template<> inline simdjson_result<double> element::get<double>() const noexcept { return get_double(); } | 
|---|
| 330 | template<> inline simdjson_result<bool> element::get<bool>() const noexcept { return get_bool(); } | 
|---|
| 331 |  | 
|---|
| 332 | inline bool element::is_array() const noexcept { return is<array>(); } | 
|---|
| 333 | inline bool element::is_object() const noexcept { return is<object>(); } | 
|---|
| 334 | inline bool element::is_string() const noexcept { return is<std::string_view>(); } | 
|---|
| 335 | inline bool element::is_int64() const noexcept { return is<int64_t>(); } | 
|---|
| 336 | inline bool element::is_uint64() const noexcept { return is<uint64_t>(); } | 
|---|
| 337 | inline bool element::is_double() const noexcept { return is<double>(); } | 
|---|
| 338 | inline bool element::is_bool() const noexcept { return is<bool>(); } | 
|---|
| 339 | inline bool element::is_number() const noexcept { return is_int64() || is_uint64() || is_double(); } | 
|---|
| 340 |  | 
|---|
| 341 | inline bool element::is_null() const noexcept { | 
|---|
| 342 | return tape.is_null_on_tape(); | 
|---|
| 343 | } | 
|---|
| 344 |  | 
|---|
| 345 | #if SIMDJSON_EXCEPTIONS | 
|---|
| 346 |  | 
|---|
| 347 | inline element::operator bool() const noexcept(false) { return get<bool>(); } | 
|---|
| 348 | inline element::operator const char*() const noexcept(false) { return get<const char *>(); } | 
|---|
| 349 | inline element::operator std::string_view() const noexcept(false) { return get<std::string_view>(); } | 
|---|
| 350 | inline element::operator uint64_t() const noexcept(false) { return get<uint64_t>(); } | 
|---|
| 351 | inline element::operator int64_t() const noexcept(false) { return get<int64_t>(); } | 
|---|
| 352 | inline element::operator double() const noexcept(false) { return get<double>(); } | 
|---|
| 353 | inline element::operator array() const noexcept(false) { return get<array>(); } | 
|---|
| 354 | inline element::operator object() const noexcept(false) { return get<object>(); } | 
|---|
| 355 |  | 
|---|
| 356 | inline array::iterator element::begin() const noexcept(false) { | 
|---|
| 357 | return get<array>().begin(); | 
|---|
| 358 | } | 
|---|
| 359 | inline array::iterator element::end() const noexcept(false) { | 
|---|
| 360 | return get<array>().end(); | 
|---|
| 361 | } | 
|---|
| 362 |  | 
|---|
| 363 | #endif // SIMDJSON_EXCEPTIONS | 
|---|
| 364 |  | 
|---|
| 365 | inline simdjson_result<element> element::operator[](std::string_view key) const noexcept { | 
|---|
| 366 | return at_key(key); | 
|---|
| 367 | } | 
|---|
| 368 | inline simdjson_result<element> element::operator[](const char *key) const noexcept { | 
|---|
| 369 | return at_key(key); | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 | inline simdjson_result<element> element::at_pointer(std::string_view json_pointer) const noexcept { | 
|---|
| 373 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 374 | switch (tape.tape_ref_type()) { | 
|---|
| 375 | case internal::tape_type::START_OBJECT: | 
|---|
| 376 | return object(tape).at_pointer(json_pointer); | 
|---|
| 377 | case internal::tape_type::START_ARRAY: | 
|---|
| 378 | return array(tape).at_pointer(json_pointer); | 
|---|
| 379 | default: { | 
|---|
| 380 | if(!json_pointer.empty()) { // a non-empty string is invalid on an atom | 
|---|
| 381 | return INVALID_JSON_POINTER; | 
|---|
| 382 | } | 
|---|
| 383 | // an empty string means that we return the current node | 
|---|
| 384 | dom::element copy(*this); | 
|---|
| 385 | return simdjson_result<element>(std::move(copy)); | 
|---|
| 386 | } | 
|---|
| 387 | } | 
|---|
| 388 | } | 
|---|
| 389 | #ifndef SIMDJSON_DISABLE_DEPRECATED_API | 
|---|
| 390 | [[deprecated( "For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]] | 
|---|
| 391 | inline simdjson_result<element> element::at(std::string_view json_pointer) const noexcept { | 
|---|
| 392 | // version 0.4 of simdjson allowed non-compliant pointers | 
|---|
| 393 | auto std_pointer = (json_pointer.empty() ? "": "/") + std::string(json_pointer.begin(), json_pointer.end()); | 
|---|
| 394 | return at_pointer(json_pointer: std_pointer); | 
|---|
| 395 | } | 
|---|
| 396 | #endif // SIMDJSON_DISABLE_DEPRECATED_API | 
|---|
| 397 |  | 
|---|
| 398 | inline simdjson_result<element> element::at(size_t index) const noexcept { | 
|---|
| 399 | return get<array>().at(index); | 
|---|
| 400 | } | 
|---|
| 401 | inline simdjson_result<element> element::at_key(std::string_view key) const noexcept { | 
|---|
| 402 | return get<object>().at_key(key); | 
|---|
| 403 | } | 
|---|
| 404 | inline simdjson_result<element> element::at_key_case_insensitive(std::string_view key) const noexcept { | 
|---|
| 405 | return get<object>().at_key_case_insensitive(key); | 
|---|
| 406 | } | 
|---|
| 407 |  | 
|---|
| 408 | inline bool element::dump_raw_tape(std::ostream &out) const noexcept { | 
|---|
| 409 | SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 | 
|---|
| 410 | return tape.doc->dump_raw_tape(os&: out); | 
|---|
| 411 | } | 
|---|
| 412 |  | 
|---|
| 413 |  | 
|---|
| 414 | inline std::ostream& operator<<(std::ostream& out, element_type type) { | 
|---|
| 415 | switch (type) { | 
|---|
| 416 | case element_type::ARRAY: | 
|---|
| 417 | return out << "array"; | 
|---|
| 418 | case element_type::OBJECT: | 
|---|
| 419 | return out << "object"; | 
|---|
| 420 | case element_type::INT64: | 
|---|
| 421 | return out << "int64_t"; | 
|---|
| 422 | case element_type::UINT64: | 
|---|
| 423 | return out << "uint64_t"; | 
|---|
| 424 | case element_type::DOUBLE: | 
|---|
| 425 | return out << "double"; | 
|---|
| 426 | case element_type::STRING: | 
|---|
| 427 | return out << "string"; | 
|---|
| 428 | case element_type::BOOL: | 
|---|
| 429 | return out << "bool"; | 
|---|
| 430 | case element_type::NULL_VALUE: | 
|---|
| 431 | return out << "null"; | 
|---|
| 432 | default: | 
|---|
| 433 | return out << "unexpected content!!!"; // abort() usage is forbidden in the library | 
|---|
| 434 | } | 
|---|
| 435 | } | 
|---|
| 436 |  | 
|---|
| 437 | } // namespace dom | 
|---|
| 438 |  | 
|---|
| 439 | } // namespace simdjson | 
|---|
| 440 |  | 
|---|
| 441 | #endif // SIMDJSON_INLINE_ELEMENT_H | 
|---|
| 442 |  | 
|---|