count_elements did not like empty arrays. (#1631)
* count_elements did not like empty arrays. * Minor cleaning. * I don't understand. * More cleaning.
This commit is contained in:
parent
1ba73b9e6b
commit
5b99a75ae1
|
@ -73,6 +73,9 @@ simdjson_really_inline simdjson_result<array_iterator> array::end() 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; }
|
||||
// The count_elements method should always be called before you have begun
|
||||
// iterating through the array.
|
||||
// To open a new array you need to be at a `[`.
|
||||
|
@ -80,15 +83,14 @@ simdjson_really_inline simdjson_result<size_t> array::count_elements() & noexcep
|
|||
// array::begin() makes the same check.
|
||||
if(!iter.is_at_container_start()) { return OUT_OF_ORDER_ITERATION; }
|
||||
#endif
|
||||
// Otherwise, we need to iterate through the array.
|
||||
iter.enter_at_container_start(); // sets the depth to indicate that we are inside the container and accesses the first element
|
||||
size_t count{0};
|
||||
// Important: we do not consume any of the values.
|
||||
for(simdjson_unused auto v : *this) { count++; }
|
||||
// The above loop will always succeed, but we want to report errors.
|
||||
if(iter.error()) { return iter.error(); }
|
||||
// We need to move back at the start because we expect users to iterator through
|
||||
// We need to move back at the start because we expect users to iterate through
|
||||
// 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.enter_at_container_start(); // sets the depth to indicate that we are inside the container and accesses the first element
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -64,31 +64,23 @@ namespace array_tests {
|
|||
for (auto value : array) {
|
||||
ondemand::object current_object;
|
||||
ASSERT_SUCCESS( value.get_object().get(current_object) );
|
||||
std::cout << "[ondemand::issue1588::sequence] acquired a new object ==========" << std::endl;
|
||||
|
||||
simdjson::ondemand::array rotation;
|
||||
if(expected_value[i][0]) {
|
||||
ASSERT_SUCCESS( current_object["rotation"].get(rotation) );
|
||||
std::cout << "[ondemand::issue1588::sequence] found 'rotation' " << std::endl;
|
||||
} else {
|
||||
ASSERT_ERROR( current_object["rotation"].get(rotation), NO_SUCH_FIELD );
|
||||
std::cout << "[ondemand::issue1588::sequence] rotation not found" << std::endl;
|
||||
}
|
||||
simdjson::ondemand::array scale;
|
||||
if(expected_value[i][1]) {
|
||||
ASSERT_SUCCESS( current_object["scale"].get(scale) );
|
||||
std::cout << "[ondemand::issue1588::sequence] found 'scale' " << std::endl;
|
||||
} else {
|
||||
ASSERT_ERROR( current_object["scale"].get(scale), NO_SUCH_FIELD );
|
||||
std::cout << "[ondemand::issue1588::sequence] scale not found" << std::endl;
|
||||
}
|
||||
simdjson::ondemand::array translation;
|
||||
if(expected_value[i][2]) {
|
||||
ASSERT_SUCCESS( current_object["translation"].get(translation) );
|
||||
std::cout << "[ondemand::issue1588::sequence] found 'translation' " << std::endl;
|
||||
} else {
|
||||
ASSERT_ERROR( current_object["translation"].get(translation), NO_SUCH_FIELD );
|
||||
std::cout << "[ondemand::issue1588::sequence] translation not found" << std::endl;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -139,15 +131,23 @@ namespace array_tests {
|
|||
bool iterate_complex_array_count() {
|
||||
TEST_START();
|
||||
ondemand::parser parser;
|
||||
auto cars_json = R"( { "test":[ { "val1":1, "val2":2 }, { "val1":1, "val2":2 } ] } )"_padded;
|
||||
auto cars_json = R"( { "zero":[], "test":[ { "val1":1, "val2":2 }, { "val1":1, "val2":2 } ] } )"_padded;
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS(parser.iterate(cars_json).get(doc));
|
||||
ondemand::array myarray;
|
||||
ASSERT_SUCCESS(doc.find_field("test").get_array().get(myarray));
|
||||
size_t count;
|
||||
ASSERT_SUCCESS(myarray.count_elements().get(count));
|
||||
size_t new_count = 0;
|
||||
for(simdjson_unused auto elem: myarray) { new_count++; }
|
||||
ondemand::array firstmyarray;
|
||||
ondemand::array secondmyarray;
|
||||
ASSERT_SUCCESS(doc.find_field("zero").get_array().get(firstmyarray));
|
||||
size_t count{0};
|
||||
ASSERT_SUCCESS(firstmyarray.count_elements().get(count));
|
||||
ASSERT_EQUAL(count, 0);
|
||||
size_t new_count{0};
|
||||
for(simdjson_unused auto elem: firstmyarray) { new_count++; }
|
||||
ASSERT_EQUAL(new_count, 0);
|
||||
ASSERT_SUCCESS(doc.find_field("test").get_array().get(secondmyarray));
|
||||
ASSERT_SUCCESS(secondmyarray.count_elements().get(count));
|
||||
ASSERT_EQUAL(count, 2);
|
||||
new_count = 0;
|
||||
for(simdjson_unused auto elem: secondmyarray) { new_count++; }
|
||||
ASSERT_EQUAL(count, new_count);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
|
|
@ -70,10 +70,6 @@ int test_main(int argc, char *argv[], const F& test_function) {
|
|||
std::abort();
|
||||
}
|
||||
// We want to know what we are testing.
|
||||
// Next line would be the runtime dispatched implementation but that's not necessarily what gets tested.
|
||||
// std::cout << "Running tests against this implementation: " << simdjson::active_implementation->name();
|
||||
// Rather, we want to display builtin_implementation()->name().
|
||||
// In practice, by default, we often end up testing against fallback.
|
||||
std::cout << "builtin_implementation -- " << simdjson::builtin_implementation()->name() << std::endl;
|
||||
std::cout << "------------------------------------------------------------" << std::endl;
|
||||
|
||||
|
|
Loading…
Reference in New Issue