Make dom::document_stream::iterator copyable and default-constructible by holding pointer to document_stream instead of ref (#1463)
Co-authored-by: Alexey Rychkov <arychkov@defytrading.com>
This commit is contained in:
parent
a3d3e347a2
commit
9d22372cc9
|
@ -121,28 +121,32 @@ simdjson_really_inline document_stream::~document_stream() noexcept {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline document_stream::iterator::iterator() noexcept
|
||||||
|
: stream{nullptr}, finished{true} {
|
||||||
|
}
|
||||||
|
|
||||||
simdjson_really_inline document_stream::iterator document_stream::begin() noexcept {
|
simdjson_really_inline document_stream::iterator document_stream::begin() noexcept {
|
||||||
start();
|
start();
|
||||||
// If there are no documents, we're finished.
|
// If there are no documents, we're finished.
|
||||||
return iterator(*this, error == EMPTY);
|
return iterator(this, error == EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline document_stream::iterator document_stream::end() noexcept {
|
simdjson_really_inline document_stream::iterator document_stream::end() noexcept {
|
||||||
return iterator(*this, true);
|
return iterator(this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline document_stream::iterator::iterator(document_stream& _stream, bool is_end) noexcept
|
simdjson_really_inline document_stream::iterator::iterator(document_stream* _stream, bool is_end) noexcept
|
||||||
: stream{_stream}, finished{is_end} {
|
: stream{_stream}, finished{is_end} {
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline simdjson_result<element> document_stream::iterator::operator*() noexcept {
|
simdjson_really_inline document_stream::iterator::reference document_stream::iterator::operator*() noexcept {
|
||||||
// Note that in case of error, we do not yet mark
|
// Note that in case of error, we do not yet mark
|
||||||
// the iterator as "finished": this detection is done
|
// the iterator as "finished": this detection is done
|
||||||
// in the operator++ function since it is possible
|
// in the operator++ function since it is possible
|
||||||
// to call operator++ repeatedly while omitting
|
// to call operator++ repeatedly while omitting
|
||||||
// calls to operator*.
|
// calls to operator*.
|
||||||
if (stream.error) { return stream.error; }
|
if (stream->error) { return stream->error; }
|
||||||
return stream.parser->doc.root();
|
return stream->parser->doc.root();
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline document_stream::iterator& document_stream::iterator::operator++() noexcept {
|
simdjson_really_inline document_stream::iterator& document_stream::iterator::operator++() noexcept {
|
||||||
|
@ -156,16 +160,16 @@ simdjson_really_inline document_stream::iterator& document_stream::iterator::ope
|
||||||
//
|
//
|
||||||
// Note that setting finished = true is essential otherwise
|
// Note that setting finished = true is essential otherwise
|
||||||
// we would enter an infinite loop.
|
// we would enter an infinite loop.
|
||||||
if (stream.error) { finished = true; }
|
if (stream->error) { finished = true; }
|
||||||
// Note that stream.error() is guarded against error conditions
|
// Note that stream->error() is guarded against error conditions
|
||||||
// (it will immediately return if stream.error casts to false).
|
// (it will immediately return if stream->error casts to false).
|
||||||
// In effect, this next function does nothing when (stream.error)
|
// In effect, this next function does nothing when (stream->error)
|
||||||
// is true (hence the risk of an infinite loop).
|
// is true (hence the risk of an infinite loop).
|
||||||
stream.next();
|
stream->next();
|
||||||
// If that was the last document, we're finished.
|
// If that was the last document, we're finished.
|
||||||
// It is the only type of error we do not want to appear
|
// It is the only type of error we do not want to appear
|
||||||
// in operator*.
|
// in operator*.
|
||||||
if (stream.error == EMPTY) { finished = true; }
|
if (stream->error == EMPTY) { finished = true; }
|
||||||
// If we had any other kind of error (not EMPTY) then we want
|
// If we had any other kind of error (not EMPTY) then we want
|
||||||
// to pass it along to the operator* and we cannot mark the result
|
// to pass it along to the operator* and we cannot mark the result
|
||||||
// as "finished" just yet.
|
// as "finished" just yet.
|
||||||
|
@ -205,12 +209,12 @@ inline void document_stream::start() noexcept {
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline size_t document_stream::iterator::current_index() const noexcept {
|
simdjson_really_inline size_t document_stream::iterator::current_index() const noexcept {
|
||||||
return stream.doc_index;
|
return stream->doc_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
simdjson_really_inline std::string_view document_stream::iterator::source() const noexcept {
|
simdjson_really_inline std::string_view document_stream::iterator::source() const noexcept {
|
||||||
size_t next_doc_index = stream.batch_start + stream.parser->implementation->structural_indexes[stream.parser->implementation->next_structural_index];
|
size_t next_doc_index = stream->batch_start + stream->parser->implementation->structural_indexes[stream->parser->implementation->next_structural_index];
|
||||||
return std::string_view(reinterpret_cast<const char*>(stream.buf) + current_index(), next_doc_index - current_index() - 1);
|
return std::string_view(reinterpret_cast<const char*>(stream->buf) + current_index(), next_doc_index - current_index() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,12 +93,23 @@ public:
|
||||||
*/
|
*/
|
||||||
class iterator {
|
class iterator {
|
||||||
public:
|
public:
|
||||||
|
using value_type = simdjson_result<element>;
|
||||||
|
using reference = value_type;
|
||||||
|
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
using iterator_category = std::input_iterator_tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default contructor.
|
||||||
|
*/
|
||||||
|
simdjson_really_inline iterator() noexcept;
|
||||||
/**
|
/**
|
||||||
* Get the current document (or error).
|
* Get the current document (or error).
|
||||||
*/
|
*/
|
||||||
simdjson_really_inline simdjson_result<element> operator*() noexcept;
|
simdjson_really_inline reference operator*() noexcept;
|
||||||
/**
|
/**
|
||||||
* Advance to the next document.
|
* Advance to the next document (prefix).
|
||||||
*/
|
*/
|
||||||
inline iterator& operator++() noexcept;
|
inline iterator& operator++() noexcept;
|
||||||
/**
|
/**
|
||||||
|
@ -144,9 +155,9 @@ public:
|
||||||
simdjson_really_inline std::string_view source() const noexcept;
|
simdjson_really_inline std::string_view source() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
simdjson_really_inline iterator(document_stream &s, bool finished) noexcept;
|
simdjson_really_inline iterator(document_stream *s, bool finished) noexcept;
|
||||||
/** The document_stream we're iterating through. */
|
/** The document_stream we're iterating through. */
|
||||||
document_stream& stream;
|
document_stream* stream;
|
||||||
/** Whether we're finished or not. */
|
/** Whether we're finished or not. */
|
||||||
bool finished;
|
bool finished;
|
||||||
friend class document_stream;
|
friend class document_stream;
|
||||||
|
|
Loading…
Reference in New Issue