Support C++ 14

This commit is contained in:
John Keiser 2020-04-05 12:00:43 -07:00
parent 74d9b41b7d
commit 406240bae3
18 changed files with 1713 additions and 108 deletions

5
.gitignore vendored
View File

@ -71,6 +71,9 @@ objs
/distinctuseridcompetition
/errortests
/examples/quickstart/quickstart
/examples/quickstart/quickstart11
/examples/quickstart/quickstart14
/examples/quickstart/quickstart17
/examples/quickstart/simdjson.cpp
/examples/quickstart/simdjson.h
/examples/quickstart/twitter.json
@ -104,6 +107,7 @@ objs
/pointercheck
/readme_examples
/readme_examples_noexceptions
/staticchecks
/statisticalmodel
/stringparsingcheck
/submodules
@ -121,6 +125,7 @@ objs
/tests/parse_many_test
/tests/readme_examples
/tests/readme_examples_noexceptions
/tests/staticchecks
/tools/json2json
/tools/jsonstats
/tools/minify

View File

@ -58,10 +58,10 @@ SRCHEADERS_ARM64= src/arm64/bitmanipulation.h src/arm64/bitmask.h src
SRCHEADERS_HASWELL= src/haswell/bitmanipulation.h src/haswell/bitmask.h src/haswell/intrinsics.h src/haswell/numberparsing.h src/haswell/simd.h src/haswell/stage1_find_marks.h src/haswell/stage2_build_tape.h src/haswell/stringparsing.h
SRCHEADERS_FALLBACK= src/fallback/bitmanipulation.h src/fallback/implementation.h src/fallback/numberparsing.h src/fallback/stage1_find_marks.h src/fallback/stage2_build_tape.h src/fallback/stringparsing.h
SRCHEADERS_WESTMERE=src/westmere/bitmanipulation.h src/westmere/bitmask.h src/westmere/intrinsics.h src/westmere/numberparsing.h src/westmere/simd.h src/westmere/stage1_find_marks.h src/westmere/stage2_build_tape.h src/westmere/stringparsing.h
SRCHEADERS_SRC=src/isadetection.h src/jsoncharutils.h src/simdprune_tables.h src/implementation.cpp src/stage1_find_marks.cpp src/stage2_build_tape.cpp src/document_parser_callbacks.h
SRCHEADERS_SRC=src/isadetection.h src/jsoncharutils.h src/simdprune_tables.h src/error.cpp src/implementation.cpp src/stage1_find_marks.cpp src/stage2_build_tape.cpp src/document_parser_callbacks.h
SRCHEADERS=$(SRCHEADERS_SRC) $(SRCHEADERS_GENERIC) $(SRCHEADERS_ARM64) $(SRCHEADERS_HASWELL) $(SRCHEADERS_WESTMERE) $(SRCHEADERS_FALLBACK)
INCLUDEHEADERS=include/simdjson.h include/simdjson/common_defs.h include/simdjson/internal/jsonformatutils.h include/simdjson/jsonioutil.h include/simdjson/jsonparser.h include/simdjson/padded_string.h include/simdjson/inline/padded_string.h include/simdjson/document.h include/simdjson/inline/document.h include/simdjson/parsedjson_iterator.h include/simdjson/inline/parsedjson_iterator.h include/simdjson/document_stream.h include/simdjson/inline/document_stream.h include/simdjson/implementation.h include/simdjson/parsedjson.h include/simdjson/portability.h include/simdjson/error.h include/simdjson/inline/error.h include/simdjson/simdjson.h include/simdjson/simdjson_version.h
INCLUDEHEADERS=include/simdjson.h include/simdjson/common_defs.h include/simdjson/internal/jsonformatutils.h include/simdjson/jsonioutil.h include/simdjson/jsonparser.h include/simdjson/padded_string.h include/simdjson/inline/padded_string.h include/simdjson/document.h include/simdjson/inline/document.h include/simdjson/parsedjson_iterator.h include/simdjson/inline/parsedjson_iterator.h include/simdjson/document_stream.h include/simdjson/inline/document_stream.h include/simdjson/implementation.h include/simdjson/parsedjson.h include/simdjson/portability.h include/simdjson/error.h include/simdjson/inline/error.h include/simdjson/nonstd/string_view.hpp include/simdjson/simdjson_version.h
ifeq ($(SIMDJSON_TEST_AMALGAMATED_HEADERS),1)
HEADERS=singleheader/simdjson.h
@ -117,6 +117,9 @@ run_numberparsingcheck: numberparsingcheck
run_integer_tests: integer_tests
./integer_tests
run_staticchecks: staticchecks
./staticchecks
run_stringparsingcheck: stringparsingcheck
./stringparsingcheck
@ -138,12 +141,24 @@ run_pointercheck: pointercheck
run_issue150_sh: allparserscheckfile
./scripts/issue150.sh
quickstart:
quickstart: singleheader/simdjson.h singleheader/simdjson.cpp
cd examples/quickstart && make quickstart
run_quickstart:
cd examples/quickstart && make test
quickstart11:
cd examples/quickstart && make quickstart11
run_quickstart11:
cd examples/quickstart && make test11
quickstart14:
cd examples/quickstart && make quickstart14
run_quickstart14:
cd examples/quickstart && make test14
run_testjson2json_sh: minify json2json
./scripts/testjson2json.sh
@ -158,7 +173,7 @@ test: quicktests slowtests
quiettest: quicktests slowtests
quicktests: run_basictests run_quickstart readme_examples readme_examples_noexceptions run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_parse_many_test run_pointercheck run_jsoncheck_westmere run_jsoncheck_fallback
quicktests: run_basictests run_quickstart readme_examples readme_examples_noexceptions run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_parse_many_test run_pointercheck run_jsoncheck_westmere run_jsoncheck_fallback run_quickstart14
slowtests: run_testjson2json_sh run_issue150_sh
@ -209,23 +224,23 @@ parse_nostringparsing: benchmark/parse.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o parse_nostringparsing -DSIMDJSON_SKIPSTRINGPARSING benchmark/parse.cpp $(LIBFILES) $(LIBFLAGS)
jsoncheck:tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
jsoncheck: tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o jsoncheck tests/jsoncheck.cpp -I. $(LIBFILES) $(LIBFLAGS)
parse_many_test:tests/parse_many_test.cpp $(HEADERS) $(LIBFILES)
parse_many_test: tests/parse_many_test.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o parse_many_test tests/parse_many_test.cpp -I. $(LIBFILES) $(LIBFLAGS)
jsoncheck_westmere:tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
jsoncheck_westmere: tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o jsoncheck_westmere tests/jsoncheck.cpp -I. $(LIBFILES) $(LIBFLAGS) -DSIMDJSON_IMPLEMENTATION_HASWELL=0
jsoncheck_fallback:tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
jsoncheck_fallback: tests/jsoncheck.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o jsoncheck_fallback tests/jsoncheck.cpp -I. $(LIBFILES) $(LIBFLAGS) -DSIMDJSON_IMPLEMENTATION_HASWELL=0 -DSIMDJSON_IMPLEMENTATION_WESTMERE=0 -DSIMDJSON_IMPLEMENTATION_ARM64=0
basictests:tests/basictests.cpp $(HEADERS) $(LIBFILES)
basictests: tests/basictests.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o basictests tests/basictests.cpp -I. $(LIBFILES) $(LIBFLAGS)
errortests:tests/errortests.cpp $(HEADERS) $(LIBFILES)
errortests: tests/errortests.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o errortests tests/errortests.cpp -I. $(LIBFILES) $(LIBFLAGS)
readme_examples: tests/readme_examples.cpp $(HEADERS) $(LIBFILES)
@ -234,6 +249,9 @@ readme_examples: tests/readme_examples.cpp $(HEADERS) $(LIBFILES)
readme_examples_noexceptions: tests/readme_examples_noexceptions.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o readme_examples_noexceptions tests/readme_examples_noexceptions.cpp -I. $(LIBFILES) $(LIBFLAGS) -fno-exceptions
staticchecks: tests/staticchecks.cpp $(HEADERS) src/simdjson.cpp
$(CXX) $(CXXFLAGS) -o staticchecks tests/staticchecks.cpp -I. $(LIBFLAGS)
numberparsingcheck: tests/numberparsingcheck.cpp $(HEADERS) src/simdjson.cpp
$(CXX) $(CXXFLAGS) -o numberparsingcheck tests/numberparsingcheck.cpp -I. $(LIBFLAGS) -DJSON_TEST_NUMBERS

View File

@ -4,13 +4,29 @@ JSONEXAMPLES=$(ROOT)/jsonexamples
test: quickstart twitter.json
./quickstart
quickstart: quickstart.cpp simdjson.cpp simdjson.h
c++ -o ./quickstart quickstart.cpp simdjson.cpp -std=c++17
clean:
rm -f simdjson.cpp simdjson.h twitter.json quickstart
simdjson.cpp: $(SINGLEHEADER)/simdjson.cpp
cp $(SINGLEHEADER)/simdjson.cpp .
simdjson.h: $(SINGLEHEADER)/simdjson.h
cp $(SINGLEHEADER)/simdjson.h .
twitter.json: $(JSONEXAMPLES)/twitter.json
cp $(JSONEXAMPLES)/twitter.json .
quickstart: quickstart.cpp simdjson.cpp simdjson.h
c++ -o ./quickstart quickstart.cpp simdjson.cpp -std=c++17
clean:
rm -f simdjson.cpp simdjson.h twitter.json quickstart
quickstart11: $(ROOT)/src/**.h $(ROOT)/src/**.cpp $(ROOT)/include/**.h $(ROOT)/src/**.cpp
rm -f simdjson.h simdjson.cpp
c++ -o ./quickstart11 quickstart.cpp $(ROOT)/src/simdjson.cpp -I$(ROOT)/src -I$(ROOT)/include -std=c++11
test11: quickstart11 twitter.json
./quickstart11
quickstart14: $(ROOT)/src/**.h $(ROOT)/src/**.cpp $(ROOT)/include/**.h $(ROOT)/src/**.cpp
rm -f simdjson.h simdjson.cpp
c++ -o ./quickstart14 quickstart.cpp $(ROOT)/src/simdjson.cpp -I$(ROOT)/src -I$(ROOT)/include -std=c++14
test14: quickstart14 twitter.json
./quickstart14
quickstart17: $(ROOT)/src/**.h $(ROOT)/src/**.cpp $(ROOT)/include/**.h $(ROOT)/src/**.cpp
rm -f simdjson.h simdjson.cpp
c++ -o ./quickstart17 quickstart.cpp $(ROOT)/src/simdjson.cpp -I$(ROOT)/src -I$(ROOT)/include -std=c++17
test17: quickstart17 twitter.json
./quickstart17

View File

@ -15,6 +15,7 @@ set(SIMDJSON_INCLUDE
${SIMDJSON_INCLUDE_DIR}/simdjson/internal/jsonformatutils.h
${SIMDJSON_INCLUDE_DIR}/simdjson/jsonioutil.h
${SIMDJSON_INCLUDE_DIR}/simdjson/jsonparser.h
${SIMDJSON_INCLUDE_DIR}/simdjson/nonstd/string_view.hpp
${SIMDJSON_INCLUDE_DIR}/simdjson/padded_string.h
${SIMDJSON_INCLUDE_DIR}/simdjson/parsedjson.h
${SIMDJSON_INCLUDE_DIR}/simdjson/parsedjson_iterator.h

View File

@ -13,8 +13,16 @@
#endif
#endif
#if (SIMDJSON_CPLUSPLUS < 201703L)
#error simdjson requires a compiler compliant with the C++17 standard
// Backfill std::string_view using nonstd::string_view on C++11
#ifndef SIMDJSON_INCLUDE_NONSTD_STRING_VIEW
#define SIMDJSON_INCLUDE_NONSTD_STRING_VIEW 1
#endif // SIMDJSON_INCLUDE_NONSTD_STRING_VIEW
#if (SIMDJSON_CPLUSPLUS < 201703L and SIMDJSON_INCLUDE_NONSTD_STRING_VIEW)
// #error simdjson requires a compiler compliant with the C++17 standard
#include "nonstd/string_view.hpp"
namespace std {
using string_view=nonstd::string_view;
}
#endif
#endif // SIMDJSON_COMPILER_CHECK_H

View File

@ -1107,7 +1107,7 @@ namespace dom {
* @param value The value to print.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, const element &value) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const element &value) { return out << minify<element>(value); }
/**
* Print JSON to an output stream.
*
@ -1117,7 +1117,7 @@ inline std::ostream& operator<<(std::ostream& out, const element &value) { retur
* @param value The value to print.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, const array &value) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const array &value) { return out << minify<array>(value); }
/**
* Print JSON to an output stream.
*
@ -1127,7 +1127,7 @@ inline std::ostream& operator<<(std::ostream& out, const array &value) { return
* @param value The value to print.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, const object &value) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const object &value) { return out << minify<object>(value); }
/**
* Print JSON to an output stream.
*
@ -1137,7 +1137,7 @@ inline std::ostream& operator<<(std::ostream& out, const object &value) { return
* @param value The value to print.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, const key_value_pair &value) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const key_value_pair &value) { return out << minify<key_value_pair>(value); }
/**
* Print element type to an output stream.
@ -1184,7 +1184,7 @@ inline std::ostream& operator<<(std::ostream& out, element_type type) {
* underlying output stream, that error will be propagated (simdjson_error will not be
* thrown).
*/
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false) { return out << minify<simdjson_result<dom::element>>(value); }
/**
* Print JSON to an output stream.
*
@ -1196,7 +1196,7 @@ inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::el
* underlying output stream, that error will be propagated (simdjson_error will not be
* thrown).
*/
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::array> &value) noexcept(false) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::array> &value) noexcept(false) { return out << minify<simdjson_result<dom::array>>(value); }
/**
* Print JSON to an output stream.
*
@ -1208,7 +1208,7 @@ inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::ar
* underlying output stream, that error will be propagated (simdjson_error will not be
* thrown).
*/
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::object> &value) noexcept(false) { return out << minify(value); }
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::object> &value) noexcept(false) { return out << minify<simdjson_result<dom::object>>(value); }
#endif

View File

@ -14,6 +14,8 @@ namespace simdjson::dom {
*/
class document_stream {
public:
/** Move one document_stream to another. */
really_inline document_stream(document_stream && other) noexcept = default;
really_inline ~document_stream() noexcept;
/**

View File

@ -200,37 +200,6 @@ public:
const implementation *detect_best_supported() const noexcept;
};
/**
* @private Detects best supported implementation on first use, and sets it
*/
class detect_best_supported_implementation_on_first_use final : public implementation {
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 parse(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept final {
return set_best()->parse(buf, len, parser);
}
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 error_code stage1(const uint8_t *buf, size_t len, dom::parser &parser, bool streaming) const noexcept final {
return set_best()->stage1(buf, len, parser, streaming);
}
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept final {
return set_best()->stage2(buf, len, parser);
}
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser, size_t &next_json) const noexcept final {
return set_best()->stage2(buf, len, parser, next_json);
}
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;
};
inline const detect_best_supported_implementation_on_first_use detect_best_supported_implementation_on_first_use_singleton;
template<typename T>
class atomic_ptr {
public:
@ -254,16 +223,14 @@ private:
/**
* The list of available implementations compiled into simdjson.
*/
inline const internal::available_implementation_list available_implementations;
extern const internal::available_implementation_list available_implementations;
/**
* The active implementation.
*
* Automatically initialized on first use to the most advanced implementation supported by this hardware.
*
* @hideinitializer
*/
inline internal::atomic_ptr<const implementation> active_implementation = &internal::detect_best_supported_implementation_on_first_use_singleton;
extern internal::atomic_ptr<const implementation> active_implementation;
} // namespace simdjson

View File

@ -367,14 +367,18 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
}
inline simdjson_result<element> parser::load(const std::string &path) noexcept {
auto [len, code] = read_file(path);
size_t len;
error_code code;
read_file(path).tie(len, code);
if (code) { return code; }
return parse(loaded_bytes.get(), len, false);
}
inline document_stream parser::load_many(const std::string &path, size_t batch_size) noexcept {
auto [len, code] = read_file(path);
size_t len;
error_code code;
read_file(path).tie(len, code);
return document_stream(*this, (const uint8_t*)loaded_bytes.get(), len, batch_size, code);
}

View File

@ -11,33 +11,7 @@ namespace simdjson::internal {
std::string message;
};
// These MUST match the codes in error_code. We check this constraint in basictests.
inline const error_code_info error_codes[] {
{ SUCCESS, "No error" },
{ SUCCESS_AND_HAS_MORE, "No error and buffer still has more data" },
{ CAPACITY, "This parser can't support a document that big" },
{ MEMALLOC, "Error allocating memory, we're most likely out of memory" },
{ TAPE_ERROR, "Something went wrong while writing to the tape" },
{ DEPTH_ERROR, "The JSON document was too deep (too many nested objects and arrays)" },
{ STRING_ERROR, "Problem while parsing a string" },
{ T_ATOM_ERROR, "Problem while parsing an atom starting with the letter 't'" },
{ F_ATOM_ERROR, "Problem while parsing an atom starting with the letter 'f'" },
{ N_ATOM_ERROR, "Problem while parsing an atom starting with the letter 'n'" },
{ NUMBER_ERROR, "Problem while parsing a number" },
{ UTF8_ERROR, "The input is not valid UTF-8" },
{ UNINITIALIZED, "Uninitialized" },
{ EMPTY, "Empty: no JSON found" },
{ UNESCAPED_CHARS, "Within strings, some characters must be escaped, we found unescaped characters" },
{ UNCLOSED_STRING, "A string is opened, but never closed." },
{ UNSUPPORTED_ARCHITECTURE, "simdjson does not have an implementation supported by this CPU architecture (perhaps it's a non-SIMD CPU?)." },
{ INCORRECT_TYPE, "The JSON element does not have the requested type." },
{ NUMBER_OUT_OF_RANGE, "The JSON number is too large or too small to fit within the requested type." },
{ INDEX_OUT_OF_BOUNDS, "Attempted to access an element of a JSON array that is beyond its length." },
{ NO_SUCH_FIELD, "The JSON field referenced does not exist in this object." },
{ IO_ERROR, "Error reading the file." },
{ INVALID_JSON_POINTER, "Invalid JSON pointer syntax." },
{ INVALID_URI_FRAGMENT, "Invalid URI fragment syntax." },
{ UNEXPECTED_ERROR, "Unexpected error, consider reporting this problem as you may have found a bug in simdjson" }
}; // error_messages[]
extern const error_code_info error_codes[];
} // namespace simdjson::internal
namespace simdjson {

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@ set(SIMDJSON_SRC
# Load headers and sources
set(SIMDJSON_SRC_HEADERS
error.cpp
implementation.cpp
isadetection.h
simdprune_tables.h

View File

@ -54,7 +54,7 @@ really_inline json_character_block json_character_block::classify(const simd::si
}
really_inline bool is_ascii(simd8x64<uint8_t> input) {
simd8<uint8_t> bits = input.reduce([&](auto a,auto b) { return a|b; });
simd8<uint8_t> bits = input.reduce([&](simd8<uint8_t> a,simd8<uint8_t> b) { return a|b; });
return bits.max() < 0b10000000u;
}

31
src/error.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "simdjson/error.h"
namespace simdjson::internal {
const error_code_info error_codes[] {
{ SUCCESS, "No error" },
{ SUCCESS_AND_HAS_MORE, "No error and buffer still has more data" },
{ CAPACITY, "This parser can't support a document that big" },
{ MEMALLOC, "Error allocating memory, we're most likely out of memory" },
{ TAPE_ERROR, "Something went wrong while writing to the tape" },
{ DEPTH_ERROR, "The JSON document was too deep (too many nested objects and arrays)" },
{ STRING_ERROR, "Problem while parsing a string" },
{ T_ATOM_ERROR, "Problem while parsing an atom starting with the letter 't'" },
{ F_ATOM_ERROR, "Problem while parsing an atom starting with the letter 'f'" },
{ N_ATOM_ERROR, "Problem while parsing an atom starting with the letter 'n'" },
{ NUMBER_ERROR, "Problem while parsing a number" },
{ UTF8_ERROR, "The input is not valid UTF-8" },
{ UNINITIALIZED, "Uninitialized" },
{ EMPTY, "Empty: no JSON found" },
{ UNESCAPED_CHARS, "Within strings, some characters must be escaped, we found unescaped characters" },
{ UNCLOSED_STRING, "A string is opened, but never closed." },
{ UNSUPPORTED_ARCHITECTURE, "simdjson does not have an implementation supported by this CPU architecture (perhaps it's a non-SIMD CPU?)." },
{ INCORRECT_TYPE, "The JSON element does not have the requested type." },
{ NUMBER_OUT_OF_RANGE, "The JSON number is too large or too small to fit within the requested type." },
{ INDEX_OUT_OF_BOUNDS, "Attempted to access an element of a JSON array that is beyond its length." },
{ NO_SUCH_FIELD, "The JSON field referenced does not exist in this object." },
{ IO_ERROR, "Error reading the file." },
{ INVALID_JSON_POINTER, "Invalid JSON pointer syntax." },
{ INVALID_URI_FRAGMENT, "Invalid URI fragment syntax." },
{ UNEXPECTED_ERROR, "Unexpected error, consider reporting this problem as you may have found a bug in simdjson" }
}; // error_messages[]
}

View File

@ -29,6 +29,39 @@ namespace simdjson::internal { const fallback::implementation fallback_singleton
namespace simdjson::internal {
/**
* @private Detects best supported implementation on first use, and sets it
*/
class detect_best_supported_implementation_on_first_use final : public implementation {
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 parse(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept final {
return set_best()->parse(buf, len, parser);
}
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 error_code stage1(const uint8_t *buf, size_t len, dom::parser &parser, bool streaming) const noexcept final {
return set_best()->stage1(buf, len, parser, streaming);
}
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept final {
return set_best()->stage2(buf, len, parser);
}
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser, size_t &next_json) const noexcept final {
return set_best()->stage2(buf, len, parser, next_json);
}
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;
};
const detect_best_supported_implementation_on_first_use detect_best_supported_implementation_on_first_use_singleton;
internal::atomic_ptr<const implementation> active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton};
constexpr const std::initializer_list<const implementation *> available_implementation_pointers {
#if SIMDJSON_IMPLEMENTATION_HASWELL
&haswell_singleton,
@ -92,3 +125,8 @@ const implementation *detect_best_supported_implementation_on_first_use::set_bes
}
} // namespace simdjson::internal
namespace simdjson {
const internal::available_implementation_list available_implementations{};
internal::atomic_ptr<const implementation> active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton};
}

View File

@ -1,4 +1,5 @@
#include "simdjson.h"
#include "error.cpp"
#include "implementation.cpp"
#include "stage1_find_marks.cpp"
#include "stage2_build_tape.cpp"

View File

@ -1824,24 +1824,6 @@ namespace format_tests {
}
}
bool error_messages_in_correct_order() {
std::cout << "Running " << __func__ << std::endl;
using namespace simdjson;
using namespace simdjson::internal;
using namespace std;
if ((sizeof(error_codes)/sizeof(error_code_info)) != NUM_ERROR_CODES) {
cerr << "error_codes does not have all codes in error_code enum (or too many)" << endl;
return false;
}
for (int i=0; i<NUM_ERROR_CODES; i++) {
if (error_codes[i].code != i) {
cerr << "Error " << int(error_codes[i].code) << " at wrong position (" << i << "): " << error_codes[i].message << endl;
return false;
}
}
return true;
}
int main(int argc, char *argv[]) {
std::cout << std::unitbuf;
#ifndef _MSC_VER
@ -1878,8 +1860,7 @@ int main(int argc, char *argv[]) {
format_tests::run() &&
document_tests::run() &&
number_tests::run() &&
document_stream_tests::run() &&
error_messages_in_correct_order()
document_stream_tests::run()
) {
std::cout << "Basic tests are ok." << std::endl;
return EXIT_SUCCESS;

29
tests/staticchecks.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "simdjson.h"
#include "simdjson.cpp"
bool error_messages_in_correct_order() {
std::cout << "Running " << __func__ << std::endl;
using namespace simdjson;
using namespace simdjson::internal;
using namespace std;
if ((sizeof(error_codes)/sizeof(error_code_info)) != NUM_ERROR_CODES) {
cerr << "error_codes does not have all codes in error_code enum (or too many)" << endl;
return false;
}
for (int i=0; i<NUM_ERROR_CODES; i++) {
if (error_codes[i].code != i) {
cerr << "Error " << int(error_codes[i].code) << " at wrong position (" << i << "): " << error_codes[i].message << endl;
return false;
}
}
return true;
}
int main(void) {
if (error_messages_in_correct_order()) {
std::cout << "All static checks successful." << std::endl;
return 0;
}
std::cerr << "Failed static checks." << std::endl;
return 1;
}