diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f8dcd3d3..1e25a3da3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,8 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) set(SIMDJSON_LIB_NAME simdjson) set(PROJECT_VERSION_MAJOR 0) set(PROJECT_VERSION_MINOR 3) -set(PROJECT_VERSION_PATCH 0) -set(SIMDJSON_LIB_VERSION "0.3.0" CACHE STRING "simdjson library version") +set(PROJECT_VERSION_PATCH 1) +set(SIMDJSON_LIB_VERSION "0.3.1" CACHE STRING "simdjson library version") set(SIMDJSON_LIB_SOVERSION "1" CACHE STRING "simdjson library soversion") option(SIMDJSON_IMPLEMENTATION_HASWELL "Include the haswell implementation" ON) diff --git a/include/simdjson/simdjson_version.h b/include/simdjson/simdjson_version.h index de1e462c7..4db17706c 100644 --- a/include/simdjson/simdjson_version.h +++ b/include/simdjson/simdjson_version.h @@ -4,7 +4,7 @@ #define SIMDJSON_SIMDJSON_VERSION_H /** The version of simdjson being used (major.minor.revision) */ -#define SIMDJSON_VERSION 0.3.0 +#define SIMDJSON_VERSION 0.3.1 namespace simdjson { enum { @@ -19,7 +19,7 @@ enum { /** * The revision (major.minor.REVISION) of simdjson being used. */ - SIMDJSON_VERSION_REVISION = 0 + SIMDJSON_VERSION_REVISION = 1 }; } // namespace simdjson diff --git a/singleheader/amalgamation_demo.cpp b/singleheader/amalgamation_demo.cpp index 3d20cb24c..35e3c3c43 100755 --- a/singleheader/amalgamation_demo.cpp +++ b/singleheader/amalgamation_demo.cpp @@ -1,4 +1,4 @@ -/* auto-generated on Tue 31 Mar 2020 17:00:28 EDT. Do not edit! */ +/* auto-generated on Thu 2 Apr 2020 18:58:25 EDT. Do not edit! */ #include #include "simdjson.h" diff --git a/singleheader/simdjson.cpp b/singleheader/simdjson.cpp index 34b0c7a11..51772ea33 100644 --- a/singleheader/simdjson.cpp +++ b/singleheader/simdjson.cpp @@ -1,4 +1,4 @@ -/* auto-generated on Tue 31 Mar 2020 17:00:28 EDT. Do not edit! */ +/* auto-generated on Thu 2 Apr 2020 18:58:25 EDT. Do not edit! */ #include "simdjson.h" /* used for http://dmalloc.com/ Dmalloc - Debug Malloc Library */ diff --git a/singleheader/simdjson.h b/singleheader/simdjson.h index f8b7b03ec..b06c4383d 100644 --- a/singleheader/simdjson.h +++ b/singleheader/simdjson.h @@ -1,4 +1,4 @@ -/* auto-generated on Tue 31 Mar 2020 17:00:28 EDT. Do not edit! */ +/* auto-generated on Thu 2 Apr 2020 18:58:25 EDT. Do not edit! */ /* begin file include/simdjson.h */ #ifndef SIMDJSON_H #define SIMDJSON_H @@ -40,7 +40,7 @@ #define SIMDJSON_SIMDJSON_VERSION_H /** The version of simdjson being used (major.minor.revision) */ -#define SIMDJSON_VERSION 0.3.0 +#define SIMDJSON_VERSION 0.3.1 namespace simdjson { enum { @@ -55,7 +55,7 @@ enum { /** * The revision (major.minor.REVISION) of simdjson being used. */ - SIMDJSON_VERSION_REVISION = 0 + SIMDJSON_VERSION_REVISION = 1 }; } // namespace simdjson @@ -744,50 +744,65 @@ namespace simdjson::internal { using namespace simdjson::dom; constexpr const uint64_t JSON_VALUE_MASK = 0x00FFFFFFFFFFFFFF; -enum class tape_type; -class tape_ref; - /** - * The possible types in the tape. Internal only. - */ - enum class tape_type { - ROOT = 'r', - START_ARRAY = '[', - START_OBJECT = '{', - END_ARRAY = ']', - END_OBJECT = '}', - STRING = '"', - INT64 = 'l', - UINT64 = 'u', - DOUBLE = 'd', - TRUE_VALUE = 't', - FALSE_VALUE = 'f', - NULL_VALUE = 'n' - }; - /** - * A reference to an element on the tape. Internal only. - */ - class tape_ref { - public: - really_inline tape_ref() noexcept; - really_inline tape_ref(const document *doc, size_t json_index) noexcept; - inline size_t after_element() const noexcept; - really_inline tape_type type() const noexcept; - really_inline uint64_t tape_value() const noexcept; - template - really_inline T next_tape_value() const noexcept; - inline std::string_view get_string_view() const noexcept; +/** + * The possible types in the tape. Internal only. + */ +enum class tape_type { + ROOT = 'r', + START_ARRAY = '[', + START_OBJECT = '{', + END_ARRAY = ']', + END_OBJECT = '}', + STRING = '"', + INT64 = 'l', + UINT64 = 'u', + DOUBLE = 'd', + TRUE_VALUE = 't', + FALSE_VALUE = 'f', + NULL_VALUE = 'n' +}; - /** The document this element references. */ - const document *doc; +/** + * A reference to an element on the tape. Internal only. + */ +class tape_ref { +public: + really_inline tape_ref() noexcept; + really_inline tape_ref(const 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; + template + really_inline T next_tape_value() const noexcept; + inline std::string_view get_string_view() const noexcept; + + /** The document this element references. */ + const document *doc; + + /** The index of this element on `doc.tape[]` */ + size_t json_index; +}; - /** The index of this element on `doc.tape[]` */ - size_t json_index; - }; } // namespace simdjson::internal namespace simdjson::dom { +/** + * The actual concrete type of a JSON element + * This is the type it is most easily cast to with get<>. + */ +enum class element_type { + ARRAY, ///< dom::array + OBJECT, ///< dom::object + INT64, ///< int64_t + UINT64, ///< uint64_t: any integer that fits in uint64_t but *not* int64_t + DOUBLE, ///< double: Any number with a "." or "e" that fits in double. + STRING, ///< std::string_view + BOOL, ///< bool + NULL_VALUE ///< null +}; + /** * JSON array. */ @@ -1070,6 +1085,9 @@ public: /** Create a new, invalid element. */ really_inline element() noexcept; + /** The type of this element. */ + really_inline element_type type() const noexcept; + /** Whether this element is a json `null`. */ really_inline bool is_null() const noexcept; @@ -1824,6 +1842,36 @@ inline std::ostream& operator<<(std::ostream& out, const object &value) { return */ inline std::ostream& operator<<(std::ostream& out, const key_value_pair &value) { return out << minify(value); } +/** + * Print element type to an output stream. + * + * @param out The output stream. + * @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, element_type type) { + switch (type) { + case element_type::ARRAY: + return out << "array"; + case element_type::OBJECT: + return out << "object"; + case element_type::INT64: + return out << "int64_t"; + case element_type::UINT64: + return out << "uint64_t"; + case element_type::DOUBLE: + return out << "double"; + case element_type::STRING: + return out << "string"; + case element_type::BOOL: + return out << "bool"; + case element_type::NULL_VALUE: + return out << "null"; + default: + abort(); + } +} + } // namespace dom #if SIMDJSON_EXCEPTIONS @@ -1875,6 +1923,7 @@ public: really_inline simdjson_result(dom::element &&value) noexcept; ///< @private really_inline simdjson_result(error_code error) noexcept; ///< @private + inline simdjson_result type() const noexcept; inline simdjson_result is_null() const noexcept; template inline simdjson_result is() const noexcept; @@ -2867,6 +2916,10 @@ really_inline simdjson_result::simdjson_result(dom::element &&valu : internal::simdjson_result_base(std::forward(value)) {} really_inline simdjson_result::simdjson_result(error_code error) noexcept : internal::simdjson_result_base(error) {} +inline simdjson_result simdjson_result::type() const noexcept { + if (error()) { return error(); } + return first.type(); +} inline simdjson_result simdjson_result::is_null() const noexcept { if (error()) { return error(); } return first.is_null(); @@ -3559,13 +3612,39 @@ inline key_value_pair::key_value_pair(const std::string_view &_key, element _val really_inline element::element() noexcept : internal::tape_ref() {} really_inline element::element(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { } +inline element_type element::type() const noexcept { + switch (tape_ref_type()) { + case internal::tape_type::START_ARRAY: + return element_type::ARRAY; + case internal::tape_type::START_OBJECT: + return element_type::OBJECT; + case internal::tape_type::INT64: + return element_type::INT64; + case internal::tape_type::UINT64: + return element_type::UINT64; + case internal::tape_type::DOUBLE: + return element_type::DOUBLE; + case internal::tape_type::STRING: + return element_type::STRING; + case internal::tape_type::TRUE_VALUE: + case internal::tape_type::FALSE_VALUE: + return element_type::BOOL; + case internal::tape_type::NULL_VALUE: + return element_type::NULL_VALUE; + case internal::tape_type::ROOT: + case internal::tape_type::END_ARRAY: + case internal::tape_type::END_OBJECT: + default: + abort(); + } +} really_inline bool element::is_null() const noexcept { - return type() == internal::tape_type::NULL_VALUE; + return tape_ref_type() == internal::tape_type::NULL_VALUE; } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::TRUE_VALUE: return true; case internal::tape_type::FALSE_VALUE: @@ -3576,7 +3655,7 @@ inline simdjson_result element::get() const noexcept { } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::STRING: { size_t string_buf_index = tape_value(); return reinterpret_cast(&doc->string_buf[string_buf_index + sizeof(uint32_t)]); @@ -3587,7 +3666,7 @@ inline simdjson_result element::get() const noexcept } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::STRING: return get_string_view(); default: @@ -3596,7 +3675,7 @@ inline simdjson_result element::get() const } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::UINT64: return next_tape_value(); case internal::tape_type::INT64: { @@ -3612,11 +3691,11 @@ inline simdjson_result element::get() const noexcept { } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::UINT64: { uint64_t result = next_tape_value(); // 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 - if (result > (std::numeric_limits::max)()) { + if (result > (std::numeric_limits::max)()) { return NUMBER_OUT_OF_RANGE; } return static_cast(result); @@ -3629,7 +3708,7 @@ inline simdjson_result element::get() const noexcept { } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::UINT64: return next_tape_value(); case internal::tape_type::INT64: { @@ -3648,7 +3727,7 @@ inline simdjson_result element::get() const noexcept { } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::START_ARRAY: return array(doc, json_index); default: @@ -3657,7 +3736,7 @@ inline simdjson_result element::get() const noexcept { } template<> inline simdjson_result element::get() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::START_OBJECT: return object(doc, json_index); default: @@ -3682,10 +3761,10 @@ inline element::operator double() const noexcept(false) { return get(); inline element::operator array() const noexcept(false) { return get(); } inline element::operator object() const noexcept(false) { return get(); } -inline dom::array::iterator dom::element::begin() const noexcept(false) { +inline array::iterator element::begin() const noexcept(false) { return get().begin(); } -inline dom::array::iterator dom::element::end() const noexcept(false) { +inline array::iterator element::end() const noexcept(false) { return get().end(); } @@ -3698,7 +3777,7 @@ inline simdjson_result element::operator[](const char *key) const noexc return at_key(key); } inline simdjson_result element::at(const std::string_view &json_pointer) const noexcept { - switch (type()) { + switch (tape_ref_type()) { case internal::tape_type::START_OBJECT: return object(doc, json_index).at(json_pointer); case internal::tape_type::START_ARRAY: @@ -3749,7 +3828,7 @@ inline std::ostream& minify::print(std::ostream& out) { out << '"' << internal::escape_json_string(iter.get_string_view()) << "\":"; iter.json_index++; } - switch (iter.type()) { + switch (iter.tape_ref_type()) { // Arrays case tape_type::START_ARRAY: { @@ -3767,7 +3846,7 @@ inline std::ostream& minify::print(std::ostream& out) { iter.json_index++; // Handle empty [] (we don't want to come back around and print commas) - if (iter.type() == tape_type::END_ARRAY) { + if (iter.tape_ref_type() == tape_type::END_ARRAY) { out << ']'; depth--; break; @@ -3794,7 +3873,7 @@ inline std::ostream& minify::print(std::ostream& out) { iter.json_index++; // Handle empty {} (we don't want to come back around and print commas) - if (iter.type() == tape_type::END_OBJECT) { + if (iter.tape_ref_type() == tape_type::END_OBJECT) { out << '}'; depth--; break; @@ -3841,8 +3920,8 @@ inline std::ostream& minify::print(std::ostream& out) { after_value = true; // Handle multiple ends in a row - while (depth != 0 && (iter.type() == tape_type::END_ARRAY || iter.type() == tape_type::END_OBJECT)) { - out << char(iter.type()); + while (depth != 0 && (iter.tape_ref_type() == tape_type::END_ARRAY || iter.tape_ref_type() == tape_type::END_OBJECT)) { + out << char(iter.tape_ref_type()); depth--; iter.json_index++; } @@ -3914,7 +3993,7 @@ really_inline tape_ref::tape_ref() noexcept : doc{nullptr}, json_index{0} {} really_inline tape_ref::tape_ref(const document *_doc, size_t _json_index) noexcept : doc{_doc}, json_index{_json_index} {} inline size_t tape_ref::after_element() const noexcept { - switch (type()) { + switch (tape_ref_type()) { case tape_type::START_ARRAY: case tape_type::START_OBJECT: return tape_value(); @@ -3926,7 +4005,7 @@ inline size_t tape_ref::after_element() const noexcept { return json_index + 1; } } -really_inline tape_type tape_ref::type() const noexcept { +really_inline tape_type tape_ref::tape_ref_type() const noexcept { return static_cast(doc->tape[json_index] >> 56); } really_inline uint64_t internal::tape_ref::tape_value() const noexcept {