diff --git a/benchmark/bench_dom_api.cpp b/benchmark/bench_dom_api.cpp index 00a3ade68..1440942c7 100644 --- a/benchmark/bench_dom_api.cpp +++ b/benchmark/bench_dom_api.cpp @@ -18,7 +18,7 @@ static void numbers_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - if (!parser.load(NUMBERS_JSON).get(arr, error)) { + if ((error = parser.load(NUMBERS_JSON).get(arr))) { cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; return; } @@ -26,7 +26,7 @@ static void numbers_scan(State& state) { std::vector container; for (auto e : arr) { double x; - if (!e.get(x,error)) { cerr << "found a node that is not an number: " << error << endl; break;} + if ((error = e.get(x))) { cerr << "found a node that is not an number: " << error << endl; break;} container.push_back(x); } benchmark::DoNotOptimize(container.data()); @@ -40,7 +40,7 @@ static void numbers_size_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - if(!parser.load(NUMBERS_JSON).get(arr, error)) { + if ((error = parser.load(NUMBERS_JSON).get(arr))) { cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; return; } @@ -50,7 +50,7 @@ static void numbers_size_scan(State& state) { size_t pos = 0; for (auto e : arr) { double x; - if (!e.get(x,error)) { cerr << "found a node that is not an number: " << error << endl; break;} + if ((error = e.get(x))) { cerr << "found a node that is not an number: " << error << endl; break;} container[pos++] = x; } if(pos != container.size()) { cerr << "bad count" << endl; } @@ -66,7 +66,7 @@ static void numbers_type_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - if(!parser.load(NUMBERS_JSON).get(arr, error)) { + if ((error = parser.load(NUMBERS_JSON).get(arr))) { cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; return; } @@ -78,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(x,error); + error = e.get(x); container.push_back(x); } benchmark::DoNotOptimize(container.data()); @@ -92,7 +92,7 @@ static void numbers_type_size_scan(State& state) { dom::parser parser; dom::array arr; simdjson::error_code error; - if (!parser.load(NUMBERS_JSON).get(arr, error)) { + if ((error = parser.load(NUMBERS_JSON).get(arr))) { cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; return; } @@ -106,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(x,error); + error = e.get(x); container[pos++] = x; } if(pos != container.size()) { cerr << "bad count" << endl; } @@ -123,14 +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 - if (!parser.load(NUMBERS_JSON).get(arr, error)) { + if ((error = parser.load(NUMBERS_JSON).get(arr))) { cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl; break; } std::vector container; for (auto e : arr) { double x; - if (!e.get(x,error)) { cerr << "found a node that is not an number: " << error << endl; break;} + if ((error = e.get(x))) { cerr << "found a node that is not an number: " << error << endl; break;} container.push_back(x); } benchmark::DoNotOptimize(container.data()); @@ -146,7 +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 - if(!parser.load(NUMBERS_JSON).get(arr, error)) { + if ((error = parser.load(NUMBERS_JSON).get(arr))) { cerr << "could not read " << NUMBERS_JSON << " as an array" << endl; break; } @@ -155,7 +155,7 @@ static void numbers_load_size_scan(State& state) { size_t pos = 0; for (auto e : arr) { double x; - if(!e.get(x,error)) { cerr << "found a node that is not an number?" << endl; break;} + if ((error = e.get(x))) { cerr << "found a node that is not an number?" << endl; break;} container[pos++] = x; } if(pos != container.size()) { cerr << "bad count" << endl; } @@ -338,7 +338,7 @@ static void twitter_image_sizes(State& state) { set> image_sizes; for (dom::object tweet : doc["statuses"]) { dom::array media; - if (tweet["entities"]["media"].get(media, error)) { + if (not (error = tweet["entities"]["media"].get(media))) { for (dom::object image : media) { for (auto size : image["sizes"].get()) { image_sizes.insert({ size.value["w"], size.value["h"] }); @@ -358,10 +358,10 @@ static void error_code_twitter_count(State& state) noexcept { dom::parser parser; simdjson::error_code error; dom::element doc; - if (!parser.load(TWITTER_JSON).get(doc, error)) { return; } + if ((error = parser.load(TWITTER_JSON).get(doc))) { return; } for (UNUSED auto _ : state) { uint64_t value; - if (!doc["search_metadata"]["count"].get(value, error)) { return; } + if ((error = doc["search_metadata"]["count"].get(value))) { return; } if (value != 100) { return; } } } @@ -372,20 +372,20 @@ static void error_code_twitter_default_profile(State& state) noexcept { dom::parser parser; simdjson::error_code error; dom::element doc; - if (!parser.load(TWITTER_JSON).get(doc, error)) { std::cerr << error << std::endl; return; } + if ((error = parser.load(TWITTER_JSON).get(doc))) { std::cerr << error << std::endl; return; } for (UNUSED auto _ : state) { set default_users; dom::array tweets; - if (!doc["statuses"].get(tweets, error)) { return; } + if ((error = doc["statuses"].get(tweets))) { return; } for (dom::element tweet : tweets) { dom::object user; - if (!tweet["user"].get(user, error)) { return; } + if ((error = tweet["user"].get(user))) { return; } bool default_profile; - if (!user["default_profile"].get(default_profile, error)) { return; } + if ((error = user["default_profile"].get(default_profile))) { return; } if (default_profile) { std::string_view screen_name; - if (!user["screen_name"].get(screen_name, error)) { return; } + if ((error = user["screen_name"].get(screen_name))) { return; } default_users.insert(screen_name); } } @@ -399,9 +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. - simdjson::padded_string json; - simdjson::error_code error; - if (!padded_string::load(TWITTER_JSON).tie(json, error)) { std::cerr << error << std::endl; return; } + padded_string json; + auto error = padded_string::load(TWITTER_JSON).get(json); + if (error) { std::cerr << error << std::endl; return; } ParsedJson pj = build_parsed_json(json); for (UNUSED auto _ : state) { set default_users; @@ -443,20 +443,21 @@ static void error_code_twitter_image_sizes(State& state) noexcept { dom::parser parser; simdjson::error_code error; dom::element doc; - if (!parser.load(TWITTER_JSON).get(doc, error)) { std::cerr << error << std::endl; return; } + if ((error = parser.load(TWITTER_JSON).get(doc))) { std::cerr << error << std::endl; return; } for (UNUSED auto _ : state) { set> image_sizes; dom::array statuses; - if (!doc["statuses"].get(statuses, error)) { return; } + if ((error = doc["statuses"].get(statuses))) { return; } for (dom::element tweet : statuses) { dom::array images; - if (tweet["entities"]["media"].get(images, error)) { + if (not (error = tweet["entities"]["media"].get(images))) { for (dom::element image : images) { dom::object sizes; - if (!image["sizes"].get(sizes, error)) { return; } + if ((error = image["sizes"].get(sizes))) { return; } for (auto size : sizes) { uint64_t width, height; - if (!size.value["w"].get(width, error) || !size.value["h"].get(height, error)) { return; } + if ((error = size.value["w"].get(width))) { return; } + if ((error = size.value["h"].get(height))) { return; } image_sizes.insert({ width, height }); } } @@ -471,9 +472,9 @@ SIMDJSON_PUSH_DISABLE_WARNINGS SIMDJSON_DISABLE_DEPRECATED_WARNING static void iterator_twitter_image_sizes(State& state) { // Count unique image sizes - simdjson::error_code error; padded_string json; - if (!padded_string::load(TWITTER_JSON).tie(json, error)) { std::cerr << error << std::endl; return; } + auto error = padded_string::load(TWITTER_JSON).get(json); + if (error) { std::cerr << error << std::endl; return; } ParsedJson pj = build_parsed_json(json); for (UNUSED auto _ : state) { set> image_sizes; @@ -531,10 +532,12 @@ BENCHMARK(iterator_twitter_image_sizes); static void print_json(State& state) noexcept { // Prints the number of results in twitter.json - 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; + + padded_string json; + auto error = padded_string::load(TWITTER_JSON).get(json); + if (error) { std::cerr << error << std::endl; return; } + int code = json_parse(json, parser); if (code) { cerr << error_message(code) << endl; return; } for (UNUSED auto _ : state) { diff --git a/benchmark/bench_parse_call.cpp b/benchmark/bench_parse_call.cpp index 94a6580c3..164c1faf6 100644 --- a/benchmark/bench_parse_call.cpp +++ b/benchmark/bench_parse_call.cpp @@ -13,8 +13,7 @@ const char *GSOC_JSON = SIMDJSON_BENCHMARK_DATA_DIR "gsoc-2018.json"; static void parse_twitter(State& state) { dom::parser parser; padded_string docdata; - simdjson::error_code error; - padded_string::load(TWITTER_JSON).tie(docdata, error); + auto error = padded_string::load(TWITTER_JSON).get(docdata); if(error) { cerr << "could not parse twitter.json" << error << endl; return; @@ -29,8 +28,8 @@ static void parse_twitter(State& state) { for (UNUSED auto _ : state) { dom::element doc; bytes += docdata.size(); - parser.parse(docdata).tie(doc,error); - if(error) { + ; + if ((error = parser.parse(docdata).get(doc))) { cerr << "could not parse twitter.json" << error << endl; return; } @@ -50,8 +49,7 @@ BENCHMARK(parse_twitter)->Repetitions(10)->ComputeStatistics("max", [](const std static void parse_gsoc(State& state) { dom::parser parser; padded_string docdata; - simdjson::error_code error; - padded_string::load(GSOC_JSON).tie(docdata, error); + auto error = padded_string::load(GSOC_JSON).get(docdata); if(error) { cerr << "could not parse gsoc-2018.json" << error << endl; return; @@ -64,10 +62,9 @@ static void parse_gsoc(State& state) { } size_t bytes = 0; for (UNUSED auto _ : state) { - dom::element doc; bytes += docdata.size(); - parser.parse(docdata).tie(doc,error); - if(error) { + dom::element doc; + if ((error = parser.parse(docdata).get(doc))) { cerr << "could not parse gsoc-2018.json" << error << endl; return; } diff --git a/benchmark/benchmarker.h b/benchmark/benchmarker.h index 3468f19d2..9a0a97dcb 100644 --- a/benchmark/benchmarker.h +++ b/benchmark/benchmarker.h @@ -267,8 +267,7 @@ struct benchmarker { benchmarker(const char *_filename, event_collector& _collector) : filename(_filename), collector(_collector), stats(NULL) { verbose() << "[verbose] loading " << filename << endl; - simdjson::error_code error; - padded_string::load(filename).tie(this->json, error); + auto error = padded_string::load(filename).get(json); if (error) { exit_error(string("Could not load the file ") + filename); } diff --git a/benchmark/distinctuseridcompetition.cpp b/benchmark/distinctuseridcompetition.cpp index a5e845daf..100c48f66 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(id,error); + error = object["user"]["id"].get(id); if(!error) { v.push_back(id); } @@ -77,17 +77,17 @@ void simdjson_recurse(std::vector & v, simdjson::dom::object object) { simdjson::error_code error; simdjson::dom::object child_object; simdjson::dom::object child_array; - if (value.get(child_object, error)) { + if (not (error = value.get(child_object))) { 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)) { + if (not (error = child_value.get(x))) { v.push_back(x); } } simdjson_recurse(v, child_value); } - } else if (value.get(child_array, error)) { + } else if (not (error = value.get(child_array))) { simdjson_recurse(v, child_array); } // end of: we are in an object under the key "user" @@ -100,9 +100,9 @@ really_inline void simdjson_recurse(std::vector & v, simdjson::dom::ele UNUSED simdjson::error_code error; simdjson::dom::array array; simdjson::dom::object object; - if (element.get(array, error)) { + if (not (error = element.get(array))) { simdjson_recurse(v, array); - } else if (element.get(object, error)) { + } else if (not (error = element.get(object))) { simdjson_recurse(v, object); } } @@ -120,8 +120,8 @@ simdjson_compute_stats(const simdjson::padded_string &p) { std::vector answer; simdjson::dom::parser parser; simdjson::dom::element doc; - simdjson::error_code error; - if (parser.parse(p).tie(doc, error)) { + auto error = parser.parse(p).get(doc); + if (!error) { simdjson_recurse(answer, doc); remove_duplicates(answer); } @@ -385,7 +385,7 @@ int main(int argc, char *argv[]) { volume, !just_data); simdjson::dom::parser parser; simdjson::dom::element doc; - parser.parse(p).tie(doc, error); + error = parser.parse(p).get(doc); BEST_TIME("simdjson (just dom) ", simdjson_just_dom(doc).size(), size, , repeat, volume, !just_data); char *buffer = (char *)malloc(p.size() + 1); diff --git a/benchmark/parseandstatcompetition.cpp b/benchmark/parseandstatcompetition.cpp index c648d768b..eb017ebd9 100644 --- a/benchmark/parseandstatcompetition.cpp +++ b/benchmark/parseandstatcompetition.cpp @@ -55,7 +55,7 @@ really_inline void simdjson_process_atom(stat_t &s, } else if (element.is()) { simdjson::error_code error; bool v; - if (element.get(v, error) && v) { + if (not (error = element.get(v)) && v) { s.true_count++; } else { s.false_count++; @@ -70,7 +70,7 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { if (element.is()) { s.array_count++; dom::array array; - if (!element.get(array, error)) { + if ((error = element.get(array))) { std::cerr << error << std::endl; abort(); } @@ -85,7 +85,7 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { } else if (element.is()) { s.object_count++; dom::object object; - if (!element.get(object, error)) { + if ((error = element.get(object))) { std::cerr << error << std::endl; abort(); } diff --git a/benchmark/statisticalmodel.cpp b/benchmark/statisticalmodel.cpp index a518d3a1b..3838f5ef9 100644 --- a/benchmark/statisticalmodel.cpp +++ b/benchmark/statisticalmodel.cpp @@ -52,7 +52,7 @@ really_inline void simdjson_process_atom(stat_t &s, } else if (element.is()) { simdjson::error_code err; bool v; - element.get(v,err); + err = element.get(v); if (v) { s.true_count++; } else { @@ -68,7 +68,7 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { if (element.is()) { s.array_count++; simdjson::dom::array array; - if (!element.get(array, error)) { std::cerr << error << std::endl; abort(); } + if ((error = element.get(array))) { std::cerr << error << std::endl; abort(); } for (auto child : array) { if (child.is() || child.is()) { simdjson_recurse(s, child); @@ -79,7 +79,7 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { } else if (element.is()) { s.object_count++; simdjson::dom::object object; - if (!element.get(object, error)) { std::cerr << error << std::endl; abort(); } + if ((error = element.get(object))) { 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 0e6a4b882..e1bb0708c 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -84,7 +84,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper 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); + error = parser.parse(numberstring).get(value); if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } std::cout << "I parsed " << value << " from " << numberstring.data() << std::endl; ``` @@ -213,7 +213,7 @@ dom::parser parser; padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded; simdjson::error_code error; dom::object object; -parser.parse(json).get(object, error); +error = parser.parse(json).get(object); if (!error) { cerr << error << endl; return; } for (dom::key_value_pair field : object) { cout << field.key << " = " << field.value << endl; @@ -260,8 +260,7 @@ behavior. > > ```c++ > dom::element doc; -> simdjson::error_code error; -> parser.parse(json).tie(doc, error); // <-- Assigns to doc and error just like "auto [doc, error]" +> auto error = parser.parse(json).get(doc); // <-- Assigns to doc and error just like "auto [doc, error]" > ``` @@ -273,13 +272,11 @@ We can write a "quick start" example where we attempt to parse a file and access int main(void) { simdjson::dom::parser parser; simdjson::dom::element tweets; - simdjson::error_code error; - parser.load("twitter.json").tie(tweets,error); + auto error = parser.load("twitter.json").get(tweets); if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } simdjson::dom::element res; - tweets["search_metadata"]["count"].tie(res,error); - if(error) { + if ((error = tweets["search_metadata"]["count"].get(res))) { std::cerr << "could not access keys" << std::endl; return EXIT_FAILURE; } @@ -299,32 +296,32 @@ auto cars_json = R"( [ ] )"_padded; dom::parser parser; dom::array cars; -simdjson::error_code error; -if (!parser.parse(cars_json).get(cars, error)) { cerr << error << endl; exit(1); } +auto error = parser.parse(cars_json).get(cars); +if (error) { cerr << error << endl; exit(1); } // Iterating through an array of objects for (dom::element car_element : cars) { dom::object car; - if (!car_element.get(car, error)) { cerr << error << endl; exit(1); } + if ((error = car_element.get(car))) { cerr << error << endl; exit(1); } // 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); } + if ((error = car["make"].get(make))) { cerr << error << endl; exit(1); } + if ((error = car["model"].get(model))) { cerr << error << endl; exit(1); } cout << "Make/Model: " << make << "/" << model << endl; // Casting a JSON element to an integer uint64_t year; - if (!car["year"].get(year, error)) { cerr << error << endl; exit(1); } + if ((error = car["year"].get(year))) { 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; - if (!car["tire_pressure"].get(tire_pressure_array, error)) { cerr << error << endl; exit(1); } + if ((error = car["tire_pressure"].get(tire_pressure_array))) { 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); } + if ((error = tire_pressure_element.get(tire_pressure))) { cerr << error << endl; exit(1); } total_tire_pressure += tire_pressure; } cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; @@ -344,27 +341,26 @@ auto abstract_json = R"( [ { "12545" : {"a":11.44, "b":12.78, "c": 11111111} } ] )"_padded; dom::parser parser; -dom::array rootarray; -simdjson::error_code error; -parser.parse(abstract_json).get(rootarray, error); +dom::array array; +auto error = parser.parse(abstract_json).get(array); if (error) { cerr << error << endl; exit(1); } // Iterate through an array of objects -for (dom::element elem : rootarray) { +for (dom::element elem : array) { dom::object obj; - if (!elem.get(obj, error)) { cerr << error << endl; exit(1); } + if ((error = elem.get(obj))) { 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); } + if ((error = key_value.value.get(innerobj))) { cerr << error << endl; exit(1); } double va, vb; - if (!innerobj["a"].get(va, error)) { cerr << error << endl; exit(1); } + if ((error = innerobj["a"].get(va))) { cerr << error << endl; exit(1); } cout << "a: " << va << ", "; - if (!innerobj["b"].get(vc, error)) { cerr << error << endl; exit(1); } + if ((error = innerobj["b"].get(vc))) { cerr << error << endl; exit(1); } cout << "b: " << vb << ", "; int64_t vc; - if (!innerobj["c"].get(vc, error)) { cerr << error << endl; exit(1); } + if ((error = innerobj["c"].get(vc))) { cerr << error << endl; exit(1); } cout << "c: " << vc << endl; } } @@ -376,9 +372,8 @@ And another one: auto abstract_json = R"( { "str" : { "123" : {"abc" : 3.14 } } } )"_padded; dom::parser parser; - simdjson::error_code error; double v; - parser.parse(abstract_json)["str"]["123"]["abc"].get(v, error); + auto error = parser.parse(abstract_json)["str"]["123"]["abc"].get(v); if (error) { cerr << error << endl; exit(1); } cout << "number: " << v << endl; ``` @@ -392,8 +387,7 @@ The next two functions will take as input a JSON document containing an array wi simdjson::dom::parser parser{}; bool parse_double(const char *j, double &d) { - simdjson::error_code error; - parser.parse(j, std::strlen(j)) + auto error = parser.parse(j, std::strlen(j)) .at(0) .get(d, error); if (error) { return false; } @@ -401,9 +395,8 @@ bool parse_double(const char *j, double &d) { } bool parse_string(const char *j, std::string &s) { - simdjson::error_code error; std::string_view answer; - parser.parse(j,strlen(j)) + auto error = parser.parse(j,strlen(j)) .at(0) .get(answer, error); if (error) { return false; } diff --git a/examples/quickstart/quickstart_noexceptions.cpp b/examples/quickstart/quickstart_noexceptions.cpp index b6ca8aebf..e49bf3a9d 100644 --- a/examples/quickstart/quickstart_noexceptions.cpp +++ b/examples/quickstart/quickstart_noexceptions.cpp @@ -3,13 +3,11 @@ int main(void) { simdjson::dom::parser parser; simdjson::dom::element tweets; - simdjson::error_code error; - parser.load("twitter.json").tie(tweets,error); + auto error = parser.load("twitter.json").get(tweets); if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } simdjson::dom::element res; - tweets["search_metadata"]["count"].tie(res,error); - if(error) { + if ((error = tweets["search_metadata"]["count"].get(res))) { std::cerr << "could not access keys" << std::endl; return EXIT_FAILURE; } diff --git a/fuzz/fuzz_dump.cpp b/fuzz/fuzz_dump.cpp index fc509182d..b70fb73f6 100644 --- a/fuzz/fuzz_dump.cpp +++ b/fuzz/fuzz_dump.cpp @@ -49,9 +49,8 @@ static void print_json(std::ostream& os, simdjson::dom::element element) { } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { simdjson::dom::parser parser; - simdjson::error_code error; simdjson::dom::element elem; - parser.parse(Data, Size).tie(elem, error); + auto error = parser.parse(Data, Size).get(elem); if (error) { return 1; } NulOStream os; diff --git a/fuzz/fuzz_dump_raw_tape.cpp b/fuzz/fuzz_dump_raw_tape.cpp index c4343ede3..3bd10fa9a 100644 --- a/fuzz/fuzz_dump_raw_tape.cpp +++ b/fuzz/fuzz_dump_raw_tape.cpp @@ -8,9 +8,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { simdjson::dom::parser parser; - simdjson::error_code error; simdjson::dom::element elem; - parser.parse(Data, Size).tie(elem, error); + auto error = parser.parse(Data, Size).get(elem); if (error) { return 1; } NulOStream os; diff --git a/fuzz/fuzz_minify.cpp b/fuzz/fuzz_minify.cpp index a8425a0a1..5bd4f04ca 100644 --- a/fuzz/fuzz_minify.cpp +++ b/fuzz/fuzz_minify.cpp @@ -9,9 +9,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { std::string str(begin, end); simdjson::dom::parser parser; - simdjson::error_code error; simdjson::dom::element elem; - parser.parse(str).tie(elem, error); + auto error = parser.parse(str).get(elem); if (error) { return 1; } std::string minified=simdjson::minify(elem); diff --git a/fuzz/fuzz_parser.cpp b/fuzz/fuzz_parser.cpp index 610cead4b..dbed1928c 100644 --- a/fuzz/fuzz_parser.cpp +++ b/fuzz/fuzz_parser.cpp @@ -4,8 +4,7 @@ #include extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { simdjson::dom::parser parser; - UNUSED simdjson::error_code error; UNUSED simdjson::dom::element elem; - parser.parse(Data, Size).tie(elem, error); + UNUSED auto error = parser.parse(Data, Size).get(elem); return 0; } diff --git a/fuzz/fuzz_print_json.cpp b/fuzz/fuzz_print_json.cpp index 02db2941a..b856241dc 100644 --- a/fuzz/fuzz_print_json.cpp +++ b/fuzz/fuzz_print_json.cpp @@ -8,9 +8,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { simdjson::dom::parser parser; - simdjson::error_code error; simdjson::dom::element elem; - parser.parse(Data, Size).tie(elem, error); + auto error = parser.parse(Data, Size).get(elem); if (!error) { NulOStream os; os< - really_inline simdjson_result get() const noexcept; + inline simdjson_result get() const noexcept; /** * Get the value as the provided type (T). @@ -219,12 +219,11 @@ public: * @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object * * @param value The variable to set to the value. May not be set if there is an error. - * @param error The variable to set to the error. Set to SUCCESS if there is no error. * - * @returns true if the value was set, or false if there wsa an error. + * @returns The error that occurred, or SUCCESS if there was no error. */ template - inline bool get(T &value, error_code &error) const noexcept; + WARN_UNUSED really_inline error_code get(T &value) const noexcept; /** * Get the value as the provided type (T), setting error if it's not the given type. @@ -473,51 +472,51 @@ public: really_inline simdjson_result(dom::element &&value) noexcept; ///< @private really_inline simdjson_result(error_code error) noexcept; ///< @private - inline simdjson_result type() const noexcept; + really_inline simdjson_result type() const noexcept; template - inline simdjson_result is() const noexcept; + really_inline simdjson_result is() const noexcept; template - inline simdjson_result get() const noexcept; + really_inline simdjson_result get() const noexcept; template - inline bool get(T &value, error_code &error) const noexcept; + WARN_UNUSED really_inline error_code get(T &value) const noexcept; - inline simdjson_result get_array() const noexcept; - inline simdjson_result get_object() const noexcept; - inline simdjson_result get_c_str() const noexcept; - inline simdjson_result get_string() const noexcept; - inline simdjson_result get_int64_t() const noexcept; - inline simdjson_result get_uint64_t() const noexcept; - inline simdjson_result get_double() const noexcept; - inline simdjson_result get_bool() const noexcept; + really_inline simdjson_result get_array() const noexcept; + really_inline simdjson_result get_object() const noexcept; + really_inline simdjson_result get_c_str() const noexcept; + really_inline simdjson_result get_string() const noexcept; + really_inline simdjson_result get_int64_t() const noexcept; + really_inline simdjson_result get_uint64_t() const noexcept; + really_inline simdjson_result get_double() const noexcept; + really_inline simdjson_result get_bool() const noexcept; - inline simdjson_result is_array() const noexcept; - inline simdjson_result is_object() const noexcept; - inline simdjson_result is_string() const noexcept; - inline simdjson_result is_int64_t() const noexcept; - inline simdjson_result is_uint64_t() const noexcept; - inline simdjson_result is_double() const noexcept; - inline simdjson_result is_bool() const noexcept; - inline simdjson_result is_null() const noexcept; + really_inline simdjson_result is_array() const noexcept; + really_inline simdjson_result is_object() const noexcept; + really_inline simdjson_result is_string() const noexcept; + really_inline simdjson_result is_int64_t() const noexcept; + really_inline simdjson_result is_uint64_t() const noexcept; + really_inline simdjson_result is_double() const noexcept; + really_inline simdjson_result is_bool() const noexcept; + really_inline simdjson_result is_null() const noexcept; - inline simdjson_result operator[](const std::string_view &key) const noexcept; - inline simdjson_result operator[](const char *key) const noexcept; - inline simdjson_result at(const std::string_view &json_pointer) const noexcept; - inline simdjson_result at(size_t index) const noexcept; - inline simdjson_result at_key(const std::string_view &key) const noexcept; - inline simdjson_result at_key_case_insensitive(const std::string_view &key) const noexcept; + really_inline simdjson_result operator[](const std::string_view &key) const noexcept; + really_inline simdjson_result operator[](const char *key) const noexcept; + really_inline simdjson_result at(const std::string_view &json_pointer) const noexcept; + really_inline simdjson_result at(size_t index) const noexcept; + really_inline simdjson_result at_key(const std::string_view &key) const noexcept; + really_inline simdjson_result at_key_case_insensitive(const std::string_view &key) const noexcept; #if SIMDJSON_EXCEPTIONS - inline operator bool() const noexcept(false); - inline explicit operator const char*() const noexcept(false); - inline operator std::string_view() const noexcept(false); - inline operator uint64_t() const noexcept(false); - inline operator int64_t() const noexcept(false); - inline operator double() const noexcept(false); - inline operator dom::array() const noexcept(false); - inline operator dom::object() const noexcept(false); + really_inline operator bool() const noexcept(false); + really_inline explicit operator const char*() const noexcept(false); + really_inline operator std::string_view() const noexcept(false); + really_inline operator uint64_t() const noexcept(false); + really_inline operator int64_t() const noexcept(false); + really_inline operator double() const noexcept(false); + really_inline operator dom::array() const noexcept(false); + really_inline operator dom::object() const noexcept(false); - inline dom::array::iterator begin() const noexcept(false); - inline dom::array::iterator end() const noexcept(false); + really_inline dom::array::iterator begin() const noexcept(false); + really_inline dom::array::iterator end() const noexcept(false); #endif // SIMDJSON_EXCEPTIONS }; @@ -533,7 +532,7 @@ public: * underlying output stream, that error will be propagated (simdjson_error will not be * thrown). */ -inline std::ostream& operator<<(std::ostream& out, const simdjson_result &value) noexcept(false); +really_inline std::ostream& operator<<(std::ostream& out, const simdjson_result &value) noexcept(false); #endif } // namespace simdjson diff --git a/include/simdjson/error.h b/include/simdjson/error.h index a7a6a351c..f272abd83 100644 --- a/include/simdjson/error.h +++ b/include/simdjson/error.h @@ -120,9 +120,17 @@ struct simdjson_result_base : public std::pair { /** * Move the value and the error to the provided variables. * - * @return true if the value was set, false if there was an error. + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. */ - really_inline bool tie(T &value, error_code &error) && noexcept; + really_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + really_inline error_code get(T &value) && noexcept; /** * The error. @@ -184,9 +192,17 @@ struct simdjson_result : public internal::simdjson_result_base { /** * Move the value and the error to the provided variables. * - * @return true if the value was set, false if there was an error. + * @param value The variable to assign the value to. May not be set if there is an error. + * @param error The variable to assign the error to. Set to SUCCESS if there is no error. */ - really_inline bool tie(T &value, error_code &error) && noexcept; + really_inline void tie(T &value, error_code &error) && noexcept; + + /** + * Move the value to the provided variable. + * + * @param value The variable to assign the value to. May not be set if there is an error. + */ + WARN_UNUSED really_inline error_code get(T &value) && noexcept; /** * The error. diff --git a/include/simdjson/inline/document_stream.h b/include/simdjson/inline/document_stream.h index 93ab4436e..3e72305b8 100644 --- a/include/simdjson/inline/document_stream.h +++ b/include/simdjson/inline/document_stream.h @@ -66,16 +66,15 @@ inline void stage1_worker::run(document_stream * ds, dom::parser * stage1, size_ really_inline document_stream::document_stream( dom::parser &_parser, - const uint8_t *_buf, - size_t _len, size_t _batch_size, - error_code _error + const uint8_t *_buf, + size_t _len ) noexcept : parser{_parser}, buf{_buf}, len{_len}, batch_size{_batch_size}, - error{_error} + error{SUCCESS} { #ifdef SIMDJSON_THREADS_ENABLED if(worker.get() == nullptr) { @@ -84,6 +83,20 @@ really_inline document_stream::document_stream( #endif } +really_inline document_stream::document_stream( + dom::parser &_parser, + size_t _batch_size, + error_code _error +) noexcept + : parser{_parser}, + buf{nullptr}, + len{0}, + batch_size{_batch_size}, + error{_error} +{ + assert(_error); +} + inline document_stream::~document_stream() noexcept { } diff --git a/include/simdjson/inline/element.h b/include/simdjson/inline/element.h index a765660fc..690f40ff6 100644 --- a/include/simdjson/inline/element.h +++ b/include/simdjson/inline/element.h @@ -24,154 +24,150 @@ inline simdjson_result simdjson_result::type() } template -inline simdjson_result simdjson_result::is() const noexcept { +really_inline simdjson_result simdjson_result::is() const noexcept { if (error()) { return error(); } return first.is(); } template -inline simdjson_result simdjson_result::get() const noexcept { +really_inline simdjson_result simdjson_result::get() const noexcept { if (error()) { return error(); } return first.get(); } template -inline bool simdjson_result::get(T &value, error_code &_error) const noexcept { - if (error()) { - _error = error(); - return !_error; - } else { - return first.get(value, _error); - } +WARN_UNUSED really_inline error_code simdjson_result::get(T &value) const noexcept { + if (error()) { return error(); } + return first.get(value); } -inline simdjson_result simdjson_result::get_array() const noexcept { +really_inline simdjson_result simdjson_result::get_array() const noexcept { if (error()) { return error(); } return first.get_array(); } -inline simdjson_result simdjson_result::get_object() const noexcept { +really_inline simdjson_result simdjson_result::get_object() const noexcept { if (error()) { return error(); } return first.get_object(); } -inline simdjson_result simdjson_result::get_c_str() const noexcept { +really_inline simdjson_result simdjson_result::get_c_str() const noexcept { if (error()) { return error(); } return first.get_c_str(); } -inline simdjson_result simdjson_result::get_string() const noexcept { +really_inline simdjson_result simdjson_result::get_string() const noexcept { if (error()) { return error(); } return first.get_string(); } -inline simdjson_result simdjson_result::get_int64_t() const noexcept { +really_inline simdjson_result simdjson_result::get_int64_t() const noexcept { if (error()) { return error(); } return first.get_int64_t(); } -inline simdjson_result simdjson_result::get_uint64_t() const noexcept { +really_inline simdjson_result simdjson_result::get_uint64_t() const noexcept { if (error()) { return error(); } return first.get_uint64_t(); } -inline simdjson_result simdjson_result::get_double() const noexcept { +really_inline simdjson_result simdjson_result::get_double() const noexcept { if (error()) { return error(); } return first.get_double(); } -inline simdjson_result simdjson_result::get_bool() const noexcept { +really_inline simdjson_result simdjson_result::get_bool() const noexcept { if (error()) { return error(); } return first.get_bool(); } -inline simdjson_result simdjson_result::is_array() const noexcept { +really_inline simdjson_result simdjson_result::is_array() const noexcept { if (error()) { return error(); } return first.is_array(); } -inline simdjson_result simdjson_result::is_object() const noexcept { +really_inline simdjson_result simdjson_result::is_object() const noexcept { if (error()) { return error(); } return first.is_object(); } -inline simdjson_result simdjson_result::is_string() const noexcept { +really_inline simdjson_result simdjson_result::is_string() const noexcept { if (error()) { return error(); } return first.is_string(); } -inline simdjson_result simdjson_result::is_int64_t() const noexcept { +really_inline simdjson_result simdjson_result::is_int64_t() const noexcept { if (error()) { return error(); } return first.is_int64_t(); } -inline simdjson_result simdjson_result::is_uint64_t() const noexcept { +really_inline simdjson_result simdjson_result::is_uint64_t() const noexcept { if (error()) { return error(); } return first.is_uint64_t(); } -inline simdjson_result simdjson_result::is_double() const noexcept { +really_inline simdjson_result simdjson_result::is_double() const noexcept { if (error()) { return error(); } return first.is_double(); } -inline simdjson_result simdjson_result::is_bool() const noexcept { +really_inline simdjson_result simdjson_result::is_bool() const noexcept { if (error()) { return error(); } return first.is_bool(); } -inline simdjson_result simdjson_result::is_null() const noexcept { +really_inline simdjson_result simdjson_result::is_null() const noexcept { if (error()) { return error(); } return first.is_null(); } -inline simdjson_result simdjson_result::operator[](const std::string_view &key) const noexcept { +really_inline simdjson_result simdjson_result::operator[](const std::string_view &key) const noexcept { if (error()) { return error(); } return first[key]; } -inline simdjson_result simdjson_result::operator[](const char *key) const noexcept { +really_inline simdjson_result simdjson_result::operator[](const char *key) const noexcept { if (error()) { return error(); } return first[key]; } -inline simdjson_result simdjson_result::at(const std::string_view &json_pointer) const noexcept { +really_inline simdjson_result simdjson_result::at(const std::string_view &json_pointer) const noexcept { if (error()) { return error(); } return first.at(json_pointer); } -inline simdjson_result simdjson_result::at(size_t index) const noexcept { +really_inline simdjson_result simdjson_result::at(size_t index) const noexcept { if (error()) { return error(); } return first.at(index); } -inline simdjson_result simdjson_result::at_key(const std::string_view &key) const noexcept { +really_inline simdjson_result simdjson_result::at_key(const std::string_view &key) const noexcept { if (error()) { return error(); } return first.at_key(key); } -inline simdjson_result simdjson_result::at_key_case_insensitive(const std::string_view &key) const noexcept { +really_inline simdjson_result simdjson_result::at_key_case_insensitive(const std::string_view &key) const noexcept { if (error()) { return error(); } return first.at_key_case_insensitive(key); } #if SIMDJSON_EXCEPTIONS -inline simdjson_result::operator bool() const noexcept(false) { +really_inline simdjson_result::operator bool() const noexcept(false) { return get(); } -inline simdjson_result::operator const char *() const noexcept(false) { +really_inline simdjson_result::operator const char *() const noexcept(false) { return get(); } -inline simdjson_result::operator std::string_view() const noexcept(false) { +really_inline simdjson_result::operator std::string_view() const noexcept(false) { return get(); } -inline simdjson_result::operator uint64_t() const noexcept(false) { +really_inline simdjson_result::operator uint64_t() const noexcept(false) { return get(); } -inline simdjson_result::operator int64_t() const noexcept(false) { +really_inline simdjson_result::operator int64_t() const noexcept(false) { return get(); } -inline simdjson_result::operator double() const noexcept(false) { +really_inline simdjson_result::operator double() const noexcept(false) { return get(); } -inline simdjson_result::operator dom::array() const noexcept(false) { +really_inline simdjson_result::operator dom::array() const noexcept(false) { return get(); } -inline simdjson_result::operator dom::object() const noexcept(false) { +really_inline simdjson_result::operator dom::object() const noexcept(false) { return get(); } -inline dom::array::iterator simdjson_result::begin() const noexcept(false) { +really_inline dom::array::iterator simdjson_result::begin() const noexcept(false) { if (error()) { throw simdjson_error(error()); } return first.begin(); } -inline dom::array::iterator simdjson_result::end() const noexcept(false) { +really_inline dom::array::iterator simdjson_result::end() const noexcept(false) { if (error()) { throw simdjson_error(error()); } return first.end(); } -#endif +#endif // SIMDJSON_EXCEPTIONS namespace dom { @@ -277,12 +273,18 @@ inline simdjson_result element::get_object() const noexcept { } template -inline bool element::get(T &value, error_code &error) const noexcept { - return get().tie(value, error); +WARN_UNUSED really_inline error_code element::get(T &value) const noexcept { + return get().get(value); +} +// An element-specific version prevents recursion with simdjson_result::get(value) +template<> +WARN_UNUSED really_inline error_code element::get(element &value) const noexcept { + value = element(tape); + return SUCCESS; } template -inline bool element::is() const noexcept { +really_inline bool element::is() const noexcept { auto result = get(); return !result.error(); } @@ -514,12 +516,12 @@ inline std::ostream& minifier::print(std::ostream& out) { #if SIMDJSON_EXCEPTIONS template<> -inline std::ostream& minifier>::print(std::ostream& out) { +really_inline std::ostream& minifier>::print(std::ostream& out) { if (value.error()) { throw simdjson_error(value.error()); } return out << minify(value.first); } -inline std::ostream& operator<<(std::ostream& out, const simdjson_result &value) noexcept(false) { +really_inline std::ostream& operator<<(std::ostream& out, const simdjson_result &value) noexcept(false) { return out << minify>(value); } #endif diff --git a/include/simdjson/inline/error.h b/include/simdjson/inline/error.h index 06afb897b..c2d884c3c 100644 --- a/include/simdjson/inline/error.h +++ b/include/simdjson/inline/error.h @@ -41,13 +41,21 @@ namespace internal { // template -really_inline bool simdjson_result_base::tie(T &value, error_code &error) && noexcept { +really_inline void simdjson_result_base::tie(T &value, error_code &error) && noexcept { // on the clang compiler that comes with current macOS (Apple clang version 11.0.0), // tie(width, error) = size["w"].get(); // fails with "error: no viable overloaded '='"" - value = std::forward>(*this).first; error = this->second; - return !error; + if (!error) { + value = std::forward>(*this).first; + } +} + +template +WARN_UNUSED really_inline error_code simdjson_result_base::get(T &value) && noexcept { + error_code error; + std::forward>(*this).tie(value, error); + return error; } template @@ -96,8 +104,13 @@ really_inline simdjson_result_base::simdjson_result_base() noexcept /// template -really_inline bool simdjson_result::tie(T &value, error_code &error) && noexcept { - return std::forward>(*this).tie(value, error); +really_inline void simdjson_result::tie(T &value, error_code &error) && noexcept { + std::forward>(*this).tie(value, error); +} + +template +WARN_UNUSED really_inline error_code simdjson_result::get(T &value) && noexcept { + return std::forward>(*this).get(value); } template diff --git a/include/simdjson/inline/parser.h b/include/simdjson/inline/parser.h index ab99d7413..16bd47c62 100644 --- a/include/simdjson/inline/parser.h +++ b/include/simdjson/inline/parser.h @@ -78,23 +78,24 @@ inline simdjson_result parser::read_file(const std::string &path) noexce inline simdjson_result parser::load(const std::string &path) & noexcept { size_t len; - error_code code; - read_file(path).tie(len, code); - if (code) { return code; } + auto _error = read_file(path).get(len); + if (_error) { return _error; } return parse(loaded_bytes.get(), len, false); } inline document_stream parser::load_many(const std::string &path, size_t batch_size) noexcept { size_t len; - error_code code; - read_file(path).tie(len, code); - return document_stream(*this, (const uint8_t*)loaded_bytes.get(), len, batch_size, code); + auto _error = read_file(path).get(len); + if (_error) { + return document_stream(*this, batch_size, _error); + } + return document_stream(*this, batch_size, (const uint8_t*)loaded_bytes.get(), len); } inline simdjson_result parser::parse(const uint8_t *buf, size_t len, bool realloc_if_needed) & noexcept { - error_code code = ensure_capacity(len); - if (code) { return code; } + error_code _error = ensure_capacity(len); + if (_error) { return _error; } if (realloc_if_needed) { const uint8_t *tmp_buf = buf; @@ -104,11 +105,11 @@ inline simdjson_result parser::parse(const uint8_t *buf, size_t len, bo memcpy((void *)buf, tmp_buf, len); } - code = implementation->parse(buf, len, doc); + _error = implementation->parse(buf, len, doc); if (realloc_if_needed) { aligned_free((void *)buf); // must free before we exit } - if (code) { return code; } + if (_error) { return _error; } return doc.root(); } @@ -123,7 +124,7 @@ really_inline simdjson_result parser::parse(const padded_string &s) & n } inline document_stream parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept { - return document_stream(*this, buf, len, batch_size); + return document_stream(*this, batch_size, buf, len); } inline document_stream parser::parse_many(const char *buf, size_t len, size_t batch_size) noexcept { return parse_many((const uint8_t *)buf, len, batch_size); diff --git a/include/simdjson/portability.h b/include/simdjson/portability.h index bcb2f3936..a936fc0df 100644 --- a/include/simdjson/portability.h +++ b/include/simdjson/portability.h @@ -199,5 +199,24 @@ static inline void aligned_free(void *mem_block) { static inline void aligned_free_char(char *mem_block) { aligned_free((void *)mem_block); } + +#ifdef NDEBUG + +#ifdef SIMDJSON_VISUAL_STUDIO +#define SIMDJSON_UNREACHABLE() __assume(0) +#define SIMDJSON_ASSUME(COND) __assume(COND) +#else +#define SIMDJSON_UNREACHABLE() __builtin_unreachable(); +#define SIMDJSON_ASSUME(COND) do { if (!(COND)) __builtin_unreachable(); } while (0) +#endif + +#else // NDEBUG + +#include +#define SIMDJSON_UNREACHABLE() assert(0); +#define SIMDJSON_ASSUME(COND) assert(COND) + +#endif + } // namespace simdjson #endif // SIMDJSON_PORTABILITY_H diff --git a/tests/basictests.cpp b/tests/basictests.cpp index 21a224c86..99a04d409 100644 --- a/tests/basictests.cpp +++ b/tests/basictests.cpp @@ -289,8 +289,7 @@ namespace document_tests { myStream << parser.parse(json); #else simdjson::dom::element doc; - simdjson::error_code error; - parser.parse(json).tie(doc, error); + UNUSED auto error = parser.parse(json).get(doc); myStream << doc; #endif std::string newjson = myStream.str(); @@ -677,7 +676,7 @@ namespace parse_api_tests { if (error) { cerr << error << endl; return false; } dom::array arr; - doc.get(arr, error); // let us get the array + error = doc.get(arr); // let us get the array if (error) { cerr << error << endl; return false; } if(arr.size() != 9) { cerr << "bad array size"<< endl; return false; } @@ -1019,8 +1018,8 @@ namespace dom_api_tests { // tie(val, error) = doc["d"]; fails with "no viable overloaded '='" on Apple clang version 11.0.0 tie(val, error) = doc["d"]; doc["d"].tie(val, error); if (error != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(doc[\"d\"]), got " << error << endl; return false; } - error = doc["d"].error(); - if (error != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(doc[\"d\"]), got " << error << endl; return false; } + if (doc["d"].get(val) != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(doc[\"d\"]), got " << error << endl; return false; } + if (doc["d"].error() != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(doc[\"d\"]), got " << error << endl; return false; } return true; } @@ -1033,11 +1032,11 @@ namespace dom_api_tests { if (doc["obj"]["a"].get().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; } object obj; - doc.get(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0 + error = doc.get(obj); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0 if (error) { cerr << "Error: " << error << endl; return false; } if (obj["obj"]["a"].get().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; } - obj["obj"].get(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0 + error = obj["obj"].get(obj); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0 if (obj["a"].get().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"].first << endl; return false; } if (obj["b"].get().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["b"].first << endl; return false; } if (obj["c/d"].get().first != 3) { cerr << "Expected uint64_t(obj[\"c\"]) to be 3, was " << obj["c"].first << endl; return false; } @@ -1047,8 +1046,7 @@ namespace dom_api_tests { if (obj["a"].get().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"].first << endl; return false; } UNUSED element val; - doc["d"].tie(val, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; - if (error != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(obj[\"d\"]), got " << error << endl; return false; } + if (doc["d"].get(val) != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(obj[\"d\"]), got " << error << endl; return false; } return true; } @@ -1071,14 +1069,14 @@ namespace dom_api_tests { if (error) { cerr << "Error: " << error << endl; return false; } for (auto tweet : tweets) { object user; - tweet["user"].get(user, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; + error = tweet["user"].get(user); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; if (error) { cerr << "Error: " << error << endl; return false; } bool default_profile; - user["default_profile"].get(default_profile, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; + error = user["default_profile"].get(default_profile); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; if (error) { cerr << "Error: " << error << endl; return false; } if (default_profile) { std::string_view screen_name; - user["screen_name"].get(screen_name, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; + error = user["screen_name"].get(screen_name); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; if (error) { cerr << "Error: " << error << endl; return false; } default_users.insert(screen_name); } @@ -1099,13 +1097,13 @@ namespace dom_api_tests { if (!not_found) { for (auto image : media) { object sizes; - image["sizes"].get(sizes, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; + error = image["sizes"].get(sizes); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; if (error) { cerr << "Error: " << error << endl; return false; } for (auto size : sizes) { uint64_t width, height; - size.value["w"].get(width, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; + error = size.value["w"].get(width); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; if (error) { cerr << "Error: " << error << endl; return false; } - size.value["h"].get(height, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; + error = size.value["h"].get(height); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0; if (error) { cerr << "Error: " << error << endl; return false; } image_sizes.insert(make_pair(width, height)); } @@ -1414,8 +1412,7 @@ namespace type_tests { std::cout << " test_type() expecting " << expected_type << std::endl; dom::element element = result.first; dom::element_type actual_type; - simdjson::error_code error; - result.type().tie(actual_type, error); + auto error = result.type().get(actual_type); ASSERT_SUCCESS(error); ASSERT_EQUAL(actual_type, expected_type); @@ -1445,8 +1442,7 @@ namespace type_tests { // Grab the element out and check success dom::element element = result.first; bool actual_is_null; - simdjson::error_code error; - result.is_null().tie(actual_is_null, error); + auto error = result.is_null().get(actual_is_null); ASSERT_SUCCESS(error); ASSERT_EQUAL(actual_is_null, expected_is_null); diff --git a/tests/cast_tester.h b/tests/cast_tester.h index 9800bf121..59cdc948d 100644 --- a/tests/cast_tester.h +++ b/tests/cast_tester.h @@ -58,7 +58,7 @@ template bool cast_tester::test_get(element element, T expected) { T actual; error_code error; - element.get(actual, error); + error = element.get(actual); ASSERT_SUCCESS(error); return assert_equal(actual, expected); } @@ -67,7 +67,7 @@ template bool cast_tester::test_get(simdjson_result element, T expected) { T actual; error_code error; - element.get(actual, error); + error = element.get(actual); ASSERT_SUCCESS(error); return assert_equal(actual, expected); } @@ -76,7 +76,7 @@ template bool cast_tester::test_get_error(element element, error_code expected_error) { T actual; error_code error; - element.get(actual, error); + error = element.get(actual); ASSERT_EQUAL(error, expected_error); return true; } @@ -85,7 +85,7 @@ template bool cast_tester::test_get_error(simdjson_result element, error_code expected_error) { T actual; error_code error; - element.get(actual, error); + error = element.get(actual); ASSERT_EQUAL(error, expected_error); return true; } @@ -93,8 +93,7 @@ bool cast_tester::test_get_error(simdjson_result element, error_code template bool cast_tester::test_named_get(element element, T expected) { T actual; - error_code error; - named_get(element).tie(actual, error); + auto error = named_get(element).get(actual); ASSERT_SUCCESS(error); return assert_equal(actual, expected); } @@ -102,8 +101,7 @@ bool cast_tester::test_named_get(element element, T expected) { template bool cast_tester::test_named_get(simdjson_result element, T expected) { T actual; - error_code error; - named_get(element).tie(actual, error); + auto error = named_get(element).get(actual); ASSERT_SUCCESS(error); return assert_equal(actual, expected); } @@ -111,8 +109,7 @@ bool cast_tester::test_named_get(simdjson_result element, T expected template bool cast_tester::test_named_get_error(element element, error_code expected_error) { T actual; - error_code error; - named_get(element).tie(actual, error); + auto error = named_get(element).get(actual); ASSERT_EQUAL(error, expected_error); return true; } @@ -120,8 +117,7 @@ bool cast_tester::test_named_get_error(element element, error_code expected_e template bool cast_tester::test_named_get_error(simdjson_result element, error_code expected_error) { T actual; - error_code error; - named_get(element).tie(actual, error); + auto error = named_get(element).get(actual); ASSERT_EQUAL(error, expected_error); return true; } @@ -192,8 +188,7 @@ bool cast_tester::test_is(element element, bool expected) { template bool cast_tester::test_is(simdjson_result element, bool expected) { bool actual; - error_code error; - element.is().tie(actual, error); + auto error = element.is().get(actual); ASSERT_SUCCESS(error); ASSERT_EQUAL(actual, expected); return true; @@ -202,8 +197,7 @@ bool cast_tester::test_is(simdjson_result element, bool expected) { template bool cast_tester::test_is_error(simdjson_result element, error_code expected_error) { UNUSED bool actual; - error_code error; - element.is().tie(actual, error); + auto error = element.is().get(actual); ASSERT_EQUAL(error, expected_error); return true; } @@ -217,8 +211,7 @@ bool cast_tester::test_named_is(element element, bool expected) { template bool cast_tester::test_named_is(simdjson_result element, bool expected) { bool actual; - error_code error; - named_is(element).tie(actual, error); + auto error = named_is(element).get(actual); ASSERT_SUCCESS(error); ASSERT_EQUAL(actual, expected); return true; @@ -227,8 +220,7 @@ bool cast_tester::test_named_is(simdjson_result element, bool expect template bool cast_tester::test_named_is_error(simdjson_result element, error_code expected_error) { bool actual; - error_code error; - named_is(element, error).tie(actual, error); + auto error = named_is(element).get(actual); ASSERT_EQUAL(error, expected_error); return true; } diff --git a/tests/extracting_values_example.cpp b/tests/extracting_values_example.cpp index 3e2715c8a..b235c5d36 100644 --- a/tests/extracting_values_example.cpp +++ b/tests/extracting_values_example.cpp @@ -6,7 +6,7 @@ int main() { 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); + error = parser.parse(numberstring).get(value); 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 ff4dcab21..c8712197f 100644 --- a/tests/readme_examples.cpp +++ b/tests/readme_examples.cpp @@ -157,7 +157,7 @@ void basics_cpp17_2() { padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded; simdjson::error_code error; dom::object object; - parser.parse(json).get(object, error); + error = parser.parse(json).get(object); 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 22e676fed..36bf89ced 100644 --- a/tests/readme_examples_noexceptions.cpp +++ b/tests/readme_examples_noexceptions.cpp @@ -22,8 +22,7 @@ void basics_error_2() { auto json = "1"_padded; dom::element doc; - simdjson::error_code error; - parser.parse(json).tie(doc, error); // <-- Assigns to doc and error just like "auto [doc, error]"} + UNUSED auto error = parser.parse(json).get(doc); // <-- Assigns to doc and error just like "auto [doc, error]"} } void basics_error_3() { @@ -34,32 +33,32 @@ void basics_error_3() { ] )"_padded; dom::parser parser; dom::array cars; - simdjson::error_code error; - if (!parser.parse(cars_json).get(cars, error)) { cerr << error << endl; exit(1); } + auto error = parser.parse(cars_json).get(cars); + if (error) { cerr << error << endl; exit(1); } // Iterating through an array of objects for (dom::element car_element : cars) { dom::object car; - if (!car_element.get(car, error)) { cerr << error << endl; exit(1); } + if ((error = car_element.get(car))) { cerr << error << endl; exit(1); } // 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); } + if ((error = car["make"].get(make))) { cerr << error << endl; exit(1); } + if ((error = car["model"].get(model))) { cerr << error << endl; exit(1); } cout << "Make/Model: " << make << "/" << model << endl; // Casting a JSON element to an integer uint64_t year; - if (!car["year"].get(year, error)) { cerr << error << endl; exit(1); } + if ((error = car["year"].get(year))) { 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; - if (!car["tire_pressure"].get(tire_pressure_array, error)) { cerr << error << endl; exit(1); } + if ((error = car["tire_pressure"].get(tire_pressure_array))) { 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); } + if ((error = tire_pressure_element.get(tire_pressure))) { cerr << error << endl; exit(1); } total_tire_pressure += tire_pressure; } cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; @@ -78,27 +77,26 @@ void basics_error_4() { { "12545" : {"a":11.44, "b":12.78, "c": 11111111} } ] )"_padded; dom::parser parser; - dom::array rootarray; - simdjson::error_code error; - parser.parse(abstract_json).get(rootarray, error); + dom::array array; + auto error = parser.parse(abstract_json).get(array); if (error) { cerr << error << endl; exit(1); } // Iterate through an array of objects - for (dom::element elem : rootarray) { + for (dom::element elem : array) { dom::object obj; - if (!elem.get(obj, error)) { cerr << error << endl; exit(1); } + if ((error = elem.get(obj))) { 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); } + if ((error = key_value.value.get(innerobj))) { cerr << error << endl; exit(1); } double va, vb; - if (!innerobj["a"].get(va, error)) { cerr << error << endl; exit(1); } + if ((error = innerobj["a"].get(va))) { cerr << error << endl; exit(1); } cout << "a: " << va << ", "; - if (!innerobj["b"].get(vb, error)) { cerr << error << endl; exit(1); } + if ((error = innerobj["b"].get(vb))) { cerr << error << endl; exit(1); } cout << "b: " << vb << ", "; int64_t vc; - if (!innerobj["c"].get(vc, error)) { cerr << error << endl; exit(1); } + if ((error = innerobj["c"].get(vc))) { cerr << error << endl; exit(1); } cout << "c: " << vc << endl; } } @@ -109,8 +107,7 @@ void basics_error_5() { { "str" : { "123" : {"abc" : 3.14 } } } )"_padded; dom::parser parser; double v; - simdjson::error_code error; - parser.parse(abstract_json)["str"]["123"]["abc"].get(v, error); + auto error = parser.parse(abstract_json)["str"]["123"]["abc"].get(v); if (error) { cerr << error << endl; exit(1); } cout << "number: " << v << endl; } @@ -126,38 +123,34 @@ void basics_error_3_cpp17() { { "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] } ] )"_padded; dom::parser parser; - auto [cars, error] = parser.parse(cars_json).get(); + dom::array cars; + auto error = parser.parse(cars_json).get(cars); if (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); + error = car_element.get(car); if (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); } + if ((error = car["make"].get(make))) { cerr << error << endl; exit(1); } + if ((error = car["model"].get(model))) { 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); } + if ((error = car["year"].get(year))) { 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); } + if ((error = car["tire_pressure"].get(tire_pressure_array))) { 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); } + if ((error = tire_pressure_element.get(tire_pressure))) { cerr << error << endl; exit(1); } total_tire_pressure += tire_pressure; } cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl; @@ -174,20 +167,18 @@ void basics_error_3_cpp17() { simdjson::dom::parser parser{}; bool parse_double(const char *j, double &d) { - simdjson::error_code error; - parser.parse(j, std::strlen(j)) + auto error = parser.parse(j, std::strlen(j)) .at(0) - .get(d, error); + .get(d); if (error) { return false; } return true; } bool parse_string(const char *j, std::string &s) { - simdjson::error_code error; std::string_view answer; - parser.parse(j,strlen(j)) + auto error = parser.parse(j,strlen(j)) .at(0) - .get(answer, error); + .get(answer); if (error) { return false; } s.assign(answer.data(), answer.size()); return true; diff --git a/tools/jsonstats.cpp b/tools/jsonstats.cpp index 0e85db14a..4f2aa4208 100644 --- a/tools/jsonstats.cpp +++ b/tools/jsonstats.cpp @@ -74,7 +74,7 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { if (element.is()) { s.array_count++; simdjson::dom::array array; - if (element.get(array, error)) { + if (not (error = element.get(array))) { size_t counter = 0; for (auto child : array) { counter++; @@ -87,7 +87,7 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { } else if (element.is()) { s.object_count++; simdjson::dom::object object; - if (element.get(object, error)) { + if (not (error = element.get(object))) { size_t counter = 0; for (auto [key, value] : object) { counter++; @@ -121,7 +121,8 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { s.integer_count++; // because an int can be sometimes represented as a double, we // to check whether it is an integer first!!! int64_t v; - element.get(v,error); + error = element.get(v); + SIMDJSON_ASSUME(!error); if((v >= std::numeric_limits::min()) and (v <= std::numeric_limits::max()) ) { s.integer32_count++; } @@ -135,7 +136,8 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { s.float_count++; } else if (element.is()) { bool v; - element.get(v,error); + error = element.get(v); + SIMDJSON_ASSUME(!error); if (v) { s.true_count++; } else { @@ -146,7 +148,8 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { } else if (element.is()) { s.string_count++; std::string_view v; - element.get(v,error); + error = element.get(v); + SIMDJSON_ASSUME(!error); if (is_ascii(v)) { s.ascii_string_count++; } @@ -155,8 +158,7 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { s.string_maximum_length = v.size(); } } else { - std::cerr << "unrecognized node." << std::endl; - abort(); + SIMDJSON_UNREACHABLE(); } } }