Skip to content

Commit

Permalink
Allow some iterators to be used in standard C++ iterator functions (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Bo98 committed Feb 5, 2024
1 parent 23290ae commit 33610b5
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 9 deletions.
5 changes: 4 additions & 1 deletion include/simdjson/dom/array.h
Expand Up @@ -19,11 +19,14 @@ class array {
public:
using value_type = element;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = value_type;
using iterator_category = std::forward_iterator_tag;

/**
* Get the actual value
*/
inline value_type operator*() const noexcept;
inline reference operator*() const noexcept;
/**
* Get the next value.
*
Expand Down
7 changes: 5 additions & 2 deletions include/simdjson/dom/object.h
Expand Up @@ -18,13 +18,16 @@ class object {

class iterator {
public:
using value_type = key_value_pair;
using value_type = const key_value_pair;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = value_type;
using iterator_category = std::forward_iterator_tag;

/**
* Get the actual key/value pair
*/
inline const value_type operator*() const noexcept;
inline reference operator*() const noexcept;
/**
* Get the next key/value pair.
*
Expand Down
9 changes: 4 additions & 5 deletions include/simdjson/generic/ondemand/document_stream.h
Expand Up @@ -122,10 +122,9 @@ class document_stream {
class iterator {
public:
using value_type = simdjson_result<document>;
using reference = value_type;

using reference = simdjson_result<ondemand::document_reference>;
using pointer = void;
using difference_type = std::ptrdiff_t;

using iterator_category = std::input_iterator_tag;

/**
Expand All @@ -135,7 +134,7 @@ class document_stream {
/**
* Get the current document (or error).
*/
simdjson_inline simdjson_result<ondemand::document_reference> operator*() noexcept;
simdjson_inline reference operator*() noexcept;
/**
* Advance to the next document (prefix).
*/
Expand Down Expand Up @@ -335,4 +334,4 @@ struct simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_stream> : pub

} // namespace simdjson

#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H
#endif // SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H
39 changes: 39 additions & 0 deletions tests/dom/basictests.cpp
Expand Up @@ -912,6 +912,43 @@ namespace dom_api_tests {
return true;
}

bool object_iterator_advance() {
std::cout << "Running " << __func__ << std::endl;
string json(R"({ "a": 1, "b": 2, "c": 3 })");
const char* expected_key[] = { "a", "b", "c" };
uint64_t expected_value[] = { 1, 2, 3 };

dom::parser parser;
dom::object object;
ASSERT_SUCCESS( parser.parse(json).get(object) );
auto iter = object.begin();
for (auto i = 0; i * sizeof(expected_value[0]) < sizeof(expected_value); i++) {
auto [key, value] = *iter;
ASSERT_EQUAL( key, expected_key[i] );
ASSERT_EQUAL( value.get_uint64().value_unsafe(), expected_value[i] );
std::advance( iter, 1 );
}
return true;
}

bool array_iterator_advance() {
std::cout << "Running " << __func__ << std::endl;
string json(R"([ 1, 10, 100 ])");
uint64_t expected_value[] = { 1, 10, 100 };

dom::parser parser;
dom::array array;
ASSERT_SUCCESS( parser.parse(json).get(array) );
auto iter = array.begin();
for (auto i = 0; i * sizeof(expected_value[0]) < sizeof(expected_value); i++) {
uint64_t v;
ASSERT_SUCCESS( (*iter).get(v) );
ASSERT_EQUAL( v, expected_value[i] );
std::advance( iter, 1 );
}
return true;
}

bool string_value() {
std::cout << "Running " << __func__ << std::endl;
string json(R"([ "hi", "has backslash\\" ])");
Expand Down Expand Up @@ -1291,6 +1328,8 @@ namespace dom_api_tests {
array_iterator() &&
object_iterator_empty() &&
array_iterator_empty() &&
object_iterator_advance() &&
array_iterator_advance() &&
string_value() &&
numeric_values() &&
boolean_values() &&
Expand Down
21 changes: 20 additions & 1 deletion tests/ondemand/ondemand_document_stream_tests.cpp
Expand Up @@ -322,6 +322,24 @@ namespace document_stream_tests {
TEST_SUCCEED();
}

bool simple_document_iteration_advance() {
TEST_START();
auto json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])"_padded;
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
std::string_view expected[4] = {"[1,[1,2]]", "{\"a\":1,\"b\":2}", "{\"o\":{\"1\":1,\"2\":2}}", "[1,2,3]"};
auto iter = stream.begin();
for (auto i = 0; i < 4; i++) {
auto doc = *iter;
std::string_view view;
ASSERT_SUCCESS(to_json_string(doc).get(view));
ASSERT_EQUAL(view, expected[i]);
std::advance(iter, 1);
}
TEST_SUCCEED();
}

bool skipbom() {
TEST_START();
auto json = "\xEF\xBB\xBF[1,[1,2]] {\"a\":1,\"b\":2} {\"o\":{\"1\":1,\"2\":2}} [1,2,3]"_padded;
Expand Down Expand Up @@ -856,6 +874,7 @@ namespace document_stream_tests {
simple_document_iteration() &&
simple_document_iteration_multiple_batches() &&
simple_document_iteration_with_parsing() &&
simple_document_iteration_advance() &&
atoms_json() &&
doc_index() &&
doc_index_multiple_batches() &&
Expand All @@ -879,4 +898,4 @@ namespace document_stream_tests {

int main (int argc, char *argv[]) {
return test_main(argc, argv, document_stream_tests::run);
}
}

0 comments on commit 33610b5

Please sign in to comment.