From 1ff55c27296ca2a2205d81f88769e37d0aed9778 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Sun, 21 Jun 2020 15:26:44 -0700 Subject: [PATCH] Replace auto [x,error] with .get() everywhere --- benchmark/bench_dom_api.cpp | 5 +- benchmark/distinctuseridcompetition.cpp | 3 +- benchmark/minifiercompetition.cpp | 3 +- benchmark/parseandstatcompetition.cpp | 13 ++- benchmark/parsingcompetition.cpp | 7 +- benchmark/statisticalmodel.cpp | 6 +- doc/basics.md | 20 +--- doc/performance.md | 10 +- include/simdjson/dom/parser.h | 20 ++-- include/simdjson/error.h | 3 +- tests/allparserscheckfile.cpp | 17 ++-- tests/basictests.cpp | 116 +++++++++--------------- tests/jsoncheck.cpp | 3 +- tests/numberparsingcheck.cpp | 3 +- tests/readme_examples.cpp | 22 +++-- tests/readme_examples_noexceptions.cpp | 19 +--- tests/singleheadertest.cpp | 7 +- tests/stringparsingcheck.cpp | 3 +- tests/test_macros.h | 12 ++- tools/json2json.cpp | 8 +- tools/jsonpointer.cpp | 9 +- tools/jsonstats.cpp | 6 +- tools/minify.cpp | 3 +- 23 files changed, 155 insertions(+), 163 deletions(-) diff --git a/benchmark/bench_dom_api.cpp b/benchmark/bench_dom_api.cpp index 294977e25..ed6467bd9 100644 --- a/benchmark/bench_dom_api.cpp +++ b/benchmark/bench_dom_api.cpp @@ -485,7 +485,8 @@ static void iterator_twitter_image_sizes(State& state) { if (iter.down()) { // first status do { - // auto [media, not_found] = tweet["entities"]["media"]; + // dom::object media; + // not_found = tweet["entities"]["media"].get(media); // if (!not_found) { if (iter.move_to_key("entities")) { if (!iter.is_object()) { return; } @@ -496,7 +497,7 @@ static void iterator_twitter_image_sizes(State& state) { if (iter.down()) { // first media do { - // for (auto [key, size] : image["sizes"].get()) { + // for (auto [key, size] : dom::object(image["sizes"])) { if (!(iter.move_to_key("sizes") && iter.is_object())) { return; } if (iter.down()) { // first size do { diff --git a/benchmark/distinctuseridcompetition.cpp b/benchmark/distinctuseridcompetition.cpp index a9bb86dc6..f2c4a6434 100644 --- a/benchmark/distinctuseridcompetition.cpp +++ b/benchmark/distinctuseridcompetition.cpp @@ -331,7 +331,8 @@ int main(int argc, char *argv[]) { std::cerr << "warning: ignoring everything after " << argv[optind + 1] << std::endl; } - auto [p, error] = simdjson::padded_string::load(filename); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); if (error) { std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE; diff --git a/benchmark/minifiercompetition.cpp b/benchmark/minifiercompetition.cpp index 2a8c1611a..08c80f7aa 100644 --- a/benchmark/minifiercompetition.cpp +++ b/benchmark/minifiercompetition.cpp @@ -75,7 +75,8 @@ int main(int argc, char *argv[]) { exit(1); } const char *filename = argv[optind]; - auto [p, error] = simdjson::padded_string::load(filename); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); if (error) { std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE; diff --git a/benchmark/parseandstatcompetition.cpp b/benchmark/parseandstatcompetition.cpp index d18ffc992..72972ca92 100644 --- a/benchmark/parseandstatcompetition.cpp +++ b/benchmark/parseandstatcompetition.cpp @@ -105,7 +105,8 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { never_inline stat_t simdjson_compute_stats(const simdjson::padded_string &p) { stat_t s{}; simdjson::dom::parser parser; - auto [doc, error] = parser.parse(p); + simdjson::dom::element doc; + auto error = parser.parse(p).get(doc); if (error) { s.valid = false; return s; @@ -409,7 +410,8 @@ int main(int argc, char *argv[]) { std::cerr << "warning: ignoring everything after " << argv[optind + 1] << std::endl; } - auto [p, error] = simdjson::padded_string::load(filename); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); if (error) { std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE; @@ -464,9 +466,10 @@ int main(int argc, char *argv[]) { printf("API traversal tests\n"); printf("Based on https://github.com/miloyip/nativejson-benchmark\n"); simdjson::dom::parser parser; - auto [doc, err] = parser.parse(p); - if (err) { - std::cerr << err << std::endl; + simdjson::dom::element doc; + auto error = parser.parse(p).get(doc); + if (error) { + std::cerr << error << std::endl; } size_t refval = simdjson_compute_stats_refplus(doc).objectCount; diff --git a/benchmark/parsingcompetition.cpp b/benchmark/parsingcompetition.cpp index 80a2a76d9..509e44087 100644 --- a/benchmark/parsingcompetition.cpp +++ b/benchmark/parsingcompetition.cpp @@ -82,9 +82,10 @@ inline void reset_stream(std::stringstream & is) { bool bench(const char *filename, bool verbose, bool just_data, double repeat_multiplier) { - auto [p, err] = simdjson::padded_string::load(filename); - if (err) { - std::cerr << "Could not load the file " << filename << std::endl; + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); + if (error) { + std::cerr << "Could not load the file " << filename << ": " << error << std::endl; return false; } diff --git a/benchmark/statisticalmodel.cpp b/benchmark/statisticalmodel.cpp index 3838f5ef9..89efe82d6 100644 --- a/benchmark/statisticalmodel.cpp +++ b/benchmark/statisticalmodel.cpp @@ -96,7 +96,8 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) { stat_t simdjson_compute_stats(const simdjson::padded_string &p) { stat_t answer{}; simdjson::dom::parser parser; - auto [doc, error] = parser.parse(p); + simdjson::dom::element doc; + auto error = parser.parse(p).get(doc); if (error) { answer.valid = false; return answer; @@ -136,7 +137,8 @@ int main(int argc, char *argv[]) { std::cerr << "warning: ignoring everything after " << argv[optind + 1] << std::endl; } - auto [p, error] = simdjson::padded_string::load(filename); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); if (error) { std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE; diff --git a/doc/basics.md b/doc/basics.md index 0f5c5d541..3751b2582 100644 --- a/doc/basics.md +++ b/doc/basics.md @@ -239,29 +239,18 @@ Error Handling -------------- All simdjson APIs that can fail return `simdjson_result`, which is a <value, error_code> -pair. The error codes and values can be accessed directly, reading the error like so: +pair. You can retrieve the value with .get(), like so: ```c++ -auto [doc, error] = parser.parse(json); // doc is a dom::element +dom::element doc; +auto error = parser.parse(json).get(doc); if (error) { cerr << error << endl; exit(1); } -// Use document here now that we've checked for the error ``` When you use the code this way, it is your responsibility to check for error before using the result: if there is an error, the result value will not be valid and using it will caused undefined behavior. -> Note: because of the way `auto [x, y]` works in C++, you have to define new variables each time you -> use it. If your project treats aliased, this means you can't use the same names in `auto [x, error]` -> without triggering warnings or error (and particularly can't use the word "error" every time). To -> circumvent this, you can use this instead: -> -> ```c++ -> dom::element doc; -> auto error = parser.parse(json).get(doc); // <-- Assigns to doc and error just like "auto [doc, error]" -> ``` - - We can write a "quick start" example where we attempt to parse a file and access some data, without triggering exceptions: ```C++ @@ -269,11 +258,12 @@ 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; auto error = parser.load("twitter.json").get(tweets); if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } - simdjson::dom::element res; + simdjson::dom::element res; if ((error = tweets["search_metadata"]["count"].get(res))) { std::cerr << "could not access keys" << std::endl; return EXIT_FAILURE; diff --git a/doc/performance.md b/doc/performance.md index bf022a4cd..1b65e995b 100644 --- a/doc/performance.md +++ b/doc/performance.md @@ -68,7 +68,8 @@ without bound: ```c++ dom::parser parser(1000*1000); // Never grow past documents > 1MB for (web_request request : listen()) { - auto [doc, error] = parser.parse(request.body); + dom::element doc; + auto error = parser.parse(request.body).get(doc); // If the document was above our limit, emit 413 = payload too large if (error == CAPACITY) { request.respond(413); continue; } // ... @@ -82,11 +83,12 @@ without bound: ```c++ dom::parser parser(0); // This parser will refuse to automatically grow capacity - simdjson::error_code allocate_error = parser.allocate(1000*1000); // This allocates enough capacity to handle documents <= 1MB - if (allocate_error) { cerr << allocate_error << endl; exit(1); } + auto error = parser.allocate(1000*1000); // This allocates enough capacity to handle documents <= 1MB + if (error) { cerr << error << endl; exit(1); } for (web_request request : listen()) { - auto [doc, error] = parser.parse(request.body); + dom::element doc; + error = parser.parse(request.body).get(doc); // If the document was above our limit, emit 413 = payload too large if (error == CAPACITY) { request.respond(413); continue; } // ... diff --git a/include/simdjson/dom/parser.h b/include/simdjson/dom/parser.h index ba3d9b668..25eccf430 100644 --- a/include/simdjson/dom/parser.h +++ b/include/simdjson/dom/parser.h @@ -173,9 +173,13 @@ public: * the same interface, requiring you to check the error before using the document: * * dom::parser parser; - * for (auto [doc, error] : parser.load_many(path)) { - * if (error) { cerr << error << endl; exit(1); } - * cout << std::string(doc["title"]) << endl; + * dom::document_stream docs; + * auto error = parser.load_many(path).get(docs); + * if (error) { cerr << error << endl; exit(1); } + * for (auto doc : docs) { + * std::string_view title; + * if ((error = doc["title"].get(title)) { cerr << error << endl; exit(1); } + * cout << title << endl; * } * * ### Threads @@ -233,9 +237,13 @@ public: * the same interface, requiring you to check the error before using the document: * * dom::parser parser; - * for (auto [doc, error] : parser.parse_many(buf, len)) { - * if (error) { cerr << error << endl; exit(1); } - * cout << std::string(doc["title"]) << endl; + * dom::document_stream docs; + * auto error = parser.load_many(path).get(docs); + * if (error) { cerr << error << endl; exit(1); } + * for (auto doc : docs) { + * std::string_view title; + * if ((error = doc["title"].get(title)) { cerr << error << endl; exit(1); } + * cout << title << endl; * } * * ### REQUIRED: Buffer Padding diff --git a/include/simdjson/error.h b/include/simdjson/error.h index f272abd83..308bc1f0b 100644 --- a/include/simdjson/error.h +++ b/include/simdjson/error.h @@ -42,7 +42,8 @@ enum error_code { * Get the error message for the given error code. * * dom::parser parser; - * auto [doc, error] = parser.parse("foo"); + * dom::element doc; + * auto error = parser.parse("foo").get(doc); * if (error) { printf("Error: %s\n", error_message(error)); } * * @return The error message. diff --git a/tests/allparserscheckfile.cpp b/tests/allparserscheckfile.cpp index 6784a0603..959268e63 100644 --- a/tests/allparserscheckfile.cpp +++ b/tests/allparserscheckfile.cpp @@ -63,9 +63,10 @@ int main(int argc, char *argv[]) { exit(1); } const char *filename = argv[optind]; - auto [p, loaderr] = simdjson::padded_string::load(filename); - if (loaderr) { - std::cerr << "Could not load the file " << filename << ": " << loaderr << std::endl; + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); + if (error) { + std::cerr << "Could not load the file " << filename << ": " << error << std::endl; return EXIT_FAILURE; } if (verbose) { @@ -79,7 +80,7 @@ int main(int argc, char *argv[]) { std::cout << std::endl; } simdjson::dom::parser parser; - auto err = parser.parse(p).error(); + error = parser.parse(p).error(); rapidjson::Document d; @@ -95,19 +96,19 @@ int main(int argc, char *argv[]) { .is_valid(); if (just_favorites) { printf("our parser : %s \n", - (err == simdjson::error_code::SUCCESS) ? "correct" : "invalid"); + (error == simdjson::error_code::SUCCESS) ? "correct" : "invalid"); printf("rapid (check encoding) : %s \n", rapid_correct_checkencoding ? "correct" : "invalid"); printf("sajson : %s \n", sajson_correct ? "correct" : "invalid"); - if (err == simdjson::DEPTH_ERROR) { + if (error == simdjson::DEPTH_ERROR) { printf("simdjson encountered a DEPTH_ERROR, it was parametrized to " "reject documents with depth exceeding %zu.\n", parser.max_depth()); } - if (((err == simdjson::error_code::SUCCESS) != rapid_correct_checkencoding) || + if (((error == simdjson::error_code::SUCCESS) != rapid_correct_checkencoding) || (rapid_correct_checkencoding != sajson_correct) || - ((err == simdjson::SUCCESS) != sajson_correct)) { + ((error == simdjson::SUCCESS) != sajson_correct)) { printf("WARNING: THEY DISAGREE\n\n"); return EXIT_FAILURE; } diff --git a/tests/basictests.cpp b/tests/basictests.cpp index e5f3d8e85..994652890 100644 --- a/tests/basictests.cpp +++ b/tests/basictests.cpp @@ -178,17 +178,14 @@ namespace number_tests { } namespace document_tests { - int issue938() { + bool issue938() { std::vector json_strings{"[true,false]", "[1,2,3,null]", R"({"yay":"json!"})"}; simdjson::dom::parser parser1; for (simdjson::padded_string str : json_strings) { - auto [element, error] = parser1.parse(str); - if(error) { - std::cerr << error << std::endl; - } else { - std::cout << element << std::endl; - } + simdjson::dom::element element; + ASSERT_SUCCESS( parser1.parse(str).get(element) ); + std::cout << element << std::endl; } std::vector file_paths{ ADVERSARIAL_JSON, FLATADVERSARIAL_JSON, DEMO_JSON, @@ -196,23 +193,17 @@ namespace document_tests { TRUENULL_JSON}; for (auto path : file_paths) { simdjson::dom::parser parser2; + simdjson::dom::element element; std::cout << "file: " << path << std::endl; - auto [element, error] = parser2.load(path); - if(error) { - std::cerr << error << std::endl; - } else { - std::cout << element.type() << std::endl; - } + ASSERT_SUCCESS( parser2.load(path).get(element) ); + std::cout << element.type() << std::endl; } simdjson::dom::parser parser3; for (auto path : file_paths) { + simdjson::dom::element element; std::cout << "file: " << path << std::endl; - auto [element, error] = parser3.load(path); - if(error) { - std::cerr << error << std::endl; - } else { - std::cout << element.type() << std::endl; - } + ASSERT_SUCCESS( parser3.load(path).get(element) ); + std::cout << element.type() << std::endl; } return true; } @@ -222,11 +213,7 @@ namespace document_tests { std::cout << __func__ << std::endl; simdjson::padded_string badjson = "[7,7,7,7,6,7,7,7,6,7,7,6,[7,7,7,7,6,7,7,7,6,7,7,6,7,7,7,7,7,7,6"_padded; simdjson::dom::parser parser; - auto error = parser.parse(badjson).error(); - if (!error) { - printf("This json should not be valid %s.\n", badjson.data()); - return false; - } + ASSERT_ERROR( parser.parse(badjson), simdjson::TAPE_ERROR ); return true; } bool count_array_example() { @@ -251,9 +238,9 @@ namespace document_tests { std::cout << __func__ << std::endl; simdjson::dom::parser parser; // This is an invalid document padded with open braces. - ASSERT_ERROR( parser.parse("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", 2, false).error(), simdjson::TAPE_ERROR); + ASSERT_ERROR( parser.parse("[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", 2, false), simdjson::TAPE_ERROR); // This is a valid document padded with open braces. - ASSERT_SUCCESS( parser.parse("[][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", 2, false).error() ); + ASSERT_SUCCESS( parser.parse("[][[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", 2, false) ); return true; } // returns true if successful @@ -400,7 +387,7 @@ namespace document_stream_tests { size_t count = 0; for(; i != stream.end(); ++i) { auto doc = *i; - ASSERT_SUCCESS(doc.error()); + ASSERT_SUCCESS(doc); if( i.current_index() != count) { std::cout << "index:" << i.current_index() << std::endl; std::cout << "expected index:" << count << std::endl; @@ -508,12 +495,7 @@ namespace document_stream_tests { size_t count = 0; simdjson::dom::document_stream stream; ASSERT_SUCCESS( parser.parse_many(str, batch_size).get(stream) ); - for (auto [doc, error] : stream) { - if (error) { - printf("Error at on document %zd at batch size %zu: %s\n", count, batch_size, simdjson::error_message(error)); - return false; - } - + for (auto doc : stream) { int64_t keyid; ASSERT_SUCCESS( doc["id"].get(keyid) ); ASSERT_EQUAL( keyid, int64_t(count) ); @@ -553,12 +535,7 @@ namespace document_stream_tests { size_t count = 0; simdjson::dom::document_stream stream; ASSERT_SUCCESS( parser.parse_many(str, batch_size).get(stream) ); - for (auto [doc, error] : stream) { - if (error) { - printf("Error at on document %zd at batch size %zu: %s\n", count, batch_size, simdjson::error_message(error)); - return false; - } - + for (auto doc : stream) { int64_t keyid; ASSERT_SUCCESS( doc["id"].get(keyid) ); ASSERT_EQUAL( keyid, int64_t(count) ); @@ -593,9 +570,9 @@ namespace parse_api_tests { bool parser_parse() { std::cout << "Running " << __func__ << std::endl; dom::parser parser; - auto [doc, error] = parser.parse(BASIC_JSON); - if (error) { cerr << error << endl; return false; } - if (!doc.is()) { cerr << "Document did not parse as an array" << endl; return false; } + dom::element doc; + ASSERT_SUCCESS( parser.parse(BASIC_JSON).get(doc) ); + ASSERT_EQUAL( doc.is(), true ); return true; } bool parser_parse_many() { @@ -604,12 +581,12 @@ namespace parse_api_tests { int count = 0; simdjson::dom::document_stream stream; ASSERT_SUCCESS( parser.parse_many(BASIC_NDJSON).get(stream) ); - for (auto [doc, error] : stream) { - if (error) { cerr << "Error in parse_many: " << endl; return false; } - if (!doc.is()) { cerr << "Document did not parse as an array" << endl; return false; } + for (auto doc : stream) { + UNUSED dom::array array; + ASSERT_SUCCESS( doc.get(array) ); count++; } - if (count != 2) { cerr << "parse_many returned " << count << " documents, expected 2" << endl; return false; } + ASSERT_EQUAL(count, 2); return true; } @@ -619,12 +596,12 @@ namespace parse_api_tests { std::cout << "Running " << __func__ << std::endl; dom::parser parser; int count = 0; - for (auto [doc, error] : parser.parse_many(BASIC_NDJSON)) { - if (error) { cerr << "Error in parse_many: " << endl; return false; } - if (!doc.is()) { cerr << "Document did not parse as an array" << endl; return false; } + for (auto doc : parser.parse_many(BASIC_NDJSON)) { + UNUSED dom::array array; + ASSERT_SUCCESS( doc.get(array) ); count++; } - if (count != 2) { cerr << "parse_many returned " << count << " documents, expected 2" << endl; return false; } + ASSERT_EQUAL(count, 2); return true; } SIMDJSON_POP_DISABLE_WARNINGS @@ -635,7 +612,7 @@ namespace parse_api_tests { simdjson::dom::document_stream stream; ASSERT_SUCCESS( parser.parse_many(EMPTY_NDJSON).get(stream) ); for (auto doc : stream) { - ASSERT_SUCCESS(doc.error()); + ASSERT_SUCCESS( doc ); count++; } ASSERT_EQUAL(count, 0); @@ -654,8 +631,7 @@ namespace parse_api_tests { memcpy(&empty_batches_ndjson[BATCH_SIZE*11+6], "3", 1); simdjson::dom::document_stream stream; ASSERT_SUCCESS( parser.parse_many(empty_batches_ndjson, BATCH_SIZE*16).get(stream) ); - for (auto [doc, error] : stream) { - ASSERT_SUCCESS(error); + for (auto doc : stream) { count++; uint64_t val; ASSERT_SUCCESS( doc.get(val) ); @@ -678,16 +654,14 @@ namespace parse_api_tests { int count = 0; simdjson::dom::document_stream stream; ASSERT_SUCCESS( parser.load_many(AMAZON_CELLPHONES_NDJSON).get(stream) ); - for (auto [doc, error] : stream) { - ASSERT_SUCCESS( error ); - + for (auto doc : stream) { dom::array arr; ASSERT_SUCCESS( doc.get(arr) ); // let us get the array - ASSERT_EQUAL(arr.size(), 9); + ASSERT_EQUAL( arr.size(), 9 ); size_t arr_count = 0; for (auto v : arr) { arr_count++; (void)v; } - ASSERT_EQUAL(arr_count, 9); + ASSERT_EQUAL( arr_count, 9 ); count++; } @@ -701,9 +675,7 @@ namespace parse_api_tests { std::cout << "Running " << __func__ << " on " << AMAZON_CELLPHONES_NDJSON << std::endl; dom::parser parser; int count = 0; - for (auto [doc, error] : parser.load_many(AMAZON_CELLPHONES_NDJSON)) { - if (error) { cerr << error << endl; return false; } - + for (auto doc : parser.load_many(AMAZON_CELLPHONES_NDJSON)) { dom::array arr; ASSERT_SUCCESS( doc.get(arr) ); ASSERT_EQUAL( arr.size(), 9 ); @@ -902,7 +874,7 @@ namespace dom_api_tests { int i = 0; for (auto [key, value] : object) { ASSERT_EQUAL( key, expected_key[i] ); - ASSERT_EQUAL( value.get().value(), expected_value[i] ); + ASSERT_EQUAL( value.get().first, expected_value[i] ); i++; } ASSERT_EQUAL( i*sizeof(uint64_t), sizeof(expected_value) ); @@ -987,18 +959,18 @@ namespace dom_api_tests { ASSERT_SUCCESS( parser.parse(json).get(array) ); auto iter = array.begin(); - ASSERT_EQUAL( (*iter).get().value(), 0 ); - ASSERT_EQUAL( (*iter).get().value(), 0 ); - ASSERT_EQUAL( (*iter).get().value(), 0 ); + ASSERT_EQUAL( (*iter).get().first, 0 ); + ASSERT_EQUAL( (*iter).get().first, 0 ); + ASSERT_EQUAL( (*iter).get().first, 0 ); ++iter; - ASSERT_EQUAL( (*iter).get().value(), 1 ); - ASSERT_EQUAL( (*iter).get().value(), 1 ); - ASSERT_EQUAL( (*iter).get().value(), 1 ); + ASSERT_EQUAL( (*iter).get().first, 1 ); + ASSERT_EQUAL( (*iter).get().first, 1 ); + ASSERT_EQUAL( (*iter).get().first, 1 ); ++iter; - ASSERT_EQUAL( (*iter).get().value(), -1 ); - ASSERT_EQUAL( (*iter).get().value(), -1 ); + ASSERT_EQUAL( (*iter).get().first, -1 ); + ASSERT_EQUAL( (*iter).get().first, -1 ); ++iter; - ASSERT_EQUAL( (*iter).get().value(), 1.1 ); + ASSERT_EQUAL( (*iter).get().first, 1.1 ); return true; } @@ -1054,7 +1026,7 @@ namespace dom_api_tests { object["d"].tie(val, error); ASSERT_ERROR( error, NO_SUCH_FIELD ); ASSERT_ERROR( object["d"].get(val), NO_SUCH_FIELD ); - ASSERT_ERROR( object["d"].error(), NO_SUCH_FIELD ); + ASSERT_ERROR( object["d"], NO_SUCH_FIELD ); return true; } diff --git a/tests/jsoncheck.cpp b/tests/jsoncheck.cpp index 55c734e69..35001c7ce 100644 --- a/tests/jsoncheck.cpp +++ b/tests/jsoncheck.cpp @@ -60,7 +60,8 @@ bool validate(const char *dirname) { char *fullpath = static_cast(malloc(fullpathlen)); snprintf(fullpath, fullpathlen, "%s%s%s", dirname, needsep ? "/" : "", name); - auto [p, error] = simdjson::padded_string::load(fullpath); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(fullpath).get(p); if (error) { std::cerr << "Could not load the file " << fullpath << std::endl; return EXIT_FAILURE; diff --git a/tests/numberparsingcheck.cpp b/tests/numberparsingcheck.cpp index 92ab25f37..dbcc30477 100644 --- a/tests/numberparsingcheck.cpp +++ b/tests/numberparsingcheck.cpp @@ -172,7 +172,8 @@ bool validate(const char *dirname) { } else { strcpy(fullpath + dirlen, name); } - auto [p, error] = simdjson::padded_string::load(fullpath); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(fullpath).get(p); if (error) { std::cerr << "Could not load the file " << fullpath << std::endl; return EXIT_FAILURE; diff --git a/tests/readme_examples.cpp b/tests/readme_examples.cpp index 1242f3ce5..c870f03ce 100644 --- a/tests/readme_examples.cpp +++ b/tests/readme_examples.cpp @@ -216,26 +216,28 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS // The web_request part of this is aspirational, so we compile as much as we can here void performance_2() { dom::parser parser(1000*1000); // Never grow past documents > 1MB -// for (web_request request : listen()) { - auto [doc, error] = parser.parse("1"_padded/*request.body*/); -// // If the document was above our limit, emit 413 = payload too large + /* for (web_request request : listen()) */ { + dom::element doc; + auto error = parser.parse("1"_padded/*request.body*/).get(doc); + // If the document was above our limit, emit 413 = payload too large if (error == CAPACITY) { /* request.respond(413); continue; */ } -// // ... -// } + // ... + } } // The web_request part of this is aspirational, so we compile as much as we can here void performance_3() { dom::parser parser(0); // This parser will refuse to automatically grow capacity - simdjson::error_code allocate_error = parser.allocate(1000*1000); // This allocates enough capacity to handle documents <= 1MB - if (allocate_error) { cerr << allocate_error << endl; exit(1); } + auto error = parser.allocate(1000*1000); // This allocates enough capacity to handle documents <= 1MB + if (error) { cerr << error << endl; exit(1); } - // for (web_request request : listen()) { - auto [doc, error] = parser.parse("1"_padded/*request.body*/); + /* for (web_request request : listen()) */ { + dom::element doc; + auto error = parser.parse("1"_padded/*request.body*/).get(doc); // If the document was above our limit, emit 413 = payload too large if (error == CAPACITY) { /* request.respond(413); continue; */ } // ... - // } + } } SIMDJSON_POP_DISABLE_WARNINGS #endif diff --git a/tests/readme_examples_noexceptions.cpp b/tests/readme_examples_noexceptions.cpp index 36bf89ced..e668a0f40 100644 --- a/tests/readme_examples_noexceptions.cpp +++ b/tests/readme_examples_noexceptions.cpp @@ -10,7 +10,8 @@ void basics_error_1() { dom::parser parser; auto json = "1"_padded; - auto [doc, error] = parser.parse(json); // doc is a dom::element + dom::element doc; + auto error = parser.parse(json).get(doc); if (error) { cerr << error << endl; exit(1); } // Use document here now that we've checked for the error } @@ -18,14 +19,6 @@ SIMDJSON_POP_DISABLE_WARNINGS #endif void basics_error_2() { - dom::parser parser; - auto json = "1"_padded; - - dom::element doc; - UNUSED auto error = parser.parse(json).get(doc); // <-- Assigns to doc and error just like "auto [doc, error]"} -} - -void basics_error_3() { auto cars_json = R"( [ { "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] }, { "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] }, @@ -70,8 +63,7 @@ void basics_error_3() { } } - -void basics_error_4() { +void basics_error_3() { auto abstract_json = R"( [ { "12345" : {"a":12.34, "b":56.78, "c": 9998877} }, { "12545" : {"a":11.44, "b":12.78, "c": 11111111} } @@ -102,7 +94,7 @@ void basics_error_4() { } } -void basics_error_5() { +void basics_error_4() { auto abstract_json = R"( { "str" : { "123" : {"abc" : 3.14 } } } )"_padded; dom::parser parser; @@ -116,7 +108,7 @@ void basics_error_5() { #ifdef SIMDJSON_CPLUSPLUS17 -void basics_error_3_cpp17() { +void basics_error_2_cpp17() { auto cars_json = R"( [ { "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] }, { "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] }, @@ -201,6 +193,5 @@ int main() { basics_error_2(); basics_error_3(); basics_error_4(); - basics_error_5(); return EXIT_SUCCESS; } diff --git a/tests/singleheadertest.cpp b/tests/singleheadertest.cpp index b2d0051d8..46a0e3cb0 100644 --- a/tests/singleheadertest.cpp +++ b/tests/singleheadertest.cpp @@ -6,12 +6,13 @@ using namespace simdjson; int main() { const char *filename = SIMDJSON_BENCHMARK_DATA_DIR "/twitter.json"; - padded_string p = get_corpus(filename); dom::parser parser; - auto [doc, error] = parser.parse(p); - if(error) { + dom::element doc; + auto error = parser.load(filename).get(doc); + if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; } + std::cout << doc << std::endl; return EXIT_SUCCESS; } diff --git a/tests/stringparsingcheck.cpp b/tests/stringparsingcheck.cpp index eeec5900b..cefaa637b 100644 --- a/tests/stringparsingcheck.cpp +++ b/tests/stringparsingcheck.cpp @@ -337,7 +337,8 @@ bool validate(const char *dirname) { } else { strcpy(fullpath + dirlen, name); } - auto [p, error] = simdjson::padded_string::load(fullpath); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(fullpath).get(p); if (error) { std::cerr << "Could not load the file " << fullpath << std::endl; return EXIT_FAILURE; diff --git a/tests/test_macros.h b/tests/test_macros.h index a44855534..661e50b81 100644 --- a/tests/test_macros.h +++ b/tests/test_macros.h @@ -27,6 +27,14 @@ bool equals_expected(const char *actual, const char return !strcmp(actual, expected); } +simdjson::error_code to_error_code(simdjson::error_code error) { + return error; +} +template +simdjson::error_code to_error_code(const simdjson::simdjson_result &result) { + return result.error(); +} + #define TEST_START() { cout << "Running " << __func__ << " ..." << endl; } #define ASSERT_EQUAL(ACTUAL, EXPECTED) \ do { \ @@ -37,10 +45,10 @@ do { \ return false; \ } \ } while(0); -#define ASSERT_ERROR(ACTUAL, EXPECTED) do { auto _actual = (ACTUAL); auto _expected = (EXPECTED); if (_actual != _expected) { std::cerr << "FAIL: Unexpected error \"" << _actual << "\" (expected \"" << _expected << "\")" << std::endl; return false; } } while (0); +#define ASSERT_ERROR(ACTUAL, EXPECTED) do { auto _actual = to_error_code(ACTUAL); auto _expected = to_error_code(EXPECTED); if (_actual != _expected) { std::cerr << "FAIL: Unexpected error \"" << _actual << "\" (expected \"" << _expected << "\")" << std::endl; return false; } } while (0); #define ASSERT(RESULT, MESSAGE) if (!(RESULT)) { std::cerr << MESSAGE << std::endl; return false; } #define RUN_TEST(RESULT) if (!RESULT) { return false; } -#define ASSERT_SUCCESS(ERROR) do { auto _error = (ERROR); if (_error) { std::cerr << _error << std::endl; return false; } } while(0); +#define ASSERT_SUCCESS(ERROR) do { auto _error = to_error_code(ERROR); if (_error) { std::cerr << _error << std::endl; return false; } } while(0); #define TEST_FAIL(MESSAGE) { std::cerr << "FAIL: " << (MESSAGE) << std::endl; return false; } #define TEST_SUCCEED() { return true; } diff --git a/tools/json2json.cpp b/tools/json2json.cpp index d02ba74c5..084ad3ca2 100644 --- a/tools/json2json.cpp +++ b/tools/json2json.cpp @@ -49,10 +49,10 @@ int main(int argc, char *argv[]) { const char *filename = result["file"].as().c_str(); simdjson::dom::parser parser; - auto [doc, error] = parser.load(filename); // do the parsing, return false on error - if (error != simdjson::SUCCESS) { - std::cerr << " Parsing failed. Error is '" << simdjson::error_message(error) - << "'." << std::endl; + simdjson::dom::element doc; + auto error = parser.load(filename).get(doc); // do the parsing, return false on error + if (error) { + std::cerr << " Parsing failed. Error is '" << error << "'." << std::endl; return EXIT_FAILURE; } if(rawdump) { diff --git a/tools/jsonpointer.cpp b/tools/jsonpointer.cpp index c5f0c6f55..ca6311a1b 100644 --- a/tools/jsonpointer.cpp +++ b/tools/jsonpointer.cpp @@ -20,16 +20,17 @@ int main(int argc, char *argv[]) { const char *filename = argv[1]; simdjson::dom::parser parser; - auto [doc, error] = parser.load(filename); + simdjson::dom::element doc; + auto error = parser.load(filename).get(doc); if (error) { std::cerr << "Error parsing " << filename << ": " << error << std::endl; } std::cout << "[" << std::endl; for (int idx = 2; idx < argc; idx++) { const char *json_pointer = argv[idx]; - auto [value, pointer_error] = doc[json_pointer]; + simdjson::dom::element value; std::cout << "{\"jsonpath\": \"" << json_pointer << "\""; - if (pointer_error) { - std::cout << ",\"error\":\"" << pointer_error << "\""; + if ((error = doc[json_pointer].get(value))) { + std::cout << ",\"error\":\"" << error << "\""; } else { std::cout << ",\"value\":" << value; } diff --git a/tools/jsonstats.cpp b/tools/jsonstats.cpp index 4f2aa4208..977d6a480 100644 --- a/tools/jsonstats.cpp +++ b/tools/jsonstats.cpp @@ -166,7 +166,8 @@ void recurse(simdjson::dom::element element, stat_t &s, size_t depth) { stat_t simdjson_compute_stats(const simdjson::padded_string &p) { stat_t s{}; simdjson::dom::parser parser; - auto [doc, error] = parser.parse(p); + simdjson::dom::element doc; + auto error = parser.parse(p).get(doc); if (error) { s.valid = false; std::cerr << error << std::endl; @@ -217,7 +218,8 @@ int main(int argc, char *argv[]) { const char *filename = result["file"].as().c_str(); - auto [p, error] = simdjson::padded_string::load(filename); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); if (error) { std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE; diff --git a/tools/minify.cpp b/tools/minify.cpp index f9f264c42..2e2acebd2 100644 --- a/tools/minify.cpp +++ b/tools/minify.cpp @@ -56,7 +56,8 @@ int main(int argc, char *argv[]) { std::string filename = result["file"].as(); - auto [p, error] = simdjson::padded_string::load(filename); + simdjson::padded_string p; + auto error = simdjson::padded_string::load(filename).get(p); if (error) { std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE;