Prefixing macros (issue 1035) (#1124)
* Renaming partially done. * More prefixing. * I thought that this was fixed. * Missed one. * Missed a few. * Missed another one. * Minor fixes.
This commit is contained in:
parent
09bd7e8ef8
commit
8a8eea53a2
|
@ -26,7 +26,7 @@ static void recover_one_string(State& state) {
|
|||
cerr << "could not parse string" << error << endl;
|
||||
return;
|
||||
}
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::string_view v;
|
||||
error = doc.get(v);
|
||||
if (error) {
|
||||
|
@ -59,7 +59,7 @@ static void serialize_twitter(State& state) {
|
|||
return;
|
||||
}
|
||||
size_t bytes = 0;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::string serial = simdjson::minify(doc);
|
||||
bytes += serial.size();
|
||||
benchmark::DoNotOptimize(serial);
|
||||
|
@ -83,7 +83,7 @@ static void numbers_scan(State& state) {
|
|||
cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl;
|
||||
return;
|
||||
}
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
for (auto e : arr) {
|
||||
double x;
|
||||
|
@ -105,7 +105,7 @@ static void numbers_size_scan(State& state) {
|
|||
cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl;
|
||||
return;
|
||||
}
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
container.resize(arr.size());
|
||||
size_t pos = 0;
|
||||
|
@ -131,7 +131,7 @@ static void numbers_type_scan(State& state) {
|
|||
cerr << "could not read " << NUMBERS_JSON << " as an array" << endl;
|
||||
return;
|
||||
}
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
for (auto e : arr) {
|
||||
dom::element_type actual_type = e.type();
|
||||
|
@ -157,7 +157,7 @@ static void numbers_type_size_scan(State& state) {
|
|||
cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl;
|
||||
return;
|
||||
}
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
container.resize(arr.size());
|
||||
size_t pos = 0;
|
||||
|
@ -182,7 +182,7 @@ static void numbers_load_scan(State& state) {
|
|||
dom::parser parser;
|
||||
dom::array arr;
|
||||
simdjson::error_code error;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
// this may hit the disk, but probably just once
|
||||
if ((error = parser.load(NUMBERS_JSON).get(arr))) {
|
||||
cerr << "could not read " << NUMBERS_JSON << " as an array: " << error << endl;
|
||||
|
@ -205,7 +205,7 @@ static void numbers_load_size_scan(State& state) {
|
|||
dom::parser parser;
|
||||
dom::array arr;
|
||||
simdjson::error_code error;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
// this may hit the disk, but probably just once
|
||||
if ((error = parser.load(NUMBERS_JSON).get(arr))) {
|
||||
cerr << "could not read " << NUMBERS_JSON << " as an array" << endl;
|
||||
|
@ -234,7 +234,7 @@ static void numbers_exceptions_scan(State& state) {
|
|||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
for (double x : arr) {
|
||||
container.push_back(x);
|
||||
|
@ -249,7 +249,7 @@ static void numbers_exceptions_size_scan(State& state) {
|
|||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
container.resize(arr.size());
|
||||
size_t pos = 0;
|
||||
|
@ -269,7 +269,7 @@ static void numbers_type_exceptions_scan(State& state) {
|
|||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
for (auto e : arr) {
|
||||
dom::element_type actual_type = e.type();
|
||||
|
@ -288,7 +288,7 @@ static void numbers_type_exceptions_size_scan(State& state) {
|
|||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::vector<double> container;
|
||||
container.resize(arr.size());
|
||||
size_t pos = 0;
|
||||
|
@ -309,7 +309,7 @@ BENCHMARK(numbers_type_exceptions_size_scan);
|
|||
static void numbers_exceptions_load_scan(State& state) {
|
||||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
// this may hit the disk, but probably just once
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
std::vector<double> container;
|
||||
|
@ -325,7 +325,7 @@ BENCHMARK(numbers_exceptions_load_scan);
|
|||
static void numbers_exceptions_load_size_scan(State& state) {
|
||||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
// this may hit the disk, but probably just once
|
||||
dom::array arr = parser.load(NUMBERS_JSON);
|
||||
std::vector<double> container;
|
||||
|
@ -346,7 +346,7 @@ static void twitter_count(State& state) {
|
|||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(TWITTER_JSON);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
uint64_t result_count = doc["search_metadata"]["count"];
|
||||
if (result_count != 100) { return; }
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ static void iterator_twitter_count(State& state) {
|
|||
// Prints the number of results in twitter.json
|
||||
padded_string json = padded_string::load(TWITTER_JSON);
|
||||
ParsedJson pj = build_parsed_json(json);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
ParsedJson::Iterator iter(pj);
|
||||
// uint64_t result_count = doc["search_metadata"]["count"];
|
||||
if (!iter.move_to_key("search_metadata")) { return; }
|
||||
|
@ -377,7 +377,7 @@ static void twitter_default_profile(State& state) {
|
|||
// Count unique users with a default profile.
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(TWITTER_JSON);
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
set<string_view> default_users;
|
||||
for (dom::object tweet : doc["statuses"]) {
|
||||
dom::object user = tweet["user"];
|
||||
|
@ -395,7 +395,7 @@ static void twitter_image_sizes(State& state) {
|
|||
dom::parser parser;
|
||||
dom::element doc = parser.load(TWITTER_JSON);
|
||||
simdjson::error_code error;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
set<tuple<uint64_t, uint64_t>> image_sizes;
|
||||
for (dom::object tweet : doc["statuses"]) {
|
||||
dom::array media;
|
||||
|
@ -420,7 +420,7 @@ static void error_code_twitter_count(State& state) noexcept {
|
|||
simdjson::error_code error;
|
||||
dom::element doc;
|
||||
if ((error = parser.load(TWITTER_JSON).get(doc))) { return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
uint64_t value;
|
||||
if ((error = doc["search_metadata"]["count"].get(value))) { return; }
|
||||
if (value != 100) { return; }
|
||||
|
@ -434,7 +434,7 @@ static void error_code_twitter_default_profile(State& state) noexcept {
|
|||
simdjson::error_code error;
|
||||
dom::element doc;
|
||||
if ((error = parser.load(TWITTER_JSON).get(doc))) { std::cerr << error << std::endl; return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
set<string_view> default_users;
|
||||
|
||||
dom::array tweets;
|
||||
|
@ -464,7 +464,7 @@ static void iterator_twitter_default_profile(State& state) {
|
|||
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) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
set<string_view> default_users;
|
||||
ParsedJson::Iterator iter(pj);
|
||||
|
||||
|
@ -505,7 +505,7 @@ static void error_code_twitter_image_sizes(State& state) noexcept {
|
|||
simdjson::error_code error;
|
||||
dom::element doc;
|
||||
if ((error = parser.load(TWITTER_JSON).get(doc))) { std::cerr << error << std::endl; return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
set<tuple<uint64_t, uint64_t>> image_sizes;
|
||||
dom::array statuses;
|
||||
if ((error = doc["statuses"].get(statuses))) { return; }
|
||||
|
@ -537,7 +537,7 @@ static void iterator_twitter_image_sizes(State& state) {
|
|||
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) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
set<tuple<uint64_t, uint64_t>> image_sizes;
|
||||
ParsedJson::Iterator iter(pj);
|
||||
|
||||
|
@ -602,7 +602,7 @@ static void print_json(State& state) noexcept {
|
|||
|
||||
int code = json_parse(json, parser);
|
||||
if (code) { cerr << error_message(code) << endl; return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
std::stringstream s;
|
||||
if (!parser.print_json(s)) { cerr << "print_json failed" << endl; return; }
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ static void unicode_validate_twitter(State& state) {
|
|||
return;
|
||||
}
|
||||
size_t bytes = 0;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
bool is_ok = simdjson::validate_utf8(docdata.data(), docdata.size());
|
||||
bytes += docdata.size();
|
||||
benchmark::DoNotOptimize(is_ok);
|
||||
|
@ -55,7 +55,7 @@ static void parse_twitter(State& state) {
|
|||
return;
|
||||
}
|
||||
size_t bytes = 0;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
dom::element doc;
|
||||
bytes += docdata.size();
|
||||
if ((error = parser.parse(docdata).get(doc))) {
|
||||
|
@ -90,7 +90,7 @@ static void parse_gsoc(State& state) {
|
|||
return;
|
||||
}
|
||||
size_t bytes = 0;
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
bytes += docdata.size();
|
||||
dom::element doc;
|
||||
if ((error = parser.parse(docdata).get(doc))) {
|
||||
|
@ -116,7 +116,7 @@ SIMDJSON_DISABLE_DEPRECATED_WARNING
|
|||
static void json_parse(State& state) {
|
||||
ParsedJson pj;
|
||||
if (!pj.allocate_capacity(EMPTY_ARRAY.length())) { return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
auto error = json_parse(EMPTY_ARRAY, pj);
|
||||
if (error) { return; }
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ BENCHMARK(json_parse);
|
|||
static void parser_parse_error_code(State& state) {
|
||||
dom::parser parser;
|
||||
if (parser.allocate(EMPTY_ARRAY.length())) { return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
auto error = parser.parse(EMPTY_ARRAY).error();
|
||||
if (error) { return; }
|
||||
}
|
||||
|
@ -138,9 +138,9 @@ BENCHMARK(parser_parse_error_code);
|
|||
static void parser_parse_exception(State& state) {
|
||||
dom::parser parser;
|
||||
if (parser.allocate(EMPTY_ARRAY.length())) { return; }
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
try {
|
||||
UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);
|
||||
SIMDJSON_UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);
|
||||
} catch(simdjson_error &j) {
|
||||
cout << j.what() << endl;
|
||||
return;
|
||||
|
@ -154,7 +154,7 @@ BENCHMARK(parser_parse_exception);
|
|||
SIMDJSON_PUSH_DISABLE_WARNINGS
|
||||
SIMDJSON_DISABLE_DEPRECATED_WARNING
|
||||
static void build_parsed_json(State& state) {
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
dom::parser parser = simdjson::build_parsed_json(EMPTY_ARRAY);
|
||||
if (!parser.valid) { return; }
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
|||
|
||||
BENCHMARK(build_parsed_json);
|
||||
static void document_parse_error_code(State& state) {
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
dom::parser parser;
|
||||
auto error = parser.parse(EMPTY_ARRAY).error();
|
||||
if (error) { return; }
|
||||
|
@ -174,10 +174,10 @@ BENCHMARK(document_parse_error_code);
|
|||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
static void document_parse_exception(State& state) {
|
||||
for (UNUSED auto _ : state) {
|
||||
for (SIMDJSON_UNUSED auto _ : state) {
|
||||
try {
|
||||
dom::parser parser;
|
||||
UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);
|
||||
SIMDJSON_UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);
|
||||
} catch(simdjson_error &j) {
|
||||
cout << j.what() << endl;
|
||||
return;
|
||||
|
|
|
@ -158,7 +158,7 @@ struct feature_benchmarker {
|
|||
|
||||
}
|
||||
|
||||
really_inline void run_iterations(size_t iterations, bool stage1_only=false) {
|
||||
simdjson_really_inline void run_iterations(size_t iterations, bool stage1_only=false) {
|
||||
struct7.run_iterations(iterations, stage1_only);
|
||||
struct7_miss.run_iterations(iterations, stage1_only);
|
||||
struct7_full.run_iterations(iterations, stage1_only);
|
||||
|
|
|
@ -308,7 +308,7 @@ struct benchmarker {
|
|||
return all_stages_without_allocation.iterations;
|
||||
}
|
||||
|
||||
really_inline void run_iteration(bool stage1_only, bool hotbuffers=false) {
|
||||
simdjson_really_inline void run_iteration(bool stage1_only, bool hotbuffers=false) {
|
||||
// Allocate dom::parser
|
||||
collector.start();
|
||||
dom::parser parser;
|
||||
|
@ -384,7 +384,7 @@ struct benchmarker {
|
|||
loop << all_loop_count;
|
||||
}
|
||||
|
||||
really_inline void run_iterations(size_t iterations, bool stage1_only, bool hotbuffers=false) {
|
||||
simdjson_really_inline void run_iterations(size_t iterations, bool stage1_only, bool hotbuffers=false) {
|
||||
for (size_t i = 0; i<iterations; i++) {
|
||||
run_iteration(stage1_only, hotbuffers);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ void print_vec(const std::vector<int64_t> &v) {
|
|||
// clang-format on
|
||||
|
||||
|
||||
really_inline void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::element element);
|
||||
simdjson_really_inline void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::element element);
|
||||
void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::array array) {
|
||||
for (auto child : array) {
|
||||
simdjson_recurse(v, child);
|
||||
|
@ -97,8 +97,8 @@ void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::object object) {
|
|||
}
|
||||
}
|
||||
}
|
||||
really_inline void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::element element) {
|
||||
UNUSED simdjson::error_code error;
|
||||
simdjson_really_inline void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::element element) {
|
||||
SIMDJSON_UNUSED simdjson::error_code error;
|
||||
simdjson::dom::array array;
|
||||
simdjson::dom::object object;
|
||||
if (not (error = element.get(array))) {
|
||||
|
@ -108,7 +108,7 @@ really_inline void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::ele
|
|||
}
|
||||
}
|
||||
|
||||
really_inline std::vector<int64_t>
|
||||
simdjson_really_inline std::vector<int64_t>
|
||||
simdjson_just_dom(simdjson::dom::element doc) {
|
||||
std::vector<int64_t> answer;
|
||||
simdjson_recurse(answer, doc);
|
||||
|
@ -116,7 +116,7 @@ simdjson_just_dom(simdjson::dom::element doc) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
really_inline std::vector<int64_t>
|
||||
simdjson_really_inline std::vector<int64_t>
|
||||
simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
std::vector<int64_t> answer;
|
||||
simdjson::dom::parser parser;
|
||||
|
@ -129,7 +129,7 @@ simdjson_compute_stats(const simdjson::padded_string &p) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
really_inline simdjson::error_code
|
||||
simdjson_really_inline simdjson::error_code
|
||||
simdjson_just_parse(const simdjson::padded_string &p) {
|
||||
simdjson::dom::parser parser;
|
||||
return parser.parse(p).error();
|
||||
|
@ -187,7 +187,7 @@ void sajson_traverse(std::vector<int64_t> &answer, const sajson::value &node) {
|
|||
}
|
||||
}
|
||||
|
||||
really_inline std::vector<int64_t>
|
||||
simdjson_really_inline std::vector<int64_t>
|
||||
sasjon_just_dom(sajson::document &d) {
|
||||
std::vector<int64_t> answer;
|
||||
sajson_traverse(answer, d.get_root());
|
||||
|
@ -195,7 +195,7 @@ sasjon_just_dom(sajson::document &d) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
really_inline std::vector<int64_t>
|
||||
simdjson_really_inline std::vector<int64_t>
|
||||
sasjon_compute_stats(const simdjson::padded_string &p) {
|
||||
std::vector<int64_t> answer;
|
||||
char *buffer = (char *)malloc(p.size());
|
||||
|
@ -212,7 +212,7 @@ sasjon_compute_stats(const simdjson::padded_string &p) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
really_inline bool
|
||||
simdjson_really_inline bool
|
||||
sasjon_just_parse(const simdjson::padded_string &p) {
|
||||
char *buffer = (char *)malloc(p.size());
|
||||
memcpy(buffer, p.data(), p.size());
|
||||
|
@ -263,7 +263,7 @@ void rapid_traverse(std::vector<int64_t> &answer, const rapidjson::Value &v) {
|
|||
}
|
||||
}
|
||||
|
||||
really_inline std::vector<int64_t>
|
||||
simdjson_really_inline std::vector<int64_t>
|
||||
rapid_just_dom(rapidjson::Document &d) {
|
||||
std::vector<int64_t> answer;
|
||||
rapid_traverse(answer, d);
|
||||
|
@ -271,7 +271,7 @@ rapid_just_dom(rapidjson::Document &d) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
really_inline std::vector<int64_t>
|
||||
simdjson_really_inline std::vector<int64_t>
|
||||
rapid_compute_stats(const simdjson::padded_string &p) {
|
||||
std::vector<int64_t> answer;
|
||||
char *buffer = (char *)malloc(p.size() + 1);
|
||||
|
@ -289,7 +289,7 @@ rapid_compute_stats(const simdjson::padded_string &p) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
really_inline bool
|
||||
simdjson_really_inline bool
|
||||
rapid_just_parse(const simdjson::padded_string &p) {
|
||||
char *buffer = (char *)malloc(p.size() + 1);
|
||||
memcpy(buffer, p.data(), p.size());
|
||||
|
|
|
@ -133,13 +133,13 @@ struct event_collector {
|
|||
}
|
||||
#endif
|
||||
|
||||
really_inline void start() {
|
||||
simdjson_really_inline void start() {
|
||||
#if defined(__linux)
|
||||
linux_events.start();
|
||||
#endif
|
||||
start_clock = steady_clock::now();
|
||||
}
|
||||
really_inline event_count& end() {
|
||||
simdjson_really_inline event_count& end() {
|
||||
time_point<steady_clock> end_clock = steady_clock::now();
|
||||
#if defined(__linux)
|
||||
linux_events.end(count.event_counts);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <iostream>
|
||||
|
||||
// Gigabyte: https://en.wikipedia.org/wiki/Gigabyte
|
||||
never_inline
|
||||
simdjson_never_inline
|
||||
double bench(std::string filename, simdjson::padded_string& p) {
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_clock =
|
||||
std::chrono::steady_clock::now();
|
||||
|
|
|
@ -48,7 +48,7 @@ void print_stat(const stat_t &s) {
|
|||
s.true_count, s.false_count);
|
||||
}
|
||||
|
||||
really_inline void simdjson_process_atom(stat_t &s,
|
||||
simdjson_really_inline void simdjson_process_atom(stat_t &s,
|
||||
simdjson::dom::element element) {
|
||||
if (element.is<double>()) {
|
||||
s.number_count++;
|
||||
|
@ -102,7 +102,7 @@ void simdjson_recurse(stat_t &s, simdjson::dom::element element) {
|
|||
}
|
||||
}
|
||||
|
||||
never_inline stat_t simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
simdjson_never_inline stat_t simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t s{};
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element doc;
|
||||
|
@ -212,13 +212,13 @@ static void RapidGenStat(Stat &stat, const rapidjson::Value &v) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
never_inline Stat rapidjson_compute_stats_ref(const rapidjson::Value &doc) {
|
||||
simdjson_never_inline Stat rapidjson_compute_stats_ref(const rapidjson::Value &doc) {
|
||||
Stat s{};
|
||||
RapidGenStat(s, doc);
|
||||
return s;
|
||||
}
|
||||
|
||||
never_inline Stat
|
||||
simdjson_never_inline Stat
|
||||
simdjson_compute_stats_refplus(const simdjson::dom::element &doc) {
|
||||
Stat s{};
|
||||
GenStatPlus(s, doc);
|
||||
|
@ -268,7 +268,7 @@ void sajson_traverse(stat_t &stats, const sajson::value &node) {
|
|||
}
|
||||
}
|
||||
|
||||
never_inline stat_t sasjon_compute_stats(const simdjson::padded_string &p) {
|
||||
simdjson_never_inline stat_t sasjon_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t answer{};
|
||||
char *buffer = (char *)malloc(p.size());
|
||||
if (buffer == nullptr) {
|
||||
|
@ -329,7 +329,7 @@ void rapid_traverse(stat_t &stats, const rapidjson::Value &v) {
|
|||
}
|
||||
}
|
||||
|
||||
never_inline stat_t rapid_compute_stats(const simdjson::padded_string &p) {
|
||||
simdjson_never_inline stat_t rapid_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t answer{};
|
||||
char *buffer = (char *)malloc(p.size() + 1);
|
||||
if (buffer == nullptr) {
|
||||
|
@ -355,7 +355,7 @@ never_inline stat_t rapid_compute_stats(const simdjson::padded_string &p) {
|
|||
return answer;
|
||||
}
|
||||
|
||||
never_inline stat_t
|
||||
simdjson_never_inline stat_t
|
||||
rapid_accurate_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t answer{};
|
||||
char *buffer = (char *)malloc(p.size() + 1);
|
||||
|
|
|
@ -53,7 +53,7 @@ using namespace rapidjson;
|
|||
|
||||
#ifdef ALLPARSER
|
||||
// fastjson has a tricky interface
|
||||
void on_json_error(void *, UNUSED const fastjson::ErrorContext &ec) {
|
||||
void on_json_error(void *, SIMDJSON_UNUSED const fastjson::ErrorContext &ec) {
|
||||
// std::cerr<<"ERROR: "<<ec.mesg<<std::endl;
|
||||
}
|
||||
bool fastjson_parse(const char *input) {
|
||||
|
@ -65,7 +65,7 @@ bool fastjson_parse(const char *input) {
|
|||
// end of fastjson stuff
|
||||
#endif
|
||||
|
||||
never_inline size_t sum_line_lengths(std::stringstream & is) {
|
||||
simdjson_never_inline size_t sum_line_lengths(std::stringstream & is) {
|
||||
std::string line;
|
||||
size_t sumofalllinelengths{0};
|
||||
while(std::getline(is, line)) {
|
||||
|
|
|
@ -41,7 +41,7 @@ using stat_t = struct stat_s;
|
|||
|
||||
|
||||
|
||||
really_inline void simdjson_process_atom(stat_t &s,
|
||||
simdjson_really_inline void simdjson_process_atom(stat_t &s,
|
||||
simdjson::dom::element element) {
|
||||
if (element.is<int64_t>()) {
|
||||
s.integer_count++;
|
||||
|
|
|
@ -13,6 +13,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||
if (error) { return 1; }
|
||||
|
||||
NulOStream os;
|
||||
UNUSED auto dumpstatus = elem.dump_raw_tape(os);
|
||||
SIMDJSON_UNUSED auto dumpstatus = elem.dump_raw_tape(os);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <string>
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
simdjson::dom::parser parser;
|
||||
UNUSED simdjson::dom::element elem;
|
||||
UNUSED auto error = parser.parse(Data, Size).get(elem);
|
||||
SIMDJSON_UNUSED simdjson::dom::element elem;
|
||||
SIMDJSON_UNUSED auto error = parser.parse(Data, Size).get(elem);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,34 +38,34 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
|
|||
|
||||
#if defined(__GNUC__)
|
||||
// Marks a block with a name so that MCA analysis can see it.
|
||||
#define BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name);
|
||||
#define END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name);
|
||||
#define DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name);
|
||||
#define SIMDJSON_BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name);
|
||||
#define SIMDJSON_END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name);
|
||||
#define SIMDJSON_DEBUG_BLOCK(name, block) BEGIN_DEBUG_BLOCK(name); block; END_DEBUG_BLOCK(name);
|
||||
#else
|
||||
#define BEGIN_DEBUG_BLOCK(name)
|
||||
#define END_DEBUG_BLOCK(name)
|
||||
#define DEBUG_BLOCK(name, block)
|
||||
#define SIMDJSON_BEGIN_DEBUG_BLOCK(name)
|
||||
#define SIMDJSON_END_DEBUG_BLOCK(name)
|
||||
#define SIMDJSON_DEBUG_BLOCK(name, block)
|
||||
#endif
|
||||
|
||||
// Align to N-byte boundary
|
||||
#define ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1))
|
||||
#define ROUNDDOWN_N(a, n) ((a) & ~((n)-1))
|
||||
#define SIMDJSON_ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1))
|
||||
#define SIMDJSON_ROUNDDOWN_N(a, n) ((a) & ~((n)-1))
|
||||
|
||||
#define ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
||||
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
|
||||
|
||||
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO)
|
||||
|
||||
#define really_inline __forceinline
|
||||
#define never_inline __declspec(noinline)
|
||||
#define simdjson_really_inline __forceinline
|
||||
#define simdjson_never_inline __declspec(noinline)
|
||||
|
||||
#define UNUSED
|
||||
#define WARN_UNUSED
|
||||
#define SIMDJSON_UNUSED
|
||||
#define SIMDJSON_WARN_UNUSED
|
||||
|
||||
#ifndef likely
|
||||
#define likely(x) x
|
||||
#ifndef simdjson_likely
|
||||
#define simdjson_likely(x) x
|
||||
#endif
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) x
|
||||
#ifndef simdjson_unlikely
|
||||
#define simdjson_unlikely(x) x
|
||||
#endif
|
||||
|
||||
#define SIMDJSON_PUSH_DISABLE_WARNINGS __pragma(warning( push ))
|
||||
|
@ -89,17 +89,17 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
|
|||
|
||||
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
|
||||
#define really_inline inline __attribute__((always_inline))
|
||||
#define never_inline inline __attribute__((noinline))
|
||||
#define simdjson_really_inline inline __attribute__((always_inline))
|
||||
#define simdjson_never_inline inline __attribute__((noinline))
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
#define WARN_UNUSED __attribute__((warn_unused_result))
|
||||
#define SIMDJSON_UNUSED __attribute__((unused))
|
||||
#define SIMDJSON_WARN_UNUSED __attribute__((warn_unused_result))
|
||||
|
||||
#ifndef likely
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#ifndef simdjson_likely
|
||||
#define simdjson_likely(x) __builtin_expect(!!(x), 1)
|
||||
#endif
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#ifndef simdjson_unlikely
|
||||
#define simdjson_unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
|
||||
#define SIMDJSON_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push")
|
||||
|
|
|
@ -19,7 +19,7 @@ class element;
|
|||
class array {
|
||||
public:
|
||||
/** Create a new, invalid array */
|
||||
really_inline array() noexcept;
|
||||
simdjson_really_inline array() noexcept;
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
|
@ -60,7 +60,7 @@ public:
|
|||
iterator(const iterator&) noexcept = default;
|
||||
iterator& operator=(const iterator&) noexcept = default;
|
||||
private:
|
||||
really_inline iterator(const internal::tape_ref &tape) noexcept;
|
||||
simdjson_really_inline iterator(const internal::tape_ref &tape) noexcept;
|
||||
internal::tape_ref tape;
|
||||
friend class array;
|
||||
};
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
inline simdjson_result<element> at(size_t index) const noexcept;
|
||||
|
||||
private:
|
||||
really_inline array(const internal::tape_ref &tape) noexcept;
|
||||
simdjson_really_inline array(const internal::tape_ref &tape) noexcept;
|
||||
internal::tape_ref tape;
|
||||
friend class element;
|
||||
friend struct simdjson_result<element>;
|
||||
|
@ -145,9 +145,9 @@ inline std::ostream& operator<<(std::ostream& out, const array &value);
|
|||
template<>
|
||||
struct simdjson_result<dom::array> : public internal::simdjson_result_base<dom::array> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept; ///< @private
|
||||
really_inline simdjson_result(dom::array value) noexcept; ///< @private
|
||||
really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result() noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(dom::array value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
|
||||
inline simdjson_result<dom::element> at_pointer(std::string_view json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||
|
|
|
@ -80,13 +80,13 @@ public:
|
|||
* error = parser.parse_many(json).get(docs);
|
||||
* ```
|
||||
*/
|
||||
really_inline document_stream() noexcept;
|
||||
simdjson_really_inline document_stream() noexcept;
|
||||
/** Move one document_stream to another. */
|
||||
really_inline document_stream(document_stream &&other) noexcept = default;
|
||||
simdjson_really_inline document_stream(document_stream &&other) noexcept = default;
|
||||
/** Move one document_stream to another. */
|
||||
really_inline document_stream &operator=(document_stream &&other) noexcept = default;
|
||||
simdjson_really_inline document_stream &operator=(document_stream &&other) noexcept = default;
|
||||
|
||||
really_inline ~document_stream() noexcept;
|
||||
simdjson_really_inline ~document_stream() noexcept;
|
||||
|
||||
/**
|
||||
* An iterator through a forward-only stream of documents.
|
||||
|
@ -96,7 +96,7 @@ public:
|
|||
/**
|
||||
* Get the current document (or error).
|
||||
*/
|
||||
really_inline simdjson_result<element> operator*() noexcept;
|
||||
simdjson_really_inline simdjson_result<element> operator*() noexcept;
|
||||
/**
|
||||
* Advance to the next document.
|
||||
*/
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
* Check if we're at the end yet.
|
||||
* @param other the end iterator to compare to.
|
||||
*/
|
||||
really_inline bool operator!=(const iterator &other) const noexcept;
|
||||
simdjson_really_inline bool operator!=(const iterator &other) const noexcept;
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
|
@ -121,7 +121,7 @@ public:
|
|||
* may change in future versions of simdjson: we find the API somewhat
|
||||
* awkward and we would like to offer something friendlier.
|
||||
*/
|
||||
really_inline size_t current_index() const noexcept;
|
||||
simdjson_really_inline size_t current_index() const noexcept;
|
||||
/**
|
||||
* @private
|
||||
*
|
||||
|
@ -141,10 +141,10 @@ public:
|
|||
* may change in future versions of simdjson: we find the API somewhat
|
||||
* awkward and we would like to offer something friendlier.
|
||||
*/
|
||||
really_inline std::string_view source() const noexcept;
|
||||
simdjson_really_inline std::string_view source() const noexcept;
|
||||
|
||||
private:
|
||||
really_inline iterator(document_stream &s, bool finished) noexcept;
|
||||
simdjson_really_inline iterator(document_stream &s, bool finished) noexcept;
|
||||
/** The document_stream we're iterating through. */
|
||||
document_stream& stream;
|
||||
/** Whether we're finished or not. */
|
||||
|
@ -155,11 +155,11 @@ public:
|
|||
/**
|
||||
* Start iterating the documents in the stream.
|
||||
*/
|
||||
really_inline iterator begin() noexcept;
|
||||
simdjson_really_inline iterator begin() noexcept;
|
||||
/**
|
||||
* The end of the stream, for iterator comparison purposes.
|
||||
*/
|
||||
really_inline iterator end() noexcept;
|
||||
simdjson_really_inline iterator end() noexcept;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -175,7 +175,7 @@ private:
|
|||
* @param len is the length of the raw byte buffer in bytes
|
||||
* @param batch_size is the size of the windows (must be strictly greater or equal to the largest JSON document)
|
||||
*/
|
||||
really_inline document_stream(
|
||||
simdjson_really_inline document_stream(
|
||||
dom::parser &parser,
|
||||
const uint8_t *buf,
|
||||
size_t len,
|
||||
|
@ -270,18 +270,18 @@ private:
|
|||
template<>
|
||||
struct simdjson_result<dom::document_stream> : public internal::simdjson_result_base<dom::document_stream> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept; ///< @private
|
||||
really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
really_inline simdjson_result(dom::document_stream &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result() noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(dom::document_stream &&value) noexcept; ///< @private
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
really_inline dom::document_stream::iterator begin() noexcept(false);
|
||||
really_inline dom::document_stream::iterator end() noexcept(false);
|
||||
simdjson_really_inline dom::document_stream::iterator begin() noexcept(false);
|
||||
simdjson_really_inline dom::document_stream::iterator end() noexcept(false);
|
||||
#else // SIMDJSON_EXCEPTIONS
|
||||
[[deprecated("parse_many() and load_many() may return errors. Use document_stream stream; error = parser.parse_many().get(doc); instead.")]]
|
||||
really_inline dom::document_stream::iterator begin() noexcept;
|
||||
simdjson_really_inline dom::document_stream::iterator begin() noexcept;
|
||||
[[deprecated("parse_many() and load_many() may return errors. Use document_stream stream; error = parser.parse_many().get(doc); instead.")]]
|
||||
really_inline dom::document_stream::iterator end() noexcept;
|
||||
simdjson_really_inline dom::document_stream::iterator end() noexcept;
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
}; // struct simdjson_result<dom::document_stream>
|
||||
|
||||
|
|
|
@ -38,10 +38,10 @@ enum class element_type {
|
|||
class element {
|
||||
public:
|
||||
/** Create a new, invalid element. */
|
||||
really_inline element() noexcept;
|
||||
simdjson_really_inline element() noexcept;
|
||||
|
||||
/** The type of this element. */
|
||||
really_inline element_type type() const noexcept;
|
||||
simdjson_really_inline element_type type() const noexcept;
|
||||
|
||||
/**
|
||||
* Cast this element to an array.
|
||||
|
@ -207,7 +207,7 @@ public:
|
|||
* @tparam T bool, double, uint64_t, int64_t, std::string_view, const char *, dom::array, dom::object
|
||||
*/
|
||||
template<typename T>
|
||||
really_inline bool is() const noexcept;
|
||||
simdjson_really_inline bool is() const noexcept;
|
||||
|
||||
/**
|
||||
* Get the value as the provided type (T).
|
||||
|
@ -244,7 +244,7 @@ public:
|
|||
* @returns The error that occurred, or SUCCESS if there was no error.
|
||||
*/
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code get(T &value) const noexcept;
|
||||
SIMDJSON_WARN_UNUSED simdjson_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.
|
||||
|
@ -466,7 +466,7 @@ public:
|
|||
inline bool dump_raw_tape(std::ostream &out) const noexcept;
|
||||
|
||||
private:
|
||||
really_inline element(const internal::tape_ref &tape) noexcept;
|
||||
simdjson_really_inline element(const internal::tape_ref &tape) noexcept;
|
||||
internal::tape_ref tape;
|
||||
friend class document;
|
||||
friend class object;
|
||||
|
@ -502,58 +502,58 @@ inline std::ostream& operator<<(std::ostream& out, element_type type);
|
|||
template<>
|
||||
struct simdjson_result<dom::element> : public internal::simdjson_result_base<dom::element> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept; ///< @private
|
||||
really_inline simdjson_result(dom::element &&value) noexcept; ///< @private
|
||||
really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result() noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(dom::element &&value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
|
||||
really_inline simdjson_result<dom::element_type> type() const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element_type> type() const noexcept;
|
||||
template<typename T>
|
||||
really_inline bool is() const noexcept;
|
||||
simdjson_really_inline bool is() const noexcept;
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T> get() const noexcept;
|
||||
simdjson_really_inline simdjson_result<T> get() const noexcept;
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code get(T &value) const noexcept;
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code get(T &value) const noexcept;
|
||||
|
||||
really_inline simdjson_result<dom::array> get_array() const noexcept;
|
||||
really_inline simdjson_result<dom::object> get_object() const noexcept;
|
||||
really_inline simdjson_result<const char *> get_c_str() const noexcept;
|
||||
really_inline simdjson_result<size_t> get_string_length() const noexcept;
|
||||
really_inline simdjson_result<std::string_view> get_string() const noexcept;
|
||||
really_inline simdjson_result<int64_t> get_int64() const noexcept;
|
||||
really_inline simdjson_result<uint64_t> get_uint64() const noexcept;
|
||||
really_inline simdjson_result<double> get_double() const noexcept;
|
||||
really_inline simdjson_result<bool> get_bool() const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::array> get_array() const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::object> get_object() const noexcept;
|
||||
simdjson_really_inline simdjson_result<const char *> get_c_str() const noexcept;
|
||||
simdjson_really_inline simdjson_result<size_t> get_string_length() const noexcept;
|
||||
simdjson_really_inline simdjson_result<std::string_view> get_string() const noexcept;
|
||||
simdjson_really_inline simdjson_result<int64_t> get_int64() const noexcept;
|
||||
simdjson_really_inline simdjson_result<uint64_t> get_uint64() const noexcept;
|
||||
simdjson_really_inline simdjson_result<double> get_double() const noexcept;
|
||||
simdjson_really_inline simdjson_result<bool> get_bool() const noexcept;
|
||||
|
||||
really_inline bool is_array() const noexcept;
|
||||
really_inline bool is_object() const noexcept;
|
||||
really_inline bool is_string() const noexcept;
|
||||
really_inline bool is_int64() const noexcept;
|
||||
really_inline bool is_uint64() const noexcept;
|
||||
really_inline bool is_double() const noexcept;
|
||||
really_inline bool is_bool() const noexcept;
|
||||
really_inline bool is_null() const noexcept;
|
||||
simdjson_really_inline bool is_array() const noexcept;
|
||||
simdjson_really_inline bool is_object() const noexcept;
|
||||
simdjson_really_inline bool is_string() const noexcept;
|
||||
simdjson_really_inline bool is_int64() const noexcept;
|
||||
simdjson_really_inline bool is_uint64() const noexcept;
|
||||
simdjson_really_inline bool is_double() const noexcept;
|
||||
simdjson_really_inline bool is_bool() const noexcept;
|
||||
simdjson_really_inline bool is_null() const noexcept;
|
||||
|
||||
really_inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
||||
really_inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
||||
really_inline simdjson_result<dom::element> at_pointer(const std::string_view json_pointer) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> at_pointer(const std::string_view json_pointer) const noexcept;
|
||||
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
||||
really_inline simdjson_result<dom::element> at(const std::string_view json_pointer) const noexcept;
|
||||
really_inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||
really_inline simdjson_result<dom::element> at_key(std::string_view key) const noexcept;
|
||||
really_inline simdjson_result<dom::element> at_key_case_insensitive(std::string_view key) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> at(const std::string_view json_pointer) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> at_key(std::string_view key) const noexcept;
|
||||
simdjson_really_inline simdjson_result<dom::element> at_key_case_insensitive(std::string_view key) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
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);
|
||||
simdjson_really_inline operator bool() const noexcept(false);
|
||||
simdjson_really_inline explicit operator const char*() const noexcept(false);
|
||||
simdjson_really_inline operator std::string_view() const noexcept(false);
|
||||
simdjson_really_inline operator uint64_t() const noexcept(false);
|
||||
simdjson_really_inline operator int64_t() const noexcept(false);
|
||||
simdjson_really_inline operator double() const noexcept(false);
|
||||
simdjson_really_inline operator dom::array() const noexcept(false);
|
||||
simdjson_really_inline operator dom::object() const noexcept(false);
|
||||
|
||||
really_inline dom::array::iterator begin() const noexcept(false);
|
||||
really_inline dom::array::iterator end() const noexcept(false);
|
||||
simdjson_really_inline dom::array::iterator begin() const noexcept(false);
|
||||
simdjson_really_inline dom::array::iterator end() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
|
@ -569,7 +569,7 @@ public:
|
|||
* underlying output stream, that error will be propagated (simdjson_error will not be
|
||||
* thrown).
|
||||
*/
|
||||
really_inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false);
|
||||
simdjson_really_inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false);
|
||||
#endif
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -59,7 +59,7 @@ inline int json_parse(const padded_string &s, dom::parser &parser) noexcept {
|
|||
}
|
||||
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const uint8_t *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
SIMDJSON_WARN_UNUSED inline dom::parser build_parsed_json(const uint8_t *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(buf, len, realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
|
@ -71,7 +71,7 @@ WARN_UNUSED inline dom::parser build_parsed_json(const uint8_t *buf, size_t len,
|
|||
return parser;
|
||||
}
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const char *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
SIMDJSON_WARN_UNUSED inline dom::parser build_parsed_json(const char *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(buf, len, realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
|
@ -83,7 +83,7 @@ WARN_UNUSED inline dom::parser build_parsed_json(const char *buf, size_t len, bo
|
|||
return parser;
|
||||
}
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const std::string &s, bool realloc_if_needed = true) noexcept {
|
||||
SIMDJSON_WARN_UNUSED inline dom::parser build_parsed_json(const std::string &s, bool realloc_if_needed = true) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(s.data(), s.length(), realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
|
@ -95,7 +95,7 @@ WARN_UNUSED inline dom::parser build_parsed_json(const std::string &s, bool real
|
|||
return parser;
|
||||
}
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const padded_string &s) noexcept {
|
||||
SIMDJSON_WARN_UNUSED inline dom::parser build_parsed_json(const padded_string &s) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(s).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
|
|
|
@ -20,7 +20,7 @@ class key_value_pair;
|
|||
class object {
|
||||
public:
|
||||
/** Create a new, invalid object */
|
||||
really_inline object() noexcept;
|
||||
simdjson_really_inline object() noexcept;
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
iterator(const iterator&) noexcept = default;
|
||||
iterator& operator=(const iterator&) noexcept = default;
|
||||
private:
|
||||
really_inline iterator(const internal::tape_ref &tape) noexcept;
|
||||
simdjson_really_inline iterator(const internal::tape_ref &tape) noexcept;
|
||||
|
||||
internal::tape_ref tape;
|
||||
|
||||
|
@ -204,7 +204,7 @@ public:
|
|||
inline simdjson_result<element> at_key_case_insensitive(std::string_view key) const noexcept;
|
||||
|
||||
private:
|
||||
really_inline object(const internal::tape_ref &tape) noexcept;
|
||||
simdjson_really_inline object(const internal::tape_ref &tape) noexcept;
|
||||
|
||||
internal::tape_ref tape;
|
||||
|
||||
|
@ -225,7 +225,7 @@ public:
|
|||
element value;
|
||||
|
||||
private:
|
||||
really_inline key_value_pair(std::string_view _key, element _value) noexcept;
|
||||
simdjson_really_inline key_value_pair(std::string_view _key, element _value) noexcept;
|
||||
friend class object;
|
||||
};
|
||||
|
||||
|
@ -256,9 +256,9 @@ inline std::ostream& operator<<(std::ostream& out, const key_value_pair &value);
|
|||
template<>
|
||||
struct simdjson_result<dom::object> : public internal::simdjson_result_base<dom::object> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept; ///< @private
|
||||
really_inline simdjson_result(dom::object value) noexcept; ///< @private
|
||||
really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result() noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(dom::object value) noexcept; ///< @private
|
||||
simdjson_really_inline simdjson_result(error_code error) noexcept; ///< @private
|
||||
|
||||
inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
|
||||
inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
|
||||
|
|
|
@ -46,20 +46,20 @@ public:
|
|||
* to allocate an initial capacity, call allocate() after constructing the parser.
|
||||
* Defaults to SIMDJSON_MAXSIZE_BYTES (the largest single document simdjson can process).
|
||||
*/
|
||||
really_inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept;
|
||||
simdjson_really_inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept;
|
||||
/**
|
||||
* Take another parser's buffers and state.
|
||||
*
|
||||
* @param other The parser to take. Its capacity is zeroed.
|
||||
*/
|
||||
really_inline parser(parser &&other) noexcept;
|
||||
simdjson_really_inline parser(parser &&other) noexcept;
|
||||
parser(const parser &) = delete; ///< @private Disallow copying
|
||||
/**
|
||||
* Take another parser's buffers and state.
|
||||
*
|
||||
* @param other The parser to take. Its capacity is zeroed.
|
||||
*/
|
||||
really_inline parser &operator=(parser &&other) noexcept;
|
||||
simdjson_really_inline parser &operator=(parser &&other) noexcept;
|
||||
parser &operator=(const parser &) = delete; ///< @private Disallow copying
|
||||
|
||||
/** Deallocate the JSON parser. */
|
||||
|
@ -129,17 +129,17 @@ public:
|
|||
inline simdjson_result<element> parse(const uint8_t *buf, size_t len, bool realloc_if_needed = true) & noexcept;
|
||||
inline simdjson_result<element> parse(const uint8_t *buf, size_t len, bool realloc_if_needed = true) && =delete;
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
really_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) & noexcept;
|
||||
really_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) && =delete;
|
||||
simdjson_really_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) & noexcept;
|
||||
simdjson_really_inline simdjson_result<element> parse(const char *buf, size_t len, bool realloc_if_needed = true) && =delete;
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
really_inline simdjson_result<element> parse(const std::string &s) & noexcept;
|
||||
really_inline simdjson_result<element> parse(const std::string &s) && =delete;
|
||||
simdjson_really_inline simdjson_result<element> parse(const std::string &s) & noexcept;
|
||||
simdjson_really_inline simdjson_result<element> parse(const std::string &s) && =delete;
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
really_inline simdjson_result<element> parse(const padded_string &s) & noexcept;
|
||||
really_inline simdjson_result<element> parse(const padded_string &s) && =delete;
|
||||
simdjson_really_inline simdjson_result<element> parse(const padded_string &s) & noexcept;
|
||||
simdjson_really_inline simdjson_result<element> parse(const padded_string &s) && =delete;
|
||||
|
||||
/** @private We do not want to allow implicit conversion from C string to std::string. */
|
||||
really_inline simdjson_result<element> parse(const char *buf) noexcept = delete;
|
||||
simdjson_really_inline simdjson_result<element> parse(const char *buf) noexcept = delete;
|
||||
|
||||
/**
|
||||
* Load a file containing many JSON documents.
|
||||
|
@ -291,7 +291,7 @@ public:
|
|||
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
|
||||
* @return The error, if there is one.
|
||||
*/
|
||||
WARN_UNUSED inline error_code allocate(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
|
||||
SIMDJSON_WARN_UNUSED inline error_code allocate(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
|
||||
|
||||
/**
|
||||
* @private deprecated because it returns bool instead of error_code, which is our standard for
|
||||
|
@ -305,14 +305,14 @@ public:
|
|||
* @return true if successful, false if allocation failed.
|
||||
*/
|
||||
[[deprecated("Use allocate() instead.")]]
|
||||
WARN_UNUSED inline bool allocate_capacity(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
|
||||
SIMDJSON_WARN_UNUSED inline bool allocate_capacity(size_t capacity, size_t max_depth = DEFAULT_MAX_DEPTH) noexcept;
|
||||
|
||||
/**
|
||||
* The largest document this parser can support without reallocating.
|
||||
*
|
||||
* @return Current capacity, in bytes.
|
||||
*/
|
||||
really_inline size_t capacity() const noexcept;
|
||||
simdjson_really_inline size_t capacity() const noexcept;
|
||||
|
||||
/**
|
||||
* The largest document this parser can automatically support.
|
||||
|
@ -321,14 +321,14 @@ public:
|
|||
*
|
||||
* @return Maximum capacity, in bytes.
|
||||
*/
|
||||
really_inline size_t max_capacity() const noexcept;
|
||||
simdjson_really_inline size_t max_capacity() const noexcept;
|
||||
|
||||
/**
|
||||
* The maximum level of nested object and arrays supported by this parser.
|
||||
*
|
||||
* @return Maximum depth, in bytes.
|
||||
*/
|
||||
really_inline size_t max_depth() const noexcept;
|
||||
simdjson_really_inline size_t max_depth() const noexcept;
|
||||
|
||||
/**
|
||||
* Set max_capacity. This is the largest document this parser can automatically support.
|
||||
|
@ -340,7 +340,7 @@ public:
|
|||
*
|
||||
* @param max_capacity The new maximum capacity, in bytes.
|
||||
*/
|
||||
really_inline void set_max_capacity(size_t max_capacity) noexcept;
|
||||
simdjson_really_inline void set_max_capacity(size_t max_capacity) noexcept;
|
||||
|
||||
#ifdef SIMDJSON_THREADS_ENABLED
|
||||
/**
|
||||
|
|
|
@ -101,22 +101,22 @@ struct simdjson_result_base : public std::pair<T, error_code> {
|
|||
/**
|
||||
* Create a new empty result with error = UNINITIALIZED.
|
||||
*/
|
||||
really_inline simdjson_result_base() noexcept;
|
||||
simdjson_really_inline simdjson_result_base() noexcept;
|
||||
|
||||
/**
|
||||
* Create a new error result.
|
||||
*/
|
||||
really_inline simdjson_result_base(error_code error) noexcept;
|
||||
simdjson_really_inline simdjson_result_base(error_code error) noexcept;
|
||||
|
||||
/**
|
||||
* Create a new successful result.
|
||||
*/
|
||||
really_inline simdjson_result_base(T &&value) noexcept;
|
||||
simdjson_really_inline simdjson_result_base(T &&value) noexcept;
|
||||
|
||||
/**
|
||||
* Create a new result with both things (use if you don't want to branch when creating the result).
|
||||
*/
|
||||
really_inline simdjson_result_base(T &&value, error_code error) noexcept;
|
||||
simdjson_really_inline simdjson_result_base(T &&value, error_code error) noexcept;
|
||||
|
||||
/**
|
||||
* Move the value and the error to the provided variables.
|
||||
|
@ -124,19 +124,19 @@ struct simdjson_result_base : public std::pair<T, error_code> {
|
|||
* @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 void tie(T &value, error_code &error) && noexcept;
|
||||
simdjson_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;
|
||||
simdjson_really_inline error_code get(T &value) && noexcept;
|
||||
|
||||
/**
|
||||
* The error.
|
||||
*/
|
||||
really_inline error_code error() const noexcept;
|
||||
simdjson_really_inline error_code error() const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
|
@ -145,21 +145,21 @@ struct simdjson_result_base : public std::pair<T, error_code> {
|
|||
*
|
||||
* @throw simdjson_error if there was an error.
|
||||
*/
|
||||
really_inline T& value() noexcept(false);
|
||||
simdjson_really_inline T& value() noexcept(false);
|
||||
|
||||
/**
|
||||
* Take the result value (move it).
|
||||
*
|
||||
* @throw simdjson_error if there was an error.
|
||||
*/
|
||||
really_inline T&& take_value() && noexcept(false);
|
||||
simdjson_really_inline T&& take_value() && noexcept(false);
|
||||
|
||||
/**
|
||||
* Cast to the value (will throw on error).
|
||||
*
|
||||
* @throw simdjson_error if there was an error.
|
||||
*/
|
||||
really_inline operator T&&() && noexcept(false);
|
||||
simdjson_really_inline operator T&&() && noexcept(false);
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
}; // struct simdjson_result_base
|
||||
|
@ -176,19 +176,19 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
|
|||
/**
|
||||
* @private Create a new empty result with error = UNINITIALIZED.
|
||||
*/
|
||||
really_inline simdjson_result() noexcept;
|
||||
simdjson_really_inline simdjson_result() noexcept;
|
||||
/**
|
||||
* @private Create a new error result.
|
||||
*/
|
||||
really_inline simdjson_result(T &&value) noexcept;
|
||||
simdjson_really_inline simdjson_result(T &&value) noexcept;
|
||||
/**
|
||||
* @private Create a new successful result.
|
||||
*/
|
||||
really_inline simdjson_result(error_code error_code) noexcept;
|
||||
simdjson_really_inline simdjson_result(error_code error_code) noexcept;
|
||||
/**
|
||||
* @private Create a new result with both things (use if you don't want to branch when creating the result).
|
||||
*/
|
||||
really_inline simdjson_result(T &&value, error_code error) noexcept;
|
||||
simdjson_really_inline simdjson_result(T &&value, error_code error) noexcept;
|
||||
|
||||
/**
|
||||
* Move the value and the error to the provided variables.
|
||||
|
@ -196,19 +196,19 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
|
|||
* @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 void tie(T &value, error_code &error) && noexcept;
|
||||
simdjson_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;
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code get(T &value) && noexcept;
|
||||
|
||||
/**
|
||||
* The error.
|
||||
*/
|
||||
really_inline error_code error() const noexcept;
|
||||
simdjson_really_inline error_code error() const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
|
@ -217,21 +217,21 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
|
|||
*
|
||||
* @throw simdjson_error if there was an error.
|
||||
*/
|
||||
really_inline T& value() noexcept(false);
|
||||
simdjson_really_inline T& value() noexcept(false);
|
||||
|
||||
/**
|
||||
* Take the result value (move it).
|
||||
*
|
||||
* @throw simdjson_error if there was an error.
|
||||
*/
|
||||
really_inline T&& take_value() && noexcept(false);
|
||||
simdjson_really_inline T&& take_value() && noexcept(false);
|
||||
|
||||
/**
|
||||
* Cast to the value (will throw on error).
|
||||
*
|
||||
* @throw simdjson_error if there was an error.
|
||||
*/
|
||||
really_inline operator T&&() && noexcept(false);
|
||||
simdjson_really_inline operator T&&() && noexcept(false);
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
}; // struct simdjson_result
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace simdjson {
|
|||
* @param len the length of the string in bytes.
|
||||
* @return true if the string is valid UTF-8.
|
||||
*/
|
||||
WARN_UNUSED bool validate_utf8(const char * buf, size_t len) noexcept;
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char * buf, size_t len) noexcept;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ WARN_UNUSED bool validate_utf8(const char * buf, size_t len) noexcept;
|
|||
* @param sv the string_view to validate.
|
||||
* @return true if the string is valid UTF-8.
|
||||
*/
|
||||
really_inline WARN_UNUSED bool validate_utf8(const std::string_view sv) noexcept {
|
||||
simdjson_really_inline SIMDJSON_WARN_UNUSED bool validate_utf8(const std::string_view sv) noexcept {
|
||||
return validate_utf8(sv.data(), sv.size());
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ really_inline WARN_UNUSED bool validate_utf8(const std::string_view sv) noexcept
|
|||
* @param p the string to validate.
|
||||
* @return true if the string is valid UTF-8.
|
||||
*/
|
||||
really_inline WARN_UNUSED bool validate_utf8(const std::string& s) noexcept {
|
||||
simdjson_really_inline SIMDJSON_WARN_UNUSED bool validate_utf8(const std::string& s) noexcept {
|
||||
return validate_utf8(s.data(), s.size());
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
* @param dst_len the number of bytes written. Output only.
|
||||
* @return the error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept = 0;
|
||||
SIMDJSON_WARN_UNUSED virtual error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept = 0;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -123,11 +123,11 @@ public:
|
|||
* @param len the length of the string in bytes.
|
||||
* @return true if and only if the string is valid UTF-8.
|
||||
*/
|
||||
WARN_UNUSED virtual bool validate_utf8(const char *buf, size_t len) const noexcept = 0;
|
||||
SIMDJSON_WARN_UNUSED virtual bool validate_utf8(const char *buf, size_t len) const noexcept = 0;
|
||||
|
||||
protected:
|
||||
/** @private Construct an implementation with the given name and description. For subclasses. */
|
||||
really_inline implementation(
|
||||
simdjson_really_inline implementation(
|
||||
std::string_view name,
|
||||
std::string_view description,
|
||||
uint32_t required_instruction_sets
|
||||
|
@ -165,7 +165,7 @@ namespace internal {
|
|||
class available_implementation_list {
|
||||
public:
|
||||
/** Get the list of available implementations compiled into simdjson */
|
||||
really_inline available_implementation_list() {}
|
||||
simdjson_really_inline available_implementation_list() {}
|
||||
/** Number of implementations */
|
||||
size_t size() const noexcept;
|
||||
/** STL const begin() iterator */
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace simdjson {
|
|||
//
|
||||
// simdjson_result<dom::array> inline implementation
|
||||
//
|
||||
really_inline simdjson_result<dom::array>::simdjson_result() noexcept
|
||||
simdjson_really_inline simdjson_result<dom::array>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<dom::array>() {}
|
||||
really_inline simdjson_result<dom::array>::simdjson_result(dom::array value) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::array>::simdjson_result(dom::array value) noexcept
|
||||
: internal::simdjson_result_base<dom::array>(std::forward<dom::array>(value)) {}
|
||||
really_inline simdjson_result<dom::array>::simdjson_result(error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::array>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<dom::array>(error) {}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
@ -50,8 +50,8 @@ namespace dom {
|
|||
//
|
||||
// array inline implementation
|
||||
//
|
||||
really_inline array::array() noexcept : tape{} {}
|
||||
really_inline array::array(const internal::tape_ref &_tape) noexcept : tape{_tape} {}
|
||||
simdjson_really_inline array::array() noexcept : tape{} {}
|
||||
simdjson_really_inline array::array(const internal::tape_ref &_tape) noexcept : tape{_tape} {}
|
||||
inline array::iterator array::begin() const noexcept {
|
||||
return internal::tape_ref(tape.doc, tape.json_index + 1);
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ inline simdjson_result<element> array::at(size_t index) const noexcept {
|
|||
//
|
||||
// array::iterator inline implementation
|
||||
//
|
||||
really_inline array::iterator::iterator(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
simdjson_really_inline array::iterator::iterator(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
inline element array::iterator::operator*() const noexcept {
|
||||
return element(tape);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ inline element document::root() const noexcept {
|
|||
return element(internal::tape_ref(this, 1));
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
SIMDJSON_WARN_UNUSED
|
||||
inline error_code document::allocate(size_t capacity) noexcept {
|
||||
if (capacity == 0) {
|
||||
string_buf.reset();
|
||||
|
@ -33,10 +33,10 @@ inline error_code document::allocate(size_t capacity) noexcept {
|
|||
// worse with "[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"
|
||||
//where len + 1 tape elements are
|
||||
// generated, see issue https://github.com/lemire/simdjson/issues/345
|
||||
size_t tape_capacity = ROUNDUP_N(capacity + 3, 64);
|
||||
size_t tape_capacity = SIMDJSON_ROUNDUP_N(capacity + 3, 64);
|
||||
// a document with only zero-length strings... could have len/3 string
|
||||
// and we would need len/3 * 5 bytes on the string buffer
|
||||
size_t string_capacity = ROUNDUP_N(5 * capacity / 3 + 32, 64);
|
||||
size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * capacity / 3 + 32, 64);
|
||||
string_buf.reset( new (std::nothrow) uint8_t[string_capacity]);
|
||||
tape.reset(new (std::nothrow) uint64_t[tape_capacity]);
|
||||
return string_buf && tape ? SUCCESS : MEMALLOC;
|
||||
|
|
|
@ -64,7 +64,7 @@ inline void stage1_worker::run(document_stream * ds, dom::parser * stage1, size_
|
|||
}
|
||||
#endif
|
||||
|
||||
really_inline document_stream::document_stream(
|
||||
simdjson_really_inline document_stream::document_stream(
|
||||
dom::parser &_parser,
|
||||
const uint8_t *_buf,
|
||||
size_t _len,
|
||||
|
@ -86,7 +86,7 @@ really_inline document_stream::document_stream(
|
|||
#endif
|
||||
}
|
||||
|
||||
really_inline document_stream::document_stream() noexcept
|
||||
simdjson_really_inline document_stream::document_stream() noexcept
|
||||
: parser{nullptr},
|
||||
buf{nullptr},
|
||||
len{0},
|
||||
|
@ -98,37 +98,37 @@ really_inline document_stream::document_stream() noexcept
|
|||
{
|
||||
}
|
||||
|
||||
really_inline document_stream::~document_stream() noexcept {
|
||||
simdjson_really_inline document_stream::~document_stream() noexcept {
|
||||
}
|
||||
|
||||
really_inline document_stream::iterator document_stream::begin() noexcept {
|
||||
simdjson_really_inline document_stream::iterator document_stream::begin() noexcept {
|
||||
start();
|
||||
// If there are no documents, we're finished.
|
||||
return iterator(*this, error == EMPTY);
|
||||
}
|
||||
|
||||
really_inline document_stream::iterator document_stream::end() noexcept {
|
||||
simdjson_really_inline document_stream::iterator document_stream::end() noexcept {
|
||||
return iterator(*this, true);
|
||||
}
|
||||
|
||||
really_inline document_stream::iterator::iterator(document_stream& _stream, bool is_end) noexcept
|
||||
simdjson_really_inline document_stream::iterator::iterator(document_stream& _stream, bool is_end) noexcept
|
||||
: stream{_stream}, finished{is_end} {
|
||||
}
|
||||
|
||||
really_inline simdjson_result<element> document_stream::iterator::operator*() noexcept {
|
||||
simdjson_really_inline simdjson_result<element> document_stream::iterator::operator*() noexcept {
|
||||
// Once we have yielded any errors, we're finished.
|
||||
if (stream.error) { finished = true; return stream.error; }
|
||||
return stream.parser->doc.root();
|
||||
}
|
||||
|
||||
really_inline document_stream::iterator& document_stream::iterator::operator++() noexcept {
|
||||
simdjson_really_inline document_stream::iterator& document_stream::iterator::operator++() noexcept {
|
||||
stream.next();
|
||||
// If that was the last document, we're finished.
|
||||
if (stream.error == EMPTY) { finished = true; }
|
||||
return *this;
|
||||
}
|
||||
|
||||
really_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept {
|
||||
simdjson_really_inline bool document_stream::iterator::operator!=(const document_stream::iterator &other) const noexcept {
|
||||
return finished != other.finished;
|
||||
}
|
||||
|
||||
|
@ -157,11 +157,11 @@ inline void document_stream::start() noexcept {
|
|||
next();
|
||||
}
|
||||
|
||||
really_inline size_t document_stream::iterator::current_index() const noexcept {
|
||||
simdjson_really_inline size_t document_stream::iterator::current_index() const noexcept {
|
||||
return stream.doc_index;
|
||||
}
|
||||
|
||||
really_inline std::string_view document_stream::iterator::source() const noexcept {
|
||||
simdjson_really_inline std::string_view document_stream::iterator::source() const noexcept {
|
||||
size_t next_doc_index = stream.batch_start + stream.parser->implementation->structural_indexes[stream.parser->implementation->next_structural_index];
|
||||
return std::string_view(reinterpret_cast<const char*>(stream.buf) + current_index(), next_doc_index - current_index() - 1);
|
||||
}
|
||||
|
@ -239,31 +239,31 @@ inline void document_stream::start_stage1_thread() noexcept {
|
|||
|
||||
} // namespace dom
|
||||
|
||||
really_inline simdjson_result<dom::document_stream>::simdjson_result() noexcept
|
||||
simdjson_really_inline simdjson_result<dom::document_stream>::simdjson_result() noexcept
|
||||
: simdjson_result_base() {
|
||||
}
|
||||
really_inline simdjson_result<dom::document_stream>::simdjson_result(error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::document_stream>::simdjson_result(error_code error) noexcept
|
||||
: simdjson_result_base(error) {
|
||||
}
|
||||
really_inline simdjson_result<dom::document_stream>::simdjson_result(dom::document_stream &&value) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::document_stream>::simdjson_result(dom::document_stream &&value) noexcept
|
||||
: simdjson_result_base(std::forward<dom::document_stream>(value)) {
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::begin() noexcept(false) {
|
||||
simdjson_really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::begin() noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.begin();
|
||||
}
|
||||
really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::end() noexcept(false) {
|
||||
simdjson_really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::end() noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.end();
|
||||
}
|
||||
#else // SIMDJSON_EXCEPTIONS
|
||||
really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::begin() noexcept {
|
||||
simdjson_really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::begin() noexcept {
|
||||
first.error = error();
|
||||
return first.begin();
|
||||
}
|
||||
really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::end() noexcept {
|
||||
simdjson_really_inline dom::document_stream::iterator simdjson_result<dom::document_stream>::end() noexcept {
|
||||
first.error = error();
|
||||
return first.end();
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace simdjson {
|
|||
//
|
||||
// simdjson_result<dom::element> inline implementation
|
||||
//
|
||||
really_inline simdjson_result<dom::element>::simdjson_result() noexcept
|
||||
simdjson_really_inline simdjson_result<dom::element>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<dom::element>() {}
|
||||
really_inline simdjson_result<dom::element>::simdjson_result(dom::element &&value) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::element>::simdjson_result(dom::element &&value) noexcept
|
||||
: internal::simdjson_result_base<dom::element>(std::forward<dom::element>(value)) {}
|
||||
really_inline simdjson_result<dom::element>::simdjson_result(error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::element>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<dom::element>(error) {}
|
||||
inline simdjson_result<dom::element_type> simdjson_result<dom::element>::type() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
|
@ -24,148 +24,148 @@ inline simdjson_result<dom::element_type> simdjson_result<dom::element>::type()
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline bool simdjson_result<dom::element>::is() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is() const noexcept {
|
||||
return !error() && first.is<T>();
|
||||
}
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T> simdjson_result<dom::element>::get() const noexcept {
|
||||
simdjson_really_inline simdjson_result<T> simdjson_result<dom::element>::get() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get<T>();
|
||||
}
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code simdjson_result<dom::element>::get(T &value) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code simdjson_result<dom::element>::get(T &value) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get<T>(value);
|
||||
}
|
||||
|
||||
really_inline simdjson_result<dom::array> simdjson_result<dom::element>::get_array() const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::array> simdjson_result<dom::element>::get_array() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_array();
|
||||
}
|
||||
really_inline simdjson_result<dom::object> simdjson_result<dom::element>::get_object() const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::object> simdjson_result<dom::element>::get_object() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_object();
|
||||
}
|
||||
really_inline simdjson_result<const char *> simdjson_result<dom::element>::get_c_str() const noexcept {
|
||||
simdjson_really_inline simdjson_result<const char *> simdjson_result<dom::element>::get_c_str() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_c_str();
|
||||
}
|
||||
really_inline simdjson_result<size_t> simdjson_result<dom::element>::get_string_length() const noexcept {
|
||||
simdjson_really_inline simdjson_result<size_t> simdjson_result<dom::element>::get_string_length() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_string_length();
|
||||
}
|
||||
really_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_string() const noexcept {
|
||||
simdjson_really_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_string() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_string();
|
||||
}
|
||||
really_inline simdjson_result<int64_t> simdjson_result<dom::element>::get_int64() const noexcept {
|
||||
simdjson_really_inline simdjson_result<int64_t> simdjson_result<dom::element>::get_int64() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_int64();
|
||||
}
|
||||
really_inline simdjson_result<uint64_t> simdjson_result<dom::element>::get_uint64() const noexcept {
|
||||
simdjson_really_inline simdjson_result<uint64_t> simdjson_result<dom::element>::get_uint64() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_uint64();
|
||||
}
|
||||
really_inline simdjson_result<double> simdjson_result<dom::element>::get_double() const noexcept {
|
||||
simdjson_really_inline simdjson_result<double> simdjson_result<dom::element>::get_double() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_double();
|
||||
}
|
||||
really_inline simdjson_result<bool> simdjson_result<dom::element>::get_bool() const noexcept {
|
||||
simdjson_really_inline simdjson_result<bool> simdjson_result<dom::element>::get_bool() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.get_bool();
|
||||
}
|
||||
|
||||
really_inline bool simdjson_result<dom::element>::is_array() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_array() const noexcept {
|
||||
return !error() && first.is_array();
|
||||
}
|
||||
really_inline bool simdjson_result<dom::element>::is_object() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_object() const noexcept {
|
||||
return !error() && first.is_object();
|
||||
}
|
||||
really_inline bool simdjson_result<dom::element>::is_string() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_string() const noexcept {
|
||||
return !error() && first.is_string();
|
||||
}
|
||||
really_inline bool simdjson_result<dom::element>::is_int64() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_int64() const noexcept {
|
||||
return !error() && first.is_int64();
|
||||
}
|
||||
really_inline bool simdjson_result<dom::element>::is_uint64() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_uint64() const noexcept {
|
||||
return !error() && first.is_uint64();
|
||||
}
|
||||
really_inline bool simdjson_result<dom::element>::is_double() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_double() const noexcept {
|
||||
return !error() && first.is_double();
|
||||
}
|
||||
really_inline bool simdjson_result<dom::element>::is_bool() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_bool() const noexcept {
|
||||
return !error() && first.is_bool();
|
||||
}
|
||||
|
||||
really_inline bool simdjson_result<dom::element>::is_null() const noexcept {
|
||||
simdjson_really_inline bool simdjson_result<dom::element>::is_null() const noexcept {
|
||||
return !error() && first.is_null();
|
||||
}
|
||||
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first[key];
|
||||
}
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](const char *key) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](const char *key) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first[key];
|
||||
}
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_pointer(const std::string_view json_pointer) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_pointer(const std::string_view json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at_pointer(json_pointer);
|
||||
}
|
||||
[[deprecated("For standard compliance, use at_pointer instead, and prefix your pointers with a slash '/', see RFC6901 ")]]
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(const std::string_view json_pointer) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(const std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_PUSH_DISABLE_WARNINGS
|
||||
SIMDJSON_DISABLE_DEPRECATED_WARNING
|
||||
if (error()) { return error(); }
|
||||
return first.at(json_pointer);
|
||||
SIMDJSON_POP_DISABLE_WARNINGS
|
||||
}
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(size_t index) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at(size_t index) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at(index);
|
||||
}
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key(std::string_view key) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key(std::string_view key) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at_key(key);
|
||||
}
|
||||
really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key_case_insensitive(std::string_view key) const noexcept {
|
||||
simdjson_really_inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key_case_insensitive(std::string_view key) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at_key_case_insensitive(key);
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
really_inline simdjson_result<dom::element>::operator bool() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator bool() const noexcept(false) {
|
||||
return get<bool>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator const char *() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator const char *() const noexcept(false) {
|
||||
return get<const char *>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator std::string_view() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator std::string_view() const noexcept(false) {
|
||||
return get<std::string_view>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator uint64_t() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator uint64_t() const noexcept(false) {
|
||||
return get<uint64_t>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator int64_t() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator int64_t() const noexcept(false) {
|
||||
return get<int64_t>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator double() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator double() const noexcept(false) {
|
||||
return get<double>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator dom::array() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator dom::array() const noexcept(false) {
|
||||
return get<dom::array>();
|
||||
}
|
||||
really_inline simdjson_result<dom::element>::operator dom::object() const noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<dom::element>::operator dom::object() const noexcept(false) {
|
||||
return get<dom::object>();
|
||||
}
|
||||
|
||||
really_inline dom::array::iterator simdjson_result<dom::element>::begin() const noexcept(false) {
|
||||
simdjson_really_inline dom::array::iterator simdjson_result<dom::element>::begin() const noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.begin();
|
||||
}
|
||||
really_inline dom::array::iterator simdjson_result<dom::element>::end() const noexcept(false) {
|
||||
simdjson_really_inline dom::array::iterator simdjson_result<dom::element>::end() const noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.end();
|
||||
}
|
||||
|
@ -177,8 +177,8 @@ namespace dom {
|
|||
//
|
||||
// element inline implementation
|
||||
//
|
||||
really_inline element::element() noexcept : tape{} {}
|
||||
really_inline element::element(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
simdjson_really_inline element::element() noexcept : tape{} {}
|
||||
simdjson_really_inline element::element(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
|
||||
inline element_type element::type() const noexcept {
|
||||
auto tape_type = tape.tape_ref_type();
|
||||
|
@ -220,7 +220,7 @@ inline simdjson_result<std::string_view> element::get_string() const noexcept {
|
|||
}
|
||||
}
|
||||
inline simdjson_result<uint64_t> element::get_uint64() const noexcept {
|
||||
if(unlikely(!tape.is_uint64())) { // branch rarely taken
|
||||
if(simdjson_unlikely(!tape.is_uint64())) { // branch rarely taken
|
||||
if(tape.is_int64()) {
|
||||
int64_t result = tape.next_tape_value<int64_t>();
|
||||
if (result < 0) {
|
||||
|
@ -233,7 +233,7 @@ inline simdjson_result<uint64_t> element::get_uint64() const noexcept {
|
|||
return tape.next_tape_value<int64_t>();
|
||||
}
|
||||
inline simdjson_result<int64_t> element::get_int64() const noexcept {
|
||||
if(unlikely(!tape.is_int64())) { // branch rarely taken
|
||||
if(simdjson_unlikely(!tape.is_int64())) { // branch rarely taken
|
||||
if(tape.is_uint64()) {
|
||||
uint64_t result = tape.next_tape_value<uint64_t>();
|
||||
// Wrapping max in parens to handle Windows issue: https://stackoverflow.com/questions/11544073/how-do-i-deal-with-the-max-macro-in-windows-h-colliding-with-max-in-std
|
||||
|
@ -256,7 +256,7 @@ inline simdjson_result<double> element::get_double() const noexcept {
|
|||
// We can expect get<double> to refer to a double type almost all the time.
|
||||
// It is important to craft the code accordingly so that the compiler can use this
|
||||
// information. (This could also be solved with profile-guided optimization.)
|
||||
if(unlikely(!tape.is_double())) { // branch rarely taken
|
||||
if(simdjson_unlikely(!tape.is_double())) { // branch rarely taken
|
||||
if(tape.is_uint64()) {
|
||||
return double(tape.next_tape_value<uint64_t>());
|
||||
} else if(tape.is_int64()) {
|
||||
|
@ -285,18 +285,18 @@ inline simdjson_result<object> element::get_object() const noexcept {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code element::get(T &value) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code element::get(T &value) const noexcept {
|
||||
return get<T>().get(value);
|
||||
}
|
||||
// An element-specific version prevents recursion with simdjson_result::get<element>(value)
|
||||
template<>
|
||||
WARN_UNUSED really_inline error_code element::get<element>(element &value) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code element::get<element>(element &value) const noexcept {
|
||||
value = element(tape);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline bool element::is() const noexcept {
|
||||
simdjson_really_inline bool element::is() const noexcept {
|
||||
auto result = get<T>();
|
||||
return !result.error();
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ inline std::ostream& minifier<dom::element>::print(std::ostream& out) {
|
|||
case tape_type::START_ARRAY: {
|
||||
// If we're too deep, we need to recurse to go deeper.
|
||||
depth++;
|
||||
if (unlikely(depth >= MAX_DEPTH)) {
|
||||
if (simdjson_unlikely(depth >= MAX_DEPTH)) {
|
||||
out << minify<dom::array>(dom::array(iter));
|
||||
iter.json_index = iter.matching_brace_index() - 1; // Jump to the ]
|
||||
depth--;
|
||||
|
@ -468,7 +468,7 @@ inline std::ostream& minifier<dom::element>::print(std::ostream& out) {
|
|||
case tape_type::START_OBJECT: {
|
||||
// If we're too deep, we need to recurse to go deeper.
|
||||
depth++;
|
||||
if (unlikely(depth >= MAX_DEPTH)) {
|
||||
if (simdjson_unlikely(depth >= MAX_DEPTH)) {
|
||||
out << minify<dom::object>(dom::object(iter));
|
||||
iter.json_index = iter.matching_brace_index() - 1; // Jump to the }
|
||||
depth--;
|
||||
|
@ -542,12 +542,12 @@ inline std::ostream& minifier<dom::element>::print(std::ostream& out) {
|
|||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<>
|
||||
really_inline std::ostream& minifier<simdjson_result<dom::element>>::print(std::ostream& out) {
|
||||
simdjson_really_inline std::ostream& minifier<simdjson_result<dom::element>>::print(std::ostream& out) {
|
||||
if (value.error()) { throw simdjson_error(value.error()); }
|
||||
return out << minify<dom::element>(value.first);
|
||||
}
|
||||
|
||||
really_inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false) {
|
||||
simdjson_really_inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false) {
|
||||
return out << minify<simdjson_result<dom::element>>(value);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace internal {
|
|||
//
|
||||
|
||||
template<typename T>
|
||||
really_inline void simdjson_result_base<T>::tie(T &value, error_code &error) && noexcept {
|
||||
simdjson_really_inline void simdjson_result_base<T>::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<uint64_t>();
|
||||
// fails with "error: no viable overloaded '='""
|
||||
|
@ -53,49 +53,49 @@ really_inline void simdjson_result_base<T>::tie(T &value, error_code &error) &&
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code simdjson_result_base<T>::get(T &value) && noexcept {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code simdjson_result_base<T>::get(T &value) && noexcept {
|
||||
error_code error;
|
||||
std::forward<simdjson_result_base<T>>(*this).tie(value, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline error_code simdjson_result_base<T>::error() const noexcept {
|
||||
simdjson_really_inline error_code simdjson_result_base<T>::error() const noexcept {
|
||||
return this->second;
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<typename T>
|
||||
really_inline T& simdjson_result_base<T>::value() noexcept(false) {
|
||||
simdjson_really_inline T& simdjson_result_base<T>::value() noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return this->first;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline T&& simdjson_result_base<T>::take_value() && noexcept(false) {
|
||||
simdjson_really_inline T&& simdjson_result_base<T>::take_value() && noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return std::forward<T>(this->first);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline simdjson_result_base<T>::operator T&&() && noexcept(false) {
|
||||
simdjson_really_inline simdjson_result_base<T>::operator T&&() && noexcept(false) {
|
||||
return std::forward<simdjson_result_base<T>>(*this).take_value();
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<typename T>
|
||||
really_inline simdjson_result_base<T>::simdjson_result_base(T &&value, error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result_base<T>::simdjson_result_base(T &&value, error_code error) noexcept
|
||||
: std::pair<T, error_code>(std::forward<T>(value), error) {}
|
||||
template<typename T>
|
||||
really_inline simdjson_result_base<T>::simdjson_result_base(error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result_base<T>::simdjson_result_base(error_code error) noexcept
|
||||
: simdjson_result_base(T{}, error) {}
|
||||
template<typename T>
|
||||
really_inline simdjson_result_base<T>::simdjson_result_base(T &&value) noexcept
|
||||
simdjson_really_inline simdjson_result_base<T>::simdjson_result_base(T &&value) noexcept
|
||||
: simdjson_result_base(std::forward<T>(value), SUCCESS) {}
|
||||
template<typename T>
|
||||
really_inline simdjson_result_base<T>::simdjson_result_base() noexcept
|
||||
simdjson_really_inline simdjson_result_base<T>::simdjson_result_base() noexcept
|
||||
: simdjson_result_base(T{}, UNINITIALIZED) {}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -105,50 +105,50 @@ really_inline simdjson_result_base<T>::simdjson_result_base() noexcept
|
|||
///
|
||||
|
||||
template<typename T>
|
||||
really_inline void simdjson_result<T>::tie(T &value, error_code &error) && noexcept {
|
||||
simdjson_really_inline void simdjson_result<T>::tie(T &value, error_code &error) && noexcept {
|
||||
std::forward<internal::simdjson_result_base<T>>(*this).tie(value, error);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code simdjson_result<T>::get(T &value) && noexcept {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code simdjson_result<T>::get(T &value) && noexcept {
|
||||
return std::forward<internal::simdjson_result_base<T>>(*this).get(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline error_code simdjson_result<T>::error() const noexcept {
|
||||
simdjson_really_inline error_code simdjson_result<T>::error() const noexcept {
|
||||
return internal::simdjson_result_base<T>::error();
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<typename T>
|
||||
really_inline T& simdjson_result<T>::value() noexcept(false) {
|
||||
simdjson_really_inline T& simdjson_result<T>::value() noexcept(false) {
|
||||
return internal::simdjson_result_base<T>::value();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline T&& simdjson_result<T>::take_value() && noexcept(false) {
|
||||
simdjson_really_inline T&& simdjson_result<T>::take_value() && noexcept(false) {
|
||||
return std::forward<internal::simdjson_result_base<T>>(*this).take_value();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T>::operator T&&() && noexcept(false) {
|
||||
simdjson_really_inline simdjson_result<T>::operator T&&() && noexcept(false) {
|
||||
return std::forward<internal::simdjson_result_base<T>>(*this).take_value();
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T>::simdjson_result(T &&value, error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result<T>::simdjson_result(T &&value, error_code error) noexcept
|
||||
: internal::simdjson_result_base<T>(std::forward<T>(value), error) {}
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T>::simdjson_result(error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result<T>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<T>(error) {}
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T>::simdjson_result(T &&value) noexcept
|
||||
simdjson_really_inline simdjson_result<T>::simdjson_result(T &&value) noexcept
|
||||
: internal::simdjson_result_base<T>(std::forward<T>(value)) {}
|
||||
template<typename T>
|
||||
really_inline simdjson_result<T>::simdjson_result() noexcept
|
||||
simdjson_really_inline simdjson_result<T>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<T>() {}
|
||||
|
||||
} // namespace simdjson
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace simdjson {
|
|||
//
|
||||
// simdjson_result<dom::object> inline implementation
|
||||
//
|
||||
really_inline simdjson_result<dom::object>::simdjson_result() noexcept
|
||||
simdjson_really_inline simdjson_result<dom::object>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<dom::object>() {}
|
||||
really_inline simdjson_result<dom::object>::simdjson_result(dom::object value) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::object>::simdjson_result(dom::object value) noexcept
|
||||
: internal::simdjson_result_base<dom::object>(std::forward<dom::object>(value)) {}
|
||||
really_inline simdjson_result<dom::object>::simdjson_result(error_code error) noexcept
|
||||
simdjson_really_inline simdjson_result<dom::object>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<dom::object>(error) {}
|
||||
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::operator[](std::string_view key) const noexcept {
|
||||
|
@ -62,8 +62,8 @@ namespace dom {
|
|||
//
|
||||
// object inline implementation
|
||||
//
|
||||
really_inline object::object() noexcept : tape{} {}
|
||||
really_inline object::object(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
simdjson_really_inline object::object() noexcept : tape{} {}
|
||||
simdjson_really_inline object::object(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
inline object::iterator object::begin() const noexcept {
|
||||
return internal::tape_ref(tape.doc, tape.json_index + 1);
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ inline simdjson_result<element> object::at_key_case_insensitive(std::string_view
|
|||
//
|
||||
// object::iterator inline implementation
|
||||
//
|
||||
really_inline object::iterator::iterator(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
simdjson_really_inline object::iterator::iterator(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
inline const key_value_pair object::iterator::operator*() const noexcept {
|
||||
return key_value_pair(key(), value());
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ SIMDJSON_DISABLE_DEPRECATED_WARNING
|
|||
|
||||
// Because of template weirdness, the actual class definition is inline in the document class
|
||||
|
||||
WARN_UNUSED bool dom::parser::Iterator::is_ok() const {
|
||||
SIMDJSON_WARN_UNUSED bool dom::parser::Iterator::is_ok() const {
|
||||
return location < tape_length;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@ namespace dom {
|
|||
//
|
||||
// parser inline implementation
|
||||
//
|
||||
really_inline parser::parser(size_t max_capacity) noexcept
|
||||
simdjson_really_inline parser::parser(size_t max_capacity) noexcept
|
||||
: _max_capacity{max_capacity},
|
||||
loaded_bytes(nullptr) {
|
||||
}
|
||||
really_inline parser::parser(parser &&other) noexcept = default;
|
||||
really_inline parser &parser::operator=(parser &&other) noexcept = default;
|
||||
simdjson_really_inline parser::parser(parser &&other) noexcept = default;
|
||||
simdjson_really_inline parser &parser::operator=(parser &&other) noexcept = default;
|
||||
|
||||
inline bool parser::is_valid() const noexcept { return valid; }
|
||||
inline int parser::get_error_code() const noexcept { return error; }
|
||||
|
@ -105,13 +105,13 @@ inline simdjson_result<element> parser::parse(const uint8_t *buf, size_t len, bo
|
|||
|
||||
return doc.root();
|
||||
}
|
||||
really_inline simdjson_result<element> parser::parse(const char *buf, size_t len, bool realloc_if_needed) & noexcept {
|
||||
simdjson_really_inline simdjson_result<element> parser::parse(const char *buf, size_t len, bool realloc_if_needed) & noexcept {
|
||||
return parse((const uint8_t *)buf, len, realloc_if_needed);
|
||||
}
|
||||
really_inline simdjson_result<element> parser::parse(const std::string &s) & noexcept {
|
||||
simdjson_really_inline simdjson_result<element> parser::parse(const std::string &s) & noexcept {
|
||||
return parse(s.data(), s.length(), s.capacity() - s.length() < SIMDJSON_PADDING);
|
||||
}
|
||||
really_inline simdjson_result<element> parser::parse(const padded_string &s) & noexcept {
|
||||
simdjson_really_inline simdjson_result<element> parser::parse(const padded_string &s) & noexcept {
|
||||
return parse(s.data(), s.length(), false);
|
||||
}
|
||||
|
||||
|
@ -128,17 +128,17 @@ inline simdjson_result<document_stream> parser::parse_many(const padded_string &
|
|||
return parse_many(s.data(), s.length(), batch_size);
|
||||
}
|
||||
|
||||
really_inline size_t parser::capacity() const noexcept {
|
||||
simdjson_really_inline size_t parser::capacity() const noexcept {
|
||||
return implementation ? implementation->capacity() : 0;
|
||||
}
|
||||
really_inline size_t parser::max_capacity() const noexcept {
|
||||
simdjson_really_inline size_t parser::max_capacity() const noexcept {
|
||||
return _max_capacity;
|
||||
}
|
||||
really_inline size_t parser::max_depth() const noexcept {
|
||||
simdjson_really_inline size_t parser::max_depth() const noexcept {
|
||||
return implementation ? implementation->max_depth() : DEFAULT_MAX_DEPTH;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
SIMDJSON_WARN_UNUSED
|
||||
inline error_code parser::allocate(size_t capacity, size_t max_depth) noexcept {
|
||||
//
|
||||
// Reallocate implementation and document if needed
|
||||
|
@ -164,7 +164,7 @@ inline error_code parser::allocate(size_t capacity, size_t max_depth) noexcept {
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
SIMDJSON_WARN_UNUSED
|
||||
inline bool parser::allocate_capacity(size_t capacity, size_t max_depth) noexcept {
|
||||
return !allocate(capacity, max_depth);
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ inline error_code parser::ensure_capacity(size_t desired_capacity) noexcept {
|
|||
// If we don't have enough capacity, (try to) automatically bump it.
|
||||
// If the document was taken, reallocate that too.
|
||||
// Both in one if statement to minimize unlikely branching.
|
||||
if (unlikely(capacity() < desired_capacity || !doc.tape)) {
|
||||
if (simdjson_unlikely(capacity() < desired_capacity || !doc.tape)) {
|
||||
if (desired_capacity > max_capacity()) {
|
||||
return error = CAPACITY;
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ inline error_code parser::ensure_capacity(size_t desired_capacity) noexcept {
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
really_inline void parser::set_max_capacity(size_t max_capacity) noexcept {
|
||||
simdjson_really_inline void parser::set_max_capacity(size_t max_capacity) noexcept {
|
||||
_max_capacity = max_capacity;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ namespace internal {
|
|||
//
|
||||
// tape_ref inline implementation
|
||||
//
|
||||
really_inline tape_ref::tape_ref() noexcept : doc{nullptr}, json_index{0} {}
|
||||
really_inline tape_ref::tape_ref(const dom::document *_doc, size_t _json_index) noexcept : doc{_doc}, json_index{_json_index} {}
|
||||
simdjson_really_inline tape_ref::tape_ref() noexcept : doc{nullptr}, json_index{0} {}
|
||||
simdjson_really_inline tape_ref::tape_ref(const dom::document *_doc, size_t _json_index) noexcept : doc{_doc}, json_index{_json_index} {}
|
||||
|
||||
|
||||
really_inline bool tape_ref::is_document_root() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_document_root() const noexcept {
|
||||
return json_index == 1; // should we ever change the structure of the tape, this should get updated.
|
||||
}
|
||||
|
||||
|
@ -22,27 +22,27 @@ really_inline bool tape_ref::is_document_root() const noexcept {
|
|||
// to check the type by doing a word-to-word comparison instead of extracting the
|
||||
// most significant 8 bits.
|
||||
|
||||
really_inline bool tape_ref::is_double() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_double() const noexcept {
|
||||
constexpr uint64_t tape_double = uint64_t(tape_type::DOUBLE)<<56;
|
||||
return doc->tape[json_index] == tape_double;
|
||||
}
|
||||
really_inline bool tape_ref::is_int64() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_int64() const noexcept {
|
||||
constexpr uint64_t tape_int64 = uint64_t(tape_type::INT64)<<56;
|
||||
return doc->tape[json_index] == tape_int64;
|
||||
}
|
||||
really_inline bool tape_ref::is_uint64() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_uint64() const noexcept {
|
||||
constexpr uint64_t tape_uint64 = uint64_t(tape_type::UINT64)<<56;
|
||||
return doc->tape[json_index] == tape_uint64;
|
||||
}
|
||||
really_inline bool tape_ref::is_false() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_false() const noexcept {
|
||||
constexpr uint64_t tape_false = uint64_t(tape_type::FALSE_VALUE)<<56;
|
||||
return doc->tape[json_index] == tape_false;
|
||||
}
|
||||
really_inline bool tape_ref::is_true() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_true() const noexcept {
|
||||
constexpr uint64_t tape_true = uint64_t(tape_type::TRUE_VALUE)<<56;
|
||||
return doc->tape[json_index] == tape_true;
|
||||
}
|
||||
really_inline bool tape_ref::is_null_on_tape() const noexcept {
|
||||
simdjson_really_inline bool tape_ref::is_null_on_tape() const noexcept {
|
||||
constexpr uint64_t tape_null = uint64_t(tape_type::NULL_VALUE)<<56;
|
||||
return doc->tape[json_index] == tape_null;
|
||||
}
|
||||
|
@ -60,21 +60,21 @@ inline size_t tape_ref::after_element() const noexcept {
|
|||
return json_index + 1;
|
||||
}
|
||||
}
|
||||
really_inline tape_type tape_ref::tape_ref_type() const noexcept {
|
||||
simdjson_really_inline tape_type tape_ref::tape_ref_type() const noexcept {
|
||||
return static_cast<tape_type>(doc->tape[json_index] >> 56);
|
||||
}
|
||||
really_inline uint64_t internal::tape_ref::tape_value() const noexcept {
|
||||
simdjson_really_inline uint64_t internal::tape_ref::tape_value() const noexcept {
|
||||
return doc->tape[json_index] & internal::JSON_VALUE_MASK;
|
||||
}
|
||||
really_inline uint32_t internal::tape_ref::matching_brace_index() const noexcept {
|
||||
simdjson_really_inline uint32_t internal::tape_ref::matching_brace_index() const noexcept {
|
||||
return uint32_t(doc->tape[json_index]);
|
||||
}
|
||||
really_inline uint32_t internal::tape_ref::scope_count() const noexcept {
|
||||
simdjson_really_inline uint32_t internal::tape_ref::scope_count() const noexcept {
|
||||
return uint32_t((doc->tape[json_index] >> 32) & internal::JSON_COUNT_MASK);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline T tape_ref::next_tape_value() const noexcept {
|
||||
simdjson_really_inline T tape_ref::next_tape_value() const noexcept {
|
||||
static_assert(sizeof(T) == sizeof(uint64_t), "next_tape_value() template parameter must be 64-bit");
|
||||
// Though the following is tempting...
|
||||
// return *reinterpret_cast<const T*>(&doc->tape[json_index + 1]);
|
||||
|
@ -85,14 +85,14 @@ really_inline T tape_ref::next_tape_value() const noexcept {
|
|||
return x;
|
||||
}
|
||||
|
||||
really_inline uint32_t internal::tape_ref::get_string_length() const noexcept {
|
||||
simdjson_really_inline uint32_t internal::tape_ref::get_string_length() const noexcept {
|
||||
size_t string_buf_index = size_t(tape_value());
|
||||
uint32_t len;
|
||||
memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len));
|
||||
return len;
|
||||
}
|
||||
|
||||
really_inline const char * internal::tape_ref::get_c_str() const noexcept {
|
||||
simdjson_really_inline const char * internal::tape_ref::get_c_str() const noexcept {
|
||||
size_t string_buf_index = size_t(tape_value());
|
||||
return reinterpret_cast<const char *>(&doc->string_buf[string_buf_index + sizeof(uint32_t)]);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
* @param len The length of the json document.
|
||||
* @return The error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept = 0;
|
||||
SIMDJSON_WARN_UNUSED virtual error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept = 0;
|
||||
|
||||
/**
|
||||
* @private For internal implementation use
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
* @param streaming Whether this is being called by parser::parse_many.
|
||||
* @return The error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept = 0;
|
||||
SIMDJSON_WARN_UNUSED virtual error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept = 0;
|
||||
|
||||
/**
|
||||
* @private For internal implementation use
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
* @param doc The document to output to.
|
||||
* @return The error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code stage2(dom::document &doc) noexcept = 0;
|
||||
SIMDJSON_WARN_UNUSED virtual error_code stage2(dom::document &doc) noexcept = 0;
|
||||
|
||||
/**
|
||||
* @private For internal implementation use
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
* @param doc The document to output to.
|
||||
* @return The error code, SUCCESS if there was no error, or EMPTY if all documents have been parsed.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code stage2_next(dom::document &doc) noexcept = 0;
|
||||
SIMDJSON_WARN_UNUSED virtual error_code stage2_next(dom::document &doc) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Change the capacity of this parser.
|
||||
|
@ -119,14 +119,14 @@ public:
|
|||
*
|
||||
* @return Current capacity, in bytes.
|
||||
*/
|
||||
really_inline size_t capacity() const noexcept;
|
||||
simdjson_really_inline size_t capacity() const noexcept;
|
||||
|
||||
/**
|
||||
* The maximum level of nested object and arrays supported by this parser.
|
||||
*
|
||||
* @return Maximum depth, in bytes.
|
||||
*/
|
||||
really_inline size_t max_depth() const noexcept;
|
||||
simdjson_really_inline size_t max_depth() const noexcept;
|
||||
|
||||
/**
|
||||
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
|
||||
|
@ -136,7 +136,7 @@ public:
|
|||
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
|
||||
* @return The error, if there is one.
|
||||
*/
|
||||
WARN_UNUSED inline error_code allocate(size_t capacity, size_t max_depth) noexcept;
|
||||
SIMDJSON_WARN_UNUSED inline error_code allocate(size_t capacity, size_t max_depth) noexcept;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -154,15 +154,15 @@ protected:
|
|||
size_t _max_depth{0};
|
||||
}; // class dom_parser_implementation
|
||||
|
||||
really_inline size_t dom_parser_implementation::capacity() const noexcept {
|
||||
simdjson_really_inline size_t dom_parser_implementation::capacity() const noexcept {
|
||||
return _capacity;
|
||||
}
|
||||
|
||||
really_inline size_t dom_parser_implementation::max_depth() const noexcept {
|
||||
simdjson_really_inline size_t dom_parser_implementation::max_depth() const noexcept {
|
||||
return _max_depth;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
SIMDJSON_WARN_UNUSED
|
||||
inline error_code dom_parser_implementation::allocate(size_t capacity, size_t max_depth) noexcept {
|
||||
if (this->max_depth() != max_depth) {
|
||||
error_code err = set_max_depth(max_depth);
|
||||
|
|
|
@ -19,25 +19,25 @@ constexpr const uint32_t JSON_COUNT_MASK = 0xFFFFFF;
|
|||
*/
|
||||
class tape_ref {
|
||||
public:
|
||||
really_inline tape_ref() noexcept;
|
||||
really_inline tape_ref(const dom::document *doc, size_t json_index) noexcept;
|
||||
simdjson_really_inline tape_ref() noexcept;
|
||||
simdjson_really_inline tape_ref(const dom::document *doc, size_t json_index) noexcept;
|
||||
inline size_t after_element() const noexcept;
|
||||
really_inline tape_type tape_ref_type() const noexcept;
|
||||
really_inline uint64_t tape_value() const noexcept;
|
||||
really_inline bool is_double() const noexcept;
|
||||
really_inline bool is_int64() const noexcept;
|
||||
really_inline bool is_uint64() const noexcept;
|
||||
really_inline bool is_false() const noexcept;
|
||||
really_inline bool is_true() const noexcept;
|
||||
really_inline bool is_null_on_tape() const noexcept;// different name to avoid clash with is_null.
|
||||
really_inline uint32_t matching_brace_index() const noexcept;
|
||||
really_inline uint32_t scope_count() const noexcept;
|
||||
simdjson_really_inline tape_type tape_ref_type() const noexcept;
|
||||
simdjson_really_inline uint64_t tape_value() const noexcept;
|
||||
simdjson_really_inline bool is_double() const noexcept;
|
||||
simdjson_really_inline bool is_int64() const noexcept;
|
||||
simdjson_really_inline bool is_uint64() const noexcept;
|
||||
simdjson_really_inline bool is_false() const noexcept;
|
||||
simdjson_really_inline bool is_true() const noexcept;
|
||||
simdjson_really_inline bool is_null_on_tape() const noexcept;// different name to avoid clash with is_null.
|
||||
simdjson_really_inline uint32_t matching_brace_index() const noexcept;
|
||||
simdjson_really_inline uint32_t scope_count() const noexcept;
|
||||
template<typename T>
|
||||
really_inline T next_tape_value() const noexcept;
|
||||
really_inline uint32_t get_string_length() const noexcept;
|
||||
really_inline const char * get_c_str() const noexcept;
|
||||
simdjson_really_inline T next_tape_value() const noexcept;
|
||||
simdjson_really_inline uint32_t get_string_length() const noexcept;
|
||||
simdjson_really_inline const char * get_c_str() const noexcept;
|
||||
inline std::string_view get_string_view() const noexcept;
|
||||
really_inline bool is_document_root() const noexcept;
|
||||
simdjson_really_inline bool is_document_root() const noexcept;
|
||||
|
||||
/** The document this element references. */
|
||||
const dom::document *doc;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace simdjson {
|
|||
* @param dst_len the number of bytes written. Output only.
|
||||
* @return the error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED error_code minify(const char *buf, size_t len, char *dst, size_t &dst_len) noexcept;
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const char *buf, size_t len, char *dst, size_t &dst_len) noexcept;
|
||||
|
||||
/**
|
||||
* Minifies a JSON element or document, printing the smallest possible valid JSON.
|
||||
|
|
|
@ -9,7 +9,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
const char * filename = argv[1];
|
||||
simdjson::dom::parser parser;
|
||||
UNUSED simdjson::dom::element elem;
|
||||
simdjson::dom::element elem;
|
||||
auto error = parser.load(filename).get(elem); // do the parsing
|
||||
if (error) {
|
||||
std::cout << "parse failed" << std::endl;
|
||||
|
@ -17,7 +17,7 @@ int main(int argc, char *argv[]) {
|
|||
std::cout << error << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
std::cout << "parse valid" << std::endl;
|
||||
std::cout << "parse valid: " << elem << std::endl;
|
||||
}
|
||||
if(argc == 2) {
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace arm64 {
|
|||
// but the algorithms do not end up using the returned value.
|
||||
// Sadly, sanitizers are not smart enough to figure it out.
|
||||
NO_SANITIZE_UNDEFINED
|
||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int trailing_zeroes(uint64_t input_num) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
unsigned long ret;
|
||||
// Search the mask data from least significant bit (LSB)
|
||||
|
@ -21,12 +21,12 @@ really_inline int trailing_zeroes(uint64_t input_num) {
|
|||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||
simdjson_really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||
return input_num & (input_num-1);
|
||||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline int leading_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int leading_zeroes(uint64_t input_num) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
unsigned long leading_zero = 0;
|
||||
// Search the mask data from most significant bit (MSB)
|
||||
|
@ -41,11 +41,11 @@ really_inline int leading_zeroes(uint64_t input_num) {
|
|||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline int count_ones(uint64_t input_num) {
|
||||
simdjson_really_inline int count_ones(uint64_t input_num) {
|
||||
return vaddv_u8(vcnt_u8(vcreate_u8(input_num)));
|
||||
}
|
||||
|
||||
really_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
||||
simdjson_really_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
*result = value1 + value2;
|
||||
return *result < value1;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace arm64 {
|
|||
//
|
||||
// For example, prefix_xor(00100100) == 00011100
|
||||
//
|
||||
really_inline uint64_t prefix_xor(uint64_t bitmask) {
|
||||
simdjson_really_inline uint64_t prefix_xor(uint64_t bitmask) {
|
||||
/////////////
|
||||
// We could do this with PMULL, but it is apparently slow.
|
||||
//
|
||||
|
|
|
@ -11,17 +11,17 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
using namespace simd;
|
||||
|
||||
struct json_character_block {
|
||||
static really_inline json_character_block classify(const simd::simd8x64<uint8_t>& in);
|
||||
static simdjson_really_inline json_character_block classify(const simd::simd8x64<uint8_t>& in);
|
||||
|
||||
really_inline uint64_t whitespace() const { return _whitespace; }
|
||||
really_inline uint64_t op() const { return _op; }
|
||||
really_inline uint64_t scalar() { return ~(op() | whitespace()); }
|
||||
simdjson_really_inline uint64_t whitespace() const { return _whitespace; }
|
||||
simdjson_really_inline uint64_t op() const { return _op; }
|
||||
simdjson_really_inline uint64_t scalar() { return ~(op() | whitespace()); }
|
||||
|
||||
uint64_t _whitespace;
|
||||
uint64_t _op;
|
||||
};
|
||||
|
||||
really_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
|
||||
// Functional programming causes trouble with Visual Studio.
|
||||
// Keeping this version in comments since it is much nicer:
|
||||
// auto v = in.map<uint8_t>([&](simd8<uint8_t> chunk) {
|
||||
|
@ -75,12 +75,12 @@ really_inline json_character_block json_character_block::classify(const simd::si
|
|||
return { whitespace, op };
|
||||
}
|
||||
|
||||
really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
simdjson_really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
simd8<uint8_t> bits = input.reduce_or();
|
||||
return bits.max() < 0b10000000u;
|
||||
}
|
||||
|
||||
UNUSED really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
SIMDJSON_UNUSED simdjson_really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<bool> is_second_byte = prev1 >= uint8_t(0b11000000u);
|
||||
simd8<bool> is_third_byte = prev2 >= uint8_t(0b11100000u);
|
||||
simd8<bool> is_fourth_byte = prev3 >= uint8_t(0b11110000u);
|
||||
|
@ -92,7 +92,7 @@ UNUSED really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1
|
|||
return is_second_byte ^ is_third_byte ^ is_fourth_byte;
|
||||
}
|
||||
|
||||
really_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simdjson_really_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<bool> is_third_byte = prev2 >= uint8_t(0b11100000u);
|
||||
simd8<bool> is_fourth_byte = prev3 >= uint8_t(0b11110000u);
|
||||
return is_third_byte ^ is_fourth_byte;
|
||||
|
@ -121,7 +121,7 @@ namespace {
|
|||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace stage1 {
|
||||
|
||||
really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
||||
simdjson_really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
||||
// On ARM, we don't short-circuit this if there are no backslashes, because the branch gives us no
|
||||
// benefit and therefore makes things worse.
|
||||
// if (!backslash) { uint64_t escaped = prev_escaped; prev_escaped = 0; return escaped; }
|
||||
|
@ -130,33 +130,33 @@ really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
|||
|
||||
} // namespace stage1
|
||||
|
||||
WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
return arm64::stage1::json_minifier::minify<64>(buf, len, dst, dst_len);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
this->buf = _buf;
|
||||
this->len = _len;
|
||||
return arm64::stage1::json_structural_indexer::index<64>(buf, len, *this, streaming);
|
||||
}
|
||||
|
||||
WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
return arm64::stage1::generic_validate_utf8(buf,len);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(*doc);
|
||||
return stage2::structural_parser::parse<false>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(_doc);
|
||||
return stage2::structural_parser::parse<true>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
auto error = stage1(_buf, _len, false);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_depth,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
|
|
|
@ -12,14 +12,14 @@ using namespace simdjson::dom;
|
|||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation("arm64", "ARM NEON", instruction_set::NEON) {}
|
||||
WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
simdjson_really_inline implementation() : simdjson::implementation("arm64", "ARM NEON", instruction_set::NEON) {}
|
||||
SIMDJSON_WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_length,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace arm64
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace arm64 {
|
|||
|
||||
// we don't have SSE, so let us use a scalar function
|
||||
// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/
|
||||
static really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
static simdjson_really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
uint64_t val;
|
||||
memcpy(&val, chars, sizeof(uint64_t));
|
||||
val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8;
|
||||
|
|
188
src/arm64/simd.h
188
src/arm64/simd.h
|
@ -27,7 +27,7 @@ namespace {
|
|||
* You should not use this function except for compile-time constants:
|
||||
* it is not efficient.
|
||||
*/
|
||||
really_inline uint8x16_t make_uint8x16_t(uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4,
|
||||
simdjson_really_inline uint8x16_t make_uint8x16_t(uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4,
|
||||
uint8_t x5, uint8_t x6, uint8_t x7, uint8_t x8,
|
||||
uint8_t x9, uint8_t x10, uint8_t x11, uint8_t x12,
|
||||
uint8_t x13, uint8_t x14, uint8_t x15, uint8_t x16) {
|
||||
|
@ -58,7 +58,7 @@ really_inline uint8x16_t make_uint8x16_t(uint8_t x1, uint8_t x2, uint8_t x3,
|
|||
|
||||
|
||||
// We have to do the same work for make_int8x16_t
|
||||
really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_t x4,
|
||||
simdjson_really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_t x4,
|
||||
int8_t x5, int8_t x6, int8_t x7, int8_t x8,
|
||||
int8_t x9, int8_t x10, int8_t x11, int8_t x12,
|
||||
int8_t x13, int8_t x14, int8_t x15, int8_t x16) {
|
||||
|
@ -104,24 +104,24 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
static const int SIZE = sizeof(value);
|
||||
|
||||
// Conversion from/to SIMD register
|
||||
really_inline base_u8(const uint8x16_t _value) : value(_value) {}
|
||||
really_inline operator const uint8x16_t&() const { return this->value; }
|
||||
really_inline operator uint8x16_t&() { return this->value; }
|
||||
simdjson_really_inline base_u8(const uint8x16_t _value) : value(_value) {}
|
||||
simdjson_really_inline operator const uint8x16_t&() const { return this->value; }
|
||||
simdjson_really_inline operator uint8x16_t&() { return this->value; }
|
||||
|
||||
// Bit operations
|
||||
really_inline simd8<T> operator|(const simd8<T> other) const { return vorrq_u8(*this, other); }
|
||||
really_inline simd8<T> operator&(const simd8<T> other) const { return vandq_u8(*this, other); }
|
||||
really_inline simd8<T> operator^(const simd8<T> other) const { return veorq_u8(*this, other); }
|
||||
really_inline simd8<T> bit_andnot(const simd8<T> other) const { return vbicq_u8(*this, other); }
|
||||
really_inline simd8<T> operator~() const { return *this ^ 0xFFu; }
|
||||
really_inline simd8<T>& operator|=(const simd8<T> other) { auto this_cast = (simd8<T>*)this; *this_cast = *this_cast | other; return *this_cast; }
|
||||
really_inline simd8<T>& operator&=(const simd8<T> other) { auto this_cast = (simd8<T>*)this; *this_cast = *this_cast & other; return *this_cast; }
|
||||
really_inline simd8<T>& operator^=(const simd8<T> other) { auto this_cast = (simd8<T>*)this; *this_cast = *this_cast ^ other; return *this_cast; }
|
||||
simdjson_really_inline simd8<T> operator|(const simd8<T> other) const { return vorrq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<T> operator&(const simd8<T> other) const { return vandq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<T> operator^(const simd8<T> other) const { return veorq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<T> bit_andnot(const simd8<T> other) const { return vbicq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<T> operator~() const { return *this ^ 0xFFu; }
|
||||
simdjson_really_inline simd8<T>& operator|=(const simd8<T> other) { auto this_cast = (simd8<T>*)this; *this_cast = *this_cast | other; return *this_cast; }
|
||||
simdjson_really_inline simd8<T>& operator&=(const simd8<T> other) { auto this_cast = (simd8<T>*)this; *this_cast = *this_cast & other; return *this_cast; }
|
||||
simdjson_really_inline simd8<T>& operator^=(const simd8<T> other) { auto this_cast = (simd8<T>*)this; *this_cast = *this_cast ^ other; return *this_cast; }
|
||||
|
||||
really_inline Mask operator==(const simd8<T> other) const { return vceqq_u8(*this, other); }
|
||||
simdjson_really_inline Mask operator==(const simd8<T> other) const { return vceqq_u8(*this, other); }
|
||||
|
||||
template<int N=1>
|
||||
really_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||
simdjson_really_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||
return vextq_u8(prev_chunk, *this, 16 - N);
|
||||
}
|
||||
};
|
||||
|
@ -132,17 +132,17 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
typedef uint16_t bitmask_t;
|
||||
typedef uint32_t bitmask2_t;
|
||||
|
||||
static really_inline simd8<bool> splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); }
|
||||
static simdjson_really_inline simd8<bool> splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); }
|
||||
|
||||
really_inline simd8(const uint8x16_t _value) : base_u8<bool>(_value) {}
|
||||
simdjson_really_inline simd8(const uint8x16_t _value) : base_u8<bool>(_value) {}
|
||||
// False constructor
|
||||
really_inline simd8() : simd8(vdupq_n_u8(0)) {}
|
||||
simdjson_really_inline simd8() : simd8(vdupq_n_u8(0)) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(bool _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(bool _value) : simd8(splat(_value)) {}
|
||||
|
||||
// We return uint32_t instead of uint16_t because that seems to be more efficient for most
|
||||
// purposes (cutting it down to uint16_t costs performance in some compilers).
|
||||
really_inline uint32_t to_bitmask() const {
|
||||
simdjson_really_inline uint32_t to_bitmask() const {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
const uint8x16_t bit_mask = make_uint8x16_t(0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
|
||||
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80);
|
||||
|
@ -156,26 +156,26 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
tmp = vpaddq_u8(tmp, tmp);
|
||||
return vgetq_lane_u16(vreinterpretq_u16_u8(tmp), 0);
|
||||
}
|
||||
really_inline bool any() const { return vmaxvq_u8(*this) != 0; }
|
||||
simdjson_really_inline bool any() const { return vmaxvq_u8(*this) != 0; }
|
||||
};
|
||||
|
||||
// Unsigned bytes
|
||||
template<>
|
||||
struct simd8<uint8_t>: base_u8<uint8_t> {
|
||||
static really_inline uint8x16_t splat(uint8_t _value) { return vmovq_n_u8(_value); }
|
||||
static really_inline uint8x16_t zero() { return vdupq_n_u8(0); }
|
||||
static really_inline uint8x16_t load(const uint8_t* values) { return vld1q_u8(values); }
|
||||
static simdjson_really_inline uint8x16_t splat(uint8_t _value) { return vmovq_n_u8(_value); }
|
||||
static simdjson_really_inline uint8x16_t zero() { return vdupq_n_u8(0); }
|
||||
static simdjson_really_inline uint8x16_t load(const uint8_t* values) { return vld1q_u8(values); }
|
||||
|
||||
really_inline simd8(const uint8x16_t _value) : base_u8<uint8_t>(_value) {}
|
||||
simdjson_really_inline simd8(const uint8x16_t _value) : base_u8<uint8_t>(_value) {}
|
||||
// Zero constructor
|
||||
really_inline simd8() : simd8(zero()) {}
|
||||
simdjson_really_inline simd8() : simd8(zero()) {}
|
||||
// Array constructor
|
||||
really_inline simd8(const uint8_t values[16]) : simd8(load(values)) {}
|
||||
simdjson_really_inline simd8(const uint8_t values[16]) : simd8(load(values)) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||
// Member-by-member initialization
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||
) : simd8(make_uint8x16_t(
|
||||
|
@ -183,7 +183,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
v8, v9, v10,v11,v12,v13,v14,v15
|
||||
)) {}
|
||||
#else
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||
) : simd8(uint8x16_t{
|
||||
|
@ -193,7 +193,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
#endif
|
||||
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
really_inline static simd8<uint8_t> repeat_16(
|
||||
simdjson_really_inline static simd8<uint8_t> repeat_16(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||
) {
|
||||
|
@ -204,44 +204,44 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
}
|
||||
|
||||
// Store to array
|
||||
really_inline void store(uint8_t dst[16]) const { return vst1q_u8(dst, *this); }
|
||||
simdjson_really_inline void store(uint8_t dst[16]) const { return vst1q_u8(dst, *this); }
|
||||
|
||||
// Saturated math
|
||||
really_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> other) const { return vqaddq_u8(*this, other); }
|
||||
really_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> other) const { return vqsubq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> other) const { return vqaddq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> other) const { return vqsubq_u8(*this, other); }
|
||||
|
||||
// Addition/subtraction are the same for signed and unsigned
|
||||
really_inline simd8<uint8_t> operator+(const simd8<uint8_t> other) const { return vaddq_u8(*this, other); }
|
||||
really_inline simd8<uint8_t> operator-(const simd8<uint8_t> other) const { return vsubq_u8(*this, other); }
|
||||
really_inline simd8<uint8_t>& operator+=(const simd8<uint8_t> other) { *this = *this + other; return *this; }
|
||||
really_inline simd8<uint8_t>& operator-=(const simd8<uint8_t> other) { *this = *this - other; return *this; }
|
||||
simdjson_really_inline simd8<uint8_t> operator+(const simd8<uint8_t> other) const { return vaddq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> operator-(const simd8<uint8_t> other) const { return vsubq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t>& operator+=(const simd8<uint8_t> other) { *this = *this + other; return *this; }
|
||||
simdjson_really_inline simd8<uint8_t>& operator-=(const simd8<uint8_t> other) { *this = *this - other; return *this; }
|
||||
|
||||
// Order-specific operations
|
||||
really_inline uint8_t max() const { return vmaxvq_u8(*this); }
|
||||
really_inline uint8_t min() const { return vminvq_u8(*this); }
|
||||
really_inline simd8<uint8_t> max(const simd8<uint8_t> other) const { return vmaxq_u8(*this, other); }
|
||||
really_inline simd8<uint8_t> min(const simd8<uint8_t> other) const { return vminq_u8(*this, other); }
|
||||
really_inline simd8<bool> operator<=(const simd8<uint8_t> other) const { return vcleq_u8(*this, other); }
|
||||
really_inline simd8<bool> operator>=(const simd8<uint8_t> other) const { return vcgeq_u8(*this, other); }
|
||||
really_inline simd8<bool> operator<(const simd8<uint8_t> other) const { return vcltq_u8(*this, other); }
|
||||
really_inline simd8<bool> operator>(const simd8<uint8_t> other) const { return vcgtq_u8(*this, other); }
|
||||
simdjson_really_inline uint8_t max() const { return vmaxvq_u8(*this); }
|
||||
simdjson_really_inline uint8_t min() const { return vminvq_u8(*this); }
|
||||
simdjson_really_inline simd8<uint8_t> max(const simd8<uint8_t> other) const { return vmaxq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> min(const simd8<uint8_t> other) const { return vminq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator<=(const simd8<uint8_t> other) const { return vcleq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator>=(const simd8<uint8_t> other) const { return vcgeq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator<(const simd8<uint8_t> other) const { return vcltq_u8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator>(const simd8<uint8_t> other) const { return vcgtq_u8(*this, other); }
|
||||
// Same as >, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's.
|
||||
really_inline simd8<uint8_t> gt_bits(const simd8<uint8_t> other) const { return simd8<uint8_t>(*this > other); }
|
||||
simdjson_really_inline simd8<uint8_t> gt_bits(const simd8<uint8_t> other) const { return simd8<uint8_t>(*this > other); }
|
||||
// Same as <, but instead of guaranteeing all 1's == true, false = 0 and true = nonzero. For ARM, returns all 1's.
|
||||
really_inline simd8<uint8_t> lt_bits(const simd8<uint8_t> other) const { return simd8<uint8_t>(*this < other); }
|
||||
simdjson_really_inline simd8<uint8_t> lt_bits(const simd8<uint8_t> other) const { return simd8<uint8_t>(*this < other); }
|
||||
|
||||
// Bit-specific operations
|
||||
really_inline simd8<bool> any_bits_set(simd8<uint8_t> bits) const { return vtstq_u8(*this, bits); }
|
||||
really_inline bool any_bits_set_anywhere() const { return this->max() != 0; }
|
||||
really_inline bool any_bits_set_anywhere(simd8<uint8_t> bits) const { return (*this & bits).any_bits_set_anywhere(); }
|
||||
simdjson_really_inline simd8<bool> any_bits_set(simd8<uint8_t> bits) const { return vtstq_u8(*this, bits); }
|
||||
simdjson_really_inline bool any_bits_set_anywhere() const { return this->max() != 0; }
|
||||
simdjson_really_inline bool any_bits_set_anywhere(simd8<uint8_t> bits) const { return (*this & bits).any_bits_set_anywhere(); }
|
||||
template<int N>
|
||||
really_inline simd8<uint8_t> shr() const { return vshrq_n_u8(*this, N); }
|
||||
simdjson_really_inline simd8<uint8_t> shr() const { return vshrq_n_u8(*this, N); }
|
||||
template<int N>
|
||||
really_inline simd8<uint8_t> shl() const { return vshlq_n_u8(*this, N); }
|
||||
simdjson_really_inline simd8<uint8_t> shl() const { return vshlq_n_u8(*this, N); }
|
||||
|
||||
// Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values)
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
simdjson_really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
return lookup_table.apply_lookup_16_to(*this);
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
// signature simd8<L> compress(uint16_t mask) would be
|
||||
// sensible, but the AVX ISA makes this kind of approach difficult.
|
||||
template<typename L>
|
||||
really_inline void compress(uint16_t mask, L * output) const {
|
||||
simdjson_really_inline void compress(uint16_t mask, L * output) const {
|
||||
// this particular implementation was inspired by work done by @animetosho
|
||||
// we do it in two steps, first 8 bytes and then second 8 bytes
|
||||
uint8_t mask1 = uint8_t(mask); // least significant 8 bits
|
||||
|
@ -286,7 +286,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
}
|
||||
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(
|
||||
simdjson_really_inline simd8<L> lookup_16(
|
||||
L replace0, L replace1, L replace2, L replace3,
|
||||
L replace4, L replace5, L replace6, L replace7,
|
||||
L replace8, L replace9, L replace10, L replace11,
|
||||
|
@ -300,7 +300,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline simd8<uint8_t> apply_lookup_16_to(const simd8<T> original) {
|
||||
simdjson_really_inline simd8<uint8_t> apply_lookup_16_to(const simd8<T> original) {
|
||||
return vqtbl1q_u8(*this, simd8<uint8_t>(original));
|
||||
}
|
||||
};
|
||||
|
@ -310,24 +310,24 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
struct simd8<int8_t> {
|
||||
int8x16_t value;
|
||||
|
||||
static really_inline simd8<int8_t> splat(int8_t _value) { return vmovq_n_s8(_value); }
|
||||
static really_inline simd8<int8_t> zero() { return vdupq_n_s8(0); }
|
||||
static really_inline simd8<int8_t> load(const int8_t values[16]) { return vld1q_s8(values); }
|
||||
static simdjson_really_inline simd8<int8_t> splat(int8_t _value) { return vmovq_n_s8(_value); }
|
||||
static simdjson_really_inline simd8<int8_t> zero() { return vdupq_n_s8(0); }
|
||||
static simdjson_really_inline simd8<int8_t> load(const int8_t values[16]) { return vld1q_s8(values); }
|
||||
|
||||
// Conversion from/to SIMD register
|
||||
really_inline simd8(const int8x16_t _value) : value{_value} {}
|
||||
really_inline operator const int8x16_t&() const { return this->value; }
|
||||
really_inline operator int8x16_t&() { return this->value; }
|
||||
simdjson_really_inline simd8(const int8x16_t _value) : value{_value} {}
|
||||
simdjson_really_inline operator const int8x16_t&() const { return this->value; }
|
||||
simdjson_really_inline operator int8x16_t&() { return this->value; }
|
||||
|
||||
// Zero constructor
|
||||
really_inline simd8() : simd8(zero()) {}
|
||||
simdjson_really_inline simd8() : simd8(zero()) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(int8_t _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(int8_t _value) : simd8(splat(_value)) {}
|
||||
// Array constructor
|
||||
really_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||
simdjson_really_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||
// Member-by-member initialization
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||
) : simd8(make_int8x16_t(
|
||||
|
@ -335,7 +335,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
v8, v9, v10,v11,v12,v13,v14,v15
|
||||
)) {}
|
||||
#else
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||
) : simd8(int8x16_t{
|
||||
|
@ -344,7 +344,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
}) {}
|
||||
#endif
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
really_inline static simd8<int8_t> repeat_16(
|
||||
simdjson_really_inline static simd8<int8_t> repeat_16(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||
) {
|
||||
|
@ -355,7 +355,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
}
|
||||
|
||||
// Store to array
|
||||
really_inline void store(int8_t dst[16]) const { return vst1q_s8(dst, *this); }
|
||||
simdjson_really_inline void store(int8_t dst[16]) const { return vst1q_s8(dst, *this); }
|
||||
|
||||
// Explicit conversion to/from unsigned
|
||||
//
|
||||
|
@ -363,35 +363,35 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
// In theory, we could check this occurence with std::same_as and std::enabled_if but it is C++14
|
||||
// and relatively ugly and hard to read.
|
||||
#ifndef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
really_inline explicit simd8(const uint8x16_t other): simd8(vreinterpretq_s8_u8(other)) {}
|
||||
simdjson_really_inline explicit simd8(const uint8x16_t other): simd8(vreinterpretq_s8_u8(other)) {}
|
||||
#endif
|
||||
really_inline explicit operator simd8<uint8_t>() const { return vreinterpretq_u8_s8(this->value); }
|
||||
simdjson_really_inline explicit operator simd8<uint8_t>() const { return vreinterpretq_u8_s8(this->value); }
|
||||
|
||||
// Math
|
||||
really_inline simd8<int8_t> operator+(const simd8<int8_t> other) const { return vaddq_s8(*this, other); }
|
||||
really_inline simd8<int8_t> operator-(const simd8<int8_t> other) const { return vsubq_s8(*this, other); }
|
||||
really_inline simd8<int8_t>& operator+=(const simd8<int8_t> other) { *this = *this + other; return *this; }
|
||||
really_inline simd8<int8_t>& operator-=(const simd8<int8_t> other) { *this = *this - other; return *this; }
|
||||
simdjson_really_inline simd8<int8_t> operator+(const simd8<int8_t> other) const { return vaddq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<int8_t> operator-(const simd8<int8_t> other) const { return vsubq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<int8_t>& operator+=(const simd8<int8_t> other) { *this = *this + other; return *this; }
|
||||
simdjson_really_inline simd8<int8_t>& operator-=(const simd8<int8_t> other) { *this = *this - other; return *this; }
|
||||
|
||||
// Order-sensitive comparisons
|
||||
really_inline simd8<int8_t> max(const simd8<int8_t> other) const { return vmaxq_s8(*this, other); }
|
||||
really_inline simd8<int8_t> min(const simd8<int8_t> other) const { return vminq_s8(*this, other); }
|
||||
really_inline simd8<bool> operator>(const simd8<int8_t> other) const { return vcgtq_s8(*this, other); }
|
||||
really_inline simd8<bool> operator<(const simd8<int8_t> other) const { return vcltq_s8(*this, other); }
|
||||
really_inline simd8<bool> operator==(const simd8<int8_t> other) const { return vceqq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<int8_t> max(const simd8<int8_t> other) const { return vmaxq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<int8_t> min(const simd8<int8_t> other) const { return vminq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator>(const simd8<int8_t> other) const { return vcgtq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator<(const simd8<int8_t> other) const { return vcltq_s8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator==(const simd8<int8_t> other) const { return vceqq_s8(*this, other); }
|
||||
|
||||
template<int N=1>
|
||||
really_inline simd8<int8_t> prev(const simd8<int8_t> prev_chunk) const {
|
||||
simdjson_really_inline simd8<int8_t> prev(const simd8<int8_t> prev_chunk) const {
|
||||
return vextq_s8(prev_chunk, *this, 16 - N);
|
||||
}
|
||||
|
||||
// Perform a lookup assuming no value is larger than 16
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
simdjson_really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
return lookup_table.apply_lookup_16_to(*this);
|
||||
}
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(
|
||||
simdjson_really_inline simd8<L> lookup_16(
|
||||
L replace0, L replace1, L replace2, L replace3,
|
||||
L replace4, L replace5, L replace6, L replace7,
|
||||
L replace8, L replace9, L replace10, L replace11,
|
||||
|
@ -405,7 +405,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline simd8<int8_t> apply_lookup_16_to(const simd8<T> original) {
|
||||
simdjson_really_inline simd8<int8_t> apply_lookup_16_to(const simd8<T> original) {
|
||||
return vqtbl1q_s8(*this, simd8<uint8_t>(original));
|
||||
}
|
||||
};
|
||||
|
@ -420,29 +420,29 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
simd8x64<T>& operator=(const simd8<T> other) = delete; // no assignment allowed
|
||||
simd8x64() = delete; // no default constructor allowed
|
||||
|
||||
really_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1, const simd8<T> chunk2, const simd8<T> chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {}
|
||||
really_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+16), simd8<T>::load(ptr+32), simd8<T>::load(ptr+48)} {}
|
||||
simdjson_really_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1, const simd8<T> chunk2, const simd8<T> chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {}
|
||||
simdjson_really_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+16), simd8<T>::load(ptr+32), simd8<T>::load(ptr+48)} {}
|
||||
|
||||
really_inline void store(T ptr[64]) const {
|
||||
simdjson_really_inline void store(T ptr[64]) const {
|
||||
this->chunks[0].store(ptr+sizeof(simd8<T>)*0);
|
||||
this->chunks[1].store(ptr+sizeof(simd8<T>)*1);
|
||||
this->chunks[2].store(ptr+sizeof(simd8<T>)*2);
|
||||
this->chunks[3].store(ptr+sizeof(simd8<T>)*3);
|
||||
}
|
||||
|
||||
really_inline simd8<T> reduce_or() const {
|
||||
simdjson_really_inline simd8<T> reduce_or() const {
|
||||
return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]);
|
||||
}
|
||||
|
||||
|
||||
really_inline void compress(uint64_t mask, T * output) const {
|
||||
simdjson_really_inline void compress(uint64_t mask, T * output) const {
|
||||
this->chunks[0].compress(uint16_t(mask), output);
|
||||
this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF));
|
||||
this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF));
|
||||
this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF));
|
||||
}
|
||||
|
||||
really_inline uint64_t to_bitmask() const {
|
||||
simdjson_really_inline uint64_t to_bitmask() const {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
const uint8x16_t bit_mask = make_uint8x16_t(
|
||||
0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
|
||||
|
@ -462,7 +462,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
return vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0);
|
||||
}
|
||||
|
||||
really_inline simd8x64<T> bit_or(const T m) const {
|
||||
simdjson_really_inline simd8x64<T> bit_or(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<T>(
|
||||
this->chunks[0] | mask,
|
||||
|
@ -472,7 +472,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
);
|
||||
}
|
||||
|
||||
really_inline uint64_t eq(const T m) const {
|
||||
simdjson_really_inline uint64_t eq(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<bool>(
|
||||
this->chunks[0] == mask,
|
||||
|
@ -482,7 +482,7 @@ really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int8_
|
|||
).to_bitmask();
|
||||
}
|
||||
|
||||
really_inline uint64_t lteq(const T m) const {
|
||||
simdjson_really_inline uint64_t lteq(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<bool>(
|
||||
this->chunks[0] <= mask,
|
||||
|
|
|
@ -14,18 +14,18 @@ using namespace simd;
|
|||
struct backslash_and_quote {
|
||||
public:
|
||||
static constexpr uint32_t BYTES_PROCESSED = 32;
|
||||
really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
simdjson_really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
|
||||
really_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; }
|
||||
really_inline bool has_backslash() { return bs_bits != 0; }
|
||||
really_inline int quote_index() { return trailing_zeroes(quote_bits); }
|
||||
really_inline int backslash_index() { return trailing_zeroes(bs_bits); }
|
||||
simdjson_really_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; }
|
||||
simdjson_really_inline bool has_backslash() { return bs_bits != 0; }
|
||||
simdjson_really_inline int quote_index() { return trailing_zeroes(quote_bits); }
|
||||
simdjson_really_inline int backslash_index() { return trailing_zeroes(bs_bits); }
|
||||
|
||||
uint32_t bs_bits;
|
||||
uint32_t quote_bits;
|
||||
}; // struct backslash_and_quote
|
||||
|
||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
simdjson_really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
// this can read up to 31 bytes beyond the buffer size, but we require
|
||||
// SIMDJSON_PADDING of padding
|
||||
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes");
|
||||
|
|
|
@ -25,7 +25,7 @@ static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) {
|
|||
#endif
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline int leading_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int leading_zeroes(uint64_t input_num) {
|
||||
#ifdef _MSC_VER
|
||||
unsigned long leading_zero = 0;
|
||||
// Search the mask data from most significant bit (MSB)
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace stage1 {
|
|||
class structural_scanner {
|
||||
public:
|
||||
|
||||
really_inline structural_scanner(dom_parser_implementation &_parser, bool _partial)
|
||||
simdjson_really_inline structural_scanner(dom_parser_implementation &_parser, bool _partial)
|
||||
: buf{_parser.buf},
|
||||
next_structural_index{_parser.structural_indexes.get()},
|
||||
parser{_parser},
|
||||
|
@ -22,18 +22,18 @@ really_inline structural_scanner(dom_parser_implementation &_parser, bool _parti
|
|||
partial{_partial} {
|
||||
}
|
||||
|
||||
really_inline void add_structural() {
|
||||
simdjson_really_inline void add_structural() {
|
||||
*next_structural_index = idx;
|
||||
next_structural_index++;
|
||||
}
|
||||
|
||||
really_inline bool is_continuation(uint8_t c) {
|
||||
simdjson_really_inline bool is_continuation(uint8_t c) {
|
||||
return (c & 0b11000000) == 0b10000000;
|
||||
}
|
||||
|
||||
really_inline void validate_utf8_character() {
|
||||
simdjson_really_inline void validate_utf8_character() {
|
||||
// Continuation
|
||||
if (unlikely((buf[idx] & 0b01000000) == 0)) {
|
||||
if (simdjson_unlikely((buf[idx] & 0b01000000) == 0)) {
|
||||
// extra continuation
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
|
@ -43,7 +43,7 @@ really_inline void validate_utf8_character() {
|
|||
// 2-byte
|
||||
if ((buf[idx] & 0b00100000) == 0) {
|
||||
// missing continuation
|
||||
if (unlikely(idx+1 > len || !is_continuation(buf[idx+1]))) {
|
||||
if (simdjson_unlikely(idx+1 > len || !is_continuation(buf[idx+1]))) {
|
||||
if (idx+1 > len && partial) { idx = len; return; }
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
|
@ -58,7 +58,7 @@ really_inline void validate_utf8_character() {
|
|||
// 3-byte
|
||||
if ((buf[idx] & 0b00010000) == 0) {
|
||||
// missing continuation
|
||||
if (unlikely(idx+2 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]))) {
|
||||
if (simdjson_unlikely(idx+2 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]))) {
|
||||
if (idx+2 > len && partial) { idx = len; return; }
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
|
@ -74,7 +74,7 @@ really_inline void validate_utf8_character() {
|
|||
|
||||
// 4-byte
|
||||
// missing continuation
|
||||
if (unlikely(idx+3 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]) || !is_continuation(buf[idx+3]))) {
|
||||
if (simdjson_unlikely(idx+3 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]) || !is_continuation(buf[idx+3]))) {
|
||||
if (idx+2 > len && partial) { idx = len; return; }
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
|
@ -92,12 +92,12 @@ really_inline void validate_utf8_character() {
|
|||
idx += 4;
|
||||
}
|
||||
|
||||
really_inline void validate_string() {
|
||||
simdjson_really_inline void validate_string() {
|
||||
idx++; // skip first quote
|
||||
while (idx < len && buf[idx] != '"') {
|
||||
if (buf[idx] == '\\') {
|
||||
idx += 2;
|
||||
} else if (unlikely(buf[idx] & 0b10000000)) {
|
||||
} else if (simdjson_unlikely(buf[idx] & 0b10000000)) {
|
||||
validate_utf8_character();
|
||||
} else {
|
||||
if (buf[idx] < 0x20) { error = UNESCAPED_CHARS; }
|
||||
|
@ -107,7 +107,7 @@ really_inline void validate_string() {
|
|||
if (idx >= len && !partial) { error = UNCLOSED_STRING; }
|
||||
}
|
||||
|
||||
really_inline bool is_whitespace_or_operator(uint8_t c) {
|
||||
simdjson_really_inline bool is_whitespace_or_operator(uint8_t c) {
|
||||
switch (c) {
|
||||
case '{': case '}': case '[': case ']': case ',': case ':':
|
||||
case ' ': case '\r': case '\n': case '\t':
|
||||
|
@ -120,7 +120,7 @@ really_inline bool is_whitespace_or_operator(uint8_t c) {
|
|||
//
|
||||
// Parse the entire input in STEP_SIZE-byte chunks.
|
||||
//
|
||||
really_inline error_code scan() {
|
||||
simdjson_really_inline error_code scan() {
|
||||
for (;idx<len;idx++) {
|
||||
switch (buf[idx]) {
|
||||
// String
|
||||
|
@ -153,7 +153,7 @@ really_inline error_code scan() {
|
|||
parser.n_structural_indexes = uint32_t(next_structural_index - parser.structural_indexes.get());
|
||||
parser.next_structural_index = 0;
|
||||
|
||||
if (unlikely(parser.n_structural_indexes == 0)) {
|
||||
if (simdjson_unlikely(parser.n_structural_indexes == 0)) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ private:
|
|||
|
||||
} // namespace stage1
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool partial) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool partial) noexcept {
|
||||
this->buf = _buf;
|
||||
this->len = _len;
|
||||
stage1::structural_scanner scanner(*this, partial);
|
||||
|
@ -222,7 +222,7 @@ static uint8_t jump_table[256 * 3] = {
|
|||
0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
|
||||
};
|
||||
|
||||
WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
size_t i = 0, pos = 0;
|
||||
uint8_t quote = 0;
|
||||
uint8_t nonescape = 1;
|
||||
|
@ -244,7 +244,7 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
|
|||
}
|
||||
|
||||
// credit: based on code from Google Fuchsia (Apache Licensed)
|
||||
WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
const uint8_t *data = (const uint8_t *)buf;
|
||||
uint64_t pos = 0;
|
||||
uint64_t next_pos = 0;
|
||||
|
@ -321,19 +321,19 @@ WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) cons
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(*doc);
|
||||
return stage2::structural_parser::parse<false>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(_doc);
|
||||
return stage2::structural_parser::parse<true>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
auto error = stage1(_buf, _len, false);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_depth,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
|
|
|
@ -12,18 +12,18 @@ using namespace simdjson::dom;
|
|||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation(
|
||||
simdjson_really_inline implementation() : simdjson::implementation(
|
||||
"fallback",
|
||||
"Generic fallback implementation",
|
||||
0
|
||||
) {}
|
||||
WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_length,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace fallback
|
||||
|
|
|
@ -10,14 +10,14 @@ void found_float(double result, const uint8_t *buf);
|
|||
|
||||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
static really_inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||
static simdjson_really_inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||
uint32_t result = 0;
|
||||
for (int i=0;i<8;i++) {
|
||||
result = result*10 + (chars[i] - '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
static simdjson_really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
return parse_eight_digits_unrolled((const char *)chars);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,17 +10,17 @@ namespace fallback {
|
|||
struct backslash_and_quote {
|
||||
public:
|
||||
static constexpr uint32_t BYTES_PROCESSED = 1;
|
||||
really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
simdjson_really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
|
||||
really_inline bool has_quote_first() { return c == '"'; }
|
||||
really_inline bool has_backslash() { return c == '\\'; }
|
||||
really_inline int quote_index() { return c == '"' ? 0 : 1; }
|
||||
really_inline int backslash_index() { return c == '\\' ? 0 : 1; }
|
||||
simdjson_really_inline bool has_quote_first() { return c == '"'; }
|
||||
simdjson_really_inline bool has_backslash() { return c == '\\'; }
|
||||
simdjson_really_inline int quote_index() { return c == '"' ? 0 : 1; }
|
||||
simdjson_really_inline int backslash_index() { return c == '\\' ? 0 : 1; }
|
||||
|
||||
uint8_t c;
|
||||
}; // struct backslash_and_quote
|
||||
|
||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
simdjson_really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
// store to dest unconditionally - we can overwrite the bits we don't like later
|
||||
dst[0] = src[0];
|
||||
return { src[0] };
|
||||
|
|
|
@ -23,17 +23,17 @@ public:
|
|||
/** Document passed to stage 2 */
|
||||
dom::document *doc{};
|
||||
|
||||
really_inline dom_parser_implementation();
|
||||
simdjson_really_inline dom_parser_implementation();
|
||||
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
||||
dom_parser_implementation & operator=(const dom_parser_implementation &) = delete;
|
||||
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool partial) noexcept final;
|
||||
WARN_UNUSED error_code check_for_unclosed_array() noexcept;
|
||||
WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
||||
WARN_UNUSED error_code stage2_next(dom::document &doc) noexcept final;
|
||||
WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
||||
WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool partial) noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code check_for_unclosed_array() noexcept;
|
||||
SIMDJSON_WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code stage2_next(dom::document &doc) noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace SIMDJSON_IMPLEMENTATION
|
||||
|
@ -45,17 +45,17 @@ public:
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
really_inline dom_parser_implementation::dom_parser_implementation() {}
|
||||
simdjson_really_inline dom_parser_implementation::dom_parser_implementation() {}
|
||||
|
||||
// Leaving these here so they can be inlined if so desired
|
||||
WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
||||
error_code err = stage1::allocate::set_capacity(*this, capacity);
|
||||
if (err) { _capacity = 0; return err; }
|
||||
_capacity = capacity;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
||||
error_code err = stage2::allocate::set_max_depth(*this, max_depth);
|
||||
if (err) { _max_depth = 0; return err; }
|
||||
_max_depth = max_depth;
|
||||
|
|
|
@ -6,8 +6,8 @@ namespace allocate {
|
|||
//
|
||||
// Allocates stage 1 internal state and outputs in the parser
|
||||
//
|
||||
really_inline error_code set_capacity(internal::dom_parser_implementation &parser, size_t capacity) {
|
||||
size_t max_structures = ROUNDUP_N(capacity, 64) + 2 + 7;
|
||||
simdjson_really_inline error_code set_capacity(internal::dom_parser_implementation &parser, size_t capacity) {
|
||||
size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7;
|
||||
parser.structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] );
|
||||
if (!parser.structural_indexes) { return MEMALLOC; }
|
||||
parser.structural_indexes[0] = 0;
|
||||
|
|
|
@ -5,10 +5,10 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
template<size_t STEP_SIZE>
|
||||
struct buf_block_reader {
|
||||
public:
|
||||
really_inline buf_block_reader(const uint8_t *_buf, size_t _len);
|
||||
really_inline size_t block_index();
|
||||
really_inline bool has_full_block() const;
|
||||
really_inline const uint8_t *full_block() const;
|
||||
simdjson_really_inline buf_block_reader(const uint8_t *_buf, size_t _len);
|
||||
simdjson_really_inline size_t block_index();
|
||||
simdjson_really_inline bool has_full_block() const;
|
||||
simdjson_really_inline const uint8_t *full_block() const;
|
||||
/**
|
||||
* Get the last block, padded with spaces.
|
||||
*
|
||||
|
@ -18,8 +18,8 @@ public:
|
|||
*
|
||||
* @return the number of effective characters in the last block.
|
||||
*/
|
||||
really_inline size_t get_remainder(uint8_t *dst) const;
|
||||
really_inline void advance();
|
||||
simdjson_really_inline size_t get_remainder(uint8_t *dst) const;
|
||||
simdjson_really_inline void advance();
|
||||
private:
|
||||
const uint8_t *buf;
|
||||
const size_t len;
|
||||
|
@ -28,7 +28,7 @@ private:
|
|||
};
|
||||
|
||||
// Routines to print masks and text for debugging bitmask operations
|
||||
UNUSED static char * format_input_text_64(const uint8_t *text) {
|
||||
SIMDJSON_UNUSED static char * format_input_text_64(const uint8_t *text) {
|
||||
static char *buf = (char*)malloc(sizeof(simd8x64<uint8_t>) + 1);
|
||||
for (size_t i=0; i<sizeof(simd8x64<uint8_t>); i++) {
|
||||
buf[i] = int8_t(text[i]) < ' ' ? '_' : int8_t(text[i]);
|
||||
|
@ -38,7 +38,7 @@ UNUSED static char * format_input_text_64(const uint8_t *text) {
|
|||
}
|
||||
|
||||
// Routines to print masks and text for debugging bitmask operations
|
||||
UNUSED static char * format_input_text(const simd8x64<uint8_t>& in) {
|
||||
SIMDJSON_UNUSED static char * format_input_text(const simd8x64<uint8_t>& in) {
|
||||
static char *buf = (char*)malloc(sizeof(simd8x64<uint8_t>) + 1);
|
||||
in.store((uint8_t*)buf);
|
||||
for (size_t i=0; i<sizeof(simd8x64<uint8_t>); i++) {
|
||||
|
@ -48,7 +48,7 @@ UNUSED static char * format_input_text(const simd8x64<uint8_t>& in) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
UNUSED static char * format_mask(uint64_t mask) {
|
||||
SIMDJSON_UNUSED static char * format_mask(uint64_t mask) {
|
||||
static char *buf = (char*)malloc(64 + 1);
|
||||
for (size_t i=0; i<64; i++) {
|
||||
buf[i] = (mask & (size_t(1) << i)) ? 'X' : ' ';
|
||||
|
@ -58,30 +58,30 @@ UNUSED static char * format_mask(uint64_t mask) {
|
|||
}
|
||||
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline buf_block_reader<STEP_SIZE>::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {}
|
||||
simdjson_really_inline buf_block_reader<STEP_SIZE>::buf_block_reader(const uint8_t *_buf, size_t _len) : buf{_buf}, len{_len}, lenminusstep{len < STEP_SIZE ? 0 : len - STEP_SIZE}, idx{0} {}
|
||||
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline size_t buf_block_reader<STEP_SIZE>::block_index() { return idx; }
|
||||
simdjson_really_inline size_t buf_block_reader<STEP_SIZE>::block_index() { return idx; }
|
||||
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline bool buf_block_reader<STEP_SIZE>::has_full_block() const {
|
||||
simdjson_really_inline bool buf_block_reader<STEP_SIZE>::has_full_block() const {
|
||||
return idx < lenminusstep;
|
||||
}
|
||||
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline const uint8_t *buf_block_reader<STEP_SIZE>::full_block() const {
|
||||
simdjson_really_inline const uint8_t *buf_block_reader<STEP_SIZE>::full_block() const {
|
||||
return &buf[idx];
|
||||
}
|
||||
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline size_t buf_block_reader<STEP_SIZE>::get_remainder(uint8_t *dst) const {
|
||||
simdjson_really_inline size_t buf_block_reader<STEP_SIZE>::get_remainder(uint8_t *dst) const {
|
||||
memset(dst, 0x20, STEP_SIZE); // memset STEP_SIZE because it's more efficient to write out 8 or 16 bytes at once.
|
||||
memcpy(dst, buf + idx, len - idx);
|
||||
return len - idx;
|
||||
}
|
||||
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline void buf_block_reader<STEP_SIZE>::advance() {
|
||||
simdjson_really_inline void buf_block_reader<STEP_SIZE>::advance() {
|
||||
idx += STEP_SIZE;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
* complete document, therefore the last json buffer location is the end of the
|
||||
* batch.
|
||||
*/
|
||||
really_inline uint32_t find_next_document_index(dom_parser_implementation &parser) {
|
||||
simdjson_really_inline uint32_t find_next_document_index(dom_parser_implementation &parser) {
|
||||
// TODO don't count separately, just figure out depth
|
||||
auto arr_cnt = 0;
|
||||
auto obj_cnt = 0;
|
||||
|
|
|
@ -13,24 +13,24 @@ public:
|
|||
static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept;
|
||||
|
||||
private:
|
||||
really_inline json_minifier(uint8_t *_dst)
|
||||
simdjson_really_inline json_minifier(uint8_t *_dst)
|
||||
: dst{_dst}
|
||||
{}
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline void step(const uint8_t *block_buf, buf_block_reader<STEP_SIZE> &reader) noexcept;
|
||||
really_inline void next(const simd::simd8x64<uint8_t>& in, json_block block);
|
||||
really_inline error_code finish(uint8_t *dst_start, size_t &dst_len);
|
||||
simdjson_really_inline void step(const uint8_t *block_buf, buf_block_reader<STEP_SIZE> &reader) noexcept;
|
||||
simdjson_really_inline void next(const simd::simd8x64<uint8_t>& in, json_block block);
|
||||
simdjson_really_inline error_code finish(uint8_t *dst_start, size_t &dst_len);
|
||||
json_scanner scanner{};
|
||||
uint8_t *dst;
|
||||
};
|
||||
|
||||
really_inline void json_minifier::next(const simd::simd8x64<uint8_t>& in, json_block block) {
|
||||
simdjson_really_inline void json_minifier::next(const simd::simd8x64<uint8_t>& in, json_block block) {
|
||||
uint64_t mask = block.whitespace();
|
||||
in.compress(mask, dst);
|
||||
dst += 64 - count_ones(mask);
|
||||
}
|
||||
|
||||
really_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) {
|
||||
simdjson_really_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_len) {
|
||||
*dst = '\0';
|
||||
error_code error = scanner.finish(false);
|
||||
if (error) { dst_len = 0; return error; }
|
||||
|
@ -39,7 +39,7 @@ really_inline error_code json_minifier::finish(uint8_t *dst_start, size_t &dst_l
|
|||
}
|
||||
|
||||
template<>
|
||||
really_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept {
|
||||
simdjson_really_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_reader<128> &reader) noexcept {
|
||||
simd::simd8x64<uint8_t> in_1(block_buf);
|
||||
simd::simd8x64<uint8_t> in_2(block_buf+64);
|
||||
json_block block_1 = scanner.next(in_1);
|
||||
|
@ -50,7 +50,7 @@ really_inline void json_minifier::step<128>(const uint8_t *block_buf, buf_block_
|
|||
}
|
||||
|
||||
template<>
|
||||
really_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept {
|
||||
simdjson_really_inline void json_minifier::step<64>(const uint8_t *block_buf, buf_block_reader<64> &reader) noexcept {
|
||||
simd::simd8x64<uint8_t> in_1(block_buf);
|
||||
json_block block_1 = scanner.next(in_1);
|
||||
this->next(block_buf, block_1);
|
||||
|
@ -69,7 +69,7 @@ error_code json_minifier::minify(const uint8_t *buf, size_t len, uint8_t *dst, s
|
|||
|
||||
// Index the last (remainder) block, padded with spaces
|
||||
uint8_t block[STEP_SIZE];
|
||||
if (likely(reader.get_remainder(block)) > 0) {
|
||||
if (simdjson_likely(reader.get_remainder(block)) > 0) {
|
||||
minifier.step<STEP_SIZE>(block, reader);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,16 +25,16 @@ public:
|
|||
* The start of structurals.
|
||||
* In simdjson prior to v0.3, these were called the pseudo-structural characters.
|
||||
**/
|
||||
really_inline uint64_t structural_start() { return potential_structural_start() & ~_string.string_tail(); }
|
||||
simdjson_really_inline uint64_t structural_start() { return potential_structural_start() & ~_string.string_tail(); }
|
||||
/** All JSON whitespace (i.e. not in a string) */
|
||||
really_inline uint64_t whitespace() { return non_quote_outside_string(_characters.whitespace()); }
|
||||
simdjson_really_inline uint64_t whitespace() { return non_quote_outside_string(_characters.whitespace()); }
|
||||
|
||||
// Helpers
|
||||
|
||||
/** Whether the given characters are inside a string (only works on non-quotes) */
|
||||
really_inline uint64_t non_quote_inside_string(uint64_t mask) { return _string.non_quote_inside_string(mask); }
|
||||
simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) { return _string.non_quote_inside_string(mask); }
|
||||
/** Whether the given characters are outside a string (only works on non-quotes) */
|
||||
really_inline uint64_t non_quote_outside_string(uint64_t mask) { return _string.non_quote_outside_string(mask); }
|
||||
simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) { return _string.non_quote_outside_string(mask); }
|
||||
|
||||
// string and escape characters
|
||||
json_string_block _string;
|
||||
|
@ -49,12 +49,12 @@ private:
|
|||
* structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc".
|
||||
* They may reside inside a string.
|
||||
**/
|
||||
really_inline uint64_t potential_structural_start() { return _characters.op() | potential_scalar_start(); }
|
||||
simdjson_really_inline uint64_t potential_structural_start() { return _characters.op() | potential_scalar_start(); }
|
||||
/**
|
||||
* The start of non-operator runs, like 123, true and "abc".
|
||||
* It main reside inside a string.
|
||||
**/
|
||||
really_inline uint64_t potential_scalar_start() {
|
||||
simdjson_really_inline uint64_t potential_scalar_start() {
|
||||
// The term "scalar" refers to anything except structural characters and white space
|
||||
// (so letters, numbers, quotes).
|
||||
// Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space
|
||||
|
@ -65,7 +65,7 @@ private:
|
|||
* Whether the given character is immediately after a non-operator like 123, true.
|
||||
* The characters following a quote are not included.
|
||||
*/
|
||||
really_inline uint64_t follows_potential_scalar() {
|
||||
simdjson_really_inline uint64_t follows_potential_scalar() {
|
||||
// _follows_potential_nonquote_scalar: is defined as marking any character that follows a character
|
||||
// that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a
|
||||
// white space.
|
||||
|
@ -90,8 +90,8 @@ private:
|
|||
class json_scanner {
|
||||
public:
|
||||
json_scanner() {}
|
||||
really_inline json_block next(const simd::simd8x64<uint8_t>& in);
|
||||
really_inline error_code finish(bool streaming);
|
||||
simdjson_really_inline json_block next(const simd::simd8x64<uint8_t>& in);
|
||||
simdjson_really_inline error_code finish(bool streaming);
|
||||
|
||||
private:
|
||||
// Whether the last character of the previous iteration is part of a scalar token
|
||||
|
@ -108,13 +108,13 @@ private:
|
|||
//
|
||||
// const uint64_t backslashed_quote = in.eq('"') & immediately_follows(in.eq('\'), prev_backslash);
|
||||
//
|
||||
really_inline uint64_t follows(const uint64_t match, uint64_t &overflow) {
|
||||
simdjson_really_inline uint64_t follows(const uint64_t match, uint64_t &overflow) {
|
||||
const uint64_t result = match << 1 | overflow;
|
||||
overflow = match >> 63;
|
||||
return result;
|
||||
}
|
||||
|
||||
really_inline json_block json_scanner::next(const simd::simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline json_block json_scanner::next(const simd::simd8x64<uint8_t>& in) {
|
||||
json_string_block strings = string_scanner.next(in);
|
||||
// identifies the white-space and the structurat characters
|
||||
json_character_block characters = json_character_block::classify(in);
|
||||
|
@ -137,7 +137,7 @@ really_inline json_block json_scanner::next(const simd::simd8x64<uint8_t>& in) {
|
|||
};
|
||||
}
|
||||
|
||||
really_inline error_code json_scanner::finish(bool streaming) {
|
||||
simdjson_really_inline error_code json_scanner::finish(bool streaming) {
|
||||
return string_scanner.finish(streaming);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,23 +4,23 @@ namespace stage1 {
|
|||
|
||||
struct json_string_block {
|
||||
// Escaped characters (characters following an escape() character)
|
||||
really_inline uint64_t escaped() const { return _escaped; }
|
||||
simdjson_really_inline uint64_t escaped() const { return _escaped; }
|
||||
// Escape characters (backslashes that are not escaped--i.e. in \\, includes only the first \)
|
||||
really_inline uint64_t escape() const { return _backslash & ~_escaped; }
|
||||
simdjson_really_inline uint64_t escape() const { return _backslash & ~_escaped; }
|
||||
// Real (non-backslashed) quotes
|
||||
really_inline uint64_t quote() const { return _quote; }
|
||||
simdjson_really_inline uint64_t quote() const { return _quote; }
|
||||
// Start quotes of strings
|
||||
really_inline uint64_t string_start() const { return _quote & _in_string; }
|
||||
simdjson_really_inline uint64_t string_start() const { return _quote & _in_string; }
|
||||
// End quotes of strings
|
||||
really_inline uint64_t string_end() const { return _quote & ~_in_string; }
|
||||
simdjson_really_inline uint64_t string_end() const { return _quote & ~_in_string; }
|
||||
// Only characters inside the string (not including the quotes)
|
||||
really_inline uint64_t string_content() const { return _in_string & ~_quote; }
|
||||
simdjson_really_inline uint64_t string_content() const { return _in_string & ~_quote; }
|
||||
// Return a mask of whether the given characters are inside a string (only works on non-quotes)
|
||||
really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; }
|
||||
simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const { return mask & _in_string; }
|
||||
// Return a mask of whether the given characters are inside a string (only works on non-quotes)
|
||||
really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; }
|
||||
simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const { return mask & ~_in_string; }
|
||||
// Tail of string (everything except the start quote)
|
||||
really_inline uint64_t string_tail() const { return _in_string ^ _quote; }
|
||||
simdjson_really_inline uint64_t string_tail() const { return _in_string ^ _quote; }
|
||||
|
||||
// backslash characters
|
||||
uint64_t _backslash;
|
||||
|
@ -35,13 +35,13 @@ struct json_string_block {
|
|||
// Scans blocks for string characters, storing the state necessary to do so
|
||||
class json_string_scanner {
|
||||
public:
|
||||
really_inline json_string_block next(const simd::simd8x64<uint8_t>& in);
|
||||
really_inline error_code finish(bool streaming);
|
||||
simdjson_really_inline json_string_block next(const simd::simd8x64<uint8_t>& in);
|
||||
simdjson_really_inline error_code finish(bool streaming);
|
||||
|
||||
private:
|
||||
// Intended to be defined by the implementation
|
||||
really_inline uint64_t find_escaped(uint64_t escape);
|
||||
really_inline uint64_t find_escaped_branchless(uint64_t escape);
|
||||
simdjson_really_inline uint64_t find_escaped(uint64_t escape);
|
||||
simdjson_really_inline uint64_t find_escaped_branchless(uint64_t escape);
|
||||
|
||||
// Whether the last iteration was still inside a string (all 1's = true, all 0's = false).
|
||||
uint64_t prev_in_string = 0ULL;
|
||||
|
@ -76,7 +76,7 @@ private:
|
|||
// desired | x | x x x x x x x x |
|
||||
// text | \\\ | \\\"\\\" \\\" \\"\\" |
|
||||
//
|
||||
really_inline uint64_t json_string_scanner::find_escaped_branchless(uint64_t backslash) {
|
||||
simdjson_really_inline uint64_t json_string_scanner::find_escaped_branchless(uint64_t backslash) {
|
||||
// If there was overflow, pretend the first character isn't a backslash
|
||||
backslash &= ~prev_escaped;
|
||||
uint64_t follows_escape = backslash << 1 | prev_escaped;
|
||||
|
@ -101,7 +101,7 @@ really_inline uint64_t json_string_scanner::find_escaped_branchless(uint64_t bac
|
|||
//
|
||||
// Backslash sequences outside of quotes will be detected in stage 2.
|
||||
//
|
||||
really_inline json_string_block json_string_scanner::next(const simd::simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline json_string_block json_string_scanner::next(const simd::simd8x64<uint8_t>& in) {
|
||||
const uint64_t backslash = in.eq('\\');
|
||||
const uint64_t escaped = find_escaped(backslash);
|
||||
const uint64_t quote = in.eq('"') & ~escaped;
|
||||
|
@ -131,7 +131,7 @@ really_inline json_string_block json_string_scanner::next(const simd::simd8x64<u
|
|||
};
|
||||
}
|
||||
|
||||
really_inline error_code json_string_scanner::finish(bool streaming) {
|
||||
simdjson_really_inline error_code json_string_scanner::finish(bool streaming) {
|
||||
if (prev_in_string and (not streaming)) {
|
||||
return UNCLOSED_STRING;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@ class bit_indexer {
|
|||
public:
|
||||
uint32_t *tail;
|
||||
|
||||
really_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {}
|
||||
simdjson_really_inline bit_indexer(uint32_t *index_buf) : tail(index_buf) {}
|
||||
|
||||
// flatten out values in 'bits' assuming that they are are to have values of idx
|
||||
// plus their position in the bitvector, and store these indexes at
|
||||
// base_ptr[base] incrementing base as we go
|
||||
// will potentially store extra values beyond end of valid bits, so base_ptr
|
||||
// needs to be large enough to handle this
|
||||
really_inline void write(uint32_t idx, uint64_t bits) {
|
||||
simdjson_really_inline void write(uint32_t idx, uint64_t bits) {
|
||||
// In some instances, the next branch is expensive because it is mispredicted.
|
||||
// Unfortunately, in other cases,
|
||||
// it helps tremendously.
|
||||
|
@ -40,7 +40,7 @@ public:
|
|||
|
||||
// Do the next 8 all together (we hope in most cases it won't happen at all
|
||||
// and the branch is easily predicted).
|
||||
if (unlikely(cnt > 8)) {
|
||||
if (simdjson_unlikely(cnt > 8)) {
|
||||
for (int i=8; i<16; i++) {
|
||||
this->tail[i] = idx + trailing_zeroes(bits);
|
||||
bits = clear_lowest_bit(bits);
|
||||
|
@ -49,7 +49,7 @@ public:
|
|||
// Most files don't have 16+ structurals per block, so we take several basically guaranteed
|
||||
// branch mispredictions here. 16+ structurals per block means either punctuation ({} [] , :)
|
||||
// or the start of a value ("abc" true 123) every four characters.
|
||||
if (unlikely(cnt > 16)) {
|
||||
if (simdjson_unlikely(cnt > 16)) {
|
||||
int i = 16;
|
||||
do {
|
||||
this->tail[i] = idx + trailing_zeroes(bits);
|
||||
|
@ -76,11 +76,11 @@ public:
|
|||
static error_code index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, bool partial) noexcept;
|
||||
|
||||
private:
|
||||
really_inline json_structural_indexer(uint32_t *structural_indexes);
|
||||
simdjson_really_inline json_structural_indexer(uint32_t *structural_indexes);
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline void step(const uint8_t *block, buf_block_reader<STEP_SIZE> &reader) noexcept;
|
||||
really_inline void next(const simd::simd8x64<uint8_t>& in, json_block block, size_t idx);
|
||||
really_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, bool partial);
|
||||
simdjson_really_inline void step(const uint8_t *block, buf_block_reader<STEP_SIZE> &reader) noexcept;
|
||||
simdjson_really_inline void next(const simd::simd8x64<uint8_t>& in, json_block block, size_t idx);
|
||||
simdjson_really_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, bool partial);
|
||||
|
||||
json_scanner scanner{};
|
||||
utf8_checker checker{};
|
||||
|
@ -89,11 +89,11 @@ private:
|
|||
uint64_t unescaped_chars_error = 0;
|
||||
};
|
||||
|
||||
really_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {}
|
||||
simdjson_really_inline json_structural_indexer::json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {}
|
||||
|
||||
// Skip the last character if it is partial
|
||||
really_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) {
|
||||
if (unlikely(len < 3)) {
|
||||
simdjson_really_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) {
|
||||
if (simdjson_unlikely(len < 3)) {
|
||||
switch (len) {
|
||||
case 2:
|
||||
if (buf[len-1] >= 0b11000000) { return len-1; } // 2-, 3- and 4-byte characters with only 1 byte left
|
||||
|
@ -131,7 +131,7 @@ really_inline size_t trim_partial_utf8(const uint8_t *buf, size_t len) {
|
|||
//
|
||||
template<size_t STEP_SIZE>
|
||||
error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_parser_implementation &parser, bool partial) noexcept {
|
||||
if (unlikely(len > parser.capacity())) { return CAPACITY; }
|
||||
if (simdjson_unlikely(len > parser.capacity())) { return CAPACITY; }
|
||||
if (partial) { len = trim_partial_utf8(buf, len); }
|
||||
|
||||
buf_block_reader<STEP_SIZE> reader(buf, len);
|
||||
|
@ -144,14 +144,14 @@ error_code json_structural_indexer::index(const uint8_t *buf, size_t len, dom_pa
|
|||
|
||||
// Take care of the last block (will always be there unless file is empty)
|
||||
uint8_t block[STEP_SIZE];
|
||||
if (unlikely(reader.get_remainder(block) == 0)) { return EMPTY; }
|
||||
if (simdjson_unlikely(reader.get_remainder(block) == 0)) { return EMPTY; }
|
||||
indexer.step<STEP_SIZE>(block, reader);
|
||||
|
||||
return indexer.finish(parser, reader.block_index(), len, partial);
|
||||
}
|
||||
|
||||
template<>
|
||||
really_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept {
|
||||
simdjson_really_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_block_reader<128> &reader) noexcept {
|
||||
simd::simd8x64<uint8_t> in_1(block);
|
||||
simd::simd8x64<uint8_t> in_2(block+64);
|
||||
json_block block_1 = scanner.next(in_1);
|
||||
|
@ -162,14 +162,14 @@ really_inline void json_structural_indexer::step<128>(const uint8_t *block, buf_
|
|||
}
|
||||
|
||||
template<>
|
||||
really_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept {
|
||||
simdjson_really_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_block_reader<64> &reader) noexcept {
|
||||
simd::simd8x64<uint8_t> in_1(block);
|
||||
json_block block_1 = scanner.next(in_1);
|
||||
this->next(in_1, block_1, reader.block_index());
|
||||
reader.advance();
|
||||
}
|
||||
|
||||
really_inline void json_structural_indexer::next(const simd::simd8x64<uint8_t>& in, json_block block, size_t idx) {
|
||||
simdjson_really_inline void json_structural_indexer::next(const simd::simd8x64<uint8_t>& in, json_block block, size_t idx) {
|
||||
uint64_t unescaped = in.lteq(0x1F);
|
||||
checker.check_next_input(in);
|
||||
indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser
|
||||
|
@ -177,12 +177,12 @@ really_inline void json_structural_indexer::next(const simd::simd8x64<uint8_t>&
|
|||
unescaped_chars_error |= block.non_quote_inside_string(unescaped);
|
||||
}
|
||||
|
||||
really_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, bool partial) {
|
||||
simdjson_really_inline error_code json_structural_indexer::finish(dom_parser_implementation &parser, size_t idx, size_t len, bool partial) {
|
||||
// Write out the final iteration's structurals
|
||||
indexer.write(uint32_t(idx-64), prev_structurals);
|
||||
|
||||
error_code error = scanner.finish(partial);
|
||||
if (unlikely(error != SUCCESS)) { return error; }
|
||||
if (simdjson_unlikely(error != SUCCESS)) { return error; }
|
||||
|
||||
if (unescaped_chars_error) {
|
||||
return UNESCAPED_CHARS;
|
||||
|
@ -208,10 +208,10 @@ really_inline error_code json_structural_indexer::finish(dom_parser_implementati
|
|||
parser.structural_indexes[parser.n_structural_indexes + 2] = 0;
|
||||
parser.next_structural_index = 0;
|
||||
// a valid JSON file cannot have zero structural indexes - we should have found something
|
||||
if (unlikely(parser.n_structural_indexes == 0u)) {
|
||||
if (simdjson_unlikely(parser.n_structural_indexes == 0u)) {
|
||||
return EMPTY;
|
||||
}
|
||||
if (unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) {
|
||||
if (simdjson_unlikely(parser.structural_indexes[parser.n_structural_indexes - 1] > len)) {
|
||||
return UNEXPECTED_ERROR;
|
||||
}
|
||||
if (partial) {
|
||||
|
|
|
@ -33,12 +33,12 @@ struct utf8_checker {
|
|||
processed_utf_bytes previous;
|
||||
|
||||
// all byte values must be no larger than 0xF4
|
||||
really_inline void check_smaller_than_0xF4(const simd8<uint8_t> current_bytes) {
|
||||
simdjson_really_inline void check_smaller_than_0xF4(const simd8<uint8_t> current_bytes) {
|
||||
// unsigned, saturates to 0 below max
|
||||
this->has_error |= current_bytes.saturating_sub(0xF4u);
|
||||
}
|
||||
|
||||
really_inline simd8<int8_t> continuation_lengths(const simd8<int8_t> high_nibbles) {
|
||||
simdjson_really_inline simd8<int8_t> continuation_lengths(const simd8<int8_t> high_nibbles) {
|
||||
return high_nibbles.lookup_16<int8_t>(
|
||||
1, 1, 1, 1, 1, 1, 1, 1, // 0xxx (ASCII)
|
||||
0, 0, 0, 0, // 10xx (continuation)
|
||||
|
@ -47,7 +47,7 @@ struct utf8_checker {
|
|||
4); // 1111, next should be 0 (not checked here)
|
||||
}
|
||||
|
||||
really_inline simd8<int8_t> carry_continuations(const simd8<int8_t>& initial_lengths) {
|
||||
simdjson_really_inline simd8<int8_t> carry_continuations(const simd8<int8_t>& initial_lengths) {
|
||||
simd8<int8_t> prev_carried_continuations = initial_lengths.prev(this->previous.carried_continuations);
|
||||
simd8<int8_t> right1 = simd8<int8_t>(simd8<uint8_t>(prev_carried_continuations).saturating_sub(1));
|
||||
simd8<int8_t> sum = initial_lengths + right1;
|
||||
|
@ -57,7 +57,7 @@ struct utf8_checker {
|
|||
return sum + right2;
|
||||
}
|
||||
|
||||
really_inline void check_continuations(const simd8<int8_t>& initial_lengths, const simd8<int8_t>& carries) {
|
||||
simdjson_really_inline void check_continuations(const simd8<int8_t>& initial_lengths, const simd8<int8_t>& carries) {
|
||||
// overlap || underlap
|
||||
// carry > length && length > 0 || !(carry > length) && !(length > 0)
|
||||
// (carries > length) == (lengths > 0)
|
||||
|
@ -66,7 +66,7 @@ struct utf8_checker {
|
|||
(carries > initial_lengths) == (initial_lengths > simd8<int8_t>::zero()));
|
||||
}
|
||||
|
||||
really_inline void check_carried_continuations() {
|
||||
simdjson_really_inline void check_carried_continuations() {
|
||||
static const int8_t last_1[32] = {
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
|
@ -79,7 +79,7 @@ struct utf8_checker {
|
|||
// when 0xED is found, next byte must be no larger than 0x9F
|
||||
// when 0xF4 is found, next byte must be no larger than 0x8F
|
||||
// next byte must be continuation, ie sign bit is set, so signed < is ok
|
||||
really_inline void check_first_continuation_max(const simd8<uint8_t> current_bytes,
|
||||
simdjson_really_inline void check_first_continuation_max(const simd8<uint8_t> current_bytes,
|
||||
const simd8<uint8_t> off1_current_bytes) {
|
||||
simd8<bool> prev_ED = off1_current_bytes == 0xEDu;
|
||||
simd8<bool> prev_F4 = off1_current_bytes == 0xF4u;
|
||||
|
@ -97,7 +97,7 @@ struct utf8_checker {
|
|||
// E => < E1 && < A0
|
||||
// F => < F1 && < 90
|
||||
// else false && false
|
||||
really_inline void check_overlong(const simd8<uint8_t> current_bytes,
|
||||
simdjson_really_inline void check_overlong(const simd8<uint8_t> current_bytes,
|
||||
const simd8<uint8_t> off1_current_bytes,
|
||||
const simd8<int8_t>& high_nibbles) {
|
||||
simd8<int8_t> off1_high_nibbles = high_nibbles.prev(this->previous.high_nibbles);
|
||||
|
@ -128,14 +128,14 @@ struct utf8_checker {
|
|||
this->has_error |= simd8<uint8_t>(initial_under & second_under);
|
||||
}
|
||||
|
||||
really_inline void count_nibbles(simd8<uint8_t> bytes, struct processed_utf_bytes *answer) {
|
||||
simdjson_really_inline void count_nibbles(simd8<uint8_t> bytes, struct processed_utf_bytes *answer) {
|
||||
answer->raw_bytes = bytes;
|
||||
answer->high_nibbles = simd8<int8_t>(bytes.shr<4>());
|
||||
}
|
||||
|
||||
// check whether the current bytes are valid UTF-8
|
||||
// at the end of the function, previous gets updated
|
||||
really_inline void check_utf8_bytes(const simd8<uint8_t> current_bytes) {
|
||||
simdjson_really_inline void check_utf8_bytes(const simd8<uint8_t> current_bytes) {
|
||||
struct processed_utf_bytes pb {};
|
||||
this->count_nibbles(current_bytes, &pb);
|
||||
|
||||
|
@ -154,17 +154,17 @@ struct utf8_checker {
|
|||
this->previous = pb;
|
||||
}
|
||||
|
||||
really_inline void check_next_input(Dconst simd8<uint8_t> in) {
|
||||
if (likely(!in.any_bits_set_anywhere(0x80u))) {
|
||||
simdjson_really_inline void check_next_input(Dconst simd8<uint8_t> in) {
|
||||
if (simdjson_likely(!in.any_bits_set_anywhere(0x80u))) {
|
||||
this->check_carried_continuations();
|
||||
} else {
|
||||
this->check_utf8_bytes(in);
|
||||
}
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& in) {
|
||||
simd8<uint8_t> bits = in.reduce_or();
|
||||
if (likely(!bits.any_bits_set_anywhere(0x80u))) {
|
||||
if (simdjson_likely(!bits.any_bits_set_anywhere(0x80u))) {
|
||||
// it is ascii, we just check carried continuations.
|
||||
this->check_carried_continuations();
|
||||
} else {
|
||||
|
@ -175,7 +175,7 @@ struct utf8_checker {
|
|||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return this->has_error.any_bits_set_anywhere() ? simdjson::UTF8_ERROR : simdjson::SUCCESS;
|
||||
}
|
||||
}; // struct utf8_checker
|
||||
|
|
|
@ -80,7 +80,7 @@ using namespace simd;
|
|||
// 3 4-bit table lookups, identifying which errors that 4 bits could match, and then &'s them together.
|
||||
// If all 3 lookups detect the same error, it's an error.
|
||||
//
|
||||
really_inline simd8<uint8_t> check_special_cases(const simd8<uint8_t> input, const simd8<uint8_t> prev1) {
|
||||
simdjson_really_inline simd8<uint8_t> check_special_cases(const simd8<uint8_t> input, const simd8<uint8_t> prev1) {
|
||||
//
|
||||
// These are the errors we're going to match for bytes 1-2, by looking at the first three
|
||||
// nibbles of the character: <high bits of byte 1>> & <low bits of byte 1> & <high bits of byte 2>
|
||||
|
@ -143,7 +143,7 @@ using namespace simd;
|
|||
return byte_1_high & byte_1_low & byte_2_high;
|
||||
}
|
||||
|
||||
really_inline simd8<uint8_t> check_multibyte_lengths(const simd8<uint8_t> input, const simd8<uint8_t> prev_input, const simd8<uint8_t> prev1) {
|
||||
simdjson_really_inline simd8<uint8_t> check_multibyte_lengths(const simd8<uint8_t> input, const simd8<uint8_t> prev_input, const simd8<uint8_t> prev1) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
|
||||
|
@ -157,7 +157,7 @@ using namespace simd;
|
|||
// Return nonzero if there are incomplete multibyte characters at the end of the block:
|
||||
// e.g. if there is a 4-byte character, but it's 3 bytes from the end.
|
||||
//
|
||||
really_inline simd8<uint8_t> is_incomplete(const simd8<uint8_t> input) {
|
||||
simdjson_really_inline simd8<uint8_t> is_incomplete(const simd8<uint8_t> input) {
|
||||
// If the previous input's last 3 bytes match this, they're too short (they ended at EOF):
|
||||
// ... 1111____ 111_____ 11______
|
||||
static const uint8_t max_array[32] = {
|
||||
|
@ -181,7 +181,7 @@ using namespace simd;
|
|||
//
|
||||
// Check whether the current bytes are valid UTF-8.
|
||||
//
|
||||
really_inline void check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
simdjson_really_inline void check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
// Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes
|
||||
// (2, 3, 4-byte leads become large positive numbers instead of small negative numbers)
|
||||
simd8<uint8_t> prev1 = input.prev<1>(prev_input);
|
||||
|
@ -190,13 +190,13 @@ using namespace simd;
|
|||
}
|
||||
|
||||
// The only problem that can happen at EOF is that a multibyte character is too short.
|
||||
really_inline void check_eof() {
|
||||
simdjson_really_inline void check_eof() {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
this->error |= this->prev_incomplete;
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
if (likely(is_ascii(input))) {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
|
@ -211,7 +211,7 @@ using namespace simd;
|
|||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return this->error.any_bits_set_anywhere() ? simdjson::UTF8_ERROR : simdjson::SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ using namespace simd;
|
|||
// 3 4-bit table lookups, identifying which errors that 4 bits could match, and then &'s them together.
|
||||
// If all 3 lookups detect the same error, it's an error.
|
||||
//
|
||||
really_inline simd8<uint8_t> check_special_cases(const simd8<uint8_t> input, const simd8<uint8_t> prev1) {
|
||||
simdjson_really_inline simd8<uint8_t> check_special_cases(const simd8<uint8_t> input, const simd8<uint8_t> prev1) {
|
||||
//
|
||||
// These are the errors we're going to match for bytes 1-2, by looking at the first three
|
||||
// nibbles of the character: <high bits of byte 1>> & <low bits of byte 1> & <high bits of byte 2>
|
||||
|
@ -154,7 +154,7 @@ using namespace simd;
|
|||
return byte_1_high & byte_1_low & byte_2_high;
|
||||
}
|
||||
|
||||
really_inline simd8<uint8_t> check_multibyte_lengths(const simd8<uint8_t> input, const simd8<uint8_t> prev_input,
|
||||
simdjson_really_inline simd8<uint8_t> check_multibyte_lengths(const simd8<uint8_t> input, const simd8<uint8_t> prev_input,
|
||||
simd8<uint8_t> prev1) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
|
@ -169,7 +169,7 @@ using namespace simd;
|
|||
// Return nonzero if there are incomplete multibyte characters at the end of the block:
|
||||
// e.g. if there is a 4-byte character, but it's 3 bytes from the end.
|
||||
//
|
||||
really_inline simd8<uint8_t> is_incomplete(const simd8<uint8_t> input) {
|
||||
simdjson_really_inline simd8<uint8_t> is_incomplete(const simd8<uint8_t> input) {
|
||||
// If the previous input's last 3 bytes match this, they're too short (they ended at EOF):
|
||||
// ... 1111____ 111_____ 11______
|
||||
static const uint8_t max_array[32] = {
|
||||
|
@ -193,7 +193,7 @@ using namespace simd;
|
|||
//
|
||||
// Check whether the current bytes are valid UTF-8.
|
||||
//
|
||||
really_inline void check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
simdjson_really_inline void check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
// Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes
|
||||
// (2, 3, 4-byte leads become large positive numbers instead of small negative numbers)
|
||||
simd8<uint8_t> prev1 = input.prev<1>(prev_input);
|
||||
|
@ -202,14 +202,14 @@ using namespace simd;
|
|||
}
|
||||
|
||||
// The only problem that can happen at EOF is that a multibyte character is too short.
|
||||
really_inline void check_eof() {
|
||||
simdjson_really_inline void check_eof() {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
this->error |= this->prev_incomplete;
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
if(likely(is_ascii(input))) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
if(simdjson_likely(is_ascii(input))) {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
this->error |= this->prev_incomplete;
|
||||
|
@ -231,7 +231,7 @@ using namespace simd;
|
|||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return this->error.any_bits_set_anywhere() ? simdjson::UTF8_ERROR : simdjson::SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace utf8_validation {
|
|||
|
||||
using namespace simd;
|
||||
|
||||
really_inline simd8<uint8_t> check_special_cases(const simd8<uint8_t> input, const simd8<uint8_t> prev1) {
|
||||
simdjson_really_inline simd8<uint8_t> check_special_cases(const simd8<uint8_t> input, const simd8<uint8_t> prev1) {
|
||||
// Bit 0 = Too Short (lead byte/ASCII followed by lead byte/ASCII)
|
||||
// Bit 1 = Too Long (ASCII followed by continuation)
|
||||
// Bit 2 = Overlong 3-byte
|
||||
|
@ -94,7 +94,7 @@ using namespace simd;
|
|||
);
|
||||
return (byte_1_high & byte_1_low & byte_2_high);
|
||||
}
|
||||
really_inline simd8<uint8_t> check_multibyte_lengths(const simd8<uint8_t> input,
|
||||
simdjson_really_inline simd8<uint8_t> check_multibyte_lengths(const simd8<uint8_t> input,
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
|
@ -107,7 +107,7 @@ using namespace simd;
|
|||
// Return nonzero if there are incomplete multibyte characters at the end of the block:
|
||||
// e.g. if there is a 4-byte character, but it's 3 bytes from the end.
|
||||
//
|
||||
really_inline simd8<uint8_t> is_incomplete(const simd8<uint8_t> input) {
|
||||
simdjson_really_inline simd8<uint8_t> is_incomplete(const simd8<uint8_t> input) {
|
||||
// If the previous input's last 3 bytes match this, they're too short (they ended at EOF):
|
||||
// ... 1111____ 111_____ 11______
|
||||
static const uint8_t max_array[32] = {
|
||||
|
@ -131,7 +131,7 @@ using namespace simd;
|
|||
//
|
||||
// Check whether the current bytes are valid UTF-8.
|
||||
//
|
||||
really_inline void check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
simdjson_really_inline void check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
// Flip prev1...prev3 so we can easily determine if they are 2+, 3+ or 4+ lead bytes
|
||||
// (2, 3, 4-byte leads become large positive numbers instead of small negative numbers)
|
||||
simd8<uint8_t> prev1 = input.prev<1>(prev_input);
|
||||
|
@ -140,14 +140,14 @@ using namespace simd;
|
|||
}
|
||||
|
||||
// The only problem that can happen at EOF is that a multibyte character is too short.
|
||||
really_inline void check_eof() {
|
||||
simdjson_really_inline void check_eof() {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
this->error |= this->prev_incomplete;
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
if(likely(is_ascii(input))) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
if(simdjson_likely(is_ascii(input))) {
|
||||
this->error |= this->prev_incomplete;
|
||||
} else {
|
||||
// you might think that a for-loop would work, but under Visual Studio, it is not good enough.
|
||||
|
@ -168,7 +168,7 @@ using namespace simd;
|
|||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return this->error.any_bits_set_anywhere() ? error_code::UTF8_ERROR : error_code::SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ struct utf8_checker {
|
|||
static const uint8_t LEAD_1111 = 0x80; // [1111]____ ...
|
||||
|
||||
// Prepare fast_path_error in case the next block is ASCII
|
||||
really_inline void set_fast_path_error() {
|
||||
simdjson_really_inline void set_fast_path_error() {
|
||||
// If any of the last 3 bytes in the input needs a continuation at the start of the next input,
|
||||
// it is an error for the next input to be ASCII.
|
||||
// static const uint8_t incomplete_long[32] = {
|
||||
|
@ -119,7 +119,7 @@ struct utf8_checker {
|
|||
this->prev_incomplete = this->prev_input_block.saturating_sub(max_value);
|
||||
}
|
||||
|
||||
really_inline simd8<uint8_t> get_lead_flags(const simd8<uint8_t> high_bits, const simd8<uint8_t> prev_high_bits) {
|
||||
simdjson_really_inline simd8<uint8_t> get_lead_flags(const simd8<uint8_t> high_bits, const simd8<uint8_t> prev_high_bits) {
|
||||
// Total: 2 instructions, 1 constant
|
||||
// - 1 byte shift (shuffle)
|
||||
// - 1 table lookup (shuffle)
|
||||
|
@ -138,7 +138,7 @@ struct utf8_checker {
|
|||
}
|
||||
|
||||
// Find errors in bytes 1 and 2 together (one single multi-nibble &)
|
||||
really_inline simd8<uint8_t> get_byte_1_2_errors(const simd8<uint8_t> input, const simd8<uint8_t> prev_input, const simd8<uint8_t> high_bits, const simd8<uint8_t> prev_high_bits) {
|
||||
simdjson_really_inline simd8<uint8_t> get_byte_1_2_errors(const simd8<uint8_t> input, const simd8<uint8_t> prev_input, const simd8<uint8_t> high_bits, const simd8<uint8_t> prev_high_bits) {
|
||||
//
|
||||
// These are the errors we're going to match for bytes 1-2, by looking at the first three
|
||||
// nibbles of the character: lead_flags & <low bits of byte 1> & <high bits of byte 2>
|
||||
|
@ -196,7 +196,7 @@ struct utf8_checker {
|
|||
return byte_1_flags & byte_2_flags;
|
||||
}
|
||||
|
||||
really_inline simd8<uint8_t> get_byte_3_4_5_errors(const simd8<uint8_t> high_bits, const simd8<uint8_t> prev_high_bits) {
|
||||
simdjson_really_inline simd8<uint8_t> get_byte_3_4_5_errors(const simd8<uint8_t> high_bits, const simd8<uint8_t> prev_high_bits) {
|
||||
// Total 7 instructions, 3 simd constants:
|
||||
// - 3 table lookups (shuffles)
|
||||
// - 2 byte shifts (shuffles)
|
||||
|
@ -224,7 +224,7 @@ struct utf8_checker {
|
|||
// Check whether the current bytes are valid UTF-8.
|
||||
// At the end of the function, previous gets updated
|
||||
// This should come down to 22 instructions if table definitions are in registers--30 if not.
|
||||
really_inline simd8<uint8_t> check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
simdjson_really_inline simd8<uint8_t> check_utf8_bytes(const simd8<uint8_t> input, const simd8<uint8_t> prev_input) {
|
||||
// When we process bytes M through N, we look for lead characters in M-4 through N-4. This allows
|
||||
// us to look for all errors related to any lead character at one time (since UTF-8 characters
|
||||
// can only be up to 4 bytes, and the next byte after a character finishes must be another lead,
|
||||
|
@ -270,15 +270,15 @@ struct utf8_checker {
|
|||
// TODO special case start of file, too, so that small documents are efficient! No shifting needed ...
|
||||
|
||||
// The only problem that can happen at EOF is that a multibyte character is too short.
|
||||
really_inline void check_eof() {
|
||||
simdjson_really_inline void check_eof() {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
this->error |= this->prev_incomplete;
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& input) {
|
||||
simd8<uint8_t> bits = input.reduce_or();
|
||||
if (likely(!bits.any_bits_set_anywhere(0b10000000u))) {
|
||||
if (simdjson_likely(!bits.any_bits_set_anywhere(0b10000000u))) {
|
||||
// If the previous block had incomplete UTF-8 characters at the end, an ASCII block can't
|
||||
// possibly finish them.
|
||||
this->error |= this->prev_incomplete;
|
||||
|
@ -292,7 +292,7 @@ struct utf8_checker {
|
|||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return this->error.any_bits_set_anywhere() ? simdjson::UTF8_ERROR : simdjson::SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ struct utf8_checker {
|
|||
simd8<bool> has_error;
|
||||
processed_utf_bytes previous;
|
||||
|
||||
really_inline void check_carried_continuations() {
|
||||
simdjson_really_inline void check_carried_continuations() {
|
||||
static const int8_t last_len[32] = {
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 9, 9, 9, 9, 9, 9, 9,
|
||||
|
@ -43,7 +43,7 @@ struct utf8_checker {
|
|||
|
||||
// check whether the current bytes are valid UTF-8
|
||||
// at the end of the function, previous gets updated
|
||||
really_inline void check_utf8_bytes(const simd8<uint8_t> current_bytes) {
|
||||
simdjson_really_inline void check_utf8_bytes(const simd8<uint8_t> current_bytes) {
|
||||
|
||||
/* high_nibbles = input >> 4 */
|
||||
const simd8<uint8_t> high_nibbles = current_bytes.shr<4>();
|
||||
|
@ -156,17 +156,17 @@ struct utf8_checker {
|
|||
this->previous.first_len = first_len;
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8<uint8_t> in) {
|
||||
if (likely(!in.any_bits_set_anywhere(0x80u))) {
|
||||
simdjson_really_inline void check_next_input(const simd8<uint8_t> in) {
|
||||
if (simdjson_likely(!in.any_bits_set_anywhere(0x80u))) {
|
||||
this->check_carried_continuations();
|
||||
} else {
|
||||
this->check_utf8_bytes(in);
|
||||
}
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& in) {
|
||||
simd8<uint8_t> bits = in.reduce_or();
|
||||
if (likely(!bits.any_bits_set_anywhere(0x80u))) {
|
||||
if (simdjson_likely(!bits.any_bits_set_anywhere(0x80u))) {
|
||||
// it is ascii, we just check carried continuations.
|
||||
this->check_carried_continuations();
|
||||
} else {
|
||||
|
@ -177,7 +177,7 @@ struct utf8_checker {
|
|||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return this->has_error.any() ? simdjson::UTF8_ERROR : simdjson::SUCCESS;
|
||||
}
|
||||
}; // struct utf8_checker
|
||||
|
|
|
@ -139,7 +139,7 @@ struct utf8_checker {
|
|||
// boundaries, so we need to keep a "carry" mask of the bits that were shifted
|
||||
// past the boundary in the last loop iteration.
|
||||
//
|
||||
really_inline void check_length_errors(const simd8<uint8_t> bytes, const vmask_t bit_7) {
|
||||
simdjson_really_inline void check_length_errors(const simd8<uint8_t> bytes, const vmask_t bit_7) {
|
||||
// Compute the continuation byte mask by finding bytes that start with
|
||||
// 11x, 111x, and 1111. For each of these prefixes, we get a bitmask
|
||||
// and shift it forward by 1, 2, or 3. This loop should be unrolled by
|
||||
|
@ -260,7 +260,7 @@ struct utf8_checker {
|
|||
// bytes, we AND them together. Only when all three have an error bit in common
|
||||
// do we fail validation.
|
||||
//
|
||||
really_inline void check_special_cases(const simd8<uint8_t> bytes) {
|
||||
simdjson_really_inline void check_special_cases(const simd8<uint8_t> bytes) {
|
||||
const simd8<uint8_t> shifted_bytes = bytes.prev<1>(this->prev_bytes);
|
||||
this->prev_bytes = bytes;
|
||||
|
||||
|
@ -332,14 +332,14 @@ struct utf8_checker {
|
|||
|
||||
// check whether the current bytes are valid UTF-8
|
||||
// at the end of the function, previous gets updated
|
||||
really_inline void check_utf8_bytes(const simd8<uint8_t> bytes, const vmask_t bit_7) {
|
||||
simdjson_really_inline void check_utf8_bytes(const simd8<uint8_t> bytes, const vmask_t bit_7) {
|
||||
this->check_length_errors(bytes, bit_7);
|
||||
this->check_special_cases(bytes);
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8<uint8_t> bytes) {
|
||||
simdjson_really_inline void check_next_input(const simd8<uint8_t> bytes) {
|
||||
vmask_t bit_7 = bytes.get_bit<7>();
|
||||
if (unlikely(bit_7)) {
|
||||
if (simdjson_unlikely(bit_7)) {
|
||||
// TODO (@jkeiser): To work with simdjson's caller model, I moved the calculation of
|
||||
// shifted_bytes inside check_utf8_bytes. I believe this adds an extra instruction to the hot
|
||||
// path (saving prev_bytes), which is undesirable, though 2 register accesses vs. 1 memory
|
||||
|
@ -350,13 +350,13 @@ struct utf8_checker {
|
|||
}
|
||||
}
|
||||
|
||||
really_inline void check_next_input(const simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline void check_next_input(const simd8x64<uint8_t>& in) {
|
||||
for (int i=0; i<simd8x64<uint8_t>::NUM_CHUNKS; i++) {
|
||||
this->check_next_input(in.chunks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
really_inline error_code errors() {
|
||||
simdjson_really_inline error_code errors() {
|
||||
return (this->special_case_errors.any_bits_set_anywhere() | this->length_errors) ? simdjson::UTF8_ERROR : simdjson::SUCCESS;
|
||||
}
|
||||
}; // struct utf8_checker
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace allocate {
|
|||
//
|
||||
// Allocates stage 2 internal state and outputs in the parser
|
||||
//
|
||||
really_inline error_code set_max_depth(dom_parser_implementation &parser, size_t max_depth) {
|
||||
simdjson_really_inline error_code set_max_depth(dom_parser_implementation &parser, size_t max_depth) {
|
||||
parser.containing_scope.reset(new (std::nothrow) scope_descriptor[max_depth]);
|
||||
parser.is_array.reset(new (std::nothrow) bool[max_depth]);
|
||||
|
||||
|
|
|
@ -9,50 +9,50 @@ namespace atomparsing {
|
|||
// You might think that using memcpy makes this function expensive, but you'd be wrong.
|
||||
// All decent optimizing compilers (GCC, clang, Visual Studio) will compile string_to_uint32("false");
|
||||
// to the compile-time constant 1936482662.
|
||||
really_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; }
|
||||
simdjson_really_inline uint32_t string_to_uint32(const char* str) { uint32_t val; std::memcpy(&val, str, sizeof(uint32_t)); return val; }
|
||||
|
||||
|
||||
// Again in str4ncmp we use a memcpy to avoid undefined behavior. The memcpy may appear expensive.
|
||||
// Yet all decent optimizing compilers will compile memcpy to a single instruction, just about.
|
||||
WARN_UNUSED
|
||||
really_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline uint32_t str4ncmp(const uint8_t *src, const char* atom) {
|
||||
uint32_t srcval; // we want to avoid unaligned 32-bit loads (undefined in C/C++)
|
||||
static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes");
|
||||
std::memcpy(&srcval, src, sizeof(uint32_t));
|
||||
return srcval ^ string_to_uint32(atom);
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
really_inline bool is_valid_true_atom(const uint8_t *src) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool is_valid_true_atom(const uint8_t *src) {
|
||||
return (str4ncmp(src, "true") | is_not_structural_or_whitespace(src[4])) == 0;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
really_inline bool is_valid_true_atom(const uint8_t *src, size_t len) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool is_valid_true_atom(const uint8_t *src, size_t len) {
|
||||
if (len > 4) { return is_valid_true_atom(src); }
|
||||
else if (len == 4) { return !str4ncmp(src, "true"); }
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
really_inline bool is_valid_false_atom(const uint8_t *src) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool is_valid_false_atom(const uint8_t *src) {
|
||||
return (str4ncmp(src+1, "alse") | is_not_structural_or_whitespace(src[5])) == 0;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
really_inline bool is_valid_false_atom(const uint8_t *src, size_t len) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool is_valid_false_atom(const uint8_t *src, size_t len) {
|
||||
if (len > 5) { return is_valid_false_atom(src); }
|
||||
else if (len == 5) { return !str4ncmp(src+1, "alse"); }
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
really_inline bool is_valid_null_atom(const uint8_t *src) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool is_valid_null_atom(const uint8_t *src) {
|
||||
return (str4ncmp(src, "null") | is_not_structural_or_whitespace(src[4])) == 0;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
really_inline bool is_valid_null_atom(const uint8_t *src, size_t len) {
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool is_valid_null_atom(const uint8_t *src, size_t len) {
|
||||
if (len > 4) { return is_valid_null_atom(src); }
|
||||
else if (len == 4) { return !str4ncmp(src, "null"); }
|
||||
else { return false; }
|
||||
|
|
|
@ -4,11 +4,11 @@ namespace stage2 {
|
|||
|
||||
// return non-zero if not a structural or whitespace char
|
||||
// zero otherwise
|
||||
really_inline uint32_t is_not_structural_or_whitespace(uint8_t c) {
|
||||
simdjson_really_inline uint32_t is_not_structural_or_whitespace(uint8_t c) {
|
||||
return structural_or_whitespace_negated[c];
|
||||
}
|
||||
|
||||
really_inline uint32_t is_structural_or_whitespace(uint8_t c) {
|
||||
simdjson_really_inline uint32_t is_structural_or_whitespace(uint8_t c) {
|
||||
return structural_or_whitespace[c];
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ static inline uint32_t hex_to_u32_nocheck(
|
|||
//
|
||||
// Note: we assume that surrogates are treated separately
|
||||
//
|
||||
really_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
|
||||
simdjson_really_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
|
||||
if (cp <= 0x7F) {
|
||||
c[0] = uint8_t(cp);
|
||||
return 1; // ascii
|
||||
|
@ -71,10 +71,10 @@ really_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
|
|||
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
|
||||
// this is a slow emulation routine for 32-bit
|
||||
//
|
||||
static really_inline uint64_t __emulu(uint32_t x, uint32_t y) {
|
||||
static simdjson_really_inline uint64_t __emulu(uint32_t x, uint32_t y) {
|
||||
return x * (uint64_t)y;
|
||||
}
|
||||
static really_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
|
||||
static simdjson_really_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
|
||||
uint64_t ad = __emulu((uint32_t)(ab >> 32), (uint32_t)cd);
|
||||
uint64_t bd = __emulu((uint32_t)ab, (uint32_t)cd);
|
||||
uint64_t adbc = ad + __emulu((uint32_t)ab, (uint32_t)(cd >> 32));
|
||||
|
@ -86,7 +86,7 @@ static really_inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
|
|||
}
|
||||
#endif
|
||||
|
||||
really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
|
||||
simdjson_really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
|
||||
value128 answer;
|
||||
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
|
||||
#ifdef _M_ARM64
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace logger {
|
|||
static int log_depth; // Not threadsafe. Log only.
|
||||
|
||||
// Helper to turn unprintable or newline characters into spaces
|
||||
static really_inline char printable_char(char c) {
|
||||
static simdjson_really_inline char printable_char(char c) {
|
||||
if (c >= 0x20) {
|
||||
return c;
|
||||
} else {
|
||||
|
@ -24,7 +24,7 @@ namespace logger {
|
|||
}
|
||||
|
||||
// Print the header and set up log_start
|
||||
static really_inline void log_start() {
|
||||
static simdjson_really_inline void log_start() {
|
||||
if (LOG_ENABLED) {
|
||||
log_depth = 0;
|
||||
printf("\n");
|
||||
|
@ -33,7 +33,7 @@ namespace logger {
|
|||
}
|
||||
}
|
||||
|
||||
static really_inline void log_string(const char *message) {
|
||||
static simdjson_really_inline void log_string(const char *message) {
|
||||
if (LOG_ENABLED) {
|
||||
printf("%s\n", message);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace logger {
|
|||
|
||||
// Logs a single line of
|
||||
template<typename S>
|
||||
static really_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) {
|
||||
static simdjson_really_inline void log_line(S &structurals, const char *title_prefix, const char *title, const char *detail) {
|
||||
if (LOG_ENABLED) {
|
||||
printf("| %*s%s%-*s ", log_depth*2, "", title_prefix, LOG_EVENT_LEN - log_depth*2 - int(strlen(title_prefix)), title);
|
||||
auto current_index = structurals.at_beginning() ? nullptr : structurals.next_structural-1;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace numberparsing {
|
|||
// set to false. This should work *most of the time* (like 99% of the time).
|
||||
// We assume that power is in the [FASTFLOAT_SMALLEST_POWER,
|
||||
// FASTFLOAT_LARGEST_POWER] interval: the caller is responsible for this check.
|
||||
really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, bool *success) {
|
||||
simdjson_really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, bool *success) {
|
||||
// we start with a fast path
|
||||
// It was described in
|
||||
// Clinger WD. How to read floating point numbers accurately.
|
||||
|
@ -117,7 +117,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative,
|
|||
// know that we have an exact computed value for the leading
|
||||
// 55 bits because any imprecision would play out as a +1, in
|
||||
// the worst case.
|
||||
if (unlikely((upper & 0x1FF) == 0x1FF) && (lower + i < lower)) {
|
||||
if (simdjson_unlikely((upper & 0x1FF) == 0x1FF) && (lower + i < lower)) {
|
||||
uint64_t factor_mantissa_low =
|
||||
mantissa_128[power - FASTFLOAT_SMALLEST_POWER];
|
||||
// next, we compute the 64-bit x 128-bit multiplication, getting a 192-bit
|
||||
|
@ -155,7 +155,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative,
|
|||
// which we guard against.
|
||||
// If we have lots of trailing zeros, we may fall right between two
|
||||
// floating-point values.
|
||||
if (unlikely((lower == 0) && ((upper & 0x1FF) == 0) &&
|
||||
if (simdjson_unlikely((lower == 0) && ((upper & 0x1FF) == 0) &&
|
||||
((mantissa & 3) == 1))) {
|
||||
// if mantissa & 1 == 1 we might need to round up.
|
||||
//
|
||||
|
@ -192,7 +192,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative,
|
|||
mantissa &= ~(1ULL << 52);
|
||||
uint64_t real_exponent = c.exp - lz;
|
||||
// we have to check that real_exponent is in range, otherwise we bail out
|
||||
if (unlikely((real_exponent < 1) || (real_exponent > 2046))) {
|
||||
if (simdjson_unlikely((real_exponent < 1) || (real_exponent > 2046))) {
|
||||
*success = false;
|
||||
return 0;
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ static bool parse_float_strtod(const uint8_t *ptr, double *outDouble) {
|
|||
// check quickly whether the next 8 chars are made of digits
|
||||
// at a glance, it looks better than Mula's
|
||||
// http://0x80.pl/articles/swar-digits-validate.html
|
||||
really_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) {
|
||||
simdjson_really_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) {
|
||||
uint64_t val;
|
||||
// this can read up to 7 bytes beyond the buffer size, but we require
|
||||
// SIMDJSON_PADDING of padding
|
||||
|
@ -252,7 +252,7 @@ really_inline bool is_made_of_eight_digits_fast(const uint8_t *chars) {
|
|||
}
|
||||
|
||||
template<typename W>
|
||||
bool slow_float_parsing(UNUSED const uint8_t * src, W writer) {
|
||||
bool slow_float_parsing(SIMDJSON_UNUSED const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_strtod(src, &d)) {
|
||||
WRITE_DOUBLE(d, src, writer);
|
||||
|
@ -263,7 +263,7 @@ bool slow_float_parsing(UNUSED const uint8_t * src, W writer) {
|
|||
|
||||
template<typename I>
|
||||
NO_SANITIZE_UNDEFINED // We deliberately allow overflow here and check later
|
||||
really_inline bool parse_digit(const uint8_t c, I &i) {
|
||||
simdjson_really_inline bool parse_digit(const uint8_t c, I &i) {
|
||||
const uint8_t digit = static_cast<uint8_t>(c - '0');
|
||||
if (digit > 9) {
|
||||
return false;
|
||||
|
@ -273,7 +273,7 @@ really_inline bool parse_digit(const uint8_t c, I &i) {
|
|||
return true;
|
||||
}
|
||||
|
||||
really_inline bool parse_decimal(UNUSED const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) {
|
||||
simdjson_really_inline bool parse_decimal(SIMDJSON_UNUSED const uint8_t *const src, const uint8_t *&p, uint64_t &i, int64_t &exponent) {
|
||||
// we continue with the fiction that we have an integer. If the
|
||||
// floating point number is representable as x * 10^z for some integer
|
||||
// z that fits in 53 bits, then we will be able to convert back the
|
||||
|
@ -299,7 +299,7 @@ really_inline bool parse_decimal(UNUSED const uint8_t *const src, const uint8_t
|
|||
return true;
|
||||
}
|
||||
|
||||
really_inline bool parse_exponent(UNUSED const uint8_t *const src, const uint8_t *&p, int64_t &exponent) {
|
||||
simdjson_really_inline bool parse_exponent(SIMDJSON_UNUSED const uint8_t *const src, const uint8_t *&p, int64_t &exponent) {
|
||||
// Exp Sign: -123.456e[-]78
|
||||
bool neg_exp = ('-' == *p);
|
||||
if (neg_exp || '+' == *p) { p++; } // Skip + as well
|
||||
|
@ -319,7 +319,7 @@ really_inline bool parse_exponent(UNUSED const uint8_t *const src, const uint8_t
|
|||
// instructions for a likely branch, an unconclusive gain.
|
||||
|
||||
// If there were no digits, it's an error.
|
||||
if (unlikely(p == start_exp)) {
|
||||
if (simdjson_unlikely(p == start_exp)) {
|
||||
return INVALID_NUMBER(src);
|
||||
}
|
||||
// We have a valid positive exponent in exp_number at this point, except that
|
||||
|
@ -327,7 +327,7 @@ really_inline bool parse_exponent(UNUSED const uint8_t *const src, const uint8_t
|
|||
|
||||
// If there were more than 18 digits, we may have overflowed the integer. We have to do
|
||||
// something!!!!
|
||||
if (unlikely(p > start_exp+18)) {
|
||||
if (simdjson_unlikely(p > start_exp+18)) {
|
||||
// Skip leading zeroes: 1e000000000000000000001 is technically valid and doesn't overflow
|
||||
while (*start_exp == '0') { start_exp++; }
|
||||
// 19 digits could overflow int64_t and is kind of absurd anyway. We don't
|
||||
|
@ -351,12 +351,12 @@ really_inline bool parse_exponent(UNUSED const uint8_t *const src, const uint8_t
|
|||
}
|
||||
|
||||
template<typename W>
|
||||
really_inline bool write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, int digit_count, int64_t exponent, W &writer) {
|
||||
simdjson_really_inline bool write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, int digit_count, int64_t exponent, W &writer) {
|
||||
// If we frequently had to deal with long strings of digits,
|
||||
// we could extend our code by using a 128-bit integer instead
|
||||
// of a 64-bit integer. However, this is uncommon in practice.
|
||||
// digit count is off by 1 because of the decimal (assuming there was one).
|
||||
if (unlikely((digit_count-1 >= 19))) { // this is uncommon
|
||||
if (simdjson_unlikely((digit_count-1 >= 19))) { // this is uncommon
|
||||
// It is possible that the integer had an overflow.
|
||||
// We have to handle the case where we have 0.0000somenumber.
|
||||
const uint8_t *start = start_digits;
|
||||
|
@ -383,7 +383,7 @@ really_inline bool write_float(const uint8_t *const src, bool negative, uint64_t
|
|||
// NOTE: it's weird that the unlikely() only wraps half the if, but it seems to get slower any other
|
||||
// way we've tried: https://github.com/simdjson/simdjson/pull/990#discussion_r448497331
|
||||
// To future reader: we'd love if someone found a better way, or at least could explain this result!
|
||||
if (unlikely(exponent < FASTFLOAT_SMALLEST_POWER) || (exponent > FASTFLOAT_LARGEST_POWER)) {
|
||||
if (simdjson_unlikely(exponent < FASTFLOAT_SMALLEST_POWER) || (exponent > FASTFLOAT_LARGEST_POWER)) {
|
||||
// this is almost never going to get called!!!
|
||||
// we start anew, going slowly!!!
|
||||
bool success = slow_float_parsing(src, writer);
|
||||
|
@ -406,7 +406,7 @@ really_inline bool write_float(const uint8_t *const src, bool negative, uint64_t
|
|||
#ifdef SIMDJSON_SKIPNUMBERPARSING
|
||||
|
||||
template<typename W>
|
||||
really_inline bool parse_number(const uint8_t *const, W &writer) {
|
||||
simdjson_really_inline bool parse_number(const uint8_t *const, W &writer) {
|
||||
writer.append_s64(0); // always write zero
|
||||
return true; // always succeeds
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ really_inline bool parse_number(const uint8_t *const, W &writer) {
|
|||
//
|
||||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||
template<typename W>
|
||||
really_inline bool parse_number(const uint8_t *const src, W &writer) {
|
||||
simdjson_really_inline bool parse_number(const uint8_t *const src, W &writer) {
|
||||
|
||||
//
|
||||
// Check for minus sign
|
||||
|
|
|
@ -38,8 +38,8 @@ static const uint8_t escape_map[256] = {
|
|||
// dest will advance a variable amount (return via pointer)
|
||||
// return true if the unicode codepoint was valid
|
||||
// We work in little-endian then swap at write time
|
||||
WARN_UNUSED
|
||||
really_inline bool handle_unicode_codepoint(const uint8_t **src_ptr,
|
||||
SIMDJSON_WARN_UNUSED
|
||||
simdjson_really_inline bool handle_unicode_codepoint(const uint8_t **src_ptr,
|
||||
uint8_t **dst_ptr) {
|
||||
// hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the
|
||||
// conversion isn't valid; we defer the check for this to inside the
|
||||
|
@ -72,7 +72,7 @@ really_inline bool handle_unicode_codepoint(const uint8_t **src_ptr,
|
|||
return offset > 0;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline uint8_t *parse_string(const uint8_t *src, uint8_t *dst) {
|
||||
src++;
|
||||
while (1) {
|
||||
// Copy the next n bytes, and find the backslash and quote in them.
|
||||
|
|
|
@ -9,40 +9,40 @@ public:
|
|||
dom_parser_implementation &dom_parser;
|
||||
|
||||
// Start a structural
|
||||
really_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index)
|
||||
simdjson_really_inline structural_iterator(dom_parser_implementation &_dom_parser, size_t start_structural_index)
|
||||
: buf{_dom_parser.buf},
|
||||
next_structural{&_dom_parser.structural_indexes[start_structural_index]},
|
||||
dom_parser{_dom_parser} {
|
||||
}
|
||||
// Get the buffer position of the current structural character
|
||||
really_inline const uint8_t* current() {
|
||||
simdjson_really_inline const uint8_t* current() {
|
||||
return &buf[*(next_structural-1)];
|
||||
}
|
||||
// Get the current structural character
|
||||
really_inline char current_char() {
|
||||
simdjson_really_inline char current_char() {
|
||||
return buf[*(next_structural-1)];
|
||||
}
|
||||
// Get the next structural character without advancing
|
||||
really_inline char peek_next_char() {
|
||||
simdjson_really_inline char peek_next_char() {
|
||||
return buf[*next_structural];
|
||||
}
|
||||
really_inline const uint8_t* peek() {
|
||||
simdjson_really_inline const uint8_t* peek() {
|
||||
return &buf[*next_structural];
|
||||
}
|
||||
really_inline const uint8_t* advance() {
|
||||
simdjson_really_inline const uint8_t* advance() {
|
||||
return &buf[*(next_structural++)];
|
||||
}
|
||||
really_inline char advance_char() {
|
||||
simdjson_really_inline char advance_char() {
|
||||
return buf[*(next_structural++)];
|
||||
}
|
||||
really_inline size_t remaining_len() {
|
||||
simdjson_really_inline size_t remaining_len() {
|
||||
return dom_parser.len - *(next_structural-1);
|
||||
}
|
||||
|
||||
really_inline bool at_end() {
|
||||
simdjson_really_inline bool at_end() {
|
||||
return next_structural == &dom_parser.structural_indexes[dom_parser.n_structural_indexes];
|
||||
}
|
||||
really_inline bool at_beginning() {
|
||||
simdjson_really_inline bool at_beginning() {
|
||||
return next_structural == dom_parser.structural_indexes.get();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,24 +17,24 @@ struct structural_parser : structural_iterator {
|
|||
uint32_t depth{0};
|
||||
|
||||
template<bool STREAMING, typename T>
|
||||
WARN_UNUSED really_inline error_code parse(T &builder) noexcept;
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse(T &builder) noexcept;
|
||||
template<bool STREAMING, typename T>
|
||||
WARN_UNUSED static really_inline error_code parse(dom_parser_implementation &dom_parser, T &builder) noexcept {
|
||||
SIMDJSON_WARN_UNUSED static simdjson_really_inline error_code parse(dom_parser_implementation &dom_parser, T &builder) noexcept {
|
||||
structural_parser parser(dom_parser, STREAMING ? dom_parser.next_structural_index : 0);
|
||||
return parser.parse<STREAMING>(builder);
|
||||
}
|
||||
|
||||
// For non-streaming, to pass an explicit 0 as next_structural, which enables optimizations
|
||||
really_inline structural_parser(dom_parser_implementation &_dom_parser, uint32_t start_structural_index)
|
||||
simdjson_really_inline structural_parser(dom_parser_implementation &_dom_parser, uint32_t start_structural_index)
|
||||
: structural_iterator(_dom_parser, start_structural_index) {
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code start_document() {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code start_document() {
|
||||
dom_parser.is_array[depth] = false;
|
||||
return SUCCESS;
|
||||
}
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline error_code start_array(T &builder) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code start_array(T &builder) {
|
||||
depth++;
|
||||
if (depth >= dom_parser.max_depth()) { log_error("Exceeded max depth!"); return DEPTH_ERROR; }
|
||||
builder.start_array(*this);
|
||||
|
@ -43,7 +43,7 @@ struct structural_parser : structural_iterator {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline bool empty_object(T &builder) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline bool empty_object(T &builder) {
|
||||
if (peek_next_char() == '}') {
|
||||
advance_char();
|
||||
builder.empty_object(*this);
|
||||
|
@ -52,7 +52,7 @@ struct structural_parser : structural_iterator {
|
|||
return false;
|
||||
}
|
||||
template<typename T>
|
||||
WARN_UNUSED really_inline bool empty_array(T &builder) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline bool empty_array(T &builder) {
|
||||
if (peek_next_char() == ']') {
|
||||
advance_char();
|
||||
builder.empty_array(*this);
|
||||
|
@ -62,7 +62,7 @@ struct structural_parser : structural_iterator {
|
|||
}
|
||||
|
||||
template<bool STREAMING>
|
||||
WARN_UNUSED really_inline error_code finish() {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code finish() {
|
||||
dom_parser.next_structural_index = uint32_t(next_structural - &dom_parser.structural_indexes[0]);
|
||||
|
||||
if (depth != 0) {
|
||||
|
@ -79,31 +79,31 @@ struct structural_parser : structural_iterator {
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
really_inline uint8_t last_structural() {
|
||||
simdjson_really_inline uint8_t last_structural() {
|
||||
return buf[dom_parser.structural_indexes[dom_parser.n_structural_indexes - 1]];
|
||||
}
|
||||
|
||||
really_inline void log_value(const char *type) {
|
||||
simdjson_really_inline void log_value(const char *type) {
|
||||
logger::log_line(*this, "", type, "");
|
||||
}
|
||||
|
||||
really_inline void log_start_value(const char *type) {
|
||||
simdjson_really_inline void log_start_value(const char *type) {
|
||||
logger::log_line(*this, "+", type, "");
|
||||
if (logger::LOG_ENABLED) { logger::log_depth++; }
|
||||
}
|
||||
|
||||
really_inline void log_end_value(const char *type) {
|
||||
simdjson_really_inline void log_end_value(const char *type) {
|
||||
if (logger::LOG_ENABLED) { logger::log_depth--; }
|
||||
logger::log_line(*this, "-", type, "");
|
||||
}
|
||||
|
||||
really_inline void log_error(const char *error) {
|
||||
simdjson_really_inline void log_error(const char *error) {
|
||||
logger::log_line(*this, "", "ERROR", error);
|
||||
}
|
||||
}; // struct structural_parser
|
||||
|
||||
template<bool STREAMING, typename T>
|
||||
WARN_UNUSED really_inline error_code structural_parser::parse(T &builder) noexcept {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code structural_parser::parse(T &builder) noexcept {
|
||||
logger::log_start();
|
||||
|
||||
//
|
||||
|
@ -164,7 +164,7 @@ object_begin: {
|
|||
} // object_begin:
|
||||
|
||||
object_field: {
|
||||
if (unlikely( advance_char() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
|
||||
if (simdjson_unlikely( advance_char() != ':' )) { log_error("Missing colon after key in object"); return TAPE_ERROR; }
|
||||
const uint8_t *value = advance();
|
||||
switch (*value) {
|
||||
case '{': if (!empty_object(builder)) { goto object_begin; }; break;
|
||||
|
@ -178,7 +178,7 @@ object_continue: {
|
|||
case ',': {
|
||||
builder.increment_count(*this);
|
||||
const uint8_t *key = advance();
|
||||
if (unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
|
||||
if (simdjson_unlikely( *key != '"' )) { log_error("Key string missing at beginning of field in object"); return TAPE_ERROR; }
|
||||
SIMDJSON_TRY( builder.parse_key(*this, key) );
|
||||
goto object_field;
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@ struct tape_builder {
|
|||
/** Next write location in the string buf for stage 2 parsing */
|
||||
uint8_t *current_string_buf_loc;
|
||||
|
||||
really_inline tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {}
|
||||
simdjson_really_inline tape_builder(dom::document &doc) noexcept : tape{doc.tape.get()}, current_string_buf_loc{doc.string_buf.get()} {}
|
||||
|
||||
private:
|
||||
friend struct structural_parser;
|
||||
|
||||
really_inline error_code parse_root_primitive(structural_parser &parser, const uint8_t *value) {
|
||||
simdjson_really_inline error_code parse_root_primitive(structural_parser &parser, const uint8_t *value) {
|
||||
switch (*value) {
|
||||
case '"': return parse_string(parser, value);
|
||||
case 't': return parse_root_true_atom(parser, value);
|
||||
|
@ -31,7 +31,7 @@ private:
|
|||
return TAPE_ERROR;
|
||||
}
|
||||
}
|
||||
really_inline error_code parse_primitive(structural_parser &parser, const uint8_t *value) {
|
||||
simdjson_really_inline error_code parse_primitive(structural_parser &parser, const uint8_t *value) {
|
||||
switch (*value) {
|
||||
case '"': return parse_string(parser, value);
|
||||
case 't': return parse_true_atom(parser, value);
|
||||
|
@ -46,47 +46,47 @@ private:
|
|||
return TAPE_ERROR;
|
||||
}
|
||||
}
|
||||
really_inline void empty_object(structural_parser &parser) {
|
||||
simdjson_really_inline void empty_object(structural_parser &parser) {
|
||||
parser.log_value("empty object");
|
||||
empty_container(parser, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT);
|
||||
}
|
||||
really_inline void empty_array(structural_parser &parser) {
|
||||
simdjson_really_inline void empty_array(structural_parser &parser) {
|
||||
parser.log_value("empty array");
|
||||
empty_container(parser, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY);
|
||||
}
|
||||
|
||||
really_inline void start_document(structural_parser &parser) {
|
||||
simdjson_really_inline void start_document(structural_parser &parser) {
|
||||
parser.log_start_value("document");
|
||||
start_container(parser);
|
||||
}
|
||||
really_inline void start_object(structural_parser &parser) {
|
||||
simdjson_really_inline void start_object(structural_parser &parser) {
|
||||
parser.log_start_value("object");
|
||||
start_container(parser);
|
||||
}
|
||||
really_inline void start_array(structural_parser &parser) {
|
||||
simdjson_really_inline void start_array(structural_parser &parser) {
|
||||
parser.log_start_value("array");
|
||||
start_container(parser);
|
||||
}
|
||||
|
||||
really_inline void end_object(structural_parser &parser) {
|
||||
simdjson_really_inline void end_object(structural_parser &parser) {
|
||||
parser.log_end_value("object");
|
||||
end_container(parser, internal::tape_type::START_OBJECT, internal::tape_type::END_OBJECT);
|
||||
}
|
||||
really_inline void end_array(structural_parser &parser) {
|
||||
simdjson_really_inline void end_array(structural_parser &parser) {
|
||||
parser.log_end_value("array");
|
||||
end_container(parser, internal::tape_type::START_ARRAY, internal::tape_type::END_ARRAY);
|
||||
}
|
||||
really_inline void end_document(structural_parser &parser) {
|
||||
simdjson_really_inline void end_document(structural_parser &parser) {
|
||||
parser.log_end_value("document");
|
||||
constexpr uint32_t start_tape_index = 0;
|
||||
tape.append(start_tape_index, internal::tape_type::ROOT);
|
||||
tape_writer::write(parser.dom_parser.doc->tape[start_tape_index], next_tape_index(parser), internal::tape_type::ROOT);
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_key(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_key(structural_parser &parser, const uint8_t *value) {
|
||||
return parse_string(parser, value, true);
|
||||
}
|
||||
WARN_UNUSED really_inline error_code parse_string(structural_parser &parser, const uint8_t *value, bool key = false) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_string(structural_parser &parser, const uint8_t *value, bool key = false) {
|
||||
parser.log_value(key ? "key" : "string");
|
||||
uint8_t *dst = on_start_string(parser);
|
||||
dst = stringparsing::parse_string(value, dst);
|
||||
|
@ -98,13 +98,13 @@ private:
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_number(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_number(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("number");
|
||||
if (!numberparsing::parse_number(value, tape)) { parser.log_error("Invalid number"); return NUMBER_ERROR; }
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
really_inline error_code parse_root_number(structural_parser &parser, const uint8_t *value) {
|
||||
simdjson_really_inline error_code parse_root_number(structural_parser &parser, const uint8_t *value) {
|
||||
//
|
||||
// We need to make a copy to make sure that the string is space terminated.
|
||||
// This is not about padding the input, which should already padded up
|
||||
|
@ -129,42 +129,42 @@ private:
|
|||
return error;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_true_atom(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_true_atom(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("true");
|
||||
if (!atomparsing::is_valid_true_atom(value)) { return T_ATOM_ERROR; }
|
||||
tape.append(0, internal::tape_type::TRUE_VALUE);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_root_true_atom(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_true_atom(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("true");
|
||||
if (!atomparsing::is_valid_true_atom(value, parser.remaining_len())) { return T_ATOM_ERROR; }
|
||||
tape.append(0, internal::tape_type::TRUE_VALUE);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_false_atom(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_false_atom(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("false");
|
||||
if (!atomparsing::is_valid_false_atom(value)) { return F_ATOM_ERROR; }
|
||||
tape.append(0, internal::tape_type::FALSE_VALUE);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_root_false_atom(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_false_atom(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("false");
|
||||
if (!atomparsing::is_valid_false_atom(value, parser.remaining_len())) { return F_ATOM_ERROR; }
|
||||
tape.append(0, internal::tape_type::FALSE_VALUE);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_null_atom(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_null_atom(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("null");
|
||||
if (!atomparsing::is_valid_null_atom(value)) { return N_ATOM_ERROR; }
|
||||
tape.append(0, internal::tape_type::NULL_VALUE);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED really_inline error_code parse_root_null_atom(structural_parser &parser, const uint8_t *value) {
|
||||
SIMDJSON_WARN_UNUSED simdjson_really_inline error_code parse_root_null_atom(structural_parser &parser, const uint8_t *value) {
|
||||
parser.log_value("null");
|
||||
if (!atomparsing::is_valid_null_atom(value, parser.remaining_len())) { return N_ATOM_ERROR; }
|
||||
tape.append(0, internal::tape_type::NULL_VALUE);
|
||||
|
@ -172,29 +172,29 @@ private:
|
|||
}
|
||||
|
||||
// increment_count increments the count of keys in an object or values in an array.
|
||||
really_inline void increment_count(structural_parser &parser) {
|
||||
simdjson_really_inline void increment_count(structural_parser &parser) {
|
||||
parser.dom_parser.containing_scope[parser.depth].count++; // we have a key value pair in the object at parser.dom_parser.depth - 1
|
||||
}
|
||||
|
||||
// private:
|
||||
|
||||
really_inline uint32_t next_tape_index(structural_parser &parser) {
|
||||
simdjson_really_inline uint32_t next_tape_index(structural_parser &parser) {
|
||||
return uint32_t(tape.next_tape_loc - parser.dom_parser.doc->tape.get());
|
||||
}
|
||||
|
||||
really_inline void empty_container(structural_parser &parser, internal::tape_type start, internal::tape_type end) {
|
||||
simdjson_really_inline void empty_container(structural_parser &parser, internal::tape_type start, internal::tape_type end) {
|
||||
auto start_index = next_tape_index(parser);
|
||||
tape.append(start_index+2, start);
|
||||
tape.append(start_index, end);
|
||||
}
|
||||
|
||||
really_inline void start_container(structural_parser &parser) {
|
||||
simdjson_really_inline void start_container(structural_parser &parser) {
|
||||
parser.dom_parser.containing_scope[parser.depth].tape_index = next_tape_index(parser);
|
||||
parser.dom_parser.containing_scope[parser.depth].count = 0;
|
||||
tape.skip(); // We don't actually *write* the start element until the end.
|
||||
}
|
||||
|
||||
really_inline void end_container(structural_parser &parser, internal::tape_type start, internal::tape_type end) noexcept {
|
||||
simdjson_really_inline void end_container(structural_parser &parser, internal::tape_type start, internal::tape_type end) noexcept {
|
||||
// Write the ending tape element, pointing at the start location
|
||||
const uint32_t start_tape_index = parser.dom_parser.containing_scope[parser.depth].tape_index;
|
||||
tape.append(start_tape_index, end);
|
||||
|
@ -206,13 +206,13 @@ private:
|
|||
tape_writer::write(parser.dom_parser.doc->tape[start_tape_index], next_tape_index(parser) | (uint64_t(cntsat) << 32), start);
|
||||
}
|
||||
|
||||
really_inline uint8_t *on_start_string(structural_parser &parser) noexcept {
|
||||
simdjson_really_inline uint8_t *on_start_string(structural_parser &parser) noexcept {
|
||||
// we advance the point, accounting for the fact that we have a NULL termination
|
||||
tape.append(current_string_buf_loc - parser.dom_parser.doc->string_buf.get(), internal::tape_type::STRING);
|
||||
return current_string_buf_loc + sizeof(uint32_t);
|
||||
}
|
||||
|
||||
really_inline void on_end_string(uint8_t *dst) noexcept {
|
||||
simdjson_really_inline void on_end_string(uint8_t *dst) noexcept {
|
||||
uint32_t str_length = uint32_t(dst - (current_string_buf_loc + sizeof(uint32_t)));
|
||||
// TODO check for overflow in case someone has a crazy string (>=4GB?)
|
||||
// But only add the overflow check when the document itself exceeds 4GB
|
||||
|
|
|
@ -7,18 +7,18 @@ struct tape_writer {
|
|||
uint64_t *next_tape_loc;
|
||||
|
||||
/** Write a signed 64-bit value to tape. */
|
||||
really_inline void append_s64(int64_t value) noexcept;
|
||||
simdjson_really_inline void append_s64(int64_t value) noexcept;
|
||||
|
||||
/** Write an unsigned 64-bit value to tape. */
|
||||
really_inline void append_u64(uint64_t value) noexcept;
|
||||
simdjson_really_inline void append_u64(uint64_t value) noexcept;
|
||||
|
||||
/** Write a double value to tape. */
|
||||
really_inline void append_double(double value) noexcept;
|
||||
simdjson_really_inline void append_double(double value) noexcept;
|
||||
|
||||
/**
|
||||
* Append a tape entry (an 8-bit type,and 56 bits worth of value).
|
||||
*/
|
||||
really_inline void append(uint64_t val, internal::tape_type t) noexcept;
|
||||
simdjson_really_inline void append(uint64_t val, internal::tape_type t) noexcept;
|
||||
|
||||
/**
|
||||
* Skip the current tape entry without writing.
|
||||
|
@ -26,24 +26,24 @@ struct tape_writer {
|
|||
* Used to skip the start of the container, since we'll come back later to fill it in when the
|
||||
* container ends.
|
||||
*/
|
||||
really_inline void skip() noexcept;
|
||||
simdjson_really_inline void skip() noexcept;
|
||||
|
||||
/**
|
||||
* Skip the number of tape entries necessary to write a large u64 or i64.
|
||||
*/
|
||||
really_inline void skip_large_integer() noexcept;
|
||||
simdjson_really_inline void skip_large_integer() noexcept;
|
||||
|
||||
/**
|
||||
* Skip the number of tape entries necessary to write a double.
|
||||
*/
|
||||
really_inline void skip_double() noexcept;
|
||||
simdjson_really_inline void skip_double() noexcept;
|
||||
|
||||
/**
|
||||
* Write a value to a known location on tape.
|
||||
*
|
||||
* Used to go back and write out the start of a container after the container ends.
|
||||
*/
|
||||
really_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept;
|
||||
simdjson_really_inline static void write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept;
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -51,50 +51,50 @@ private:
|
|||
* all 64 bits, such as double and uint64_t.
|
||||
*/
|
||||
template<typename T>
|
||||
really_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept;
|
||||
simdjson_really_inline void append2(uint64_t val, T val2, internal::tape_type t) noexcept;
|
||||
}; // struct number_writer
|
||||
|
||||
really_inline void tape_writer::append_s64(int64_t value) noexcept {
|
||||
simdjson_really_inline void tape_writer::append_s64(int64_t value) noexcept {
|
||||
append2(0, value, internal::tape_type::INT64);
|
||||
}
|
||||
|
||||
really_inline void tape_writer::append_u64(uint64_t value) noexcept {
|
||||
simdjson_really_inline void tape_writer::append_u64(uint64_t value) noexcept {
|
||||
append(0, internal::tape_type::UINT64);
|
||||
*next_tape_loc = value;
|
||||
next_tape_loc++;
|
||||
}
|
||||
|
||||
/** Write a double value to tape. */
|
||||
really_inline void tape_writer::append_double(double value) noexcept {
|
||||
simdjson_really_inline void tape_writer::append_double(double value) noexcept {
|
||||
append2(0, value, internal::tape_type::DOUBLE);
|
||||
}
|
||||
|
||||
really_inline void tape_writer::skip() noexcept {
|
||||
simdjson_really_inline void tape_writer::skip() noexcept {
|
||||
next_tape_loc++;
|
||||
}
|
||||
|
||||
really_inline void tape_writer::skip_large_integer() noexcept {
|
||||
simdjson_really_inline void tape_writer::skip_large_integer() noexcept {
|
||||
next_tape_loc += 2;
|
||||
}
|
||||
|
||||
really_inline void tape_writer::skip_double() noexcept {
|
||||
simdjson_really_inline void tape_writer::skip_double() noexcept {
|
||||
next_tape_loc += 2;
|
||||
}
|
||||
|
||||
really_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept {
|
||||
simdjson_really_inline void tape_writer::append(uint64_t val, internal::tape_type t) noexcept {
|
||||
*next_tape_loc = val | ((uint64_t(char(t))) << 56);
|
||||
next_tape_loc++;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
really_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept {
|
||||
simdjson_really_inline void tape_writer::append2(uint64_t val, T val2, internal::tape_type t) noexcept {
|
||||
append(val, t);
|
||||
static_assert(sizeof(val2) == sizeof(*next_tape_loc), "Type is not 64 bits!");
|
||||
memcpy(next_tape_loc, &val2, sizeof(val2));
|
||||
next_tape_loc++;
|
||||
}
|
||||
|
||||
really_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept {
|
||||
simdjson_really_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, internal::tape_type t) noexcept {
|
||||
tape_loc = val | ((uint64_t(char(t))) << 56);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
// but the algorithms do not end up using the returned value.
|
||||
// Sadly, sanitizers are not smart enough to figure it out.
|
||||
NO_SANITIZE_UNDEFINED
|
||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int trailing_zeroes(uint64_t input_num) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
return (int)_tzcnt_u64(input_num);
|
||||
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
|
@ -22,27 +22,27 @@ really_inline int trailing_zeroes(uint64_t input_num) {
|
|||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||
simdjson_really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||
return _blsr_u64(input_num);
|
||||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline int leading_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int leading_zeroes(uint64_t input_num) {
|
||||
return int(_lzcnt_u64(input_num));
|
||||
}
|
||||
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
really_inline unsigned __int64 count_ones(uint64_t input_num) {
|
||||
simdjson_really_inline unsigned __int64 count_ones(uint64_t input_num) {
|
||||
// note: we do not support legacy 32-bit Windows
|
||||
return __popcnt64(input_num);// Visual Studio wants two underscores
|
||||
}
|
||||
#else
|
||||
really_inline long long int count_ones(uint64_t input_num) {
|
||||
simdjson_really_inline long long int count_ones(uint64_t input_num) {
|
||||
return _popcnt64(input_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
really_inline bool add_overflow(uint64_t value1, uint64_t value2,
|
||||
simdjson_really_inline bool add_overflow(uint64_t value1, uint64_t value2,
|
||||
uint64_t *result) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
return _addcarry_u64(0, value1, value2,
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
//
|
||||
// For example, prefix_xor(00100100) == 00011100
|
||||
//
|
||||
really_inline uint64_t prefix_xor(const uint64_t bitmask) {
|
||||
simdjson_really_inline uint64_t prefix_xor(const uint64_t bitmask) {
|
||||
// There should be no such thing with a processor supporting avx2
|
||||
// but not clmul.
|
||||
__m128i all_ones = _mm_set1_epi8('\xFF');
|
||||
|
|
|
@ -12,13 +12,13 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
using namespace simd;
|
||||
|
||||
struct json_character_block {
|
||||
static really_inline json_character_block classify(const simd::simd8x64<uint8_t>& in);
|
||||
static simdjson_really_inline json_character_block classify(const simd::simd8x64<uint8_t>& in);
|
||||
// ASCII white-space ('\r','\n','\t',' ')
|
||||
really_inline uint64_t whitespace() const { return _whitespace; }
|
||||
simdjson_really_inline uint64_t whitespace() const { return _whitespace; }
|
||||
// non-quote structural characters (comma, colon, braces, brackets)
|
||||
really_inline uint64_t op() const { return _op; }
|
||||
simdjson_really_inline uint64_t op() const { return _op; }
|
||||
// neither a structural character nor a white-space, so letters, numbers and quotes
|
||||
really_inline uint64_t scalar() { return ~(op() | whitespace()); }
|
||||
simdjson_really_inline uint64_t scalar() { return ~(op() | whitespace()); }
|
||||
|
||||
uint64_t _whitespace; // ASCII white-space ('\r','\n','\t',' ')
|
||||
uint64_t _op; // structural characters (comma, colon, braces, brackets but not quotes)
|
||||
|
@ -26,7 +26,7 @@ struct json_character_block {
|
|||
|
||||
// This identifies structural characters (comma, colon, braces, brackets),
|
||||
// and ASCII white-space ('\r','\n','\t',' ').
|
||||
really_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
|
||||
// These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why
|
||||
// we can't use the generic lookup_16.
|
||||
auto whitespace_table = simd8<uint8_t>::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100);
|
||||
|
@ -49,11 +49,11 @@ really_inline json_character_block json_character_block::classify(const simd::si
|
|||
return { whitespace, op };
|
||||
}
|
||||
|
||||
really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
simdjson_really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
return input.reduce_or().is_ascii();
|
||||
}
|
||||
|
||||
UNUSED really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
SIMDJSON_UNUSED simdjson_really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_second_byte = prev1.saturating_sub(0b11000000u-1); // Only 11______ will be > 0
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0b11100000u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0b11110000u-1); // Only 1111____ will be > 0
|
||||
|
@ -61,7 +61,7 @@ UNUSED really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1
|
|||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
really_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simdjson_really_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0b11100000u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0b11110000u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
|
@ -90,40 +90,40 @@ namespace {
|
|||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace stage1 {
|
||||
|
||||
really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
||||
simdjson_really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
||||
if (!backslash) { uint64_t escaped = prev_escaped; prev_escaped = 0; return escaped; }
|
||||
return find_escaped_branchless(backslash);
|
||||
}
|
||||
|
||||
} // namespace stage1
|
||||
|
||||
WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
return haswell::stage1::json_minifier::minify<128>(buf, len, dst, dst_len);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
this->buf = _buf;
|
||||
this->len = _len;
|
||||
return haswell::stage1::json_structural_indexer::index<128>(_buf, _len, *this, streaming);
|
||||
}
|
||||
|
||||
WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
return haswell::stage1::generic_validate_utf8(buf,len);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(_doc);
|
||||
return stage2::structural_parser::parse<false>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(_doc);
|
||||
return stage2::structural_parser::parse<true>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
auto error = stage1(_buf, _len, false);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_depth,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
|
|
|
@ -12,18 +12,18 @@ using namespace simdjson;
|
|||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation(
|
||||
simdjson_really_inline implementation() : simdjson::implementation(
|
||||
"haswell",
|
||||
"Intel/AMD AVX2",
|
||||
instruction_set::AVX2 | instruction_set::PCLMULQDQ | instruction_set::BMI1 | instruction_set::BMI2
|
||||
) {}
|
||||
WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_length,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace haswell
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#ifndef _blsr_u64
|
||||
// we roll our own
|
||||
SIMDJSON_TARGET_HASWELL
|
||||
static really_inline uint64_t _blsr_u64(uint64_t n) {
|
||||
static simdjson_really_inline uint64_t _blsr_u64(uint64_t n) {
|
||||
return (n - 1) & n;
|
||||
}
|
||||
SIMDJSON_UNTARGET_REGION
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
static really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
static simdjson_really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
// this actually computes *16* values so we are being wasteful.
|
||||
const __m128i ascii0 = _mm_set1_epi8('0');
|
||||
const __m128i mul_1_10 =
|
||||
|
|
|
@ -13,23 +13,23 @@ namespace simd {
|
|||
__m256i value;
|
||||
|
||||
// Zero constructor
|
||||
really_inline base() : value{__m256i()} {}
|
||||
simdjson_really_inline base() : value{__m256i()} {}
|
||||
|
||||
// Conversion from SIMD register
|
||||
really_inline base(const __m256i _value) : value(_value) {}
|
||||
simdjson_really_inline base(const __m256i _value) : value(_value) {}
|
||||
|
||||
// Conversion to SIMD register
|
||||
really_inline operator const __m256i&() const { return this->value; }
|
||||
really_inline operator __m256i&() { return this->value; }
|
||||
simdjson_really_inline operator const __m256i&() const { return this->value; }
|
||||
simdjson_really_inline operator __m256i&() { return this->value; }
|
||||
|
||||
// Bit operations
|
||||
really_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); }
|
||||
really_inline Child operator&(const Child other) const { return _mm256_and_si256(*this, other); }
|
||||
really_inline Child operator^(const Child other) const { return _mm256_xor_si256(*this, other); }
|
||||
really_inline Child bit_andnot(const Child other) const { return _mm256_andnot_si256(other, *this); }
|
||||
really_inline Child& operator|=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast | other; return *this_cast; }
|
||||
really_inline Child& operator&=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast & other; return *this_cast; }
|
||||
really_inline Child& operator^=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast ^ other; return *this_cast; }
|
||||
simdjson_really_inline Child operator|(const Child other) const { return _mm256_or_si256(*this, other); }
|
||||
simdjson_really_inline Child operator&(const Child other) const { return _mm256_and_si256(*this, other); }
|
||||
simdjson_really_inline Child operator^(const Child other) const { return _mm256_xor_si256(*this, other); }
|
||||
simdjson_really_inline Child bit_andnot(const Child other) const { return _mm256_andnot_si256(other, *this); }
|
||||
simdjson_really_inline Child& operator|=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast | other; return *this_cast; }
|
||||
simdjson_really_inline Child& operator&=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast & other; return *this_cast; }
|
||||
simdjson_really_inline Child& operator^=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast ^ other; return *this_cast; }
|
||||
};
|
||||
|
||||
// Forward-declared so they can be used by splat and friends.
|
||||
|
@ -41,15 +41,15 @@ namespace simd {
|
|||
typedef uint32_t bitmask_t;
|
||||
typedef uint64_t bitmask2_t;
|
||||
|
||||
really_inline base8() : base<simd8<T>>() {}
|
||||
really_inline base8(const __m256i _value) : base<simd8<T>>(_value) {}
|
||||
simdjson_really_inline base8() : base<simd8<T>>() {}
|
||||
simdjson_really_inline base8(const __m256i _value) : base<simd8<T>>(_value) {}
|
||||
|
||||
really_inline Mask operator==(const simd8<T> other) const { return _mm256_cmpeq_epi8(*this, other); }
|
||||
simdjson_really_inline Mask operator==(const simd8<T> other) const { return _mm256_cmpeq_epi8(*this, other); }
|
||||
|
||||
static const int SIZE = sizeof(base<T>::value);
|
||||
|
||||
template<int N=1>
|
||||
really_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||
simdjson_really_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||
return _mm256_alignr_epi8(*this, _mm256_permute2x128_si256(prev_chunk, *this, 0x21), 16 - N);
|
||||
}
|
||||
};
|
||||
|
@ -57,27 +57,27 @@ namespace simd {
|
|||
// SIMD byte mask type (returned by things like eq and gt)
|
||||
template<>
|
||||
struct simd8<bool>: base8<bool> {
|
||||
static really_inline simd8<bool> splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); }
|
||||
static simdjson_really_inline simd8<bool> splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); }
|
||||
|
||||
really_inline simd8<bool>() : base8() {}
|
||||
really_inline simd8<bool>(const __m256i _value) : base8<bool>(_value) {}
|
||||
simdjson_really_inline simd8<bool>() : base8() {}
|
||||
simdjson_really_inline simd8<bool>(const __m256i _value) : base8<bool>(_value) {}
|
||||
// Splat constructor
|
||||
really_inline simd8<bool>(bool _value) : base8<bool>(splat(_value)) {}
|
||||
simdjson_really_inline simd8<bool>(bool _value) : base8<bool>(splat(_value)) {}
|
||||
|
||||
really_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); }
|
||||
really_inline bool any() const { return !_mm256_testz_si256(*this, *this); }
|
||||
really_inline simd8<bool> operator~() const { return *this ^ true; }
|
||||
simdjson_really_inline int to_bitmask() const { return _mm256_movemask_epi8(*this); }
|
||||
simdjson_really_inline bool any() const { return !_mm256_testz_si256(*this, *this); }
|
||||
simdjson_really_inline simd8<bool> operator~() const { return *this ^ true; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct base8_numeric: base8<T> {
|
||||
static really_inline simd8<T> splat(T _value) { return _mm256_set1_epi8(_value); }
|
||||
static really_inline simd8<T> zero() { return _mm256_setzero_si256(); }
|
||||
static really_inline simd8<T> load(const T values[32]) {
|
||||
static simdjson_really_inline simd8<T> splat(T _value) { return _mm256_set1_epi8(_value); }
|
||||
static simdjson_really_inline simd8<T> zero() { return _mm256_setzero_si256(); }
|
||||
static simdjson_really_inline simd8<T> load(const T values[32]) {
|
||||
return _mm256_loadu_si256(reinterpret_cast<const __m256i *>(values));
|
||||
}
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
static really_inline simd8<T> repeat_16(
|
||||
static simdjson_really_inline simd8<T> repeat_16(
|
||||
T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7,
|
||||
T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15
|
||||
) {
|
||||
|
@ -89,24 +89,24 @@ namespace simd {
|
|||
);
|
||||
}
|
||||
|
||||
really_inline base8_numeric() : base8<T>() {}
|
||||
really_inline base8_numeric(const __m256i _value) : base8<T>(_value) {}
|
||||
simdjson_really_inline base8_numeric() : base8<T>() {}
|
||||
simdjson_really_inline base8_numeric(const __m256i _value) : base8<T>(_value) {}
|
||||
|
||||
// Store to array
|
||||
really_inline void store(T dst[32]) const { return _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), *this); }
|
||||
simdjson_really_inline void store(T dst[32]) const { return _mm256_storeu_si256(reinterpret_cast<__m256i *>(dst), *this); }
|
||||
|
||||
// Addition/subtraction are the same for signed and unsigned
|
||||
really_inline simd8<T> operator+(const simd8<T> other) const { return _mm256_add_epi8(*this, other); }
|
||||
really_inline simd8<T> operator-(const simd8<T> other) const { return _mm256_sub_epi8(*this, other); }
|
||||
really_inline simd8<T>& operator+=(const simd8<T> other) { *this = *this + other; return *(simd8<T>*)this; }
|
||||
really_inline simd8<T>& operator-=(const simd8<T> other) { *this = *this - other; return *(simd8<T>*)this; }
|
||||
simdjson_really_inline simd8<T> operator+(const simd8<T> other) const { return _mm256_add_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<T> operator-(const simd8<T> other) const { return _mm256_sub_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<T>& operator+=(const simd8<T> other) { *this = *this + other; return *(simd8<T>*)this; }
|
||||
simdjson_really_inline simd8<T>& operator-=(const simd8<T> other) { *this = *this - other; return *(simd8<T>*)this; }
|
||||
|
||||
// Override to distinguish from bool version
|
||||
really_inline simd8<T> operator~() const { return *this ^ 0xFFu; }
|
||||
simdjson_really_inline simd8<T> operator~() const { return *this ^ 0xFFu; }
|
||||
|
||||
// Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values)
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
simdjson_really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
return _mm256_shuffle_epi8(lookup_table, *this);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ namespace simd {
|
|||
// signature simd8<L> compress(uint32_t mask) would be
|
||||
// sensible, but the AVX ISA makes this kind of approach difficult.
|
||||
template<typename L>
|
||||
really_inline void compress(uint32_t mask, L * output) const {
|
||||
simdjson_really_inline void compress(uint32_t mask, L * output) const {
|
||||
// this particular implementation was inspired by work done by @animetosho
|
||||
// we do it in four steps, first 8 bytes and then second 8 bytes...
|
||||
uint8_t mask1 = uint8_t(mask); // least significant 8 bits
|
||||
|
@ -161,7 +161,7 @@ namespace simd {
|
|||
}
|
||||
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(
|
||||
simdjson_really_inline simd8<L> lookup_16(
|
||||
L replace0, L replace1, L replace2, L replace3,
|
||||
L replace4, L replace5, L replace6, L replace7,
|
||||
L replace8, L replace9, L replace10, L replace11,
|
||||
|
@ -178,14 +178,14 @@ namespace simd {
|
|||
// Signed bytes
|
||||
template<>
|
||||
struct simd8<int8_t> : base8_numeric<int8_t> {
|
||||
really_inline simd8() : base8_numeric<int8_t>() {}
|
||||
really_inline simd8(const __m256i _value) : base8_numeric<int8_t>(_value) {}
|
||||
simdjson_really_inline simd8() : base8_numeric<int8_t>() {}
|
||||
simdjson_really_inline simd8(const __m256i _value) : base8_numeric<int8_t>(_value) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(int8_t _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(int8_t _value) : simd8(splat(_value)) {}
|
||||
// Array constructor
|
||||
really_inline simd8(const int8_t values[32]) : simd8(load(values)) {}
|
||||
simdjson_really_inline simd8(const int8_t values[32]) : simd8(load(values)) {}
|
||||
// Member-by-member initialization
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15,
|
||||
int8_t v16, int8_t v17, int8_t v18, int8_t v19, int8_t v20, int8_t v21, int8_t v22, int8_t v23,
|
||||
|
@ -197,7 +197,7 @@ namespace simd {
|
|||
v24,v25,v26,v27,v28,v29,v30,v31
|
||||
)) {}
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
really_inline static simd8<int8_t> repeat_16(
|
||||
simdjson_really_inline static simd8<int8_t> repeat_16(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||
) {
|
||||
|
@ -210,23 +210,23 @@ namespace simd {
|
|||
}
|
||||
|
||||
// Order-sensitive comparisons
|
||||
really_inline simd8<int8_t> max(const simd8<int8_t> other) const { return _mm256_max_epi8(*this, other); }
|
||||
really_inline simd8<int8_t> min(const simd8<int8_t> other) const { return _mm256_min_epi8(*this, other); }
|
||||
really_inline simd8<bool> operator>(const simd8<int8_t> other) const { return _mm256_cmpgt_epi8(*this, other); }
|
||||
really_inline simd8<bool> operator<(const simd8<int8_t> other) const { return _mm256_cmpgt_epi8(other, *this); }
|
||||
simdjson_really_inline simd8<int8_t> max(const simd8<int8_t> other) const { return _mm256_max_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<int8_t> min(const simd8<int8_t> other) const { return _mm256_min_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator>(const simd8<int8_t> other) const { return _mm256_cmpgt_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator<(const simd8<int8_t> other) const { return _mm256_cmpgt_epi8(other, *this); }
|
||||
};
|
||||
|
||||
// Unsigned bytes
|
||||
template<>
|
||||
struct simd8<uint8_t>: base8_numeric<uint8_t> {
|
||||
really_inline simd8() : base8_numeric<uint8_t>() {}
|
||||
really_inline simd8(const __m256i _value) : base8_numeric<uint8_t>(_value) {}
|
||||
simdjson_really_inline simd8() : base8_numeric<uint8_t>() {}
|
||||
simdjson_really_inline simd8(const __m256i _value) : base8_numeric<uint8_t>(_value) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||
// Array constructor
|
||||
really_inline simd8(const uint8_t values[32]) : simd8(load(values)) {}
|
||||
simdjson_really_inline simd8(const uint8_t values[32]) : simd8(load(values)) {}
|
||||
// Member-by-member initialization
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15,
|
||||
uint8_t v16, uint8_t v17, uint8_t v18, uint8_t v19, uint8_t v20, uint8_t v21, uint8_t v22, uint8_t v23,
|
||||
|
@ -238,7 +238,7 @@ namespace simd {
|
|||
v24,v25,v26,v27,v28,v29,v30,v31
|
||||
)) {}
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
really_inline static simd8<uint8_t> repeat_16(
|
||||
simdjson_really_inline static simd8<uint8_t> repeat_16(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||
) {
|
||||
|
@ -251,39 +251,39 @@ namespace simd {
|
|||
}
|
||||
|
||||
// Saturated math
|
||||
really_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> other) const { return _mm256_adds_epu8(*this, other); }
|
||||
really_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> other) const { return _mm256_subs_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> other) const { return _mm256_adds_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> other) const { return _mm256_subs_epu8(*this, other); }
|
||||
|
||||
// Order-specific operations
|
||||
really_inline simd8<uint8_t> max(const simd8<uint8_t> other) const { return _mm256_max_epu8(*this, other); }
|
||||
really_inline simd8<uint8_t> min(const simd8<uint8_t> other) const { return _mm256_min_epu8(other, *this); }
|
||||
simdjson_really_inline simd8<uint8_t> max(const simd8<uint8_t> other) const { return _mm256_max_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> min(const simd8<uint8_t> other) const { return _mm256_min_epu8(other, *this); }
|
||||
// Same as >, but only guarantees true is nonzero (< guarantees true = -1)
|
||||
really_inline simd8<uint8_t> gt_bits(const simd8<uint8_t> other) const { return this->saturating_sub(other); }
|
||||
simdjson_really_inline simd8<uint8_t> gt_bits(const simd8<uint8_t> other) const { return this->saturating_sub(other); }
|
||||
// Same as <, but only guarantees true is nonzero (< guarantees true = -1)
|
||||
really_inline simd8<uint8_t> lt_bits(const simd8<uint8_t> other) const { return other.saturating_sub(*this); }
|
||||
really_inline simd8<bool> operator<=(const simd8<uint8_t> other) const { return other.max(*this) == other; }
|
||||
really_inline simd8<bool> operator>=(const simd8<uint8_t> other) const { return other.min(*this) == other; }
|
||||
really_inline simd8<bool> operator>(const simd8<uint8_t> other) const { return this->gt_bits(other).any_bits_set(); }
|
||||
really_inline simd8<bool> operator<(const simd8<uint8_t> other) const { return this->lt_bits(other).any_bits_set(); }
|
||||
simdjson_really_inline simd8<uint8_t> lt_bits(const simd8<uint8_t> other) const { return other.saturating_sub(*this); }
|
||||
simdjson_really_inline simd8<bool> operator<=(const simd8<uint8_t> other) const { return other.max(*this) == other; }
|
||||
simdjson_really_inline simd8<bool> operator>=(const simd8<uint8_t> other) const { return other.min(*this) == other; }
|
||||
simdjson_really_inline simd8<bool> operator>(const simd8<uint8_t> other) const { return this->gt_bits(other).any_bits_set(); }
|
||||
simdjson_really_inline simd8<bool> operator<(const simd8<uint8_t> other) const { return this->lt_bits(other).any_bits_set(); }
|
||||
|
||||
// Bit-specific operations
|
||||
really_inline simd8<bool> bits_not_set() const { return *this == uint8_t(0); }
|
||||
really_inline simd8<bool> bits_not_set(simd8<uint8_t> bits) const { return (*this & bits).bits_not_set(); }
|
||||
really_inline simd8<bool> any_bits_set() const { return ~this->bits_not_set(); }
|
||||
really_inline simd8<bool> any_bits_set(simd8<uint8_t> bits) const { return ~this->bits_not_set(bits); }
|
||||
really_inline bool is_ascii() const { return _mm256_movemask_epi8(*this) == 0; }
|
||||
really_inline bool bits_not_set_anywhere() const { return _mm256_testz_si256(*this, *this); }
|
||||
really_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); }
|
||||
really_inline bool bits_not_set_anywhere(simd8<uint8_t> bits) const { return _mm256_testz_si256(*this, bits); }
|
||||
really_inline bool any_bits_set_anywhere(simd8<uint8_t> bits) const { return !bits_not_set_anywhere(bits); }
|
||||
simdjson_really_inline simd8<bool> bits_not_set() const { return *this == uint8_t(0); }
|
||||
simdjson_really_inline simd8<bool> bits_not_set(simd8<uint8_t> bits) const { return (*this & bits).bits_not_set(); }
|
||||
simdjson_really_inline simd8<bool> any_bits_set() const { return ~this->bits_not_set(); }
|
||||
simdjson_really_inline simd8<bool> any_bits_set(simd8<uint8_t> bits) const { return ~this->bits_not_set(bits); }
|
||||
simdjson_really_inline bool is_ascii() const { return _mm256_movemask_epi8(*this) == 0; }
|
||||
simdjson_really_inline bool bits_not_set_anywhere() const { return _mm256_testz_si256(*this, *this); }
|
||||
simdjson_really_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); }
|
||||
simdjson_really_inline bool bits_not_set_anywhere(simd8<uint8_t> bits) const { return _mm256_testz_si256(*this, bits); }
|
||||
simdjson_really_inline bool any_bits_set_anywhere(simd8<uint8_t> bits) const { return !bits_not_set_anywhere(bits); }
|
||||
template<int N>
|
||||
really_inline simd8<uint8_t> shr() const { return simd8<uint8_t>(_mm256_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); }
|
||||
simdjson_really_inline simd8<uint8_t> shr() const { return simd8<uint8_t>(_mm256_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); }
|
||||
template<int N>
|
||||
really_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(_mm256_slli_epi16(*this, N)) & uint8_t(0xFFu << N); }
|
||||
simdjson_really_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(_mm256_slli_epi16(*this, N)) & uint8_t(0xFFu << N); }
|
||||
// Get one of the bits and make a bitmask out of it.
|
||||
// e.g. value.get_bit<7>() gets the high bit
|
||||
template<int N>
|
||||
really_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); }
|
||||
simdjson_really_inline int get_bit() const { return _mm256_movemask_epi8(_mm256_slli_epi16(*this, 7-N)); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -296,32 +296,32 @@ namespace simd {
|
|||
simd8x64<T>& operator=(const simd8<T> other) = delete; // no assignment allowed
|
||||
simd8x64() = delete; // no default constructor allowed
|
||||
|
||||
really_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1) : chunks{chunk0, chunk1} {}
|
||||
really_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+32)} {}
|
||||
simdjson_really_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1) : chunks{chunk0, chunk1} {}
|
||||
simdjson_really_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+32)} {}
|
||||
|
||||
really_inline void compress(uint64_t mask, T * output) const {
|
||||
simdjson_really_inline void compress(uint64_t mask, T * output) const {
|
||||
uint32_t mask1 = uint32_t(mask);
|
||||
uint32_t mask2 = uint32_t(mask >> 32);
|
||||
this->chunks[0].compress(mask1, output);
|
||||
this->chunks[1].compress(mask2, output + 32 - count_ones(mask1));
|
||||
}
|
||||
|
||||
really_inline void store(T ptr[64]) const {
|
||||
simdjson_really_inline void store(T ptr[64]) const {
|
||||
this->chunks[0].store(ptr+sizeof(simd8<T>)*0);
|
||||
this->chunks[1].store(ptr+sizeof(simd8<T>)*1);
|
||||
}
|
||||
|
||||
really_inline uint64_t to_bitmask() const {
|
||||
simdjson_really_inline uint64_t to_bitmask() const {
|
||||
uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask());
|
||||
uint64_t r_hi = this->chunks[1].to_bitmask();
|
||||
return r_lo | (r_hi << 32);
|
||||
}
|
||||
|
||||
really_inline simd8<T> reduce_or() const {
|
||||
simdjson_really_inline simd8<T> reduce_or() const {
|
||||
return this->chunks[0] | this->chunks[1];
|
||||
}
|
||||
|
||||
really_inline simd8x64<T> bit_or(const T m) const {
|
||||
simdjson_really_inline simd8x64<T> bit_or(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<T>(
|
||||
this->chunks[0] | mask,
|
||||
|
@ -329,7 +329,7 @@ namespace simd {
|
|||
);
|
||||
}
|
||||
|
||||
really_inline uint64_t eq(const T m) const {
|
||||
simdjson_really_inline uint64_t eq(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<bool>(
|
||||
this->chunks[0] == mask,
|
||||
|
@ -337,7 +337,7 @@ namespace simd {
|
|||
).to_bitmask();
|
||||
}
|
||||
|
||||
really_inline uint64_t lteq(const T m) const {
|
||||
simdjson_really_inline uint64_t lteq(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<bool>(
|
||||
this->chunks[0] <= mask,
|
||||
|
|
|
@ -14,18 +14,18 @@ using namespace simd;
|
|||
struct backslash_and_quote {
|
||||
public:
|
||||
static constexpr uint32_t BYTES_PROCESSED = 32;
|
||||
really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
simdjson_really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
|
||||
really_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; }
|
||||
really_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; }
|
||||
really_inline int quote_index() { return trailing_zeroes(quote_bits); }
|
||||
really_inline int backslash_index() { return trailing_zeroes(bs_bits); }
|
||||
simdjson_really_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; }
|
||||
simdjson_really_inline bool has_backslash() { return ((quote_bits - 1) & bs_bits) != 0; }
|
||||
simdjson_really_inline int quote_index() { return trailing_zeroes(quote_bits); }
|
||||
simdjson_really_inline int backslash_index() { return trailing_zeroes(bs_bits); }
|
||||
|
||||
uint32_t bs_bits;
|
||||
uint32_t quote_bits;
|
||||
}; // struct backslash_and_quote
|
||||
|
||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
simdjson_really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
// this can read up to 15 bytes beyond the buffer size, but we require
|
||||
// SIMDJSON_PADDING of padding
|
||||
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes");
|
||||
|
|
|
@ -38,20 +38,20 @@ public:
|
|||
const std::string &name() const noexcept final { return set_best()->name(); }
|
||||
const std::string &description() const noexcept final { return set_best()->description(); }
|
||||
uint32_t required_instruction_sets() const noexcept final { return set_best()->required_instruction_sets(); }
|
||||
WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_length,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
) const noexcept final {
|
||||
return set_best()->create_dom_parser_implementation(capacity, max_length, dst);
|
||||
}
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final {
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final {
|
||||
return set_best()->minify(buf, len, dst, dst_len);
|
||||
}
|
||||
WARN_UNUSED bool validate_utf8(const char * buf, size_t len) const noexcept final override {
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char * buf, size_t len) const noexcept final override {
|
||||
return set_best()->validate_utf8(buf, len);
|
||||
}
|
||||
really_inline detect_best_supported_implementation_on_first_use() noexcept : implementation("best_supported_detector", "Detects the best supported implementation and sets it", 0) {}
|
||||
simdjson_really_inline detect_best_supported_implementation_on_first_use() noexcept : implementation("best_supported_detector", "Detects the best supported implementation and sets it", 0) {}
|
||||
private:
|
||||
const implementation *set_best() const noexcept;
|
||||
};
|
||||
|
@ -76,17 +76,17 @@ const std::initializer_list<const implementation *> available_implementation_poi
|
|||
// So we can return UNSUPPORTED_ARCHITECTURE from the parser when there is no support
|
||||
class unsupported_implementation final : public implementation {
|
||||
public:
|
||||
WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
size_t,
|
||||
size_t,
|
||||
std::unique_ptr<internal::dom_parser_implementation>&
|
||||
) const noexcept final {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
WARN_UNUSED error_code minify(const uint8_t *, size_t, uint8_t *, size_t &) const noexcept final override {
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const uint8_t *, size_t, uint8_t *, size_t &) const noexcept final override {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
WARN_UNUSED bool validate_utf8(const char *, size_t) const noexcept final override {
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char *, size_t) const noexcept final override {
|
||||
return false; // Just refuse to validate. Given that we have a fallback implementation
|
||||
// it seems unlikely that unsupported_implementation will ever be used. If it is used,
|
||||
// then it will flag all strings as invalid. The alternative is to return an error_code
|
||||
|
@ -143,10 +143,10 @@ const implementation *detect_best_supported_implementation_on_first_use::set_bes
|
|||
SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list available_implementations{};
|
||||
SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr<const implementation> active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton};
|
||||
|
||||
WARN_UNUSED error_code minify(const char *buf, size_t len, char *dst, size_t &dst_len) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const char *buf, size_t len, char *dst, size_t &dst_len) noexcept {
|
||||
return active_implementation->minify((const uint8_t *)buf, len, (uint8_t *)dst, dst_len);
|
||||
}
|
||||
WARN_UNUSED bool validate_utf8(const char *buf, size_t len) noexcept {
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char *buf, size_t len) noexcept {
|
||||
return active_implementation->validate_utf8(buf, len);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
// but the algorithms do not end up using the returned value.
|
||||
// Sadly, sanitizers are not smart enough to figure it out.
|
||||
NO_SANITIZE_UNDEFINED
|
||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int trailing_zeroes(uint64_t input_num) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
unsigned long ret;
|
||||
// Search the mask data from least significant bit (LSB)
|
||||
|
@ -21,12 +21,12 @@ really_inline int trailing_zeroes(uint64_t input_num) {
|
|||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||
simdjson_really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||
return input_num & (input_num-1);
|
||||
}
|
||||
|
||||
/* result might be undefined when input_num is zero */
|
||||
really_inline int leading_zeroes(uint64_t input_num) {
|
||||
simdjson_really_inline int leading_zeroes(uint64_t input_num) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
unsigned long leading_zero = 0;
|
||||
// Search the mask data from most significant bit (MSB)
|
||||
|
@ -41,17 +41,17 @@ really_inline int leading_zeroes(uint64_t input_num) {
|
|||
}
|
||||
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
really_inline unsigned __int64 count_ones(uint64_t input_num) {
|
||||
simdjson_really_inline unsigned __int64 count_ones(uint64_t input_num) {
|
||||
// note: we do not support legacy 32-bit Windows
|
||||
return __popcnt64(input_num);// Visual Studio wants two underscores
|
||||
}
|
||||
#else
|
||||
really_inline long long int count_ones(uint64_t input_num) {
|
||||
simdjson_really_inline long long int count_ones(uint64_t input_num) {
|
||||
return _popcnt64(input_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
really_inline bool add_overflow(uint64_t value1, uint64_t value2,
|
||||
simdjson_really_inline bool add_overflow(uint64_t value1, uint64_t value2,
|
||||
uint64_t *result) {
|
||||
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
|
||||
return _addcarry_u64(0, value1, value2,
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
//
|
||||
// For example, prefix_xor(00100100) == 00011100
|
||||
//
|
||||
really_inline uint64_t prefix_xor(const uint64_t bitmask) {
|
||||
simdjson_really_inline uint64_t prefix_xor(const uint64_t bitmask) {
|
||||
// There should be no such thing with a processing supporting avx2
|
||||
// but not clmul.
|
||||
__m128i all_ones = _mm_set1_epi8('\xFF');
|
||||
|
|
|
@ -12,17 +12,17 @@ namespace SIMDJSON_IMPLEMENTATION {
|
|||
using namespace simd;
|
||||
|
||||
struct json_character_block {
|
||||
static really_inline json_character_block classify(const simd::simd8x64<uint8_t>& in);
|
||||
static simdjson_really_inline json_character_block classify(const simd::simd8x64<uint8_t>& in);
|
||||
|
||||
really_inline uint64_t whitespace() const { return _whitespace; }
|
||||
really_inline uint64_t op() const { return _op; }
|
||||
really_inline uint64_t scalar() { return ~(op() | whitespace()); }
|
||||
simdjson_really_inline uint64_t whitespace() const { return _whitespace; }
|
||||
simdjson_really_inline uint64_t op() const { return _op; }
|
||||
simdjson_really_inline uint64_t scalar() { return ~(op() | whitespace()); }
|
||||
|
||||
uint64_t _whitespace;
|
||||
uint64_t _op;
|
||||
};
|
||||
|
||||
really_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
|
||||
simdjson_really_inline json_character_block json_character_block::classify(const simd::simd8x64<uint8_t>& in) {
|
||||
// These lookups rely on the fact that anything < 127 will match the lower 4 bits, which is why
|
||||
// we can't use the generic lookup_16.
|
||||
auto whitespace_table = simd8<uint8_t>::repeat_16(' ', 100, 100, 100, 17, 100, 113, 2, 100, '\t', '\n', 112, 100, '\r', 100, 100);
|
||||
|
@ -50,11 +50,11 @@ really_inline json_character_block json_character_block::classify(const simd::si
|
|||
return { whitespace, op };
|
||||
}
|
||||
|
||||
really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
simdjson_really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
|
||||
return input.reduce_or().is_ascii();
|
||||
}
|
||||
|
||||
UNUSED really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
SIMDJSON_UNUSED simdjson_really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_second_byte = prev1.saturating_sub(0b11000000u-1); // Only 11______ will be > 0
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0b11100000u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0b11110000u-1); // Only 1111____ will be > 0
|
||||
|
@ -62,7 +62,7 @@ UNUSED really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1
|
|||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
really_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simdjson_really_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0b11100000u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0b11110000u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
|
@ -92,40 +92,40 @@ namespace {
|
|||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace stage1 {
|
||||
|
||||
really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
||||
simdjson_really_inline uint64_t json_string_scanner::find_escaped(uint64_t backslash) {
|
||||
if (!backslash) { uint64_t escaped = prev_escaped; prev_escaped = 0; return escaped; }
|
||||
return find_escaped_branchless(backslash);
|
||||
}
|
||||
|
||||
} // namespace stage1
|
||||
|
||||
WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept {
|
||||
return westmere::stage1::json_minifier::minify<64>(buf, len, dst, dst_len);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
this->buf = _buf;
|
||||
this->len = _len;
|
||||
return westmere::stage1::json_structural_indexer::index<64>(_buf, _len, *this, streaming);
|
||||
}
|
||||
|
||||
WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
SIMDJSON_WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
return westmere::stage1::generic_validate_utf8(buf,len);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(*doc);
|
||||
return stage2::structural_parser::parse<false>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
|
||||
doc = &_doc;
|
||||
stage2::tape_builder builder(_doc);
|
||||
return stage2::structural_parser::parse<true>(*this, builder);
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
SIMDJSON_WARN_UNUSED error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
|
||||
auto error = stage1(_buf, _len, false);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
SIMDJSON_WARN_UNUSED error_code implementation::create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_depth,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
|
|
|
@ -14,14 +14,14 @@ using namespace simdjson::dom;
|
|||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", instruction_set::SSE42 | instruction_set::PCLMULQDQ) {}
|
||||
WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
simdjson_really_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", instruction_set::SSE42 | instruction_set::PCLMULQDQ) {}
|
||||
SIMDJSON_WARN_UNUSED error_code create_dom_parser_implementation(
|
||||
size_t capacity,
|
||||
size_t max_length,
|
||||
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||
) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
SIMDJSON_WARN_UNUSED bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace westmere
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
namespace {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
|
||||
static really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
static simdjson_really_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
||||
// this actually computes *16* values so we are being wasteful.
|
||||
const __m128i ascii0 = _mm_set1_epi8('0');
|
||||
const __m128i mul_1_10 =
|
||||
|
|
|
@ -12,23 +12,23 @@ namespace simd {
|
|||
__m128i value;
|
||||
|
||||
// Zero constructor
|
||||
really_inline base() : value{__m128i()} {}
|
||||
simdjson_really_inline base() : value{__m128i()} {}
|
||||
|
||||
// Conversion from SIMD register
|
||||
really_inline base(const __m128i _value) : value(_value) {}
|
||||
simdjson_really_inline base(const __m128i _value) : value(_value) {}
|
||||
|
||||
// Conversion to SIMD register
|
||||
really_inline operator const __m128i&() const { return this->value; }
|
||||
really_inline operator __m128i&() { return this->value; }
|
||||
simdjson_really_inline operator const __m128i&() const { return this->value; }
|
||||
simdjson_really_inline operator __m128i&() { return this->value; }
|
||||
|
||||
// Bit operations
|
||||
really_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); }
|
||||
really_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); }
|
||||
really_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); }
|
||||
really_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); }
|
||||
really_inline Child& operator|=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast | other; return *this_cast; }
|
||||
really_inline Child& operator&=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast & other; return *this_cast; }
|
||||
really_inline Child& operator^=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast ^ other; return *this_cast; }
|
||||
simdjson_really_inline Child operator|(const Child other) const { return _mm_or_si128(*this, other); }
|
||||
simdjson_really_inline Child operator&(const Child other) const { return _mm_and_si128(*this, other); }
|
||||
simdjson_really_inline Child operator^(const Child other) const { return _mm_xor_si128(*this, other); }
|
||||
simdjson_really_inline Child bit_andnot(const Child other) const { return _mm_andnot_si128(other, *this); }
|
||||
simdjson_really_inline Child& operator|=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast | other; return *this_cast; }
|
||||
simdjson_really_inline Child& operator&=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast & other; return *this_cast; }
|
||||
simdjson_really_inline Child& operator^=(const Child other) { auto this_cast = (Child*)this; *this_cast = *this_cast ^ other; return *this_cast; }
|
||||
};
|
||||
|
||||
// Forward-declared so they can be used by splat and friends.
|
||||
|
@ -40,15 +40,15 @@ namespace simd {
|
|||
typedef uint16_t bitmask_t;
|
||||
typedef uint32_t bitmask2_t;
|
||||
|
||||
really_inline base8() : base<simd8<T>>() {}
|
||||
really_inline base8(const __m128i _value) : base<simd8<T>>(_value) {}
|
||||
simdjson_really_inline base8() : base<simd8<T>>() {}
|
||||
simdjson_really_inline base8(const __m128i _value) : base<simd8<T>>(_value) {}
|
||||
|
||||
really_inline Mask operator==(const simd8<T> other) const { return _mm_cmpeq_epi8(*this, other); }
|
||||
simdjson_really_inline Mask operator==(const simd8<T> other) const { return _mm_cmpeq_epi8(*this, other); }
|
||||
|
||||
static const int SIZE = sizeof(base<simd8<T>>::value);
|
||||
|
||||
template<int N=1>
|
||||
really_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||
simdjson_really_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||
return _mm_alignr_epi8(*this, prev_chunk, 16 - N);
|
||||
}
|
||||
};
|
||||
|
@ -56,27 +56,27 @@ namespace simd {
|
|||
// SIMD byte mask type (returned by things like eq and gt)
|
||||
template<>
|
||||
struct simd8<bool>: base8<bool> {
|
||||
static really_inline simd8<bool> splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); }
|
||||
static simdjson_really_inline simd8<bool> splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); }
|
||||
|
||||
really_inline simd8<bool>() : base8() {}
|
||||
really_inline simd8<bool>(const __m128i _value) : base8<bool>(_value) {}
|
||||
simdjson_really_inline simd8<bool>() : base8() {}
|
||||
simdjson_really_inline simd8<bool>(const __m128i _value) : base8<bool>(_value) {}
|
||||
// Splat constructor
|
||||
really_inline simd8<bool>(bool _value) : base8<bool>(splat(_value)) {}
|
||||
simdjson_really_inline simd8<bool>(bool _value) : base8<bool>(splat(_value)) {}
|
||||
|
||||
really_inline int to_bitmask() const { return _mm_movemask_epi8(*this); }
|
||||
really_inline bool any() const { return !_mm_testz_si128(*this, *this); }
|
||||
really_inline simd8<bool> operator~() const { return *this ^ true; }
|
||||
simdjson_really_inline int to_bitmask() const { return _mm_movemask_epi8(*this); }
|
||||
simdjson_really_inline bool any() const { return !_mm_testz_si128(*this, *this); }
|
||||
simdjson_really_inline simd8<bool> operator~() const { return *this ^ true; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct base8_numeric: base8<T> {
|
||||
static really_inline simd8<T> splat(T _value) { return _mm_set1_epi8(_value); }
|
||||
static really_inline simd8<T> zero() { return _mm_setzero_si128(); }
|
||||
static really_inline simd8<T> load(const T values[16]) {
|
||||
static simdjson_really_inline simd8<T> splat(T _value) { return _mm_set1_epi8(_value); }
|
||||
static simdjson_really_inline simd8<T> zero() { return _mm_setzero_si128(); }
|
||||
static simdjson_really_inline simd8<T> load(const T values[16]) {
|
||||
return _mm_loadu_si128(reinterpret_cast<const __m128i *>(values));
|
||||
}
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
static really_inline simd8<T> repeat_16(
|
||||
static simdjson_really_inline simd8<T> repeat_16(
|
||||
T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7,
|
||||
T v8, T v9, T v10, T v11, T v12, T v13, T v14, T v15
|
||||
) {
|
||||
|
@ -86,24 +86,24 @@ namespace simd {
|
|||
);
|
||||
}
|
||||
|
||||
really_inline base8_numeric() : base8<T>() {}
|
||||
really_inline base8_numeric(const __m128i _value) : base8<T>(_value) {}
|
||||
simdjson_really_inline base8_numeric() : base8<T>() {}
|
||||
simdjson_really_inline base8_numeric(const __m128i _value) : base8<T>(_value) {}
|
||||
|
||||
// Store to array
|
||||
really_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); }
|
||||
simdjson_really_inline void store(T dst[16]) const { return _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), *this); }
|
||||
|
||||
// Override to distinguish from bool version
|
||||
really_inline simd8<T> operator~() const { return *this ^ 0xFFu; }
|
||||
simdjson_really_inline simd8<T> operator~() const { return *this ^ 0xFFu; }
|
||||
|
||||
// Addition/subtraction are the same for signed and unsigned
|
||||
really_inline simd8<T> operator+(const simd8<T> other) const { return _mm_add_epi8(*this, other); }
|
||||
really_inline simd8<T> operator-(const simd8<T> other) const { return _mm_sub_epi8(*this, other); }
|
||||
really_inline simd8<T>& operator+=(const simd8<T> other) { *this = *this + other; return *(simd8<T>*)this; }
|
||||
really_inline simd8<T>& operator-=(const simd8<T> other) { *this = *this - other; return *(simd8<T>*)this; }
|
||||
simdjson_really_inline simd8<T> operator+(const simd8<T> other) const { return _mm_add_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<T> operator-(const simd8<T> other) const { return _mm_sub_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<T>& operator+=(const simd8<T> other) { *this = *this + other; return *(simd8<T>*)this; }
|
||||
simdjson_really_inline simd8<T>& operator-=(const simd8<T> other) { *this = *this - other; return *(simd8<T>*)this; }
|
||||
|
||||
// Perform a lookup assuming the value is between 0 and 16 (undefined behavior for out of range values)
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
simdjson_really_inline simd8<L> lookup_16(simd8<L> lookup_table) const {
|
||||
return _mm_shuffle_epi8(lookup_table, *this);
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ namespace simd {
|
|||
// signature simd8<L> compress(uint32_t mask) would be
|
||||
// sensible, but the AVX ISA makes this kind of approach difficult.
|
||||
template<typename L>
|
||||
really_inline void compress(uint16_t mask, L * output) const {
|
||||
simdjson_really_inline void compress(uint16_t mask, L * output) const {
|
||||
// this particular implementation was inspired by work done by @animetosho
|
||||
// we do it in two steps, first 8 bytes and then second 8 bytes
|
||||
uint8_t mask1 = uint8_t(mask); // least significant 8 bits
|
||||
|
@ -143,7 +143,7 @@ namespace simd {
|
|||
}
|
||||
|
||||
template<typename L>
|
||||
really_inline simd8<L> lookup_16(
|
||||
simdjson_really_inline simd8<L> lookup_16(
|
||||
L replace0, L replace1, L replace2, L replace3,
|
||||
L replace4, L replace5, L replace6, L replace7,
|
||||
L replace8, L replace9, L replace10, L replace11,
|
||||
|
@ -160,14 +160,14 @@ namespace simd {
|
|||
// Signed bytes
|
||||
template<>
|
||||
struct simd8<int8_t> : base8_numeric<int8_t> {
|
||||
really_inline simd8() : base8_numeric<int8_t>() {}
|
||||
really_inline simd8(const __m128i _value) : base8_numeric<int8_t>(_value) {}
|
||||
simdjson_really_inline simd8() : base8_numeric<int8_t>() {}
|
||||
simdjson_really_inline simd8(const __m128i _value) : base8_numeric<int8_t>(_value) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(int8_t _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(int8_t _value) : simd8(splat(_value)) {}
|
||||
// Array constructor
|
||||
really_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||
simdjson_really_inline simd8(const int8_t* values) : simd8(load(values)) {}
|
||||
// Member-by-member initialization
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||
) : simd8(_mm_setr_epi8(
|
||||
|
@ -175,7 +175,7 @@ namespace simd {
|
|||
v8, v9, v10,v11,v12,v13,v14,v15
|
||||
)) {}
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
really_inline static simd8<int8_t> repeat_16(
|
||||
simdjson_really_inline static simd8<int8_t> repeat_16(
|
||||
int8_t v0, int8_t v1, int8_t v2, int8_t v3, int8_t v4, int8_t v5, int8_t v6, int8_t v7,
|
||||
int8_t v8, int8_t v9, int8_t v10, int8_t v11, int8_t v12, int8_t v13, int8_t v14, int8_t v15
|
||||
) {
|
||||
|
@ -186,23 +186,23 @@ namespace simd {
|
|||
}
|
||||
|
||||
// Order-sensitive comparisons
|
||||
really_inline simd8<int8_t> max(const simd8<int8_t> other) const { return _mm_max_epi8(*this, other); }
|
||||
really_inline simd8<int8_t> min(const simd8<int8_t> other) const { return _mm_min_epi8(*this, other); }
|
||||
really_inline simd8<bool> operator>(const simd8<int8_t> other) const { return _mm_cmpgt_epi8(*this, other); }
|
||||
really_inline simd8<bool> operator<(const simd8<int8_t> other) const { return _mm_cmpgt_epi8(other, *this); }
|
||||
simdjson_really_inline simd8<int8_t> max(const simd8<int8_t> other) const { return _mm_max_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<int8_t> min(const simd8<int8_t> other) const { return _mm_min_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator>(const simd8<int8_t> other) const { return _mm_cmpgt_epi8(*this, other); }
|
||||
simdjson_really_inline simd8<bool> operator<(const simd8<int8_t> other) const { return _mm_cmpgt_epi8(other, *this); }
|
||||
};
|
||||
|
||||
// Unsigned bytes
|
||||
template<>
|
||||
struct simd8<uint8_t>: base8_numeric<uint8_t> {
|
||||
really_inline simd8() : base8_numeric<uint8_t>() {}
|
||||
really_inline simd8(const __m128i _value) : base8_numeric<uint8_t>(_value) {}
|
||||
simdjson_really_inline simd8() : base8_numeric<uint8_t>() {}
|
||||
simdjson_really_inline simd8(const __m128i _value) : base8_numeric<uint8_t>(_value) {}
|
||||
// Splat constructor
|
||||
really_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||
simdjson_really_inline simd8(uint8_t _value) : simd8(splat(_value)) {}
|
||||
// Array constructor
|
||||
really_inline simd8(const uint8_t* values) : simd8(load(values)) {}
|
||||
simdjson_really_inline simd8(const uint8_t* values) : simd8(load(values)) {}
|
||||
// Member-by-member initialization
|
||||
really_inline simd8(
|
||||
simdjson_really_inline simd8(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||
) : simd8(_mm_setr_epi8(
|
||||
|
@ -210,7 +210,7 @@ namespace simd {
|
|||
v8, v9, v10,v11,v12,v13,v14,v15
|
||||
)) {}
|
||||
// Repeat 16 values as many times as necessary (usually for lookup tables)
|
||||
really_inline static simd8<uint8_t> repeat_16(
|
||||
simdjson_really_inline static simd8<uint8_t> repeat_16(
|
||||
uint8_t v0, uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5, uint8_t v6, uint8_t v7,
|
||||
uint8_t v8, uint8_t v9, uint8_t v10, uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14, uint8_t v15
|
||||
) {
|
||||
|
@ -221,39 +221,39 @@ namespace simd {
|
|||
}
|
||||
|
||||
// Saturated math
|
||||
really_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> other) const { return _mm_adds_epu8(*this, other); }
|
||||
really_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> other) const { return _mm_subs_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> other) const { return _mm_adds_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> other) const { return _mm_subs_epu8(*this, other); }
|
||||
|
||||
// Order-specific operations
|
||||
really_inline simd8<uint8_t> max(const simd8<uint8_t> other) const { return _mm_max_epu8(*this, other); }
|
||||
really_inline simd8<uint8_t> min(const simd8<uint8_t> other) const { return _mm_min_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> max(const simd8<uint8_t> other) const { return _mm_max_epu8(*this, other); }
|
||||
simdjson_really_inline simd8<uint8_t> min(const simd8<uint8_t> other) const { return _mm_min_epu8(*this, other); }
|
||||
// Same as >, but only guarantees true is nonzero (< guarantees true = -1)
|
||||
really_inline simd8<uint8_t> gt_bits(const simd8<uint8_t> other) const { return this->saturating_sub(other); }
|
||||
simdjson_really_inline simd8<uint8_t> gt_bits(const simd8<uint8_t> other) const { return this->saturating_sub(other); }
|
||||
// Same as <, but only guarantees true is nonzero (< guarantees true = -1)
|
||||
really_inline simd8<uint8_t> lt_bits(const simd8<uint8_t> other) const { return other.saturating_sub(*this); }
|
||||
really_inline simd8<bool> operator<=(const simd8<uint8_t> other) const { return other.max(*this) == other; }
|
||||
really_inline simd8<bool> operator>=(const simd8<uint8_t> other) const { return other.min(*this) == other; }
|
||||
really_inline simd8<bool> operator>(const simd8<uint8_t> other) const { return this->gt_bits(other).any_bits_set(); }
|
||||
really_inline simd8<bool> operator<(const simd8<uint8_t> other) const { return this->gt_bits(other).any_bits_set(); }
|
||||
simdjson_really_inline simd8<uint8_t> lt_bits(const simd8<uint8_t> other) const { return other.saturating_sub(*this); }
|
||||
simdjson_really_inline simd8<bool> operator<=(const simd8<uint8_t> other) const { return other.max(*this) == other; }
|
||||
simdjson_really_inline simd8<bool> operator>=(const simd8<uint8_t> other) const { return other.min(*this) == other; }
|
||||
simdjson_really_inline simd8<bool> operator>(const simd8<uint8_t> other) const { return this->gt_bits(other).any_bits_set(); }
|
||||
simdjson_really_inline simd8<bool> operator<(const simd8<uint8_t> other) const { return this->gt_bits(other).any_bits_set(); }
|
||||
|
||||
// Bit-specific operations
|
||||
really_inline simd8<bool> bits_not_set() const { return *this == uint8_t(0); }
|
||||
really_inline simd8<bool> bits_not_set(simd8<uint8_t> bits) const { return (*this & bits).bits_not_set(); }
|
||||
really_inline simd8<bool> any_bits_set() const { return ~this->bits_not_set(); }
|
||||
really_inline simd8<bool> any_bits_set(simd8<uint8_t> bits) const { return ~this->bits_not_set(bits); }
|
||||
really_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; }
|
||||
really_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); }
|
||||
really_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); }
|
||||
really_inline bool bits_not_set_anywhere(simd8<uint8_t> bits) const { return _mm_testz_si128(*this, bits); }
|
||||
really_inline bool any_bits_set_anywhere(simd8<uint8_t> bits) const { return !bits_not_set_anywhere(bits); }
|
||||
simdjson_really_inline simd8<bool> bits_not_set() const { return *this == uint8_t(0); }
|
||||
simdjson_really_inline simd8<bool> bits_not_set(simd8<uint8_t> bits) const { return (*this & bits).bits_not_set(); }
|
||||
simdjson_really_inline simd8<bool> any_bits_set() const { return ~this->bits_not_set(); }
|
||||
simdjson_really_inline simd8<bool> any_bits_set(simd8<uint8_t> bits) const { return ~this->bits_not_set(bits); }
|
||||
simdjson_really_inline bool is_ascii() const { return _mm_movemask_epi8(*this) == 0; }
|
||||
simdjson_really_inline bool bits_not_set_anywhere() const { return _mm_testz_si128(*this, *this); }
|
||||
simdjson_really_inline bool any_bits_set_anywhere() const { return !bits_not_set_anywhere(); }
|
||||
simdjson_really_inline bool bits_not_set_anywhere(simd8<uint8_t> bits) const { return _mm_testz_si128(*this, bits); }
|
||||
simdjson_really_inline bool any_bits_set_anywhere(simd8<uint8_t> bits) const { return !bits_not_set_anywhere(bits); }
|
||||
template<int N>
|
||||
really_inline simd8<uint8_t> shr() const { return simd8<uint8_t>(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); }
|
||||
simdjson_really_inline simd8<uint8_t> shr() const { return simd8<uint8_t>(_mm_srli_epi16(*this, N)) & uint8_t(0xFFu >> N); }
|
||||
template<int N>
|
||||
really_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); }
|
||||
simdjson_really_inline simd8<uint8_t> shl() const { return simd8<uint8_t>(_mm_slli_epi16(*this, N)) & uint8_t(0xFFu << N); }
|
||||
// Get one of the bits and make a bitmask out of it.
|
||||
// e.g. value.get_bit<7>() gets the high bit
|
||||
template<int N>
|
||||
really_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); }
|
||||
simdjson_really_inline int get_bit() const { return _mm_movemask_epi8(_mm_slli_epi16(*this, 7-N)); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -266,28 +266,28 @@ namespace simd {
|
|||
simd8x64<T>& operator=(const simd8<T> other) = delete; // no assignment allowed
|
||||
simd8x64() = delete; // no default constructor allowed
|
||||
|
||||
really_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1, const simd8<T> chunk2, const simd8<T> chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {}
|
||||
really_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+16), simd8<T>::load(ptr+32), simd8<T>::load(ptr+48)} {}
|
||||
simdjson_really_inline simd8x64(const simd8<T> chunk0, const simd8<T> chunk1, const simd8<T> chunk2, const simd8<T> chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {}
|
||||
simdjson_really_inline simd8x64(const T ptr[64]) : chunks{simd8<T>::load(ptr), simd8<T>::load(ptr+16), simd8<T>::load(ptr+32), simd8<T>::load(ptr+48)} {}
|
||||
|
||||
really_inline void store(T ptr[64]) const {
|
||||
simdjson_really_inline void store(T ptr[64]) const {
|
||||
this->chunks[0].store(ptr+sizeof(simd8<T>)*0);
|
||||
this->chunks[1].store(ptr+sizeof(simd8<T>)*1);
|
||||
this->chunks[2].store(ptr+sizeof(simd8<T>)*2);
|
||||
this->chunks[3].store(ptr+sizeof(simd8<T>)*3);
|
||||
}
|
||||
|
||||
really_inline simd8<T> reduce_or() const {
|
||||
simdjson_really_inline simd8<T> reduce_or() const {
|
||||
return (this->chunks[0] | this->chunks[1]) | (this->chunks[2] | this->chunks[3]);
|
||||
}
|
||||
|
||||
really_inline void compress(uint64_t mask, T * output) const {
|
||||
simdjson_really_inline void compress(uint64_t mask, T * output) const {
|
||||
this->chunks[0].compress(uint16_t(mask), output);
|
||||
this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF));
|
||||
this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF));
|
||||
this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF));
|
||||
}
|
||||
|
||||
really_inline uint64_t to_bitmask() const {
|
||||
simdjson_really_inline uint64_t to_bitmask() const {
|
||||
uint64_t r0 = uint32_t(this->chunks[0].to_bitmask());
|
||||
uint64_t r1 = this->chunks[1].to_bitmask();
|
||||
uint64_t r2 = this->chunks[2].to_bitmask();
|
||||
|
@ -295,7 +295,7 @@ namespace simd {
|
|||
return r0 | (r1 << 16) | (r2 << 32) | (r3 << 48);
|
||||
}
|
||||
|
||||
really_inline simd8x64<T> bit_or(const T m) const {
|
||||
simdjson_really_inline simd8x64<T> bit_or(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<T>(
|
||||
this->chunks[0] | mask,
|
||||
|
@ -305,7 +305,7 @@ namespace simd {
|
|||
);
|
||||
}
|
||||
|
||||
really_inline uint64_t eq(const T m) const {
|
||||
simdjson_really_inline uint64_t eq(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<bool>(
|
||||
this->chunks[0] == mask,
|
||||
|
@ -315,7 +315,7 @@ namespace simd {
|
|||
).to_bitmask();
|
||||
}
|
||||
|
||||
really_inline uint64_t lteq(const T m) const {
|
||||
simdjson_really_inline uint64_t lteq(const T m) const {
|
||||
const simd8<T> mask = simd8<T>::splat(m);
|
||||
return simd8x64<bool>(
|
||||
this->chunks[0] <= mask,
|
||||
|
|
|
@ -10,18 +10,18 @@ using namespace simd;
|
|||
struct backslash_and_quote {
|
||||
public:
|
||||
static constexpr uint32_t BYTES_PROCESSED = 32;
|
||||
really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
simdjson_really_inline static backslash_and_quote copy_and_find(const uint8_t *src, uint8_t *dst);
|
||||
|
||||
really_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; }
|
||||
really_inline bool has_backslash() { return bs_bits != 0; }
|
||||
really_inline int quote_index() { return trailing_zeroes(quote_bits); }
|
||||
really_inline int backslash_index() { return trailing_zeroes(bs_bits); }
|
||||
simdjson_really_inline bool has_quote_first() { return ((bs_bits - 1) & quote_bits) != 0; }
|
||||
simdjson_really_inline bool has_backslash() { return bs_bits != 0; }
|
||||
simdjson_really_inline int quote_index() { return trailing_zeroes(quote_bits); }
|
||||
simdjson_really_inline int backslash_index() { return trailing_zeroes(bs_bits); }
|
||||
|
||||
uint32_t bs_bits;
|
||||
uint32_t quote_bits;
|
||||
}; // struct backslash_and_quote
|
||||
|
||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
simdjson_really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||
// this can read up to 31 bytes beyond the buffer size, but we require
|
||||
// SIMDJSON_PADDING of padding
|
||||
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes");
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace parse_api_tests {
|
|||
simdjson::dom::document_stream stream;
|
||||
ASSERT_SUCCESS( parser.parse_many(BASIC_NDJSON).get(stream) );
|
||||
for (auto doc : stream) {
|
||||
UNUSED dom::array array;
|
||||
SIMDJSON_UNUSED dom::array array;
|
||||
ASSERT_SUCCESS( doc.get(array) );
|
||||
count++;
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ namespace parse_api_tests {
|
|||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (auto doc : parser.parse_many(BASIC_NDJSON)) {
|
||||
UNUSED dom::array array;
|
||||
SIMDJSON_UNUSED dom::array array;
|
||||
ASSERT_SUCCESS( doc.get(array) );
|
||||
count++;
|
||||
}
|
||||
|
@ -326,14 +326,14 @@ namespace parse_api_tests {
|
|||
bool parser_parse_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
UNUSED dom::array array = parser.parse(BASIC_JSON);
|
||||
SIMDJSON_UNUSED dom::array array = parser.parse(BASIC_JSON);
|
||||
return true;
|
||||
}
|
||||
bool parser_parse_many_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (UNUSED dom::array doc : parser.parse_many(BASIC_NDJSON)) {
|
||||
for (SIMDJSON_UNUSED dom::array doc : parser.parse_many(BASIC_NDJSON)) {
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL(count, 2);
|
||||
|
@ -345,7 +345,7 @@ namespace parse_api_tests {
|
|||
dom::parser parser;
|
||||
size_t count = 0;
|
||||
dom::object object = parser.load(TWITTER_JSON);
|
||||
for (UNUSED auto field : object) {
|
||||
for (SIMDJSON_UNUSED auto field : object) {
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL( count, object.size() );
|
||||
|
@ -355,7 +355,7 @@ namespace parse_api_tests {
|
|||
std::cout << "Running " << __func__ << std::endl;
|
||||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (UNUSED dom::array doc : parser.load_many(AMAZON_CELLPHONES_NDJSON)) {
|
||||
for (SIMDJSON_UNUSED dom::array doc : parser.load_many(AMAZON_CELLPHONES_NDJSON)) {
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL( count, AMAZON_CELLPHONES_NDJSON_DOC_COUNT );
|
||||
|
@ -538,7 +538,7 @@ namespace dom_api_tests {
|
|||
dom::parser parser;
|
||||
dom::object object;
|
||||
ASSERT_SUCCESS( parser.parse(json).get(object) );
|
||||
for (UNUSED auto field : object) {
|
||||
for (SIMDJSON_UNUSED auto field : object) {
|
||||
TEST_FAIL("Unexpected field");
|
||||
i++;
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ namespace dom_api_tests {
|
|||
dom::parser parser;
|
||||
dom::array array;
|
||||
ASSERT_SUCCESS( parser.parse(json).get(array) );
|
||||
for (UNUSED auto value : array) {
|
||||
for (SIMDJSON_UNUSED auto value : array) {
|
||||
TEST_FAIL("Unexpected value");
|
||||
i++;
|
||||
}
|
||||
|
@ -645,7 +645,7 @@ namespace dom_api_tests {
|
|||
ASSERT_EQUAL( object["a"].get<uint64_t>().first, 1 );
|
||||
|
||||
simdjson::error_code error;
|
||||
UNUSED element val;
|
||||
SIMDJSON_UNUSED element val;
|
||||
#ifndef _LIBCPP_VERSION // should work everywhere but with libc++, must include the <ciso646> header.
|
||||
std::tie(val,error) = object["d"];
|
||||
ASSERT_ERROR( error, NO_SUCH_FIELD );
|
||||
|
@ -681,7 +681,7 @@ namespace dom_api_tests {
|
|||
ASSERT_EQUAL( obj["b"].get<uint64_t>().first, 2 );
|
||||
ASSERT_EQUAL( obj["a"].get<uint64_t>().first, 1 );
|
||||
|
||||
UNUSED element val;
|
||||
SIMDJSON_UNUSED element val;
|
||||
ASSERT_ERROR( doc["d"].get(val), NO_SUCH_FIELD);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ bool cast_tester<T>::test_implicit_cast(simdjson_result<element> element, T expe
|
|||
template<typename T>
|
||||
bool cast_tester<T>::test_implicit_cast_error(element element, error_code expected_error) {
|
||||
try {
|
||||
UNUSED T actual;
|
||||
SIMDJSON_UNUSED T actual;
|
||||
actual = element;
|
||||
return false;
|
||||
} catch(simdjson_error &e) {
|
||||
|
@ -180,7 +180,7 @@ bool cast_tester<T>::test_implicit_cast_error(element element, error_code expect
|
|||
template<typename T>
|
||||
bool cast_tester<T>::test_implicit_cast_error(simdjson_result<element> element, error_code expected_error) {
|
||||
try {
|
||||
UNUSED T actual;
|
||||
SIMDJSON_UNUSED T actual;
|
||||
actual = element;
|
||||
return false;
|
||||
} catch(simdjson_error &e) {
|
||||
|
|
|
@ -21,11 +21,11 @@ std::string trim(const std::string s) {
|
|||
namespace document_stream_tests {
|
||||
static simdjson::dom::document_stream parse_many_stream_return(simdjson::dom::parser &parser, simdjson::padded_string &str) {
|
||||
simdjson::dom::document_stream stream;
|
||||
UNUSED auto error = parser.parse_many(str).get(stream);
|
||||
SIMDJSON_UNUSED auto error = parser.parse_many(str).get(stream);
|
||||
return stream;
|
||||
}
|
||||
// this is a compilation test
|
||||
UNUSED static void parse_many_stream_assign() {
|
||||
SIMDJSON_UNUSED static void parse_many_stream_assign() {
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::padded_string str("{}",2);
|
||||
simdjson::dom::document_stream s1 = parse_many_stream_return(parser, str);
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace document_tests {
|
|||
myStream << parser.parse(json);
|
||||
#else
|
||||
simdjson::dom::element doc;
|
||||
UNUSED auto error = parser.parse(json).get(doc);
|
||||
SIMDJSON_UNUSED auto error = parser.parse(json).get(doc);
|
||||
myStream << doc;
|
||||
#endif
|
||||
std::string newjson = myStream.str();
|
||||
|
|
|
@ -117,14 +117,14 @@ namespace parser_load {
|
|||
bool parser_load_chain() {
|
||||
TEST_START();
|
||||
dom::parser parser;
|
||||
UNUSED uint64_t foo;
|
||||
SIMDJSON_UNUSED uint64_t foo;
|
||||
ASSERT_ERROR( parser.load(NONEXISTENT_FILE)["foo"].get(foo), IO_ERROR);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool parser_load_many_chain() {
|
||||
TEST_START();
|
||||
dom::parser parser;
|
||||
UNUSED dom::document_stream stream;
|
||||
SIMDJSON_UNUSED dom::document_stream stream;
|
||||
ASSERT_ERROR( parser.load_many(NONEXISTENT_FILE).get(stream), IO_ERROR );
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
|
|
@ -19,19 +19,19 @@ const char *TRUENULL_JSON = SIMDJSON_BENCHMARK_SMALLDATA_DIR "truenull.json";
|
|||
|
||||
// For the ASSERT_EQUAL macro
|
||||
template<typename T, typename S>
|
||||
really_inline bool equals_expected(T actual, S expected) {
|
||||
simdjson_really_inline bool equals_expected(T actual, S expected) {
|
||||
return actual == T(expected);
|
||||
}
|
||||
template<>
|
||||
really_inline bool equals_expected<const char *, const char *>(const char *actual, const char *expected) {
|
||||
simdjson_really_inline bool equals_expected<const char *, const char *>(const char *actual, const char *expected) {
|
||||
return !strcmp(actual, expected);
|
||||
}
|
||||
|
||||
really_inline simdjson::error_code to_error_code(simdjson::error_code error) {
|
||||
simdjson_really_inline simdjson::error_code to_error_code(simdjson::error_code error) {
|
||||
return error;
|
||||
}
|
||||
template<typename T>
|
||||
really_inline simdjson::error_code to_error_code(const simdjson::simdjson_result<T> &result) {
|
||||
simdjson_really_inline simdjson::error_code to_error_code(const simdjson::simdjson_result<T> &result) {
|
||||
return result.error();
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ std::vector<uint8_t> RandomUTF8::generate(size_t output_bytes, long seed) {
|
|||
}
|
||||
|
||||
// credit: based on code from Google Fuchsia (Apache Licensed)
|
||||
WARN_UNUSED bool basic_validate_utf8(const char *buf, size_t len) noexcept {
|
||||
SIMDJSON_WARN_UNUSED bool basic_validate_utf8(const char *buf, size_t len) noexcept {
|
||||
const uint8_t *data = (const uint8_t *)buf;
|
||||
uint64_t pos = 0;
|
||||
uint64_t next_pos = 0;
|
||||
|
|
Loading…
Reference in New Issue