json_iterator * -> json_iterator_ref
This commit is contained in:
parent
283ac3191f
commit
0ddff4ec7d
|
@ -41,18 +41,18 @@ namespace ondemand {
|
|||
//
|
||||
|
||||
simdjson_really_inline array::array() noexcept = default;
|
||||
simdjson_really_inline array::array(json_iterator *_iter, bool has_value) noexcept
|
||||
: iter{_iter}, has_next{has_value}, error{SUCCESS}
|
||||
simdjson_really_inline array::array(json_iterator_ref &&_iter, bool has_value) noexcept
|
||||
: iter{std::forward<json_iterator_ref>(_iter)}, has_next{has_value}, error{SUCCESS}
|
||||
{
|
||||
}
|
||||
simdjson_really_inline array::array(array &&other) noexcept
|
||||
: iter{other.iter}, has_next{other.has_next}, error{other.error}
|
||||
: iter{std::forward<array>(other).iter}, has_next{other.has_next}, error{other.error}
|
||||
{
|
||||
// Terminate the other iterator
|
||||
other.has_next = false;
|
||||
}
|
||||
simdjson_really_inline array &array::operator=(array &&other) noexcept {
|
||||
iter = other.iter;
|
||||
iter = std::forward<array>(other).iter;
|
||||
has_next = other.has_next;
|
||||
error = other.error;
|
||||
// Terminate the other iterator
|
||||
|
@ -67,13 +67,13 @@ simdjson_really_inline array::~array() noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<array> array::start(json_iterator *iter) noexcept {
|
||||
simdjson_really_inline simdjson_result<array> array::start(json_iterator_ref &&iter) noexcept {
|
||||
bool has_value;
|
||||
SIMDJSON_TRY( iter->start_array().get(has_value) );
|
||||
return array(iter, has_value);
|
||||
return array(std::forward<json_iterator_ref>(iter), has_value);
|
||||
}
|
||||
simdjson_really_inline array array::started(json_iterator *iter) noexcept {
|
||||
return array(iter, iter->started_array());
|
||||
simdjson_really_inline array array::started(json_iterator_ref &&iter) noexcept {
|
||||
return array(std::forward<json_iterator_ref>(iter), iter->started_array());
|
||||
}
|
||||
simdjson_really_inline array::iterator array::begin() noexcept {
|
||||
return *this;
|
||||
|
@ -96,7 +96,7 @@ simdjson_really_inline array::iterator &array::iterator::operator=(const array::
|
|||
|
||||
simdjson_really_inline simdjson_result<value> array::iterator::operator*() noexcept {
|
||||
if (a->error) { return a->report_error(); }
|
||||
return value::start(a->iter);
|
||||
return value::start(a->iter.borrow());
|
||||
}
|
||||
simdjson_really_inline bool array::iterator::operator==(const array::iterator &) noexcept {
|
||||
return !a->has_next;
|
||||
|
|
|
@ -53,13 +53,13 @@ protected:
|
|||
* @param doc The document containing the array.
|
||||
* @error INCORRECT_TYPE if the iterator is not at [.
|
||||
*/
|
||||
static simdjson_really_inline simdjson_result<array> start(json_iterator *iter) noexcept;
|
||||
static simdjson_really_inline simdjson_result<array> start(json_iterator_ref &&iter) noexcept;
|
||||
/**
|
||||
* Begin array iteration.
|
||||
*
|
||||
* @param doc The document containing the array. The iterator must be just after the opening `[`.
|
||||
*/
|
||||
static simdjson_really_inline array started(json_iterator *iter) noexcept;
|
||||
static simdjson_really_inline array started(json_iterator_ref &&iter) noexcept;
|
||||
|
||||
/**
|
||||
* Report the current error and set finished so it won't be reported again.
|
||||
|
@ -73,7 +73,7 @@ protected:
|
|||
* reflect the array's depth. The iterator must be just after the opening `[`.
|
||||
* @param has_value Whether the array has a value (false means empty array).
|
||||
*/
|
||||
simdjson_really_inline array(json_iterator *iter, bool has_value) noexcept;
|
||||
simdjson_really_inline array(json_iterator_ref &&iter, bool has_value) noexcept;
|
||||
|
||||
/**
|
||||
* Document containing this array.
|
||||
|
@ -81,7 +81,7 @@ protected:
|
|||
* PERF NOTE: expected to be elided in favor of the parent document: this is set when the array
|
||||
* is first used, and never changes afterwards.
|
||||
*/
|
||||
json_iterator *iter{};
|
||||
json_iterator_ref iter{};
|
||||
/**
|
||||
* Whether we have anything to yield.
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace ondemand {
|
|||
|
||||
simdjson_really_inline document::document(document &&other) noexcept = default;
|
||||
simdjson_really_inline document &document::operator=(document &&other) noexcept = default;
|
||||
simdjson_really_inline document::document(ondemand::json_iterator && _iter) noexcept
|
||||
simdjson_really_inline document::document(ondemand::json_iterator &&_iter) noexcept
|
||||
: iter(std::forward<json_iterator>(_iter))
|
||||
{
|
||||
logger::log_start_value(iter, "document");
|
||||
|
@ -20,7 +20,7 @@ simdjson_really_inline value document::as_value() noexcept {
|
|||
logger::log_error(iter, "Document value can only be used once! ondemand::document is a forward-only input iterator.");
|
||||
abort(); // TODO is there anything softer we can do? I'd rather not make this a simdjson_result just for user error.
|
||||
}
|
||||
return value::start(&iter);
|
||||
return value::start(iter.borrow());
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<array> document::get_array() & noexcept { return as_value().get_array(); }
|
||||
|
|
|
@ -12,15 +12,15 @@ simdjson_really_inline field::field(raw_json_string key, ondemand::value &&value
|
|||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<field> field::start(json_iterator *iter) noexcept {
|
||||
simdjson_really_inline simdjson_result<field> field::start(json_iterator_ref &&iter) noexcept {
|
||||
raw_json_string key;
|
||||
SIMDJSON_TRY( iter->field_key().get(key) );
|
||||
SIMDJSON_TRY( iter->field_value() );
|
||||
return field::start(iter, key);
|
||||
return field::start(std::forward<json_iterator_ref>(iter), key);
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<field> field::start(json_iterator *iter, raw_json_string key) noexcept {
|
||||
return field(key, value::start(iter));
|
||||
simdjson_really_inline simdjson_result<field> field::start(json_iterator_ref &&iter, raw_json_string key) noexcept {
|
||||
return field(key, value::start(std::forward<json_iterator_ref>(iter)));
|
||||
}
|
||||
|
||||
simdjson_really_inline raw_json_string field::key() const noexcept {
|
||||
|
|
|
@ -19,8 +19,8 @@ public:
|
|||
simdjson_really_inline ondemand::value &value() noexcept;
|
||||
protected:
|
||||
simdjson_really_inline field(raw_json_string key, ondemand::value &&value) noexcept;
|
||||
static simdjson_really_inline simdjson_result<field> start(json_iterator *iter) noexcept;
|
||||
static simdjson_really_inline simdjson_result<field> start(json_iterator *iter, raw_json_string key) noexcept;
|
||||
static simdjson_really_inline simdjson_result<field> start(json_iterator_ref &&iter) noexcept;
|
||||
static simdjson_really_inline simdjson_result<field> start(json_iterator_ref &&iter, raw_json_string key) noexcept;
|
||||
friend struct simdjson_result<field>;
|
||||
friend class object;
|
||||
};
|
||||
|
|
|
@ -260,6 +260,41 @@ simdjson_really_inline bool json_iterator::is_alive() const noexcept {
|
|||
return parser;
|
||||
}
|
||||
|
||||
simdjson_really_inline json_iterator_ref json_iterator::borrow() noexcept {
|
||||
return json_iterator_ref(this);
|
||||
}
|
||||
|
||||
//
|
||||
// json_iterator_ref
|
||||
//
|
||||
simdjson_really_inline json_iterator_ref::json_iterator_ref() noexcept = default;
|
||||
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator_ref &&other) noexcept = default;
|
||||
simdjson_really_inline json_iterator_ref &json_iterator_ref::operator=(json_iterator_ref &&other) noexcept = default;
|
||||
simdjson_really_inline json_iterator_ref::json_iterator_ref(json_iterator *_iter) noexcept
|
||||
: iter{_iter}
|
||||
{
|
||||
}
|
||||
simdjson_really_inline json_iterator_ref::~json_iterator_ref() noexcept = default;
|
||||
|
||||
simdjson_really_inline json_iterator_ref json_iterator_ref::borrow() noexcept {
|
||||
return json_iterator_ref(iter);
|
||||
}
|
||||
|
||||
simdjson_really_inline json_iterator *json_iterator_ref::operator->() noexcept {
|
||||
return iter;
|
||||
}
|
||||
simdjson_really_inline json_iterator &json_iterator_ref::operator*() noexcept {
|
||||
return *iter;
|
||||
}
|
||||
simdjson_really_inline const json_iterator &json_iterator_ref::operator*() const noexcept {
|
||||
return *iter;
|
||||
}
|
||||
|
||||
simdjson_really_inline bool json_iterator_ref::is_alive() const noexcept {
|
||||
return iter != nullptr;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // namespace {
|
||||
|
|
|
@ -2,6 +2,8 @@ namespace {
|
|||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace ondemand {
|
||||
|
||||
class json_iterator_ref;
|
||||
|
||||
/**
|
||||
* Iterates through JSON, with structure-sensitive algorithms.
|
||||
*
|
||||
|
@ -140,6 +142,8 @@ protected:
|
|||
template<int N>
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline bool advance_to_buffer(uint8_t (&buf)[N]) noexcept;
|
||||
|
||||
simdjson_really_inline json_iterator_ref borrow() noexcept;
|
||||
|
||||
friend class document;
|
||||
friend class object;
|
||||
friend class array;
|
||||
|
@ -147,7 +151,31 @@ protected:
|
|||
friend class raw_json_string;
|
||||
friend class parser;
|
||||
friend simdjson_really_inline void logger::log_line(const json_iterator &iter, const char *title_prefix, const char *title, std::string_view detail, int delta, int depth_delta) noexcept;
|
||||
};
|
||||
}; // json_iterator
|
||||
|
||||
class json_iterator_ref {
|
||||
public:
|
||||
simdjson_really_inline json_iterator_ref() noexcept;
|
||||
simdjson_really_inline json_iterator_ref(json_iterator_ref &&other) noexcept;
|
||||
simdjson_really_inline json_iterator_ref &operator=(json_iterator_ref &&other) noexcept;
|
||||
simdjson_really_inline json_iterator_ref(const json_iterator_ref &other) noexcept = delete;
|
||||
simdjson_really_inline json_iterator_ref &operator=(const json_iterator_ref &other) noexcept = delete;
|
||||
simdjson_really_inline ~json_iterator_ref() noexcept;
|
||||
|
||||
simdjson_really_inline json_iterator_ref borrow() noexcept;
|
||||
|
||||
simdjson_really_inline json_iterator *operator->() noexcept;
|
||||
simdjson_really_inline json_iterator &operator*() noexcept;
|
||||
simdjson_really_inline const json_iterator &operator*() const noexcept;
|
||||
|
||||
simdjson_really_inline bool is_alive() const noexcept;
|
||||
|
||||
private:
|
||||
simdjson_really_inline json_iterator_ref(json_iterator *iter) noexcept;
|
||||
json_iterator *iter;
|
||||
|
||||
friend class json_iterator;
|
||||
}; // class json_iterator_ref
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
|
|
|
@ -44,18 +44,18 @@ namespace ondemand {
|
|||
//
|
||||
|
||||
simdjson_really_inline object::object() noexcept = default;
|
||||
simdjson_really_inline object::object(json_iterator *_iter, bool _has_value) noexcept
|
||||
: iter{_iter}, has_next{_has_value}, at_start{true}, error{SUCCESS}
|
||||
simdjson_really_inline object::object(json_iterator_ref &&_iter, bool _has_value) noexcept
|
||||
: iter{std::forward<json_iterator_ref>(_iter)}, has_next{_has_value}, at_start{true}, error{SUCCESS}
|
||||
{
|
||||
}
|
||||
simdjson_really_inline object::object(object &&other) noexcept
|
||||
: iter{other.iter}, has_next{other.has_next}, at_start{other.at_start}, error{other.error}
|
||||
: iter{std::forward<object>(other).iter}, has_next{other.has_next}, at_start{other.at_start}, error{other.error}
|
||||
{
|
||||
// Terminate the other iterator
|
||||
other.has_next = false;
|
||||
}
|
||||
simdjson_really_inline object &object::operator=(object &&other) noexcept {
|
||||
iter = other.iter;
|
||||
iter = std::forward<object>(other).iter;
|
||||
has_next = other.has_next;
|
||||
at_start = other.at_start;
|
||||
error = other.error;
|
||||
|
@ -91,7 +91,7 @@ simdjson_really_inline simdjson_result<value> object::operator[](const std::stri
|
|||
// Check if it matches
|
||||
if (actual_key == key) {
|
||||
logger::log_event(*iter, "match", key, -2);
|
||||
return value::start(iter);
|
||||
return value::start(iter.borrow());
|
||||
}
|
||||
logger::log_event(*iter, "no match", key, -2);
|
||||
iter->skip(); // Skip the value entirely
|
||||
|
@ -102,13 +102,13 @@ simdjson_really_inline simdjson_result<value> object::operator[](const std::stri
|
|||
return NO_SUCH_FIELD;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<object> object::start(json_iterator *iter) noexcept {
|
||||
simdjson_really_inline simdjson_result<object> object::start(json_iterator_ref &&iter) noexcept {
|
||||
bool has_value;
|
||||
SIMDJSON_TRY( iter->start_object().get(has_value) );
|
||||
return object(iter, has_value);
|
||||
return object(std::forward<json_iterator_ref>(iter), has_value);
|
||||
}
|
||||
simdjson_really_inline object object::started(json_iterator *iter) noexcept {
|
||||
return object(iter, iter->started_object());
|
||||
simdjson_really_inline object object::started(json_iterator_ref &&iter) noexcept {
|
||||
return object(std::forward<json_iterator_ref>(iter), iter->started_object());
|
||||
}
|
||||
simdjson_really_inline object::iterator object::begin() noexcept {
|
||||
return *this;
|
||||
|
@ -135,7 +135,7 @@ simdjson_really_inline object::iterator &object::iterator::operator=(const objec
|
|||
simdjson_really_inline simdjson_result<field> object::iterator::operator*() noexcept {
|
||||
if (o->error) { return o->report_error(); }
|
||||
if (o->at_start) { o->at_start = false; }
|
||||
return field::start(o->iter);
|
||||
return field::start(o->iter.borrow());
|
||||
}
|
||||
simdjson_really_inline bool object::iterator::operator==(const object::iterator &) noexcept {
|
||||
return !o->has_next;
|
||||
|
|
|
@ -51,8 +51,8 @@ protected:
|
|||
* @param doc The document containing the object. The iterator must be just after the opening `{`.
|
||||
* @param error If this is not SUCCESS, creates an error chained object.
|
||||
*/
|
||||
static simdjson_really_inline simdjson_result<object> start(json_iterator *iter) noexcept;
|
||||
static simdjson_really_inline object started(json_iterator *iter) noexcept;
|
||||
static simdjson_really_inline simdjson_result<object> start(json_iterator_ref &&iter) noexcept;
|
||||
static simdjson_really_inline object started(json_iterator_ref &&iter) noexcept;
|
||||
|
||||
/**
|
||||
* Internal object creation. Call object::begin(doc) instead of this.
|
||||
|
@ -62,7 +62,7 @@ protected:
|
|||
* @param is_empty Whether this container is empty or not.
|
||||
* @param error The error to report. If the error is not SUCCESS, this is an error chained object.
|
||||
*/
|
||||
simdjson_really_inline object(json_iterator *_iter, bool is_empty) noexcept;
|
||||
simdjson_really_inline object(json_iterator_ref &&_iter, bool is_empty) noexcept;
|
||||
|
||||
simdjson_really_inline error_code report_error() noexcept;
|
||||
|
||||
|
@ -72,7 +72,7 @@ protected:
|
|||
* PERF NOTE: expected to be elided in favor of the parent document: this is set when the object
|
||||
* is first used, and never changes afterwards.
|
||||
*/
|
||||
json_iterator *iter{};
|
||||
json_iterator_ref iter{};
|
||||
/**
|
||||
* Whether we have anything to yield.
|
||||
*
|
||||
|
|
|
@ -3,17 +3,23 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
namespace ondemand {
|
||||
|
||||
simdjson_really_inline value::value() noexcept = default;
|
||||
simdjson_really_inline value::value(value &&other) noexcept {
|
||||
*this = std::forward<value>(other);
|
||||
simdjson_really_inline value::value(value &&other) noexcept
|
||||
: iter{std::forward<value>(other).iter},
|
||||
json{other.json}
|
||||
{
|
||||
other.json = nullptr;
|
||||
};
|
||||
simdjson_really_inline value &value::operator=(value &&other) noexcept {
|
||||
iter = other.iter;
|
||||
iter = std::forward<value>(other).iter;
|
||||
json = other.json;
|
||||
other.json = nullptr;
|
||||
return *this;
|
||||
}
|
||||
simdjson_really_inline value::value(json_iterator *_iter, const uint8_t *_json) noexcept : iter{_iter}, json{_json} {
|
||||
SIMDJSON_ASSUME(iter != nullptr);
|
||||
simdjson_really_inline value::value(json_iterator_ref && _iter, const uint8_t *_json) noexcept
|
||||
: iter{std::forward<json_iterator_ref>(_iter)},
|
||||
json{_json}
|
||||
{
|
||||
SIMDJSON_ASSUME(iter.is_alive());
|
||||
SIMDJSON_ASSUME(json != nullptr);
|
||||
}
|
||||
|
||||
|
@ -32,8 +38,8 @@ simdjson_really_inline value::~value() noexcept {
|
|||
}
|
||||
}
|
||||
|
||||
simdjson_really_inline value value::start(json_iterator *iter) noexcept {
|
||||
return { iter, iter->advance() };
|
||||
simdjson_really_inline value value::start(json_iterator_ref &&iter) noexcept {
|
||||
return { std::forward<json_iterator_ref>(iter), iter->advance() };
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<array> value::get_array() noexcept {
|
||||
|
@ -42,7 +48,7 @@ simdjson_really_inline simdjson_result<array> value::get_array() noexcept {
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
json = nullptr; // Communicate that we have handled the value PERF TODO elided, right?
|
||||
return array::started(iter);
|
||||
return array::started(std::move(iter));
|
||||
}
|
||||
simdjson_really_inline simdjson_result<object> value::get_object() noexcept {
|
||||
if (*json != '{') {
|
||||
|
@ -50,7 +56,7 @@ simdjson_really_inline simdjson_result<object> value::get_object() noexcept {
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
json = nullptr; // Communicate that we have handled the value PERF TODO elided, right?
|
||||
return object::started(iter);
|
||||
return object::started(std::move(iter));
|
||||
}
|
||||
simdjson_really_inline simdjson_result<raw_json_string> value::get_raw_json_string() noexcept {
|
||||
log_value("string");
|
||||
|
|
|
@ -59,7 +59,7 @@ protected:
|
|||
*
|
||||
* Use value::read() instead of this.
|
||||
*/
|
||||
simdjson_really_inline value(json_iterator *iter, const uint8_t *json) noexcept;
|
||||
simdjson_really_inline value(json_iterator_ref &&iter, const uint8_t *json) noexcept;
|
||||
|
||||
/**
|
||||
* Read a value.
|
||||
|
@ -68,12 +68,12 @@ protected:
|
|||
*
|
||||
* @param doc The document containing the value. Iterator must be at the value start position.
|
||||
*/
|
||||
static simdjson_really_inline value start(json_iterator *iter) noexcept;
|
||||
static simdjson_really_inline value start(json_iterator_ref &&iter) noexcept;
|
||||
|
||||
simdjson_really_inline void log_value(const char *type) const noexcept;
|
||||
simdjson_really_inline void log_error(const char *message) const noexcept;
|
||||
|
||||
json_iterator *iter{}; // For the string buffer (if we need it)
|
||||
json_iterator_ref iter{}; // For the string buffer (if we need it)
|
||||
const uint8_t *json{}; // The JSON text of the value
|
||||
|
||||
friend class document;
|
||||
|
|
Loading…
Reference in New Issue