Iterate value without going through indirection
Avoids issues with value being released early
This commit is contained in:
parent
fe7a4d42d3
commit
8fd0cdc732
|
@ -40,7 +40,7 @@ simdjson_really_inline bool OnDemand::Run(const padded_string &json) {
|
|||
|
||||
// Walk the document, parsing the tweets as we go
|
||||
auto doc = parser.iterate(json);
|
||||
for (ondemand::object tweet : doc["statuses"].get_array()) {
|
||||
for (ondemand::object tweet : doc["statuses"]) {
|
||||
tweets.emplace_back(partial_tweets::tweet{
|
||||
tweet["created_at"],
|
||||
tweet["id"],
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "generic/ondemand/raw_json_string.h"
|
||||
#include "generic/ondemand/token_iterator.h"
|
||||
#include "generic/ondemand/json_iterator.h"
|
||||
#include "generic/ondemand/array_iterator.h"
|
||||
#include "generic/ondemand/object_iterator.h"
|
||||
#include "generic/ondemand/array.h"
|
||||
#include "generic/ondemand/document.h"
|
||||
#include "generic/ondemand/value.h"
|
||||
|
@ -13,6 +15,8 @@
|
|||
#include "generic/ondemand/raw_json_string-inl.h"
|
||||
#include "generic/ondemand/token_iterator-inl.h"
|
||||
#include "generic/ondemand/json_iterator-inl.h"
|
||||
#include "generic/ondemand/array_iterator-inl.h"
|
||||
#include "generic/ondemand/object_iterator-inl.h"
|
||||
#include "generic/ondemand/array-inl.h"
|
||||
#include "generic/ondemand/document-inl.h"
|
||||
#include "generic/ondemand/value-inl.h"
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace ondemand {
|
|||
|
||||
simdjson_really_inline array::array() noexcept = default;
|
||||
simdjson_really_inline array::array(json_iterator_ref &&_iter) noexcept
|
||||
: iter{std::forward<json_iterator_ref>(_iter)}, error{SUCCESS}
|
||||
: iter{std::forward<json_iterator_ref>(_iter)}
|
||||
{
|
||||
}
|
||||
simdjson_really_inline array::array(array &&other) noexcept = default;
|
||||
|
@ -66,36 +66,14 @@ simdjson_really_inline array array::started(json_iterator_ref &&iter) noexcept {
|
|||
if (!iter->started_array()) { iter.release(); }
|
||||
return array(std::forward<json_iterator_ref>(iter));
|
||||
}
|
||||
simdjson_really_inline array::iterator array::begin() & noexcept {
|
||||
return *this;
|
||||
|
||||
simdjson_really_inline array_iterator array::begin() & noexcept {
|
||||
return iter;
|
||||
}
|
||||
simdjson_really_inline array::iterator array::end() & noexcept {
|
||||
simdjson_really_inline array_iterator array::end() & noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
simdjson_really_inline array::iterator::iterator(array &_a) noexcept : a{&_a} {}
|
||||
|
||||
simdjson_really_inline array::iterator::iterator() noexcept = default;
|
||||
simdjson_really_inline array::iterator::iterator(const array::iterator &_a) noexcept = default;
|
||||
simdjson_really_inline array::iterator &array::iterator::operator=(const array::iterator &_a) noexcept = default;
|
||||
|
||||
simdjson_really_inline simdjson_result<value> array::iterator::operator*() noexcept {
|
||||
if (a->error) { a->iter.release(); return a->error; }
|
||||
return value::start(a->iter.borrow());
|
||||
}
|
||||
simdjson_really_inline bool array::iterator::operator==(const array::iterator &other) noexcept {
|
||||
return !(*this != other);
|
||||
}
|
||||
simdjson_really_inline bool array::iterator::operator!=(const array::iterator &) noexcept {
|
||||
return a->iter.is_alive();
|
||||
}
|
||||
simdjson_really_inline array::iterator &array::iterator::operator++() noexcept {
|
||||
bool has_value;
|
||||
a->error = a->iter->has_next_element().get(has_value); // If there's an error, has_next stays true.
|
||||
if (!(a->error || has_value)) { a->iter.release(); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // unnamed namespace
|
||||
|
@ -117,69 +95,13 @@ simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>
|
|||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::begin() & noexcept {
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::begin() & noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.begin();
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::end() & noexcept {
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array>::end() & noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.end();
|
||||
}
|
||||
|
||||
//
|
||||
// array::iterator
|
||||
//
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>({}, SUCCESS)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::simdjson_result(
|
||||
SIMDJSON_IMPLEMENTATION::ondemand::array::iterator &&value
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>(value))
|
||||
{
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>({}, error)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::simdjson_result(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &a
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>(a)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::operator=(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &a
|
||||
) noexcept {
|
||||
first = a.first;
|
||||
second = a.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::operator*() noexcept {
|
||||
if (error()) { second = SUCCESS; return error(); }
|
||||
return *first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &other) noexcept {
|
||||
if (error()) { return true; }
|
||||
return first == other.first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &other) noexcept {
|
||||
if (error()) { return false; }
|
||||
return first != other.first;
|
||||
}
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator>::operator++() noexcept {
|
||||
if (error()) { return *this; }
|
||||
++first;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -19,33 +19,8 @@ public:
|
|||
array(const array &) = delete;
|
||||
array &operator=(const array &) = delete;
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
simdjson_really_inline iterator(array &a) noexcept;
|
||||
simdjson_really_inline iterator(const array::iterator &a) noexcept;
|
||||
simdjson_really_inline iterator &operator=(const array::iterator &a) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<value> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const array::iterator &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const array::iterator &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline array::iterator &operator++() noexcept;
|
||||
private:
|
||||
array *a{};
|
||||
simdjson_really_inline iterator() noexcept;
|
||||
friend class array;
|
||||
friend struct simdjson_result<array::iterator>;
|
||||
};
|
||||
|
||||
simdjson_really_inline array::iterator begin() & noexcept;
|
||||
simdjson_really_inline array::iterator end() & noexcept;
|
||||
simdjson_really_inline array_iterator begin() & noexcept;
|
||||
simdjson_really_inline array_iterator end() & noexcept;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -77,15 +52,6 @@ protected:
|
|||
* is first used, and never changes afterwards.
|
||||
*/
|
||||
json_iterator_ref iter{};
|
||||
/**
|
||||
* Error, if there is one. Errors are only yielded once.
|
||||
*
|
||||
* PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first
|
||||
* iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If
|
||||
* this is not elided, we should make sure it's at least not using up a register. Failing that,
|
||||
* we should store it in document so there's only one of them.
|
||||
*/
|
||||
error_code error{};
|
||||
|
||||
friend class value;
|
||||
friend struct simdjson_result<value>;
|
||||
|
@ -104,31 +70,8 @@ public:
|
|||
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::array &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> begin() & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> end() & noexcept;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> : public internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> {
|
||||
public:
|
||||
simdjson_really_inline simdjson_result() noexcept;
|
||||
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::array::iterator &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &a) noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &operator=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &a) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> &operator++() noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> begin() & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept;
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace ondemand {
|
||||
|
||||
simdjson_really_inline array_iterator::array_iterator(json_iterator_ref &_iter) noexcept : iter{&_iter} {}
|
||||
|
||||
simdjson_really_inline array_iterator::array_iterator() noexcept = default;
|
||||
simdjson_really_inline array_iterator::array_iterator(const array_iterator &_a) noexcept = default;
|
||||
simdjson_really_inline array_iterator &array_iterator::operator=(const array_iterator &_a) noexcept = default;
|
||||
|
||||
simdjson_really_inline simdjson_result<value> array_iterator::operator*() noexcept {
|
||||
if (error) { iter->release(); return error; }
|
||||
return value::start(iter->borrow());
|
||||
}
|
||||
simdjson_really_inline bool array_iterator::operator==(const array_iterator &other) noexcept {
|
||||
return !(*this != other);
|
||||
}
|
||||
simdjson_really_inline bool array_iterator::operator!=(const array_iterator &) noexcept {
|
||||
return iter->is_alive();
|
||||
}
|
||||
simdjson_really_inline array_iterator &array_iterator::operator++() noexcept {
|
||||
bool has_value;
|
||||
error = (*iter)->has_next_element().get(has_value); // If there's an error, has_next stays true.
|
||||
if (!(error || has_value)) { iter->release(); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // unnamed namespace
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>({}, SUCCESS)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result(
|
||||
SIMDJSON_IMPLEMENTATION::ondemand::array_iterator &&value
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(value))
|
||||
{
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>({}, error)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::simdjson_result(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>(a)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::operator=(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a
|
||||
) noexcept {
|
||||
first = a.first;
|
||||
second = a.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::operator*() noexcept {
|
||||
if (error()) { second = SUCCESS; return error(); }
|
||||
return *first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &other) noexcept {
|
||||
if (error()) { return true; }
|
||||
return first == other.first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &other) noexcept {
|
||||
if (error()) { return false; }
|
||||
return first != other.first;
|
||||
}
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator>::operator++() noexcept {
|
||||
if (error()) { return *this; }
|
||||
++first;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace simdjson
|
|
@ -0,0 +1,78 @@
|
|||
#include "simdjson/error.h"
|
||||
|
||||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace ondemand {
|
||||
|
||||
class value;
|
||||
class document;
|
||||
|
||||
/**
|
||||
* A forward-only JSON array.
|
||||
*/
|
||||
class array_iterator {
|
||||
public:
|
||||
simdjson_really_inline array_iterator(json_iterator_ref &iter) noexcept;
|
||||
simdjson_really_inline array_iterator(const array_iterator &a) noexcept;
|
||||
simdjson_really_inline array_iterator &operator=(const array_iterator &a) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<value> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const array_iterator &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const array_iterator &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline array_iterator &operator++() noexcept;
|
||||
private:
|
||||
json_iterator_ref *iter{};
|
||||
/**
|
||||
* Error, if there is one. Errors are only yielded once.
|
||||
*
|
||||
* PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first
|
||||
* iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If
|
||||
* this is not elided, we should make sure it's at least not using up a register. Failing that,
|
||||
* we should store it in document so there's only one of them.
|
||||
*/
|
||||
error_code error{};
|
||||
|
||||
simdjson_really_inline array_iterator() noexcept;
|
||||
|
||||
friend class array;
|
||||
friend struct simdjson_result<array_iterator>;
|
||||
};
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // unnamed namespace
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
template<>
|
||||
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> : public internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> {
|
||||
public:
|
||||
simdjson_really_inline simdjson_result() noexcept;
|
||||
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::array_iterator &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a) noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &operator=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &a) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> &operator++() noexcept;
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
|
@ -22,7 +22,7 @@ protected:
|
|||
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;
|
||||
friend class object_iterator;
|
||||
};
|
||||
|
||||
} // namespace ondemand
|
||||
|
|
|
@ -46,8 +46,7 @@ namespace ondemand {
|
|||
simdjson_really_inline object::object() noexcept = default;
|
||||
simdjson_really_inline object::object(json_iterator_ref &&_iter) noexcept
|
||||
: iter{std::forward<json_iterator_ref>(_iter)},
|
||||
at_start{true},
|
||||
error{SUCCESS}
|
||||
at_start{true}
|
||||
{
|
||||
}
|
||||
simdjson_really_inline object::object(object &&other) noexcept = default;
|
||||
|
@ -63,22 +62,22 @@ simdjson_really_inline object::~object() noexcept {
|
|||
}
|
||||
|
||||
simdjson_really_inline error_code object::find_field(const std::string_view key) noexcept {
|
||||
if (error) { return report_error(); }
|
||||
if (!iter.is_alive()) { return NO_SUCH_FIELD; }
|
||||
|
||||
// Unless this is the first field, we need to advance past the , and check for }
|
||||
error_code error;
|
||||
bool has_value;
|
||||
if (at_start) {
|
||||
at_start = false;
|
||||
has_value = true;
|
||||
} else {
|
||||
if ((error = iter->has_next_field().get(has_value) )) { return report_error(); }
|
||||
if ((error = iter->has_next_field().get(has_value) )) { iter.release(); return error; }
|
||||
}
|
||||
while (has_value) {
|
||||
// Get the key
|
||||
raw_json_string actual_key;
|
||||
if ((error = iter->field_key().get(actual_key) )) { return report_error(); };
|
||||
if ((error = iter->field_value() )) { return report_error(); }
|
||||
if ((error = iter->field_key().get(actual_key) )) { iter.release(); return error; };
|
||||
if ((error = iter->field_value() )) { iter.release(); return error; }
|
||||
|
||||
// Check if it matches
|
||||
if (actual_key == key) {
|
||||
|
@ -87,7 +86,7 @@ simdjson_really_inline error_code object::find_field(const std::string_view key)
|
|||
}
|
||||
logger::log_event(*iter, "no match", key, -2);
|
||||
SIMDJSON_TRY( iter->skip() ); // Skip the value entirely
|
||||
if ((error = iter->has_next_field().get(has_value) )) { return report_error(); }
|
||||
if ((error = iter->has_next_field().get(has_value) )) { iter.release(); return error; }
|
||||
}
|
||||
|
||||
// If the loop ended, we're out of fields to look at.
|
||||
|
@ -115,46 +114,13 @@ simdjson_really_inline object object::started(json_iterator_ref &&iter) noexcept
|
|||
if (!iter->started_object()) { iter.release(); }
|
||||
return object(std::forward<json_iterator_ref>(iter));
|
||||
}
|
||||
simdjson_really_inline object::iterator object::begin() noexcept {
|
||||
return *this;
|
||||
simdjson_really_inline object_iterator object::begin() noexcept {
|
||||
SIMDJSON_ASSUME(!iter.is_alive() || at_start);
|
||||
at_start = false;
|
||||
return iter;
|
||||
}
|
||||
simdjson_really_inline object::iterator object::end() noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
simdjson_really_inline error_code object::report_error() noexcept {
|
||||
SIMDJSON_ASSUME(error);
|
||||
iter.release();
|
||||
return error;
|
||||
}
|
||||
|
||||
//
|
||||
// object::iterator
|
||||
//
|
||||
|
||||
simdjson_really_inline object::iterator::iterator(object &_o) noexcept : o{&_o} {}
|
||||
|
||||
simdjson_really_inline object::iterator::iterator() noexcept = default;
|
||||
simdjson_really_inline object::iterator::iterator(const object::iterator &_o) noexcept = default;
|
||||
simdjson_really_inline object::iterator &object::iterator::operator=(const object::iterator &_o) noexcept = default;
|
||||
|
||||
simdjson_really_inline simdjson_result<field> object::iterator::operator*() noexcept {
|
||||
if (o->error) { return o->report_error(); }
|
||||
return field::start(o->iter.borrow());
|
||||
}
|
||||
simdjson_really_inline bool object::iterator::operator==(const object::iterator &other) noexcept {
|
||||
return !(*this != other);
|
||||
}
|
||||
simdjson_really_inline bool object::iterator::operator!=(const object::iterator &) noexcept {
|
||||
return o->iter.is_alive();
|
||||
}
|
||||
simdjson_really_inline object::iterator &object::iterator::operator++() noexcept {
|
||||
if (o->error) { return *this; }
|
||||
o->at_start = false;
|
||||
bool has_value;
|
||||
o->error = o->iter->has_next_field().get(has_value);
|
||||
if (!(o->error || has_value)) { o->iter.release(); }
|
||||
return *this;
|
||||
simdjson_really_inline object_iterator object::end() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
|
@ -168,13 +134,13 @@ simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object
|
|||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object>(error) {}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::begin() noexcept {
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::begin() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return SIMDJSON_IMPLEMENTATION::ondemand::object::iterator(first);
|
||||
return first.begin();
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::end() noexcept {
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::end() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return {};
|
||||
return first.end();
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object>::operator[](std::string_view key) & noexcept {
|
||||
if (error()) { return error(); }
|
||||
|
@ -185,60 +151,4 @@ simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>
|
|||
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object>(first)[key];
|
||||
}
|
||||
|
||||
//
|
||||
// object::iterator
|
||||
//
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>({}, SUCCESS)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::simdjson_result(
|
||||
SIMDJSON_IMPLEMENTATION::ondemand::object::iterator &&value
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>(value))
|
||||
{
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>({}, error)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::simdjson_result(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &o
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>(o)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::operator=(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &o
|
||||
) noexcept {
|
||||
first = o.first;
|
||||
second = o.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::field> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::operator*() noexcept {
|
||||
if (error()) { second = SUCCESS; return error(); }
|
||||
return *first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &other) noexcept {
|
||||
if (error()) { return true; }
|
||||
return first == other.first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &other) noexcept {
|
||||
if (error()) { return false; }
|
||||
return first != other.first;
|
||||
}
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator>::operator++() noexcept {
|
||||
if (error()) { return *this; }
|
||||
++first;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -16,32 +16,8 @@ public:
|
|||
object(const object &) = delete;
|
||||
object &operator=(const object &) = delete;
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
simdjson_really_inline iterator(object &o) noexcept;
|
||||
simdjson_really_inline iterator(const object::iterator &o) noexcept;
|
||||
simdjson_really_inline iterator &operator=(const object::iterator &o) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<field> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const object::iterator &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const object::iterator &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline object::iterator &operator++() noexcept;
|
||||
private:
|
||||
object *o{};
|
||||
simdjson_really_inline iterator() noexcept;
|
||||
friend struct simdjson_result<object::iterator>;
|
||||
};
|
||||
|
||||
simdjson_really_inline object::iterator begin() noexcept;
|
||||
simdjson_really_inline object::iterator end() noexcept;
|
||||
simdjson_really_inline object_iterator begin() noexcept;
|
||||
simdjson_really_inline object_iterator end() noexcept;
|
||||
simdjson_really_inline simdjson_result<value> operator[](const std::string_view key) & noexcept;
|
||||
simdjson_really_inline simdjson_result<value> operator[](const std::string_view key) && noexcept;
|
||||
|
||||
|
@ -63,8 +39,6 @@ protected:
|
|||
*/
|
||||
simdjson_really_inline object(json_iterator_ref &&_iter) noexcept;
|
||||
|
||||
simdjson_really_inline error_code report_error() noexcept;
|
||||
|
||||
simdjson_really_inline error_code find_field(const std::string_view key) noexcept;
|
||||
|
||||
/**
|
||||
|
@ -81,15 +55,6 @@ protected:
|
|||
* or * call, and SSA optimizers commonly do first-iteration loop optimization.
|
||||
*/
|
||||
bool at_start{};
|
||||
/**
|
||||
* Error, if there is one. Errors are only yielded once.
|
||||
*
|
||||
* PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first
|
||||
* iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If
|
||||
* this is not elided, we should make sure it's at least not using up a register. Failing that,
|
||||
* we should store it in document so there's only one of them.
|
||||
*/
|
||||
error_code error{};
|
||||
|
||||
friend class value;
|
||||
friend class document;
|
||||
|
@ -108,33 +73,10 @@ public:
|
|||
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::object &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> begin() noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> end() noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> begin() noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> end() noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) && noexcept;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> : public internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> {
|
||||
public:
|
||||
simdjson_really_inline simdjson_result() noexcept;
|
||||
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::object::iterator &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &a) noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &operator=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &a) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::field> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object::iterator> &operator++() noexcept;
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace ondemand {
|
||||
|
||||
//
|
||||
// object_iterator
|
||||
//
|
||||
|
||||
simdjson_really_inline object_iterator::object_iterator(json_iterator_ref &_iter) noexcept : iter{&_iter} {}
|
||||
|
||||
simdjson_really_inline object_iterator::object_iterator() noexcept = default;
|
||||
simdjson_really_inline object_iterator::object_iterator(const object_iterator &_o) noexcept = default;
|
||||
simdjson_really_inline object_iterator &object_iterator::operator=(const object_iterator &_o) noexcept = default;
|
||||
|
||||
simdjson_really_inline simdjson_result<field> object_iterator::operator*() noexcept {
|
||||
if (error) { iter->release(); return error; }
|
||||
return field::start(iter->borrow());
|
||||
}
|
||||
simdjson_really_inline bool object_iterator::operator==(const object_iterator &other) noexcept {
|
||||
return !(*this != other);
|
||||
}
|
||||
simdjson_really_inline bool object_iterator::operator!=(const object_iterator &) noexcept {
|
||||
return iter->is_alive();
|
||||
}
|
||||
simdjson_really_inline object_iterator &object_iterator::operator++() noexcept {
|
||||
if (error) { return *this; }
|
||||
bool has_value;
|
||||
error = (*iter)->has_next_field().get(has_value);
|
||||
if (!(error || has_value)) { iter->release(); }
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // unnamed namespace
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>({}, SUCCESS)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::simdjson_result(
|
||||
SIMDJSON_IMPLEMENTATION::ondemand::object_iterator &&value
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>(value))
|
||||
{
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>({}, error)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::simdjson_result(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &o
|
||||
) noexcept
|
||||
: internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>(o)
|
||||
{
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::operator=(
|
||||
const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &o
|
||||
) noexcept {
|
||||
first = o.first;
|
||||
second = o.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::field> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::operator*() noexcept {
|
||||
if (error()) { second = SUCCESS; return error(); }
|
||||
return *first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &other) noexcept {
|
||||
if (error()) { return true; }
|
||||
return first == other.first;
|
||||
}
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &other) noexcept {
|
||||
if (error()) { return false; }
|
||||
return first != other.first;
|
||||
}
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator>::operator++() noexcept {
|
||||
if (error()) { return *this; }
|
||||
++first;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace simdjson
|
|
@ -0,0 +1,73 @@
|
|||
#include "simdjson/error.h"
|
||||
|
||||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace ondemand {
|
||||
|
||||
class field;
|
||||
|
||||
class object_iterator {
|
||||
public:
|
||||
simdjson_really_inline object_iterator(json_iterator_ref &iter) noexcept;
|
||||
simdjson_really_inline object_iterator(const object_iterator &o) noexcept;
|
||||
simdjson_really_inline object_iterator &operator=(const object_iterator &o) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
// MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
simdjson_really_inline simdjson_result<field> operator*() noexcept;
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const object_iterator &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const object_iterator &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline object_iterator &operator++() noexcept;
|
||||
private:
|
||||
json_iterator_ref *iter{};
|
||||
/**
|
||||
* Error, if there is one. Errors are only yielded once.
|
||||
*
|
||||
* PERF NOTE: we *hope* this will be elided into control flow, as it is only used (a) in the first
|
||||
* iteration of the loop, or (b) for the final iteration after a missing comma is found in ++. If
|
||||
* this is not elided, we should make sure it's at least not using up a register. Failing that,
|
||||
* we should store it in document so there's only one of them.
|
||||
*/
|
||||
error_code error{};
|
||||
simdjson_really_inline object_iterator() noexcept;
|
||||
friend struct simdjson_result<object_iterator>;
|
||||
friend class object;
|
||||
};
|
||||
|
||||
} // namespace ondemand
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
} // unnamed namespace
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
template<>
|
||||
struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> : public internal::simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> {
|
||||
public:
|
||||
simdjson_really_inline simdjson_result() noexcept;
|
||||
simdjson_really_inline simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::object_iterator &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &a) noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &operator=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &a) noexcept;
|
||||
|
||||
//
|
||||
// Iterator interface
|
||||
//
|
||||
|
||||
// Reads key and value, yielding them to the user.
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::field> operator*() noexcept; // MUST ONLY BE CALLED ONCE PER ITERATION.
|
||||
// Assumes it's being compared with the end. true if depth < iter->depth.
|
||||
simdjson_really_inline bool operator==(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &) noexcept;
|
||||
// Assumes it's being compared with the end. true if depth >= iter->depth.
|
||||
simdjson_really_inline bool operator!=(const simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &) noexcept;
|
||||
// Checks for ']' and ','
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object_iterator> &operator++() noexcept;
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
|
@ -141,6 +141,17 @@ simdjson_really_inline value::operator bool() && noexcept(false) {
|
|||
}
|
||||
#endif
|
||||
|
||||
simdjson_really_inline simdjson_result<array_iterator> value::begin() & noexcept {
|
||||
if (*json != '[') {
|
||||
log_error("not an array");
|
||||
return INCORRECT_TYPE;
|
||||
}
|
||||
if (!iter->started_array()) { iter.release(); }
|
||||
return array_iterator(iter);
|
||||
}
|
||||
simdjson_really_inline simdjson_result<array_iterator> value::end() & noexcept {
|
||||
return {};
|
||||
}
|
||||
simdjson_really_inline simdjson_result<value> value::operator[](std::string_view key) && noexcept {
|
||||
return std::forward<value>(*this).get_object()[key];
|
||||
}
|
||||
|
@ -188,14 +199,14 @@ simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>
|
|||
{
|
||||
}
|
||||
|
||||
// simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::begin() & noexcept {
|
||||
// if (error()) { return error(); }
|
||||
// return std::move(first).get_array().begin();
|
||||
// }
|
||||
// simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::end() & noexcept {
|
||||
// if (error()) { return error(); }
|
||||
// return {};
|
||||
// }
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::begin() & noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.begin();
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::end() & noexcept {
|
||||
if (error()) { return error(); }
|
||||
return {};
|
||||
}
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::operator[](std::string_view key) noexcept {
|
||||
if (error()) { return error(); }
|
||||
return std::forward<SIMDJSON_IMPLEMENTATION::ondemand::value>(first)[key];
|
||||
|
|
|
@ -9,6 +9,7 @@ class document;
|
|||
class field;
|
||||
class object;
|
||||
class raw_json_string;
|
||||
class array_iterator;
|
||||
|
||||
/**
|
||||
* An ephemeral JSON value returned during iteration.
|
||||
|
@ -49,8 +50,8 @@ public:
|
|||
simdjson_really_inline operator bool() && noexcept(false);
|
||||
#endif
|
||||
|
||||
// simdjson_really_inline simdjson_result<array_iterator<value>> begin() & noexcept;
|
||||
// simdjson_really_inline simdjson_result<array_iterator<value>> end() & noexcept;
|
||||
simdjson_really_inline simdjson_result<array_iterator> begin() & noexcept;
|
||||
simdjson_really_inline simdjson_result<array_iterator> end() & noexcept;
|
||||
simdjson_really_inline simdjson_result<value> operator[](std::string_view key) && noexcept;
|
||||
simdjson_really_inline simdjson_result<value> operator[](const char *key) && noexcept;
|
||||
|
||||
|
@ -78,7 +79,7 @@ protected:
|
|||
const uint8_t *json{}; // The JSON text of the value
|
||||
|
||||
friend class document;
|
||||
friend class array;
|
||||
friend class array_iterator;
|
||||
friend class field;
|
||||
friend class object;
|
||||
friend struct simdjson_result<value>;
|
||||
|
@ -121,8 +122,8 @@ public:
|
|||
simdjson_really_inline operator bool() && noexcept(false);
|
||||
#endif
|
||||
|
||||
// simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> begin() & noexcept;
|
||||
// simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array::iterator> end() & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> begin() & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array_iterator> end() & noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](std::string_view key) noexcept;
|
||||
simdjson_really_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> operator[](const char *key) noexcept;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue