1#include "simdjson/error.h"
2
3namespace simdjson {
4namespace SIMDJSON_IMPLEMENTATION {
5namespace ondemand {
6
7class parser;
8class array;
9class object;
10class value;
11class raw_json_string;
12class array_iterator;
13class document_stream;
14
15/**
16 * A JSON document. It holds a json_iterator instance.
17 *
18 * Used by tokens to get text, and string buffer location.
19 *
20 * You must keep the document around during iteration.
21 */
22class document {
23public:
24 /**
25 * Create a new invalid document.
26 *
27 * Exists so you can declare a variable and later assign to it before use.
28 */
29 simdjson_inline document() noexcept = default;
30 simdjson_inline document(const document &other) noexcept = delete; // pass your documents by reference, not by copy
31 simdjson_inline document(document &&other) noexcept = default;
32 simdjson_inline document &operator=(const document &other) noexcept = delete;
33 simdjson_inline document &operator=(document &&other) noexcept = default;
34
35 /**
36 * Cast this JSON value to an array.
37 *
38 * @returns An object that can be used to iterate the array.
39 * @returns INCORRECT_TYPE If the JSON value is not an array.
40 */
41 simdjson_inline simdjson_result<array> get_array() & noexcept;
42 /**
43 * Cast this JSON value to an object.
44 *
45 * @returns An object that can be used to look up or iterate fields.
46 * @returns INCORRECT_TYPE If the JSON value is not an object.
47 */
48 simdjson_inline simdjson_result<object> get_object() & noexcept;
49 /**
50 * Cast this JSON value to an unsigned integer.
51 *
52 * @returns A signed 64-bit integer.
53 * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer.
54 */
55 simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
56 /**
57 * Cast this JSON value (inside string) to an unsigned integer.
58 *
59 * @returns A signed 64-bit integer.
60 * @returns INCORRECT_TYPE If the JSON value is not a 64-bit unsigned integer.
61 */
62 simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
63 /**
64 * Cast this JSON value to a signed integer.
65 *
66 * @returns A signed 64-bit integer.
67 * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer.
68 */
69 simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
70 /**
71 * Cast this JSON value (inside string) to a signed integer.
72 *
73 * @returns A signed 64-bit integer.
74 * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer.
75 */
76 simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
77 /**
78 * Cast this JSON value to a double.
79 *
80 * @returns A double.
81 * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number.
82 */
83 simdjson_inline simdjson_result<double> get_double() noexcept;
84
85 /**
86 * Cast this JSON value (inside string) to a double.
87 *
88 * @returns A double.
89 * @returns INCORRECT_TYPE If the JSON value is not a valid floating-point number.
90 */
91 simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
92 /**
93 * Cast this JSON value to a string.
94 *
95 * The string is guaranteed to be valid UTF-8.
96 *
97 * Important: Calling get_string() twice on the same document is an error.
98 *
99 * @param Whether to allow a replacement character for unmatched surrogate pairs.
100 * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next
101 * time it parses a document or when it is destroyed.
102 * @returns INCORRECT_TYPE if the JSON value is not a string.
103 */
104 simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
105 /**
106 * Cast this JSON value to a string.
107 *
108 * The string is not guaranteed to be valid UTF-8. See https://simonsapin.github.io/wtf-8/
109 *
110 * Important: Calling get_wobbly_string() twice on the same document is an error.
111 *
112 * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next
113 * time it parses a document or when it is destroyed.
114 * @returns INCORRECT_TYPE if the JSON value is not a string.
115 */
116 simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
117 /**
118 * Cast this JSON value to a raw_json_string.
119 *
120 * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n).
121 *
122 * @returns A pointer to the raw JSON for the given string.
123 * @returns INCORRECT_TYPE if the JSON value is not a string.
124 */
125 simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
126 /**
127 * Cast this JSON value to a bool.
128 *
129 * @returns A bool value.
130 * @returns INCORRECT_TYPE if the JSON value is not true or false.
131 */
132 simdjson_inline simdjson_result<bool> get_bool() noexcept;
133 /**
134 * Cast this JSON value to a value when the document is an object or an array.
135 *
136 * @returns A value if a JSON array or object cannot be found.
137 * @returns SCALAR_DOCUMENT_AS_VALUE error is the document is a scalar (see is_scalar() function).
138 */
139 simdjson_inline simdjson_result<value> get_value() noexcept;
140
141 /**
142 * Checks if this JSON value is null. If and only if the value is
143 * null, then it is consumed (we advance). If we find a token that
144 * begins with 'n' but is not 'null', then an error is returned.
145 *
146 * @returns Whether the value is null.
147 * @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'.
148 */
149 simdjson_inline simdjson_result<bool> is_null() noexcept;
150
151 /**
152 * Get this value as the given type.
153 *
154 * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool
155 *
156 * You may use get_double(), get_bool(), get_uint64(), get_int64(),
157 * get_object(), get_array(), get_raw_json_string(), or get_string() instead.
158 *
159 * @returns A value of the given type, parsed from the JSON.
160 * @returns INCORRECT_TYPE If the JSON value is not the given type.
161 */
162 template<typename T> simdjson_inline simdjson_result<T> get() & noexcept {
163 // Unless the simdjson library provides an inline implementation, calling this method should
164 // immediately fail.
165 static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
166 }
167 /** @overload template<typename T> simdjson_result<T> get() & noexcept */
168 template<typename T> simdjson_inline simdjson_result<T> get() && noexcept {
169 // Unless the simdjson library provides an inline implementation, calling this method should
170 // immediately fail.
171 static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
172 }
173
174 /**
175 * Get this value as the given type.
176 *
177 * Supported types: object, array, raw_json_string, string_view, uint64_t, int64_t, double, bool, value
178 *
179 * Be mindful that the document instance must remain in scope while you are accessing object, array and value instances.
180 *
181 * @param out This is set to a value of the given type, parsed from the JSON. If there is an error, this may not be initialized.
182 * @returns INCORRECT_TYPE If the JSON value is not an object.
183 * @returns SUCCESS If the parse succeeded and the out parameter was set to the value.
184 */
185 template<typename T> simdjson_inline error_code get(T &out) & noexcept;
186 /** @overload template<typename T> error_code get(T &out) & noexcept */
187 template<typename T> simdjson_inline error_code get(T &out) && noexcept;
188
189#if SIMDJSON_EXCEPTIONS
190 /**
191 * Cast this JSON value to an array.
192 *
193 * @returns An object that can be used to iterate the array.
194 * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an array.
195 */
196 simdjson_inline operator array() & noexcept(false);
197 /**
198 * Cast this JSON value to an object.
199 *
200 * @returns An object that can be used to look up or iterate fields.
201 * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not an object.
202 */
203 simdjson_inline operator object() & noexcept(false);
204 /**
205 * Cast this JSON value to an unsigned integer.
206 *
207 * @returns A signed 64-bit integer.
208 * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer.
209 */
210 simdjson_inline operator uint64_t() noexcept(false);
211 /**
212 * Cast this JSON value to a signed integer.
213 *
214 * @returns A signed 64-bit integer.
215 * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer.
216 */
217 simdjson_inline operator int64_t() noexcept(false);
218 /**
219 * Cast this JSON value to a double.
220 *
221 * @returns A double.
222 * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number.
223 */
224 simdjson_inline operator double() noexcept(false);
225 /**
226 * Cast this JSON value to a string.
227 *
228 * The string is guaranteed to be valid UTF-8.
229 *
230 * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next
231 * time it parses a document or when it is destroyed.
232 * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
233 */
234 simdjson_inline operator std::string_view() noexcept(false);
235 /**
236 * Cast this JSON value to a raw_json_string.
237 *
238 * The string is guaranteed to be valid UTF-8, and may have escapes in it (e.g. \\ or \n).
239 *
240 * @returns A pointer to the raw JSON for the given string.
241 * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
242 */
243 simdjson_inline operator raw_json_string() noexcept(false);
244 /**
245 * Cast this JSON value to a bool.
246 *
247 * @returns A bool value.
248 * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false.
249 */
250 simdjson_inline operator bool() noexcept(false);
251 /**
252 * Cast this JSON value to a value.
253 *
254 * @returns A value value.
255 * @exception if a JSON value cannot be found
256 */
257 simdjson_inline operator value() noexcept(false);
258#endif
259 /**
260 * This method scans the array and counts the number of elements.
261 * The count_elements method should always be called before you have begun
262 * iterating through the array: it is expected that you are pointing at
263 * the beginning of the array.
264 * The runtime complexity is linear in the size of the array. After
265 * calling this function, if successful, the array is 'rewinded' at its
266 * beginning as if it had never been accessed. If the JSON is malformed (e.g.,
267 * there is a missing comma), then an error is returned and it is no longer
268 * safe to continue.
269 */
270 simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
271 /**
272 * This method scans the object and counts the number of key-value pairs.
273 * The count_fields method should always be called before you have begun
274 * iterating through the object: it is expected that you are pointing at
275 * the beginning of the object.
276 * The runtime complexity is linear in the size of the object. After
277 * calling this function, if successful, the object is 'rewinded' at its
278 * beginning as if it had never been accessed. If the JSON is malformed (e.g.,
279 * there is a missing comma), then an error is returned and it is no longer
280 * safe to continue.
281 *
282 * To check that an object is empty, it is more performant to use
283 * the is_empty() method.
284 */
285 simdjson_inline simdjson_result<size_t> count_fields() & noexcept;
286 /**
287 * Get the value at the given index in the array. This function has linear-time complexity.
288 * This function should only be called once on an array instance since the array iterator is not reset between each call.
289 *
290 * @return The value at the given index, or:
291 * - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length
292 */
293 simdjson_inline simdjson_result<value> at(size_t index) & noexcept;
294 /**
295 * Begin array iteration.
296 *
297 * Part of the std::iterable interface.
298 */
299 simdjson_inline simdjson_result<array_iterator> begin() & noexcept;
300 /**
301 * Sentinel representing the end of the array.
302 *
303 * Part of the std::iterable interface.
304 */
305 simdjson_inline simdjson_result<array_iterator> end() & noexcept;
306
307 /**
308 * Look up a field by name on an object (order-sensitive).
309 *
310 * The following code reads z, then y, then x, and thus will not retrieve x or y if fed the
311 * JSON `{ "x": 1, "y": 2, "z": 3 }`:
312 *
313 * ```c++
314 * simdjson::ondemand::parser parser;
315 * auto obj = parser.parse(R"( { "x": 1, "y": 2, "z": 3 } )"_padded);
316 * double z = obj.find_field("z");
317 * double y = obj.find_field("y");
318 * double x = obj.find_field("x");
319 * ```
320 *
321 * **Raw Keys:** The lookup will be done against the *raw* key, and will not unescape keys.
322 * e.g. `object["a"]` will match `{ "a": 1 }`, but will *not* match `{ "\u0061": 1 }`.
323 *
324 *
325 * You must consume the fields on an object one at a time. A request for a new key
326 * invalidates previous field values: it makes them unsafe. E.g., the array
327 * given by content["bids"].get_array() should not be accessed after you have called
328 * content["asks"].get_array(). You can detect such mistakes by first compiling and running
329 * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an
330 * OUT_OF_ORDER_ITERATION error is generated.
331 *
332 * You are expected to access keys only once. You should access the value corresponding to
333 * a key a single time. Doing object["mykey"].to_string()and then again object["mykey"].to_string()
334 * is an error.
335 *
336 * @param key The key to look up.
337 * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object.
338 */
339 simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept;
340 /** @overload simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept; */
341 simdjson_inline simdjson_result<value> find_field(const char *key) & noexcept;
342
343 /**
344 * Look up a field by name on an object, without regard to key order.
345 *
346 * **Performance Notes:** This is a bit less performant than find_field(), though its effect varies
347 * and often appears negligible. It starts out normally, starting out at the last field; but if
348 * the field is not found, it scans from the beginning of the object to see if it missed it. That
349 * missing case has a non-cache-friendly bump and lots of extra scanning, especially if the object
350 * in question is large. The fact that the extra code is there also bumps the executable size.
351 *
352 * It is the default, however, because it would be highly surprising (and hard to debug) if the
353 * default behavior failed to look up a field just because it was in the wrong order--and many
354 * APIs assume this. Therefore, you must be explicit if you want to treat objects as out of order.
355 *
356 * Use find_field() if you are sure fields will be in order (or are willing to treat it as if the
357 * field wasn't there when they aren't).
358 *
359 * You must consume the fields on an object one at a time. A request for a new key
360 * invalidates previous field values: it makes them unsafe. E.g., the array
361 * given by content["bids"].get_array() should not be accessed after you have called
362 * content["asks"].get_array(). You can detect such mistakes by first compiling and running
363 * the code in Debug mode (or with the macro `SIMDJSON_DEVELOPMENT_CHECKS` set to 1): an
364 * OUT_OF_ORDER_ITERATION error is generated.
365 *
366 * You are expected to access keys only once. You should access the value corresponding to a key
367 * a single time. Doing object["mykey"].to_string() and then again object["mykey"].to_string()
368 * is an error.
369 *
370 * @param key The key to look up.
371 * @returns The value of the field, or NO_SUCH_FIELD if the field is not in the object.
372 */
373 simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept;
374 /** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept; */
375 simdjson_inline simdjson_result<value> find_field_unordered(const char *key) & noexcept;
376 /** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept; */
377 simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
378 /** @overload simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept; */
379 simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
380
381 /**
382 * Get the type of this JSON value. It does not validate or consume the value.
383 * E.g., you must still call "is_null()" to check that a value is null even if
384 * "type()" returns json_type::null.
385 *
386 * NOTE: If you're only expecting a value to be one type (a typical case), it's generally
387 * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
388 * let it throw an exception).
389 *
390 * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse".
391 */
392 simdjson_inline simdjson_result<json_type> type() noexcept;
393
394 /**
395 * Checks whether the document is a scalar (string, number, null, Boolean).
396 * Returns false when there it is an array or object.
397 *
398 * @returns true if the type is string, number, null, Boolean
399 * @error TAPE_ERROR when the JSON value is a bad token like "}" "," or "alse".
400 */
401 simdjson_inline simdjson_result<bool> is_scalar() noexcept;
402
403 /**
404 * Checks whether the document is a negative number.
405 *
406 * @returns true if the number if negative.
407 */
408 simdjson_inline bool is_negative() noexcept;
409 /**
410 * Checks whether the document is an integer number. Note that
411 * this requires to partially parse the number string. If
412 * the value is determined to be an integer, it may still
413 * not parse properly as an integer in subsequent steps
414 * (e.g., it might overflow).
415 *
416 * @returns true if the number if negative.
417 */
418 simdjson_inline simdjson_result<bool> is_integer() noexcept;
419 /**
420 * Determine the number type (integer or floating-point number) as quickly
421 * as possible. This function does not fully validate the input. It is
422 * useful when you only need to classify the numbers, without parsing them.
423 *
424 * If you are planning to retrieve the value or you need full validation,
425 * consider using the get_number() method instead: it will fully parse
426 * and validate the input, and give you access to the type:
427 * get_number().get_number_type().
428 *
429 * get_number_type() is number_type::unsigned_integer if we have
430 * an integer greater or equal to 9223372036854775808
431 * get_number_type() is number_type::signed_integer if we have an
432 * integer that is less than 9223372036854775808
433 * Otherwise, get_number_type() has value number_type::floating_point_number
434 *
435 * This function requires processing the number string, but it is expected
436 * to be faster than get_number().get_number_type() because it is does not
437 * parse the number value.
438 *
439 * @returns the type of the number
440 */
441 simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
442
443 /**
444 * Attempt to parse an ondemand::number. An ondemand::number may
445 * contain an integer value or a floating-point value, the simdjson
446 * library will autodetect the type. Thus it is a dynamically typed
447 * number. Before accessing the value, you must determine the detected
448 * type.
449 *
450 * number.get_number_type() is number_type::signed_integer if we have
451 * an integer in [-9223372036854775808,9223372036854775808)
452 * You can recover the value by calling number.get_int64() and you
453 * have that number.is_int64() is true.
454 *
455 * number.get_number_type() is number_type::unsigned_integer if we have
456 * an integer in [9223372036854775808,18446744073709551616)
457 * You can recover the value by calling number.get_uint64() and you
458 * have that number.is_uint64() is true.
459 *
460 * Otherwise, number.get_number_type() has value number_type::floating_point_number
461 * and we have a binary64 number.
462 * You can recover the value by calling number.get_double() and you
463 * have that number.is_double() is true.
464 *
465 * You must check the type before accessing the value: it is an error
466 * to call "get_int64()" when number.get_number_type() is not
467 * number_type::signed_integer and when number.is_int64() is false.
468 */
469 simdjson_warn_unused simdjson_inline simdjson_result<number> get_number() noexcept;
470
471 /**
472 * Get the raw JSON for this token.
473 *
474 * The string_view will always point into the input buffer.
475 *
476 * The string_view will start at the beginning of the token, and include the entire token
477 * *as well as all spaces until the next token (or EOF).* This means, for example, that a
478 * string token always begins with a " and is always terminated by the final ", possibly
479 * followed by a number of spaces.
480 *
481 * The string_view is *not* null-terminated. If this is a scalar (string, number,
482 * boolean, or null), the character after the end of the string_view may be the padded buffer.
483 *
484 * Tokens include:
485 * - {
486 * - [
487 * - "a string (possibly with UTF-8 or backslashed characters like \\\")".
488 * - -1.2e-100
489 * - true
490 * - false
491 * - null
492 */
493 simdjson_inline simdjson_result<std::string_view> raw_json_token() noexcept;
494
495 /**
496 * Reset the iterator inside the document instance so we are pointing back at the
497 * beginning of the document, as if it had just been created. It invalidates all
498 * values, objects and arrays that you have created so far (including unescaped strings).
499 */
500 inline void rewind() noexcept;
501 /**
502 * Returns debugging information.
503 */
504 inline std::string to_debug_string() noexcept;
505 /**
506 * Some unrecoverable error conditions may render the document instance unusable.
507 * The is_alive() method returns true when the document is still suitable.
508 */
509 inline bool is_alive() noexcept;
510
511 /**
512 * Returns the current location in the document if in bounds.
513 */
514 inline simdjson_result<const char *> current_location() noexcept;
515
516 /**
517 * Returns the current depth in the document if in bounds.
518 *
519 * E.g.,
520 * 0 = finished with document
521 * 1 = document root value (could be [ or {, not yet known)
522 * 2 = , or } inside root array/object
523 * 3 = key or value inside root array/object.
524 */
525 simdjson_inline int32_t current_depth() const noexcept;
526
527 /**
528 * Get the value associated with the given JSON pointer. We use the RFC 6901
529 * https://tools.ietf.org/html/rfc6901 standard.
530 *
531 * ondemand::parser parser;
532 * auto json = R"({ "foo": { "a": [ 10, 20, 30 ] }})"_padded;
533 * auto doc = parser.iterate(json);
534 * doc.at_pointer("/foo/a/1") == 20
535 *
536 * It is allowed for a key to be the empty string:
537 *
538 * ondemand::parser parser;
539 * auto json = R"({ "": { "a": [ 10, 20, 30 ] }})"_padded;
540 * auto doc = parser.iterate(json);
541 * doc.at_pointer("//a/1") == 20
542 *
543 * Note that at_pointer() automatically calls rewind between each call. Thus
544 * all values, objects and arrays that you have created so far (including unescaped strings)
545 * are invalidated. After calling at_pointer, you need to consume the result: string values
546 * should be stored in your own variables, arrays should be decoded and stored in your own array-like
547 * structures and so forth.
548 *
549 * Also note that at_pointer() relies on find_field() which implies that we do not unescape keys when matching
550 *
551 * @return The value associated with the given JSON pointer, or:
552 * - NO_SUCH_FIELD if a field does not exist in an object
553 * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length
554 * - INCORRECT_TYPE if a non-integer is used to access an array
555 * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed
556 * - SCALAR_DOCUMENT_AS_VALUE if the json_pointer is empty and the document is not a scalar (see is_scalar() function).
557 */
558 simdjson_inline simdjson_result<value> at_pointer(std::string_view json_pointer) noexcept;
559 /**
560 * Consumes the document and returns a string_view instance corresponding to the
561 * document as represented in JSON. It points inside the original byte array containing
562 * the JSON document.
563 */
564 simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
565protected:
566 /**
567 * Consumes the document.
568 */
569 simdjson_inline error_code consume() noexcept;
570
571 simdjson_inline document(ondemand::json_iterator &&iter) noexcept;
572 simdjson_inline const uint8_t *text(uint32_t idx) const noexcept;
573
574 simdjson_inline value_iterator resume_value_iterator() noexcept;
575 simdjson_inline value_iterator get_root_value_iterator() noexcept;
576 simdjson_inline simdjson_result<object> start_or_resume_object() noexcept;
577 static simdjson_inline document start(ondemand::json_iterator &&iter) noexcept;
578
579 //
580 // Fields
581 //
582 json_iterator iter{}; ///< Current position in the document
583 static constexpr depth_t DOCUMENT_DEPTH = 0; ///< document depth is always 0
584
585 friend class array_iterator;
586 friend class value;
587 friend class ondemand::parser;
588 friend class object;
589 friend class array;
590 friend class field;
591 friend class token;
592 friend class document_stream;
593 friend class document_reference;
594};
595
596
597/**
598 * A document_reference is a thin wrapper around a document reference instance.
599 */
600class document_reference {
601public:
602 simdjson_inline document_reference() noexcept;
603 simdjson_inline document_reference(document &d) noexcept;
604 simdjson_inline document_reference(const document_reference &other) noexcept = default;
605 simdjson_inline document_reference& operator=(const document_reference &other) noexcept = default;
606 simdjson_inline void rewind() noexcept;
607 simdjson_inline simdjson_result<array> get_array() & noexcept;
608 simdjson_inline simdjson_result<object> get_object() & noexcept;
609 simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
610 simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
611 simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
612 simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
613 simdjson_inline simdjson_result<double> get_double() noexcept;
614 simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
615 simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
616 simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
617 simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
618 simdjson_inline simdjson_result<bool> get_bool() noexcept;
619 simdjson_inline simdjson_result<value> get_value() noexcept;
620
621 simdjson_inline simdjson_result<bool> is_null() noexcept;
622 simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
623 simdjson_inline operator document&() const noexcept;
624
625#if SIMDJSON_EXCEPTIONS
626 simdjson_inline operator array() & noexcept(false);
627 simdjson_inline operator object() & noexcept(false);
628 simdjson_inline operator uint64_t() noexcept(false);
629 simdjson_inline operator int64_t() noexcept(false);
630 simdjson_inline operator double() noexcept(false);
631 simdjson_inline operator std::string_view() noexcept(false);
632 simdjson_inline operator raw_json_string() noexcept(false);
633 simdjson_inline operator bool() noexcept(false);
634 simdjson_inline operator value() noexcept(false);
635#endif
636 simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
637 simdjson_inline simdjson_result<size_t> count_fields() & noexcept;
638 simdjson_inline simdjson_result<value> at(size_t index) & noexcept;
639 simdjson_inline simdjson_result<array_iterator> begin() & noexcept;
640 simdjson_inline simdjson_result<array_iterator> end() & noexcept;
641 simdjson_inline simdjson_result<value> find_field(std::string_view key) & noexcept;
642 simdjson_inline simdjson_result<value> find_field(const char *key) & noexcept;
643 simdjson_inline simdjson_result<value> operator[](std::string_view key) & noexcept;
644 simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
645 simdjson_inline simdjson_result<value> find_field_unordered(std::string_view key) & noexcept;
646 simdjson_inline simdjson_result<value> find_field_unordered(const char *key) & noexcept;
647
648 simdjson_inline simdjson_result<json_type> type() noexcept;
649 simdjson_inline simdjson_result<bool> is_scalar() noexcept;
650
651 simdjson_inline simdjson_result<const char *> current_location() noexcept;
652 simdjson_inline int32_t current_depth() const noexcept;
653 simdjson_inline bool is_negative() noexcept;
654 simdjson_inline simdjson_result<bool> is_integer() noexcept;
655 simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
656 simdjson_inline simdjson_result<number> get_number() noexcept;
657 simdjson_inline simdjson_result<std::string_view> raw_json_token() noexcept;
658 simdjson_inline simdjson_result<value> at_pointer(std::string_view json_pointer) noexcept;
659private:
660 document *doc{nullptr};
661};
662} // namespace ondemand
663} // namespace SIMDJSON_IMPLEMENTATION
664} // namespace simdjson
665
666namespace simdjson {
667
668template<>
669struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::document> {
670public:
671 simdjson_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::document &&value) noexcept; ///< @private
672 simdjson_inline simdjson_result(error_code error) noexcept; ///< @private
673 simdjson_inline simdjson_result() noexcept = default;
674 simdjson_inline error_code rewind() noexcept;
675
676 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
677 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
678 simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
679 simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
680 simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
681 simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
682 simdjson_inline simdjson_result<double> get_double() noexcept;
683 simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
684 simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
685 simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
686 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
687 simdjson_inline simdjson_result<bool> get_bool() noexcept;
688 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> get_value() noexcept;
689 simdjson_inline simdjson_result<bool> is_null() noexcept;
690
691 template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
692 template<typename T> simdjson_inline simdjson_result<T> get() && noexcept;
693
694 template<typename T> simdjson_inline error_code get(T &out) & noexcept;
695 template<typename T> simdjson_inline error_code get(T &out) && noexcept;
696
697#if SIMDJSON_EXCEPTIONS
698 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
699 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
700 simdjson_inline operator uint64_t() noexcept(false);
701 simdjson_inline operator int64_t() noexcept(false);
702 simdjson_inline operator double() noexcept(false);
703 simdjson_inline operator std::string_view() noexcept(false);
704 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
705 simdjson_inline operator bool() noexcept(false);
706 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
707#endif
708 simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
709 simdjson_inline simdjson_result<size_t> count_fields() & noexcept;
710 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at(size_t index) & noexcept;
711 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> begin() & noexcept;
712 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept;
713 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(std::string_view key) & noexcept;
714 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(const char *key) & noexcept;
715 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
716 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
717 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
718 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
719 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
720 simdjson_inline simdjson_result<bool> is_scalar() noexcept;
721 simdjson_inline simdjson_result<const char *> current_location() noexcept;
722 simdjson_inline int32_t current_depth() const noexcept;
723 simdjson_inline bool is_negative() noexcept;
724 simdjson_inline simdjson_result<bool> is_integer() noexcept;
725 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number_type> get_number_type() noexcept;
726 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number> get_number() noexcept;
727 /** @copydoc simdjson_inline std::string_view document::raw_json_token() const noexcept */
728 simdjson_inline simdjson_result<std::string_view> raw_json_token() noexcept;
729
730 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
731};
732
733
734} // namespace simdjson
735
736
737
738namespace simdjson {
739
740template<>
741struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference> : public SIMDJSON_IMPLEMENTATION::implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::document_reference> {
742public:
743 simdjson_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::document_reference value, error_code error) noexcept;
744 simdjson_inline simdjson_result() noexcept = default;
745 simdjson_inline error_code rewind() noexcept;
746
747 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
748 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
749 simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
750 simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
751 simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
752 simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
753 simdjson_inline simdjson_result<double> get_double() noexcept;
754 simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
755 simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
756 simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
757 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
758 simdjson_inline simdjson_result<bool> get_bool() noexcept;
759 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> get_value() noexcept;
760 simdjson_inline simdjson_result<bool> is_null() noexcept;
761
762#if SIMDJSON_EXCEPTIONS
763 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
764 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
765 simdjson_inline operator uint64_t() noexcept(false);
766 simdjson_inline operator int64_t() noexcept(false);
767 simdjson_inline operator double() noexcept(false);
768 simdjson_inline operator std::string_view() noexcept(false);
769 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
770 simdjson_inline operator bool() noexcept(false);
771 simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
772#endif
773 simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
774 simdjson_inline simdjson_result<size_t> count_fields() & noexcept;
775 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at(size_t index) & noexcept;
776 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> begin() & noexcept;
777 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept;
778 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(std::string_view key) & noexcept;
779 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field(const char *key) & noexcept;
780 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
781 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) & noexcept;
782 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(std::string_view key) & noexcept;
783 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> find_field_unordered(const char *key) & noexcept;
784 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
785 simdjson_inline simdjson_result<bool> is_scalar() noexcept;
786 simdjson_inline simdjson_result<const char *> current_location() noexcept;
787 simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
788 simdjson_inline simdjson_result<bool> is_negative() noexcept;
789 simdjson_inline simdjson_result<bool> is_integer() noexcept;
790 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number_type> get_number_type() noexcept;
791 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number> get_number() noexcept;
792 /** @copydoc simdjson_inline std::string_view document_reference::raw_json_token() const noexcept */
793 simdjson_inline simdjson_result<std::string_view> raw_json_token() noexcept;
794
795 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
796};
797
798
799} // namespace simdjson
800