From 03c828c7ad80219fa692066b151aa285cefaf959 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 13 Mar 2020 10:38:23 -0700 Subject: [PATCH] Add SIMDJSON_EXCEPTIONS=ON to turn on exception interface --- CMakeLists.txt | 11 ++++------- include/simdjson/common_defs.h | 8 ++++++++ include/simdjson/document.h | 19 +++++++++++++++++++ include/simdjson/inline/document.h | 30 ++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eefe0a7..de0d1980 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,17 +18,12 @@ project(simdjson # set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) #endif() -# usage: cmake -DSIMDJSON_DISABLE_AVX=on .. -option(SIMDJSON_DISABLE_AVX "Forcefully disable AVX even if hardware supports it" OFF) - set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_MACOSX_RPATH OFF) set(CMAKE_THREAD_PREFER_PTHREAD ON) set(THREADS_PREFER_PTHREAD_FLAG ON) - - set(SIMDJSON_LIB_NAME simdjson) set(PROJECT_VERSION_MAJOR 0) set(PROJECT_VERSION_MINOR 2) @@ -36,19 +31,22 @@ set(PROJECT_VERSION_PATCH 1) set(SIMDJSON_LIB_VERSION "0.2.1" CACHE STRING "simdjson library version") set(SIMDJSON_LIB_SOVERSION "0" CACHE STRING "simdjson library soversion") +option(SIMDJSON_DISABLE_AVX "Forcefully disable AVX even if hardware supports it" OFF) if(NOT MSVC) option(SIMDJSON_BUILD_STATIC "Build a static library" OFF) # turning it on disables the production of a dynamic library else() option(SIMDJSON_BUILD_STATIC "Build a static library" ON) # turning it on disables the production of a dynamic library endif() option(SIMDJSON_SANITIZE "Sanitize addresses" OFF) +option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" OFF) +option(SIMDJSON_ENABLE_THREADS "enable threaded operation" ON) +option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake") find_package(CTargets) find_package(Options) -option(SIMDJSON_ENABLE_THREADS "enable threaded operation" ON) install(DIRECTORY include/${SIMDJSON_LIB_NAME} DESTINATION include) set (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jsonchecker/") set (BENCHMARK_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/") @@ -61,7 +59,6 @@ add_subdirectory(tools) add_subdirectory(tests) add_subdirectory(benchmark) -option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" OFF) if (SIMDJSON_GOOGLE_BENCHMARKS) if(NOT EXISTS dependencies/benchmark/CMakeLists.txt) # message(STATUS "Unable to find dependencies/benchmark/CMakeLists.txt") diff --git a/include/simdjson/common_defs.h b/include/simdjson/common_defs.h index d16af75a..8ae5fdd2 100644 --- a/include/simdjson/common_defs.h +++ b/include/simdjson/common_defs.h @@ -6,6 +6,14 @@ namespace simdjson { +#ifndef SIMDJSON_EXCEPTIONS +#ifdef __cpp_exceptions +#define SIMDJSON_EXCEPTIONS 1 +#else +#define SIMDJSON_EXCEPTIONS 0 +#endif +#endif + /** The maximum document size supported by simdjson. */ constexpr size_t SIMDJSON_MAXSIZE_BYTES = 0xFFFFFFFF; diff --git a/include/simdjson/document.h b/include/simdjson/document.h index 52accebe..e439ac5e 100644 --- a/include/simdjson/document.h +++ b/include/simdjson/document.h @@ -84,6 +84,8 @@ public: * Get the root element of this document. */ operator element() const noexcept; + +#if SIMDJSON_EXCEPTIONS /** * Read the root element of this document as a JSON array. * @@ -98,6 +100,7 @@ public: * @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an object */ operator object() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS /** * Get the value associated with the given key. @@ -253,6 +256,7 @@ public: */ error_code error; +#if SIMDJSON_EXCEPTIONS /** * Return the document, or throw an exception if it is invalid. * @@ -260,6 +264,7 @@ public: * @exception simdjson_error if the document is invalid or there was an error parsing it. */ operator document() noexcept(false); +#endif // SIMDJSON_EXCEPTIONS /** * Get the value associated with the given key. @@ -339,6 +344,7 @@ public: */ error_code error; +#if SIMDJSON_EXCEPTIONS /** * A reference to the document, or throw an exception if it is invalid. * @@ -346,6 +352,7 @@ public: * @exception simdjson_error if the document is invalid or there was an error parsing it. */ operator document&() noexcept(false); +#endif // SIMDJSON_EXCEPTIONS /** * Get the value associated with the given key. @@ -521,6 +528,7 @@ public: */ inline element_result as_object() const noexcept; +#if SIMDJSON_EXCEPTIONS /** * Read this element as a boolean. * @@ -589,6 +597,7 @@ public: * @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an object */ inline operator document::object() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS /** * Get the value associated with the given key. @@ -806,7 +815,9 @@ public: /** The error code (or 0 if there is no error) */ error_code error; +#if SIMDJSON_EXCEPTIONS inline operator T() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS private: really_inline element_result(T value) noexcept; @@ -835,6 +846,7 @@ public: inline element_result as_array() const noexcept; inline element_result as_object() const noexcept; +#if SIMDJSON_EXCEPTIONS inline operator element() const noexcept(false); inline operator bool() const noexcept(false); inline explicit operator const char*() const noexcept(false); @@ -844,6 +856,7 @@ public: inline operator double() const noexcept(false); inline operator array() const noexcept(false); inline operator object() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS inline element_result operator[](const std::string_view &s) const noexcept; inline element_result operator[](const char *s) const noexcept; @@ -864,10 +877,12 @@ public: /** The error code (or 0 if there is no error) */ error_code error; +#if SIMDJSON_EXCEPTIONS inline operator array() const noexcept(false); inline array::iterator begin() const noexcept(false); inline array::iterator end() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS private: really_inline element_result(array value) noexcept; @@ -885,10 +900,12 @@ public: /** The error code (or 0 if there is no error) */ error_code error; +#if SIMDJSON_EXCEPTIONS inline operator object() const noexcept(false); inline object::iterator begin() const noexcept(false); inline object::iterator end() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS inline element_result operator[](const std::string_view &s) const noexcept; inline element_result operator[](const char *s) const noexcept; @@ -1593,8 +1610,10 @@ private: // and auto-allocate if not. inline error_code ensure_capacity(size_t desired_capacity) noexcept; +#if SIMDJSON_EXCEPTIONS // Used internally to get the document inline const document &get_document() const noexcept(false); +#endif // SIMDJSON_EXCEPTIONS template friend class document_iterator; friend class document::stream; diff --git a/include/simdjson/inline/document.h b/include/simdjson/inline/document.h index 6cf94991..518fbab8 100644 --- a/include/simdjson/inline/document.h +++ b/include/simdjson/inline/document.h @@ -19,6 +19,9 @@ template inline document::element_result::element_result(T _value) noexcept : value(_value), error{SUCCESS} {} template inline document::element_result::element_result(error_code _error) noexcept : value(), error{_error} {} + +#if SIMDJSON_EXCEPTIONS + template<> inline document::element_result::operator std::string_view() const noexcept(false) { if (error) { throw simdjson_error(error); } @@ -50,11 +53,16 @@ inline document::element_result::operator double() const noexcept(false) return value; } +#endif // SIMDJSON_EXCEPTIONS + // // document::element_result inline implementation // inline document::element_result::element_result(document::array _value) noexcept : value(_value), error{SUCCESS} {} inline document::element_result::element_result(error_code _error) noexcept : value(), error{_error} {} + +#if SIMDJSON_EXCEPTIONS + inline document::element_result::operator document::array() const noexcept(false) { if (error) { throw simdjson_error(error); } return value; @@ -68,11 +76,16 @@ inline document::array::iterator document::element_result::end( return value.end(); } +#endif // SIMDJSON_EXCEPTIONS + // // document::element_result inline implementation // inline document::element_result::element_result(document::object _value) noexcept : value(_value), error{SUCCESS} {} inline document::element_result::element_result(error_code _error) noexcept : value(), error{_error} {} + +#if SIMDJSON_EXCEPTIONS + inline document::element_result::operator document::object() const noexcept(false) { if (error) { throw simdjson_error(error); } return value; @@ -94,6 +107,8 @@ inline document::object::iterator document::element_result::en return value.end(); } +#endif // SIMDJSON_EXCEPTIONS + // // document::element_result inline implementation // @@ -341,6 +356,9 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept { // document::doc_ref_result inline implementation // inline document::doc_ref_result::doc_ref_result(document &_doc, error_code _error) noexcept : doc(_doc), error(_error) { } + +#if SIMDJSON_EXCEPTIONS + inline document::doc_ref_result::operator document&() noexcept(false) { if (error) { throw simdjson_error(error); } return doc; @@ -354,12 +372,17 @@ inline document::element_result document::doc_ref_result::ope return doc[key]; } +#endif // SIMDJSON_EXCEPTIONS + // // document::doc_result inline implementation // inline document::doc_result::doc_result(document &&_doc, error_code _error) noexcept : doc(std::move(_doc)), error(_error) { } inline document::doc_result::doc_result(document &&_doc) noexcept : doc(std::move(_doc)), error(SUCCESS) { } inline document::doc_result::doc_result(error_code _error) noexcept : doc(), error(_error) { } + +#if SIMDJSON_EXCEPTIONS + inline document::doc_result::operator document() noexcept(false) { if (error) { throw simdjson_error(error); } return std::move(doc); @@ -373,6 +396,8 @@ inline document::element_result document::doc_result::operato return doc[key]; } +#endif // SIMDJSON_EXCEPTIONS + // // document::parser inline implementation // @@ -391,6 +416,9 @@ inline bool document::parser::print_json(std::ostream &os) const noexcept { inline bool document::parser::dump_raw_tape(std::ostream &os) const noexcept { return is_valid() ? doc.dump_raw_tape(os) : false; } + +#if SIMDJSON_EXCEPTIONS + inline const document &document::parser::get_document() const noexcept(false) { if (!is_valid()) { throw simdjson_error(error); @@ -398,6 +426,8 @@ inline const document &document::parser::get_document() const noexcept(false) { return doc; } +#endif // SIMDJSON_EXCEPTIONS + inline document::doc_ref_result document::parser::load(const std::string &path) noexcept { auto [json, _error] = padded_string::load(path); if (_error) { return doc_ref_result(doc, _error); }