From f336103f6390be34c6db8bb7fcdcce1d21f7b46e Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 19 Jun 2020 16:00:11 -0700 Subject: [PATCH] Convert tools/docs/benchmarks to bool get() idiom --- benchmark/bench_dom_api.cpp | 123 +++++++++++------------ benchmark/distinctuseridcompetition.cpp | 75 +++++++------- benchmark/parseandstatcompetition.cpp | 18 ++-- benchmark/statisticalmodel.cpp | 9 +- doc/basics.md | 106 +++++++++----------- tests/extracting_values_example.cpp | 2 +- tests/readme_examples.cpp | 3 +- tests/readme_examples_noexceptions.cpp | 126 ++++++++++-------------- tools/jsonstats.cpp | 10 +- 9 files changed, 218 insertions(+), 254 deletions(-) diff --git a/benchmark/bench_dom_api.cpp b/benchmark/bench_dom_api.cpp index 25efaef59..00a3ade68 100644 --- a/benchmark/bench_dom_api.cpp +++ b/benchmark/bench_dom_api.cpp @@ -18,17 +18,15 @@ static void numbers_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - parser.load(NUMBERS_JSON).get().tie(arr, error); - if(error) { - cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; + if (!parser.load(NUMBERS_JSON).get(arr, error)) { + cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; return; } for (UNUSED auto _ : state) { std::vector container; for (auto e : arr) { double x; - e.get().tie(x,error); - if(error) { cerr << "found a node that is not an number?" << endl; break;} + if (!e.get(x,error)) { cerr << "found a node that is not an number: " << error << endl; break;} container.push_back(x); } benchmark::DoNotOptimize(container.data()); @@ -42,9 +40,8 @@ static void numbers_size_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - parser.load(NUMBERS_JSON).get().tie(arr, error); - if(error) { - cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; + if(!parser.load(NUMBERS_JSON).get(arr, error)) { + cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; return; } for (UNUSED auto _ : state) { @@ -53,8 +50,7 @@ static void numbers_size_scan(State& state) { size_t pos = 0; for (auto e : arr) { double x; - e.get().tie(x,error); - if(error) { cerr << "found a node that is not an number?" << endl; break;} + if (!e.get(x,error)) { cerr << "found a node that is not an number: " << error << endl; break;} container[pos++] = x; } if(pos != container.size()) { cerr << "bad count" << endl; } @@ -70,8 +66,7 @@ static void numbers_type_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - parser.load(NUMBERS_JSON).get().tie(arr, error); - if(error) { + if(!parser.load(NUMBERS_JSON).get(arr, error)) { cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; return; } @@ -83,7 +78,7 @@ static void numbers_type_scan(State& state) { cerr << "found a node that is not an number?" << endl; break; } double x; - e.get().tie(x,error); + e.get(x,error); container.push_back(x); } benchmark::DoNotOptimize(container.data()); @@ -97,9 +92,8 @@ static void numbers_type_size_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - parser.load(NUMBERS_JSON).get().tie(arr, error); - if(error) { - cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; + if (!parser.load(NUMBERS_JSON).get(arr, error)) { + cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; return; } for (UNUSED auto _ : state) { @@ -112,7 +106,7 @@ static void numbers_type_size_scan(State& state) { cerr << "found a node that is not an number?" << endl; break; } double x; - e.get().tie(x,error); + e.get(x,error); container[pos++] = x; } if(pos != container.size()) { cerr << "bad count" << endl; } @@ -129,16 +123,14 @@ static void numbers_load_scan(State& state) { simdjson::error_code error; for (UNUSED auto _ : state) { // this may hit the disk, but probably just once - parser.load(NUMBERS_JSON).get().tie(arr, error); - if(error) { - cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; + if (!parser.load(NUMBERS_JSON).get(arr, error)) { + cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; break; } std::vector container; for (auto e : arr) { double x; - e.get().tie(x,error); - if(error) { cerr << "found a node that is not an number?" << endl; break;} + if (!e.get(x,error)) { cerr << "found a node that is not an number: " << error << endl; break;} container.push_back(x); } benchmark::DoNotOptimize(container.data()); @@ -154,8 +146,7 @@ static void numbers_load_size_scan(State& state) { simdjson::error_code error; for (UNUSED auto _ : state) { // this may hit the disk, but probably just once - parser.load(NUMBERS_JSON).get().tie(arr, error); - if(error) { + if(!parser.load(NUMBERS_JSON).get(arr, error)) { cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; break; } @@ -164,8 +155,7 @@ static void numbers_load_size_scan(State& state) { size_t pos = 0; for (auto e : arr) { double x; - e.get().tie(x,error); - if(error) { cerr << "found a node that is not an number?" << endl; break;} + if(!e.get(x,error)) { cerr << "found a node that is not an number?" << endl; break;} container[pos++] = x; } if(pos != container.size()) { cerr << "bad count" << endl; } @@ -328,7 +318,7 @@ static void twitter_default_profile(State& state) { dom::element doc = parser.load(TWITTER_JSON); for (UNUSED auto _ : state) { set default_users; - for (dom::object tweet : doc["statuses"].get()) { + for (dom::object tweet : doc["statuses"]) { dom::object user = tweet["user"]; if (user["default_profile"]) { default_users.insert(user["screen_name"]); @@ -343,12 +333,13 @@ static void twitter_image_sizes(State& state) { // Count unique image sizes dom::parser parser; dom::element doc = parser.load(TWITTER_JSON); + simdjson::error_code error; for (UNUSED auto _ : state) { set> image_sizes; - for (dom::object tweet : doc["statuses"].get()) { - auto [media, not_found] = tweet["entities"]["media"]; - if (!not_found) { - for (dom::object image : media.get()) { + for (dom::object tweet : doc["statuses"]) { + dom::array media; + if (tweet["entities"]["media"].get(media, error)) { + for (dom::object image : media) { for (auto size : image["sizes"].get()) { image_sizes.insert({ size.value["w"], size.value["h"] }); } @@ -365,11 +356,12 @@ BENCHMARK(twitter_image_sizes); static void error_code_twitter_count(State& state) noexcept { // Prints the number of results in twitter.json dom::parser parser; - auto [doc, error1] = parser.load(TWITTER_JSON); - if (error1) { return; } + simdjson::error_code error; + dom::element doc; + if (!parser.load(TWITTER_JSON).get(doc, error)) { return; } for (UNUSED auto _ : state) { - auto [value, error] = doc["search_metadata"]["count"].get(); - if (error) { return; } + uint64_t value; + if (!doc["search_metadata"]["count"].get(value, error)) { return; } if (value != 100) { return; } } } @@ -378,21 +370,22 @@ BENCHMARK(error_code_twitter_count); static void error_code_twitter_default_profile(State& state) noexcept { // Count unique users with a default profile. dom::parser parser; - auto [doc, error1] = parser.load(TWITTER_JSON); - if (error1) { std::cerr << error1 << std::endl; return; } + simdjson::error_code error; + dom::element doc; + if (!parser.load(TWITTER_JSON).get(doc, error)) { std::cerr << error << std::endl; return; } for (UNUSED auto _ : state) { set default_users; - auto [tweets, error] = doc["statuses"].get(); - if (error) { return; } + dom::array tweets; + if (!doc["statuses"].get(tweets, error)) { return; } for (dom::element tweet : tweets) { - auto [user, error2] = tweet["user"].get(); - if (error2) { return; } - auto [default_profile, error3] = user["default_profile"].get(); - if (error3) { return; } + dom::object user; + if (!tweet["user"].get(user, error)) { return; } + bool default_profile; + if (!user["default_profile"].get(default_profile, error)) { return; } if (default_profile) { - auto [screen_name, error4] = user["screen_name"].get(); - if (error4) { return; } + std::string_view screen_name; + if (!user["screen_name"].get(screen_name, error)) { return; } default_users.insert(screen_name); } } @@ -406,8 +399,9 @@ SIMDJSON_PUSH_DISABLE_WARNINGS SIMDJSON_DISABLE_DEPRECATED_WARNING static void iterator_twitter_default_profile(State& state) { // Count unique users with a default profile. - auto [json, error1] = padded_string::load(TWITTER_JSON); - if (error1) { std::cerr << error1 << std::endl; return; } + simdjson::padded_string json; + simdjson::error_code error; + if (!padded_string::load(TWITTER_JSON).tie(json, error)) { std::cerr << error << std::endl; return; } ParsedJson pj = build_parsed_json(json); for (UNUSED auto _ : state) { set default_users; @@ -447,22 +441,22 @@ BENCHMARK(iterator_twitter_default_profile); static void error_code_twitter_image_sizes(State& state) noexcept { // Count unique image sizes dom::parser parser; - auto [doc, error1] = parser.load(TWITTER_JSON); - if (error1) { std::cerr << error1 << std::endl; return; } + simdjson::error_code error; + dom::element doc; + if (!parser.load(TWITTER_JSON).get(doc, error)) { std::cerr << error << std::endl; return; } for (UNUSED auto _ : state) { set> image_sizes; - auto [statuses, error] = doc["statuses"].get(); - if (error) { return; } + dom::array statuses; + if (!doc["statuses"].get(statuses, error)) { return; } for (dom::element tweet : statuses) { - auto [images, not_found] = tweet["entities"]["media"].get(); - if (!not_found) { + dom::array images; + if (tweet["entities"]["media"].get(images, error)) { for (dom::element image : images) { - auto [sizes, error2] = image["sizes"].get(); - if (error2) { return; } + dom::object sizes; + if (!image["sizes"].get(sizes, error)) { return; } for (auto size : sizes) { - auto [width, error3] = size.value["w"].get(); - auto [height, error4] = size.value["h"].get(); - if (error3 || error4) { return; } + uint64_t width, height; + if (!size.value["w"].get(width, error) || !size.value["h"].get(height, error)) { return; } image_sizes.insert({ width, height }); } } @@ -477,8 +471,9 @@ SIMDJSON_PUSH_DISABLE_WARNINGS SIMDJSON_DISABLE_DEPRECATED_WARNING static void iterator_twitter_image_sizes(State& state) { // Count unique image sizes - auto [json, error1] = padded_string::load(TWITTER_JSON); - if (error1) { std::cerr << error1 << std::endl; return; } + simdjson::error_code error; + padded_string json; + if (!padded_string::load(TWITTER_JSON).tie(json, error)) { std::cerr << error << std::endl; return; } ParsedJson pj = build_parsed_json(json); for (UNUSED auto _ : state) { set> image_sizes; @@ -536,10 +531,12 @@ BENCHMARK(iterator_twitter_image_sizes); static void print_json(State& state) noexcept { // Prints the number of results in twitter.json - auto [json, error1] = padded_string::load(TWITTER_JSON); - if (error1) { std::cerr << error1 << std::endl; return; } + simdjson::error_code error; + padded_string json; + if (!padded_string::load(TWITTER_JSON).tie(json, error)) { std::cerr << error << std::endl; return; } dom::parser parser; - if (int error = json_parse(json, parser); error != SUCCESS) { cerr << error_message(error) << endl; return; } + int code = json_parse(json, parser); + if (code) { cerr << error_message(code) << endl; return; } for (UNUSED auto _ : state) { std::stringstream s; if (!parser.print_json(s)) { cerr << "print_json failed" << endl; return; } diff --git a/benchmark/distinctuseridcompetition.cpp b/benchmark/distinctuseridcompetition.cpp index 1fb7108be..a5e845daf 100644 --- a/benchmark/distinctuseridcompetition.cpp +++ b/benchmark/distinctuseridcompetition.cpp @@ -50,7 +50,7 @@ void print_vec(const std::vector &v) { } else if (element.is()) { auto [object, error] = element.get(); int64_t id; - object["user"]["id"].get().tie(id,error); + object["user"]["id"].get(id,error); if(!error) { v.push_back(id); } @@ -64,48 +64,48 @@ void print_vec(const std::vector &v) { // clang-format on -void simdjson_recurse(std::vector & v, simdjson::dom::element element) { - if (element.is()) { - simdjson::dom::array array; - simdjson::error_code error; - element.get().tie(array, error); - for (auto child : array) { - if (child.is() || child.is()) { - simdjson_recurse(v, child); - } - } - } else if (element.is()) { - simdjson::dom::object object; - simdjson::error_code error; - element.get().tie(object, error); - for (auto [key, value] : object) { - if((key.size() == 4) && (memcmp(key.data(), "user", 4) == 0)) { - // we are in an object under the key "user" - if(value.is()) { - simdjson::dom::object child_object; - value.get().tie(child_object, error); - for (auto [child_key, child_value] : child_object) { - if((child_key.size() == 2) && (memcmp(child_key.data(), "id", 2) == 0)) { - if(child_value.is()) { - int64_t x; - child_value.get().tie(x, error); - v.push_back(x); - } +really_inline void simdjson_recurse(std::vector & v, simdjson::dom::element element); +void simdjson_recurse(std::vector & v, simdjson::dom::array array) { + for (auto child : array) { + simdjson_recurse(v, child); + } +} +void simdjson_recurse(std::vector & v, simdjson::dom::object object) { + for (auto [key, value] : object) { + if((key.size() == 4) && (memcmp(key.data(), "user", 4) == 0)) { + // we are in an object under the key "user" + simdjson::error_code error; + simdjson::dom::object child_object; + simdjson::dom::object child_array; + if (value.get(child_object, error)) { + for (auto [child_key, child_value] : child_object) { + if((child_key.size() == 2) && (memcmp(child_key.data(), "id", 2) == 0)) { + int64_t x; + if (child_value.get(x, error)) { + v.push_back(x); } - if (child_value.is() || child_value.is()) { - simdjson_recurse(v, child_value); - } } - } else if (value.is()) { - simdjson_recurse(v, value); + simdjson_recurse(v, child_value); } - // end of: we are in an object under the key "user" - } else if (value.is() || value.is()) { - simdjson_recurse(v, value); + } else if (value.get(child_array, error)) { + simdjson_recurse(v, child_array); } + // end of: we are in an object under the key "user" + } else { + simdjson_recurse(v, value); } } } +really_inline void simdjson_recurse(std::vector & v, simdjson::dom::element element) { + UNUSED simdjson::error_code error; + simdjson::dom::array array; + simdjson::dom::object object; + if (element.get(array, error)) { + simdjson_recurse(v, array); + } else if (element.get(object, error)) { + simdjson_recurse(v, object); + } +} really_inline std::vector simdjson_just_dom(simdjson::dom::element doc) { @@ -121,8 +121,7 @@ simdjson_compute_stats(const simdjson::padded_string &p) { simdjson::dom::parser parser; simdjson::dom::element doc; simdjson::error_code error; - parser.parse(p).tie(doc, error); - if(!error) { + if (parser.parse(p).tie(doc, error)) { simdjson_recurse(answer, doc); remove_duplicates(answer); } diff --git a/benchmark/parseandstatcompetition.cpp b/benchmark/parseandstatcompetition.cpp index 3ea105e08..c648d768b 100644 --- a/benchmark/parseandstatcompetition.cpp +++ b/benchmark/parseandstatcompetition.cpp @@ -53,10 +53,9 @@ really_inline void simdjson_process_atom(stat_t &s, if (element.is()) { s.number_count++; } else if (element.is()) { - simdjson::error_code err; + simdjson::error_code error; bool v; - element.get().tie(v, err); - if (v) { + if (element.get(v, error) && v) { s.true_count++; } else { s.false_count++; @@ -67,11 +66,12 @@ really_inline void simdjson_process_atom(stat_t &s, } void simdjson_recurse(stat_t &s, simdjson::dom::element element) { + error_code error; if (element.is()) { s.array_count++; - auto [array, array_error] = element.get(); - if (array_error) { - std::cerr << array_error << std::endl; + dom::array array; + if (!element.get(array, error)) { + std::cerr << error << std::endl; abort(); } for (auto child : array) { @@ -84,9 +84,9 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { } } else if (element.is()) { s.object_count++; - auto [object, object_error] = element.get(); - if (object_error) { - std::cerr << object_error << std::endl; + dom::object object; + if (!element.get(object, error)) { + std::cerr << error << std::endl; abort(); } for (auto field : object) { diff --git a/benchmark/statisticalmodel.cpp b/benchmark/statisticalmodel.cpp index 9e6b53e78..a518d3a1b 100644 --- a/benchmark/statisticalmodel.cpp +++ b/benchmark/statisticalmodel.cpp @@ -64,10 +64,11 @@ really_inline void simdjson_process_atom(stat_t &s, } void simdjson_recurse(stat_t &s, simdjson::dom::element element) { + simdjson::error_code error; if (element.is()) { s.array_count++; - auto [array, array_error] = element.get(); - if (array_error) { std::cerr << array_error << std::endl; abort(); } + simdjson::dom::array array; + if (!element.get(array, error)) { std::cerr << error << std::endl; abort(); } for (auto child : array) { if (child.is() || child.is()) { simdjson_recurse(s, child); @@ -77,8 +78,8 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { } } else if (element.is()) { s.object_count++; - auto [object, object_error] = element.get(); - if (object_error) { std::cerr << object_error << std::endl; abort(); } + simdjson::dom::object object; + if (!element.get(object, error)) { std::cerr << error << std::endl; abort(); } for (auto field : object) { s.string_count++; // for key if (field.value.is() || field.value.is()) { diff --git a/doc/basics.md b/doc/basics.md index 8583432ba..0e6a4b882 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -81,9 +81,9 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper given type, or use the `type()` method: e.g., `element.type() == dom::element_type::DOUBLE`. Instead of casting, you can use get<*typename*>() to get the value: casts and get<*typename*>() can be used interchangeably. You can use a variant usage of get<*typename*>() with error codes to avoid exceptions: e.g., ```c++ simdjson::error_code error; - double value; // variable where we store the value to be parsed simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2") simdjson::dom::parser parser; + double value; // variable where we store the value to be parsed parser.parse(numberstring).get(value,error); if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } std::cout << "I parsed " << value << " from " << numberstring.data() << std::endl; @@ -211,9 +211,10 @@ For comparison, here is the C++ 11 version of the same code: // C++ 11 version for comparison dom::parser parser; padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded; -dom::object object; simdjson::error_code error; +dom::object object; parser.parse(json).get(object, error); +if (!error) { cerr << error << endl; return; } for (dom::key_value_pair field : object) { cout << field.key << " = " << field.value << endl; } @@ -299,45 +300,39 @@ auto cars_json = R"( [ dom::parser parser; dom::array cars; simdjson::error_code error; -parser.parse(cars_json).get(cars, error); -if (error) { cerr << error << endl; exit(1); } +if (!parser.parse(cars_json).get(cars, error)) { cerr << error << endl; exit(1); } // Iterating through an array of objects for (dom::element car_element : cars) { -dom::object car; -car_element.get(car, error); -if (error) { cerr << error << endl; exit(1); } + dom::object car; + if (!car_element.get(car, error)) { cerr << error << endl; exit(1); } -// Accessing a field by name -dom::element make, model; -car["make"].tie(make, error); -if (error) { cerr << error << endl; exit(1); } -car["model"].tie(model, error); -if (error) { cerr << error << endl; exit(1); } -cout << "Make/Model: " << make << "/" << model << endl; + // Accessing a field by name + std::string_view make, model; + if (!car["make"].get(make, error)) { cerr << error << endl; exit(1); } + if (!car["model"].get(model, error)) { cerr << error << endl; exit(1); } + cout << "Make/Model: " << make << "/" << model << endl; -// Casting a JSON element to an integer -uint64_t year; -car["year"].get(year, error); -if (error) { cerr << error << endl; exit(1); } -cout << "- This car is " << 2020 - year << "years old." << endl; + // Casting a JSON element to an integer + uint64_t year; + if (!car["year"].get(year, error)) { cerr << error << endl; exit(1); } + cout << "- This car is " << 2020 - year << "years old." << endl; -// Iterating through an array of floats -double total_tire_pressure = 0; -dom::array tire_pressure_array; -car["tire_pressure"].get(tire_pressure_array, error); -if (error) { cerr << error << endl; exit(1); } -for (dom::element tire_pressure_element : tire_pressure_array) { - double tire_pressure; - tire_pressure_element.get(tire_pressure, error); - if (error) { cerr << error << endl; exit(1); } - total_tire_pressure += tire_pressure; -} -cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; + // Iterating through an array of floats + double total_tire_pressure = 0; + dom::array tire_pressure_array; + if (!car["tire_pressure"].get(tire_pressure_array, error)) { cerr << error << endl; exit(1); } + for (dom::element tire_pressure_element : tire_pressure_array) { + double tire_pressure; + if (!tire_pressure_element.get(tire_pressure, error)) { cerr << error << endl; exit(1); } + total_tire_pressure += tire_pressure; + } + cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; -// Writing out all the information about the car -for (auto field : car) { - cout << "- " << field.key << ": " << field.value << endl; + // Writing out all the information about the car + for (auto field : car) { + cout << "- " << field.key << ": " << field.value << endl; + } } ``` @@ -356,32 +351,23 @@ if (error) { cerr << error << endl; exit(1); } // Iterate through an array of objects for (dom::element elem : rootarray) { dom::object obj; - elem.get(obj, error); - if (error) { cerr << error << endl; exit(1); } - for(auto & key_value : obj) { - cout << "key: " << key_value.key << " : "; - dom::object innerobj; - key_value.value.get(innerobj, error); - if (error) { cerr << error << endl; exit(1); } + if (!elem.get(obj, error)) { cerr << error << endl; exit(1); } + for (auto & key_value : obj) { + cout << "key: " << key_value.key << " : "; + dom::object innerobj; + if (!key_value.value.get(innerobj, error)) { cerr << error << endl; exit(1); } - double va; - innerobj["a"].get(va, error); - if (error) { cerr << error << endl; exit(1); } - cout << "a: " << va << ", "; - - double vb; - innerobj["b"].get(vb, error); - if (error) { cerr << error << endl; exit(1); } - cout << "b: " << vb << ", "; - - int64_t vc; - innerobj["c"].get(vc, error); - if (error) { cerr << error << endl; exit(1); } - cout << "c: " << vc << endl; + double va, vb; + if (!innerobj["a"].get(va, error)) { cerr << error << endl; exit(1); } + cout << "a: " << va << ", "; + if (!innerobj["b"].get(vc, error)) { cerr << error << endl; exit(1); } + cout << "b: " << vb << ", "; + int64_t vc; + if (!innerobj["c"].get(vc, error)) { cerr << error << endl; exit(1); } + cout << "c: " << vc << endl; } } - ``` And another one: @@ -390,8 +376,8 @@ And another one: auto abstract_json = R"( { "str" : { "123" : {"abc" : 3.14 } } } )"_padded; dom::parser parser; - double v; simdjson::error_code error; + double v; parser.parse(abstract_json)["str"]["123"]["abc"].get(v, error); if (error) { cerr << error << endl; exit(1); } cout << "number: " << v << endl; @@ -409,8 +395,7 @@ bool parse_double(const char *j, double &d) { simdjson::error_code error; parser.parse(j, std::strlen(j)) .at(0) - .get() - .tie(d, error); + .get(d, error); if (error) { return false; } return true; } @@ -420,8 +405,7 @@ bool parse_string(const char *j, std::string &s) { std::string_view answer; parser.parse(j,strlen(j)) .at(0) - .get() - .tie(answer, error); + .get(answer, error); if (error) { return false; } s.assign(answer.data(), answer.size()); return true; diff --git a/tests/extracting_values_example.cpp b/tests/extracting_values_example.cpp index 637f461dd..3e2715c8a 100644 --- a/tests/extracting_values_example.cpp +++ b/tests/extracting_values_example.cpp @@ -3,9 +3,9 @@ int main() { simdjson::error_code error; - double value; // variable where we store the value to be parsed simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2") simdjson::dom::parser parser; + double value; // variable where we store the value to be parsed parser.parse(numberstring).get(value,error); if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } std::cout << "I parsed " << value << " from " << numberstring.data() << std::endl; diff --git a/tests/readme_examples.cpp b/tests/readme_examples.cpp index 3b9f84cbb..ff4dcab21 100644 --- a/tests/readme_examples.cpp +++ b/tests/readme_examples.cpp @@ -155,9 +155,10 @@ void basics_cpp17_2() { // C++ 11 version for comparison dom::parser parser; padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded; - dom::object object; simdjson::error_code error; + dom::object object; parser.parse(json).get(object, error); + if (!error) { cerr << error << endl; return; } for (dom::key_value_pair field : object) { cout << field.key << " = " << field.value << endl; } diff --git a/tests/readme_examples_noexceptions.cpp b/tests/readme_examples_noexceptions.cpp index 454b056da..22e676fed 100644 --- a/tests/readme_examples_noexceptions.cpp +++ b/tests/readme_examples_noexceptions.cpp @@ -35,55 +35,48 @@ void basics_error_3() { dom::parser parser; dom::array cars; simdjson::error_code error; - parser.parse(cars_json).get(cars, error); - if (error) { cerr << error << endl; exit(1); } + if (!parser.parse(cars_json).get(cars, error)) { cerr << error << endl; exit(1); } // Iterating through an array of objects for (dom::element car_element : cars) { - dom::object car; - car_element.get(car, error); - if (error) { cerr << error << endl; exit(1); } + dom::object car; + if (!car_element.get(car, error)) { cerr << error << endl; exit(1); } - // Accessing a field by name - dom::element make, model; - car["make"].tie(make, error); - if (error) { cerr << error << endl; exit(1); } - car["model"].tie(model, error); - if (error) { cerr << error << endl; exit(1); } - cout << "Make/Model: " << make << "/" << model << endl; + // Accessing a field by name + std::string_view make, model; + if (!car["make"].get(make, error)) { cerr << error << endl; exit(1); } + if (!car["model"].get(model, error)) { cerr << error << endl; exit(1); } + cout << "Make/Model: " << make << "/" << model << endl; - // Casting a JSON element to an integer - uint64_t year; - car["year"].get(year, error); - if (error) { cerr << error << endl; exit(1); } - cout << "- This car is " << 2020 - year << "years old." << endl; + // Casting a JSON element to an integer + uint64_t year; + if (!car["year"].get(year, error)) { cerr << error << endl; exit(1); } + cout << "- This car is " << 2020 - year << "years old." << endl; - // Iterating through an array of floats - double total_tire_pressure = 0; - dom::array tire_pressure_array; - car["tire_pressure"].get(tire_pressure_array, error); - if (error) { cerr << error << endl; exit(1); } - for (dom::element tire_pressure_element : tire_pressure_array) { - double tire_pressure; - tire_pressure_element.get(tire_pressure, error); - if (error) { cerr << error << endl; exit(1); } - total_tire_pressure += tire_pressure; - } - cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; + // Iterating through an array of floats + double total_tire_pressure = 0; + dom::array tire_pressure_array; + if (!car["tire_pressure"].get(tire_pressure_array, error)) { cerr << error << endl; exit(1); } + for (dom::element tire_pressure_element : tire_pressure_array) { + double tire_pressure; + if (!tire_pressure_element.get(tire_pressure, error)) { cerr << error << endl; exit(1); } + total_tire_pressure += tire_pressure; + } + cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; - // Writing out all the information about the car - for (auto field : car) { - cout << "- " << field.key << ": " << field.value << endl; - } + // Writing out all the information about the car + for (auto field : car) { + cout << "- " << field.key << ": " << field.value << endl; + } } } void basics_error_4() { auto abstract_json = R"( [ - { "12345" : {"a":12.34, "b":56.78, "c": 9998877} }, - { "12545" : {"a":11.44, "b":12.78, "c": 11111111} } - ] )"_padded; + { "12345" : {"a":12.34, "b":56.78, "c": 9998877} }, + { "12545" : {"a":11.44, "b":12.78, "c": 11111111} } + ] )"_padded; dom::parser parser; dom::array rootarray; simdjson::error_code error; @@ -91,31 +84,23 @@ void basics_error_4() { if (error) { cerr << error << endl; exit(1); } // Iterate through an array of objects for (dom::element elem : rootarray) { - dom::object obj; - elem.get(obj, error); - if (error) { cerr << error << endl; exit(1); } - for(auto & key_value : obj) { - cout << "key: " << key_value.key << " : "; - dom::object innerobj; - key_value.value.get(innerobj, error); - if (error) { cerr << error << endl; exit(1); } + dom::object obj; + if (!elem.get(obj, error)) { cerr << error << endl; exit(1); } + for (auto & key_value : obj) { + cout << "key: " << key_value.key << " : "; + dom::object innerobj; + if (!key_value.value.get(innerobj, error)) { cerr << error << endl; exit(1); } - double va; - innerobj["a"].get(va, error); - if (error) { cerr << error << endl; exit(1); } - cout << "a: " << va << ", "; + double va, vb; + if (!innerobj["a"].get(va, error)) { cerr << error << endl; exit(1); } + cout << "a: " << va << ", "; + if (!innerobj["b"].get(vb, error)) { cerr << error << endl; exit(1); } + cout << "b: " << vb << ", "; - double vb; - innerobj["b"].get(vb, error); - if (error) { cerr << error << endl; exit(1); } - cout << "b: " << vb << ", "; - - int64_t vc; - innerobj["c"].get(vc, error); - if (error) { cerr << error << endl; exit(1); } - cout << "c: " << vc << endl; - - } + int64_t vc; + if (!innerobj["c"].get(vc, error)) { cerr << error << endl; exit(1); } + cout << "c: " << vc << endl; + } } } @@ -185,27 +170,24 @@ void basics_error_3_cpp17() { } #endif -simdjson::dom::parser parser; - // See https://github.com/miloyip/nativejson-benchmark/blob/master/src/tests/simdjsontest.cpp -bool ParseDouble(const char *j, double &d) { +simdjson::dom::parser parser{}; + +bool parse_double(const char *j, double &d) { simdjson::error_code error; parser.parse(j, std::strlen(j)) .at(0) - .get() - .tie(d, error); + .get(d, error); if (error) { return false; } return true; } -// See https://github.com/miloyip/nativejson-benchmark/blob/master/src/tests/simdjsontest.cpp -bool ParseString(const char *j, std::string &s) { +bool parse_string(const char *j, std::string &s) { simdjson::error_code error; std::string_view answer; parser.parse(j,strlen(j)) .at(0) - .get() - .tie(answer, error); + .get(answer, error); if (error) { return false; } s.assign(answer.data(), answer.size()); return true; @@ -214,15 +196,15 @@ bool ParseString(const char *j, std::string &s) { int main() { double x{}; - ParseDouble("[1.1]",x); + parse_double("[1.1]",x); if(x != 1.1) { - std::cerr << "bug in ParseDouble!" << std::endl; + std::cerr << "bug in parse_double!" << std::endl; return EXIT_FAILURE; } std::string s{}; - ParseString("[\"my string\"]", s); + parse_string("[\"my string\"]", s); if(s != "my string") { - std::cerr << "bug in ParseString!" << std::endl; + std::cerr << "bug in parse_string!" << std::endl; return EXIT_FAILURE; } basics_error_2(); diff --git a/tools/jsonstats.cpp b/tools/jsonstats.cpp index bdfce9917..0e85db14a 100644 --- a/tools/jsonstats.cpp +++ b/tools/jsonstats.cpp @@ -70,10 +70,11 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { if (depth > s.maximum_depth) { s.maximum_depth = depth; } + simdjson::error_code error; if (element.is()) { s.array_count++; - auto [array, array_error] = element.get(); - if (!array_error) { + simdjson::dom::array array; + if (element.get(array, error)) { size_t counter = 0; for (auto child : array) { counter++; @@ -85,8 +86,8 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { } } else if (element.is()) { s.object_count++; - auto [object, object_error] = element.get(); - if (!object_error) { + simdjson::dom::object object; + if (element.get(object, error)) { size_t counter = 0; for (auto [key, value] : object) { counter++; @@ -116,7 +117,6 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { } } } else { - simdjson::error_code error; if (element.is()) { s.integer_count++; // because an int can be sometimes represented as a double, we // to check whether it is an integer first!!!