This introduces a reset functionality for object and array containers (#1639)
* This introduces a reset functionality. * Minor simplification. * Tweaking further. * This should fix the tests.
This commit is contained in:
parent
1fd3e32051
commit
374de826ab
|
@ -5,6 +5,9 @@
|
||||||
],
|
],
|
||||||
"files.trimTrailingWhitespace": true,
|
"files.trimTrailingWhitespace": true,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"array": "cpp"
|
"array": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"optional": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -73,9 +73,6 @@ simdjson_really_inline simdjson_result<array_iterator> array::end() noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline simdjson_result<size_t> array::count_elements() & noexcept {
|
simdjson_really_inline simdjson_result<size_t> array::count_elements() & noexcept {
|
||||||
// If the array is empty (i.e., we already scanned past it), then we use a
|
|
||||||
// fast path and return 0.
|
|
||||||
if(!iter.is_open()) { return 0; }
|
|
||||||
size_t count{0};
|
size_t count{0};
|
||||||
// Important: we do not consume any of the values.
|
// Important: we do not consume any of the values.
|
||||||
for(simdjson_unused auto v : *this) { count++; }
|
for(simdjson_unused auto v : *this) { count++; }
|
||||||
|
@ -83,8 +80,7 @@ simdjson_really_inline simdjson_result<size_t> array::count_elements() & noexcep
|
||||||
if(iter.error()) { return iter.error(); }
|
if(iter.error()) { return iter.error(); }
|
||||||
// We need to move back at the start because we expect users to iterate through
|
// We need to move back at the start because we expect users to iterate through
|
||||||
// the array after counting the number of elements.
|
// the array after counting the number of elements.
|
||||||
// enter_at_container_start is safe here because we know that we do not have an empty array.
|
iter.reset_array();
|
||||||
iter.enter_at_container_start(); // sets the depth to indicate that we are inside the container and accesses the first element
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,9 +194,8 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator
|
||||||
// this object iterator will blithely scan that object for fields.
|
// this object iterator will blithely scan that object for fields.
|
||||||
if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; }
|
if (_json_iter->depth() < depth() - 1) { return OUT_OF_ORDER_ITERATION; }
|
||||||
#endif
|
#endif
|
||||||
_json_iter->reenter_child(_start_position + 1, _depth);
|
has_value = reset_object();
|
||||||
at_first = true;
|
at_first = true;
|
||||||
has_value = started_object();
|
|
||||||
// 3. When a previous search found a field or an iterator yielded a value:
|
// 3. When a previous search found a field or an iterator yielded a value:
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
|
@ -288,8 +287,7 @@ simdjson_warn_unused simdjson_really_inline simdjson_result<bool> value_iterator
|
||||||
// beginning of the object.
|
// beginning of the object.
|
||||||
// (We have already run through the object before, so we've already validated its structure. We
|
// (We have already run through the object before, so we've already validated its structure. We
|
||||||
// don't check errors in this bit.)
|
// don't check errors in this bit.)
|
||||||
_json_iter->reenter_child(_start_position + 1, _depth);
|
has_value = reset_object();
|
||||||
has_value = started_object();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object
|
SIMDJSON_ASSUME(has_value); // we should reach search_start before ever reaching the end of the object
|
||||||
SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field
|
SIMDJSON_ASSUME( _json_iter->_depth == _depth ); // We must be at the start of a field
|
||||||
|
@ -628,17 +626,26 @@ inline void value_iterator::assert_at_next() const noexcept {
|
||||||
SIMDJSON_ASSUME( _depth > 0 );
|
SIMDJSON_ASSUME( _depth > 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
simdjson_really_inline void value_iterator::enter_at_container_start() noexcept {
|
|
||||||
_json_iter->_depth = _depth + 1;
|
|
||||||
_json_iter->token.index = _start_position + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
simdjson_really_inline void value_iterator::move_at_start() noexcept {
|
simdjson_really_inline void value_iterator::move_at_start() noexcept {
|
||||||
_json_iter->_depth = _depth;
|
_json_iter->_depth = _depth;
|
||||||
_json_iter->token.index = _start_position;
|
_json_iter->token.index = _start_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline void value_iterator::move_at_container_start() noexcept {
|
||||||
|
_json_iter->_depth = _depth;
|
||||||
|
_json_iter->token.index = _start_position + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline bool value_iterator::reset_array() noexcept {
|
||||||
|
move_at_container_start();
|
||||||
|
return started_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline bool value_iterator::reset_object() noexcept {
|
||||||
|
move_at_container_start();
|
||||||
|
return started_object();
|
||||||
|
}
|
||||||
|
|
||||||
inline void value_iterator::assert_at_child() const noexcept {
|
inline void value_iterator::assert_at_child() const noexcept {
|
||||||
SIMDJSON_ASSUME( _json_iter->token.index > _start_position );
|
SIMDJSON_ASSUME( _json_iter->token.index > _start_position );
|
||||||
SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 );
|
SIMDJSON_ASSUME( _json_iter->_depth == _depth + 1 );
|
||||||
|
|
|
@ -281,24 +281,32 @@ public:
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Restarts an array iteration.
|
||||||
|
* @returns Whether the array has any elements (returns false for empty).
|
||||||
|
*/
|
||||||
|
simdjson_really_inline bool reset_array() noexcept;
|
||||||
|
/**
|
||||||
|
* Restarts an object iteration.
|
||||||
|
* @returns Whether the object has any fields (returns false for empty).
|
||||||
|
*/
|
||||||
|
simdjson_really_inline bool reset_object() noexcept;
|
||||||
/**
|
/**
|
||||||
* move_at_start(): moves us so that we are pointing at the beginning of
|
* move_at_start(): moves us so that we are pointing at the beginning of
|
||||||
* the container. It updates the index so that at_start() is true and it
|
* the container. It updates the index so that at_start() is true and it
|
||||||
* syncs the depth. The user can then create a new container instance.
|
* syncs the depth. The user can then create a new container instance.
|
||||||
*
|
*
|
||||||
* Usage: used with value::count_elements()
|
* Usage: used with value::count_elements().
|
||||||
**/
|
**/
|
||||||
simdjson_really_inline void move_at_start() noexcept;
|
simdjson_really_inline void move_at_start() noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enter_at_container_start moves at the beginning of the container
|
* move_at_container_start(): moves us so that we are pointing at the beginning of
|
||||||
* and sets the depth to indicate that we are inside the
|
* the container so that assert_at_container_start() passes.
|
||||||
* container and ready to access the first element. It is only
|
|
||||||
* safely used with non-empty containers. The caller is responsible
|
|
||||||
* to ensure that the container is not empty!
|
|
||||||
*
|
*
|
||||||
* Usage: used with array::count_elements().
|
* Usage: used with reset_array() and reset_object().
|
||||||
**/
|
**/
|
||||||
simdjson_really_inline void enter_at_container_start() noexcept;
|
simdjson_really_inline void move_at_container_start() noexcept;
|
||||||
/* Useful for debugging and logging purposes. */
|
/* Useful for debugging and logging purposes. */
|
||||||
inline std::string to_string() const noexcept;
|
inline std::string to_string() const noexcept;
|
||||||
simdjson_really_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept;
|
simdjson_really_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept;
|
||||||
|
|
Loading…
Reference in New Issue