diff --git a/DEPENDENCIES b/DEPENDENCIES index 7dadbc11..0cce3fe7 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,5 +1,5 @@ vendorpull https://github.com/sourcemeta/vendorpull dea311b5bfb53b6926a4140267959ae334d3ecf4 noa https://github.com/sourcemeta/noa 7e26abce7a4e31e86a16ef2851702a56773ca527 -jsontoolkit https://github.com/sourcemeta/jsontoolkit 2b5158f237584fff7e35d520c2e5a722d01fd678 +jsontoolkit https://github.com/sourcemeta/jsontoolkit 6c78f131029c647be79cc5da5874fa8d50415cde hydra https://github.com/sourcemeta/hydra 3c53d3fdef79e9ba603d48470a508cc45472a0dc alterschema https://github.com/sourcemeta/alterschema a31722f04ae2d7e57f2fe5bbb0613670866c0840 diff --git a/src/command_compile.cc b/src/command_compile.cc index 6e141d9a..a06ef86c 100644 --- a/src/command_compile.cc +++ b/src/command_compile.cc @@ -23,8 +23,7 @@ auto sourcemeta::jsonschema::cli::compile( const auto compiled_schema{sourcemeta::jsontoolkit::compile( schema, sourcemeta::jsontoolkit::default_schema_walker, resolver(options, options.contains("h") || options.contains("http")), - sourcemeta::jsontoolkit::default_schema_compiler, - sourcemeta::jsontoolkit::SchemaCompilerCompilationMode::Optimized)}; + sourcemeta::jsontoolkit::default_schema_compiler)}; const sourcemeta::jsontoolkit::JSON result{ sourcemeta::jsontoolkit::to_json(compiled_schema)}; diff --git a/src/command_metaschema.cc b/src/command_metaschema.cc index 2afc5924..1ff28611 100644 --- a/src/command_metaschema.cc +++ b/src/command_metaschema.cc @@ -37,8 +37,7 @@ auto sourcemeta::jsonschema::cli::metaschema( if (!cache.contains(dialect.value())) { const auto metaschema_template{sourcemeta::jsontoolkit::compile( metaschema, sourcemeta::jsontoolkit::default_schema_walker, - custom_resolver, sourcemeta::jsontoolkit::default_schema_compiler, - sourcemeta::jsontoolkit::SchemaCompilerCompilationMode::Optimized)}; + custom_resolver, sourcemeta::jsontoolkit::default_schema_compiler)}; cache.insert({dialect.value(), metaschema_template}); } diff --git a/src/command_test.cc b/src/command_test.cc index 7e0d9ab4..78ad3a3c 100644 --- a/src/command_test.cc +++ b/src/command_test.cc @@ -142,8 +142,7 @@ auto sourcemeta::jsonschema::cli::test( try { schema_template = sourcemeta::jsontoolkit::compile( schema.value(), sourcemeta::jsontoolkit::default_schema_walker, - test_resolver, sourcemeta::jsontoolkit::default_schema_compiler, - sourcemeta::jsontoolkit::SchemaCompilerCompilationMode::Optimized); + test_resolver, sourcemeta::jsontoolkit::default_schema_compiler); } catch (const sourcemeta::jsontoolkit::SchemaReferenceError &error) { if (error.location().empty() && error.id() == schema_uri.recompose()) { std::cout << "\n"; diff --git a/src/command_validate.cc b/src/command_validate.cc index 0b90c7e8..6d314f4f 100644 --- a/src/command_validate.cc +++ b/src/command_validate.cc @@ -50,8 +50,7 @@ auto sourcemeta::jsonschema::cli::validate( const auto benchmark{options.contains("b") || options.contains("benchmark")}; const auto schema_template{sourcemeta::jsontoolkit::compile( schema, sourcemeta::jsontoolkit::default_schema_walker, custom_resolver, - sourcemeta::jsontoolkit::default_schema_compiler, - sourcemeta::jsontoolkit::SchemaCompilerCompilationMode::Optimized)}; + sourcemeta::jsontoolkit::default_schema_compiler)}; bool result{true}; diff --git a/test/compile/pass_1.sh b/test/compile/pass_1.sh index 2f8e964c..ac1b5643 100755 --- a/test/compile/pass_1.sh +++ b/test/compile/pass_1.sh @@ -21,21 +21,21 @@ EOF cat << 'EOF' > "$TMP/expected.json" [ { - "category": "logical", - "type": "and", - "value": null, + "category": "loop", + "type": "properties-match", + "value": { + "category": "value", + "type": "named-indexes", + "value": { + "foo": 0 + } + }, "schemaResource": "", "absoluteKeywordLocation": "#/properties", "relativeSchemaLocation": "/properties", "relativeInstanceLocation": "", - "target": { - "category": "target", - "type": "instance", - "location": "" - }, "report": true, "dynamic": false, - "condition": [], "children": [ { "category": "logical", @@ -45,36 +45,8 @@ cat << 'EOF' > "$TMP/expected.json" "absoluteKeywordLocation": "#/properties", "relativeSchemaLocation": "", "relativeInstanceLocation": "", - "target": { - "category": "target", - "type": "instance", - "location": "" - }, "report": false, "dynamic": false, - "condition": [ - { - "category": "assertion", - "type": "defines", - "value": { - "category": "value", - "type": "string", - "value": "foo" - }, - "schemaResource": "", - "absoluteKeywordLocation": "#/properties", - "relativeSchemaLocation": "", - "relativeInstanceLocation": "", - "target": { - "category": "target", - "type": "instance", - "location": "" - }, - "report": false, - "dynamic": false, - "condition": [] - } - ], "children": [ { "category": "assertion", @@ -88,14 +60,8 @@ cat << 'EOF' > "$TMP/expected.json" "absoluteKeywordLocation": "#/properties/foo/type", "relativeSchemaLocation": "/foo/type", "relativeInstanceLocation": "/foo", - "target": { - "category": "target", - "type": "instance", - "location": "" - }, "report": true, - "dynamic": false, - "condition": [] + "dynamic": false } ] } diff --git a/vendor/jsontoolkit/CMakeLists.txt b/vendor/jsontoolkit/CMakeLists.txt index be6a37aa..e52fde65 100644 --- a/vendor/jsontoolkit/CMakeLists.txt +++ b/vendor/jsontoolkit/CMakeLists.txt @@ -89,14 +89,14 @@ if(JSONTOOLKIT_TESTS) add_subdirectory(test/json) endif() - if(JSONTOOLKIT_JSON AND JSONTOOLKIT_JSONSCHEMA) - add_subdirectory(test/jsonschema) - endif() - if(JSONTOOLKIT_JSON AND JSONTOOLKIT_JSONPOINTER) add_subdirectory(test/jsonpointer) endif() + if(JSONTOOLKIT_JSON AND JSONTOOLKIT_JSONSCHEMA) + add_subdirectory(test/jsonschema) + endif() + if(JSONTOOLKIT_JSON AND JSONTOOLKIT_JSONL) add_subdirectory(test/jsonl) endif() diff --git a/vendor/jsontoolkit/src/json/include/sourcemeta/jsontoolkit/json_object.h b/vendor/jsontoolkit/src/json/include/sourcemeta/jsontoolkit/json_object.h index c7bf278d..1330eeec 100644 --- a/vendor/jsontoolkit/src/json/include/sourcemeta/jsontoolkit/json_object.h +++ b/vendor/jsontoolkit/src/json/include/sourcemeta/jsontoolkit/json_object.h @@ -1,9 +1,14 @@ #ifndef SOURCEMETA_JSONTOOLKIT_JSON_OBJECT_H_ #define SOURCEMETA_JSONTOOLKIT_JSON_OBJECT_H_ -#include // std::less +#include // std::equal_to, std::less #include // std::initializer_list -#include // std::map + +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 12) +#include // std::map +#else +#include // std::unordered_map +#endif namespace sourcemeta::jsontoolkit { @@ -11,10 +16,18 @@ namespace sourcemeta::jsontoolkit { template class JSONObject { public: // Constructors + + // Older versions of GCC don't allow `std::unordered_map` to incomplete + // types, and in this case, `Value` is an incomplete type. using Container = +#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 12) std::map, +#else + std::unordered_map, std::equal_to, +#endif typename Value::template Allocator< std::pair>>; + JSONObject() : data{} {} JSONObject(std::initializer_list values) : data{values} {} @@ -22,8 +35,8 @@ template class JSONObject { // Operators // We cannot default given that this class references // a JSON "value" as an incomplete type - auto operator<(const JSONObject &other) const noexcept -> bool { - return this->data < other.data; + auto operator<(const JSONObject &) const noexcept -> bool { + return false; } auto operator<=(const JSONObject &other) const noexcept -> bool { return this->data <= other.data; @@ -47,7 +60,6 @@ template class JSONObject { using value_type = typename Container::value_type; using size_type = typename Container::size_type; using difference_type = typename Container::difference_type; - using key_compare = typename Container::key_compare; using allocator_type = typename Container::allocator_type; using reference = typename Container::reference; using const_reference = typename Container::const_reference; @@ -55,8 +67,6 @@ template class JSONObject { using const_pointer = typename Container::const_pointer; using iterator = typename Container::iterator; using const_iterator = typename Container::const_iterator; - using reverse_iterator = typename Container::reverse_iterator; - using const_reverse_iterator = typename Container::const_reverse_iterator; /// Get a mutable begin iterator on the object auto begin() noexcept -> iterator { return this->data.begin(); } @@ -70,26 +80,6 @@ template class JSONObject { auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); } /// Get a constant end iterator on the object auto cend() const noexcept -> const_iterator { return this->data.cend(); } - /// Get a mutable reverse begin iterator on the object - auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); } - /// Get a mutable reverse end iterator on the object - auto rend() noexcept -> reverse_iterator { return this->data.rend(); } - /// Get a constant reverse begin iterator on the object - auto rbegin() const noexcept -> const_reverse_iterator { - return this->data.rbegin(); - } - /// Get a constant reverse end iterator on the object - auto rend() const noexcept -> const_reverse_iterator { - return this->data.rend(); - } - /// Get a constant reverse begin iterator on the object - auto crbegin() const noexcept -> const_reverse_iterator { - return this->data.crbegin(); - } - /// Get a constant reverse end iterator on the object - auto crend() const noexcept -> const_reverse_iterator { - return this->data.crend(); - } private: friend Value; diff --git a/vendor/jsontoolkit/src/json/json_value.cc b/vendor/jsontoolkit/src/json/json_value.cc index 93244062..60e3d75f 100644 --- a/vendor/jsontoolkit/src/json/json_value.cc +++ b/vendor/jsontoolkit/src/json/json_value.cc @@ -313,13 +313,13 @@ JSON::at(const typename JSON::Array::size_type index) -> JSON & { [[nodiscard]] auto JSON::at(const JSON::String &key) const -> const JSON & { assert(this->is_object()); assert(this->defines(key)); - return std::get(this->data).data.at(key); + return std::get(this->data).data.find(key)->second; } [[nodiscard]] auto JSON::at(const JSON::String &key) -> JSON & { assert(this->is_object()); assert(this->defines(key)); - return std::get(this->data).data.at(key); + return std::get(this->data).data.find(key)->second; } [[nodiscard]] auto JSON::front() -> JSON & { diff --git a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer.h b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer.h index 7e8ded20..fe789e60 100644 --- a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer.h +++ b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer.h @@ -11,9 +11,10 @@ #include #include -#include // std::allocator -#include // std::basic_ostream -#include // std::basic_string +#include // std::reference_wrapper +#include // std::allocator +#include // std::basic_ostream +#include // std::basic_string /// @defgroup jsonpointer JSON Pointer /// @brief An growing implementation of RFC 6901 JSON Pointer. @@ -24,12 +25,13 @@ /// #include /// ``` -// TODO: Remove character and character traits template arguments from pointers - namespace sourcemeta::jsontoolkit { /// @ingroup jsonpointer -using Pointer = GenericPointer; +using Pointer = GenericPointer; + +/// @ingroup jsonpointer +using WeakPointer = GenericPointer>; /// @ingroup jsonpointer /// A global constant instance of the empty JSON Pointer. @@ -81,6 +83,50 @@ auto get(const JSON &document, const Pointer &pointer) -> const JSON &; SOURCEMETA_JSONTOOLKIT_JSONPOINTER_EXPORT auto get(JSON &document, const Pointer &pointer) -> JSON &; +/// @ingroup jsonpointer +/// Get a value from a JSON document using a JSON Pointer token (`const` +/// overload). +/// +/// ```cpp +/// #include +/// #include +/// #include +/// #include +/// +/// std::istringstream stream{"{ \"foo\": 1 }"}; +/// const sourcemeta::jsontoolkit::JSON document = +/// sourcemeta::jsontoolkit::parse(stream); +/// +/// const sourcemeta::jsontoolkit::JSON &value{ +/// sourcemeta::jsontoolkit::get(document, "bar")}; +/// assert(value.is_integer()); +/// assert(value.to_integer() == 2); +/// ``` +SOURCEMETA_JSONTOOLKIT_JSONPOINTER_EXPORT +auto get(const JSON &document, const Pointer::Token &token) -> const JSON &; + +/// @ingroup jsonpointer +/// Get a value from a JSON document using a JSON Pointer token (non-`const` +/// overload). +/// +/// ```cpp +/// #include +/// #include +/// #include +/// #include +/// +/// std::istringstream stream{"{ \"foo\": 1 }"}; +/// sourcemeta::jsontoolkit::JSON document = +/// sourcemeta::jsontoolkit::parse(stream); +/// +/// sourcemeta::jsontoolkit::JSON &value{ +/// sourcemeta::jsontoolkit::get(document, "bar")}; +/// assert(value.is_integer()); +/// assert(value.to_integer() == 2); +/// ``` +SOURCEMETA_JSONTOOLKIT_JSONPOINTER_EXPORT +auto get(JSON &document, const Pointer::Token &token) -> JSON &; + /// @ingroup jsonpointer /// Set a value in a JSON document using a JSON Pointer (`const` overload). /// @@ -270,8 +316,7 @@ auto to_uri(const Pointer &pointer, const URI &base) -> URI; /// assert(subpointers.at(2) == sourcemeta::jsontoolkit::Pointer{1}); /// assert(subpointers.at(3) == sourcemeta::jsontoolkit::Pointer{2}); /// ``` -using PointerWalker = - GenericPointerWalker; +using PointerWalker = GenericPointerWalker; /// @ingroup jsonpointer /// @@ -297,8 +342,7 @@ using PointerWalker = /// assert(subpointers.at(1) == sourcemeta::jsontoolkit::Pointer{"foo"}); /// assert(subpointers.at(2) == sourcemeta::jsontoolkit::Pointer{}); /// ``` -using SubPointerWalker = - GenericSubPointerWalker; +using SubPointerWalker = GenericSubPointerWalker; } // namespace sourcemeta::jsontoolkit diff --git a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_pointer.h b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_pointer.h index 703bcd92..44c1ab0a 100644 --- a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_pointer.h +++ b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_pointer.h @@ -15,11 +15,9 @@ namespace sourcemeta::jsontoolkit { /// @ingroup jsonpointer -template typename Allocator> -class GenericPointer { +template class GenericPointer { public: - using Token = GenericToken; + using Token = GenericToken; using Value = typename Token::Value; using Container = std::vector; @@ -194,8 +192,14 @@ class GenericPointer { /// assert(pointer.at(1).to_property() == "bar"); /// assert(pointer.at(2).to_property() == "baz"); /// ``` - auto - push_back(const GenericPointer &other) -> void { + auto push_back(const GenericPointer &other) -> void { + if (other.empty()) { + return; + } else if (other.size() == 1) { + this->emplace_back(other.back()); + return; + } + this->data.reserve(this->data.size() + other.size()); std::copy(other.data.cbegin(), other.data.cend(), std::back_inserter(this->data)); @@ -221,12 +225,84 @@ class GenericPointer { /// assert(pointer.at(1).to_property() == "bar"); /// assert(pointer.at(2).to_property() == "baz"); /// ``` - auto push_back(GenericPointer &&other) -> void { + auto push_back(GenericPointer &&other) -> void { + if (other.empty()) { + return; + } else if (other.size() == 1) { + this->emplace_back(std::move(other.back())); + return; + } + this->data.reserve(this->data.size() + other.size()); std::move(other.data.begin(), other.data.end(), std::back_inserter(this->data)); } + /// Push a property token into the back of a JSON Pointer. + /// For example: + /// + /// ```cpp + /// #include + /// #include + /// + /// sourcemeta::jsontoolkit::Pointer pointer{"foo"}; + /// const sourcemeta::jsontoolkit::Pointer other{"bar"}; + /// pointer.push_back(other.back().to_property()); + /// assert(pointer.size() == 2); + /// + /// assert(pointer.at(0).is_property()); + /// assert(pointer.at(1).is_property()); + /// + /// assert(pointer.at(0).to_property() == "foo"); + /// assert(pointer.at(1).to_property() == "bar"); + /// ``` + auto push_back(const typename Token::Property &property) -> void { + this->data.emplace_back(property); + } + + /// Move a property token into the back of a JSON Pointer. + /// For example: + /// + /// ```cpp + /// #include + /// #include + /// + /// sourcemeta::jsontoolkit::Pointer pointer{"foo"}; + /// pointer.push_back("bar"); + /// assert(pointer.size() == 2); + /// + /// assert(pointer.at(0).is_property()); + /// assert(pointer.at(1).is_property()); + /// + /// assert(pointer.at(0).to_property() == "foo"); + /// assert(pointer.at(1).to_property() == "bar"); + /// ``` + auto push_back(typename Token::Property &&property) -> void { + this->data.emplace_back(std::move(property)); + } + + /// Push an index token into the back of a JSON Pointer. + /// For example: + /// + /// ```cpp + /// #include + /// #include + /// + /// sourcemeta::jsontoolkit::Pointer pointer{"foo"}; + /// const sourcemeta::jsontoolkit::Pointer other{0}; + /// pointer.push_back(other.back().to_index()); + /// assert(pointer.size() == 2); + /// + /// assert(pointer.at(0).is_property()); + /// assert(pointer.at(1).is_index()); + /// + /// assert(pointer.at(0).to_property() == "foo"); + /// assert(pointer.at(1).to_index() == 0); + /// ``` + auto push_back(const typename Token::Index &index) -> void { + this->data.emplace_back(index); + } + /// Remove the last token of a JSON Pointer. For example: /// /// ```cpp @@ -283,10 +359,9 @@ class GenericPointer { /// assert(pointer.at(1).is_property()); /// assert(pointer.at(1).to_property() == "bar"); /// ``` - [[nodiscard]] auto - initial() const -> GenericPointer { + [[nodiscard]] auto initial() const -> GenericPointer { assert(!this->empty()); - GenericPointer result{*this}; + GenericPointer result{*this}; result.pop_back(); return result; } @@ -303,9 +378,9 @@ class GenericPointer { /// assert(left.concat(right) == /// sourcemeta::jsontoolkit::Pointer{"foo", "bar", "baz"}); /// ``` - auto concat(const GenericPointer &other) const - -> GenericPointer { - GenericPointer result{*this}; + auto concat(const GenericPointer &other) const + -> GenericPointer { + GenericPointer result{*this}; result.push_back(other); return result; } @@ -321,8 +396,7 @@ class GenericPointer { /// const sourcemeta::jsontoolkit::Pointer prefix{"foo", "bar"}; /// assert(pointer.starts_with(prefix)); /// ``` - auto starts_with(const GenericPointer &other) const - -> bool { + auto starts_with(const GenericPointer &other) const -> bool { return other.data.size() <= this->data.size() && std::equal(other.data.cbegin(), other.data.cend(), this->data.cbegin()); @@ -341,9 +415,9 @@ class GenericPointer { /// assert(pointer.rebase(prefix, replacement) == /// sourcemeta::jsontoolkit::Pointer{"qux", "baz"}); /// ``` - auto rebase(const GenericPointer &prefix, - const GenericPointer &replacement) const - -> GenericPointer { + auto rebase(const GenericPointer &prefix, + const GenericPointer &replacement) const + -> GenericPointer { typename Container::size_type index{0}; while (index < prefix.size()) { if (index >= this->size() || prefix.data[index] != this->data[index]) { @@ -357,7 +431,7 @@ class GenericPointer { assert(this->starts_with(prefix)); auto new_begin{this->data.cbegin()}; std::advance(new_begin, index); - GenericPointer result{replacement}; + GenericPointer result{replacement}; std::copy(new_begin, this->data.cend(), std::back_inserter(result.data)); return result; } @@ -376,8 +450,8 @@ class GenericPointer { /// /// If the JSON Pointer is not relative to the base, a copy of the original /// input pointer is returned. - auto resolve_from(const GenericPointer &base) const - -> GenericPointer { + auto resolve_from(const GenericPointer &base) const + -> GenericPointer { typename Container::size_type index{0}; while (index < base.size()) { if (index >= this->size() || base.data[index] != this->data[index]) { @@ -390,21 +464,21 @@ class GenericPointer { // Make a pointer from the remaining tokens auto new_begin{this->data.cbegin()}; std::advance(new_begin, index); - GenericPointer result; + GenericPointer result; std::copy(new_begin, this->data.cend(), std::back_inserter(result.data)); return result; } /// Compare JSON Pointer instances - auto operator==(const GenericPointer &other) - const noexcept -> bool { + auto + operator==(const GenericPointer &other) const noexcept -> bool { return this->data == other.data; } /// Overload to support ordering of JSON Pointers. Typically for sorting /// reasons. - auto operator<(const GenericPointer &other) - const noexcept -> bool { + auto + operator<(const GenericPointer &other) const noexcept -> bool { return this->data < other.data; } diff --git a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_subpointer_walker.h b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_subpointer_walker.h index 5a812aa3..8b953d9a 100644 --- a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_subpointer_walker.h +++ b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_subpointer_walker.h @@ -10,13 +10,11 @@ namespace sourcemeta::jsontoolkit { /// @ingroup jsonpointer /// A forward iterator to traverse all subpointers of a given JSON Pointer. -template typename Allocator> -class GenericSubPointerIterator { +template class GenericSubPointerIterator { public: using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; - using value_type = GenericPointer; + using value_type = PointerT; using pointer = value_type *; using reference = value_type &; @@ -53,13 +51,10 @@ class GenericSubPointerIterator { /// @ingroup jsonpointer /// A walker to traverse all subpointers of a given JSON Pointer. -template typename Allocator> -class GenericSubPointerWalker { +template class GenericSubPointerWalker { public: - using const_iterator = GenericSubPointerIterator; - GenericSubPointerWalker(const typename const_iterator::value_type &pointer) - : data{pointer} {} + using const_iterator = GenericSubPointerIterator; + GenericSubPointerWalker(const PointerT &pointer) : data{pointer} {} const_iterator begin() { return {&this->data}; } const_iterator end() { return {nullptr}; } @@ -67,7 +62,7 @@ class GenericSubPointerWalker { const_iterator cend() { return {nullptr}; } private: - typename const_iterator::value_type data; + PointerT data; }; } // namespace sourcemeta::jsontoolkit diff --git a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_token.h b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_token.h index 775feb98..b763eb0c 100644 --- a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_token.h +++ b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_token.h @@ -10,12 +10,10 @@ namespace sourcemeta::jsontoolkit { /// @ingroup jsonpointer -template typename Allocator> -class GenericToken { +template class GenericToken { public: using Value = JSON; - using Property = typename Value::String; + using Property = PropertyT; using Index = typename Value::Array::size_type; /// This constructor creates an JSON Pointer token from a string. For @@ -39,7 +37,7 @@ class GenericToken { /// /// const sourcemeta::jsontoolkit::Pointer::Token token{"foo"}; /// ``` - GenericToken(const CharT *const property) + GenericToken(const JSON::Char *const property) : data{std::in_place_type, property} {} /// This constructor creates an JSON Pointer token from a character. For @@ -51,7 +49,7 @@ class GenericToken { /// /// const sourcemeta::jsontoolkit::Pointer::Token token{'a'}; /// ``` - GenericToken(const CharT character) + GenericToken(const JSON::Char character) : data{std::in_place_type, Property{character}} {} /// This constructor creates an JSON Pointer token from an item index. For @@ -146,9 +144,13 @@ class GenericToken { /// assert(token.is_property()); /// assert(token.to_property() == "foo"); /// ``` - [[nodiscard]] auto to_property() const noexcept -> const Property & { + [[nodiscard]] auto to_property() const noexcept -> const auto & { assert(this->is_property()); - return std::get(this->data); + if constexpr (requires { std::get(this->data).get(); }) { + return std::get(this->data).get(); + } else { + return std::get(this->data); + } } /// Get the underlying value of a JSON Pointer object property token @@ -162,9 +164,13 @@ class GenericToken { /// assert(token.is_property()); /// assert(token.to_property() == "foo"); /// ``` - auto to_property() noexcept -> Property & { + auto to_property() noexcept -> auto & { assert(this->is_property()); - return std::get(this->data); + if constexpr (requires { std::get(this->data).get(); }) { + return std::get(this->data).get(); + } else { + return std::get(this->data); + } } /// Get the underlying value of a JSON Pointer array index token @@ -208,16 +214,26 @@ class GenericToken { } /// Compare JSON Pointer tokens - auto operator==(const GenericToken &other) - const noexcept -> bool { - return this->data == other.data; + auto operator==(const GenericToken &other) const noexcept -> bool { + if (this->data.index() != other.data.index()) { + return false; + } + if (this->is_property()) { + return this->to_property() == other.to_property(); + } + return this->to_index() == other.to_index(); } /// Overload to support ordering of JSON Pointer token. Typically for sorting /// reasons. - auto operator<(const GenericToken &other) - const noexcept -> bool { - return this->data < other.data; + auto operator<(const GenericToken &other) const noexcept -> bool { + if (this->data.index() != other.data.index()) { + return this->data.index() < other.data.index(); + } + if (this->is_property()) { + return this->to_property() < other.to_property(); + } + return this->to_index() < other.to_index(); } private: diff --git a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_walker.h b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_walker.h index 17e141d6..08da9061 100644 --- a/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_walker.h +++ b/vendor/jsontoolkit/src/jsonpointer/include/sourcemeta/jsontoolkit/jsonpointer_walker.h @@ -9,13 +9,11 @@ namespace sourcemeta::jsontoolkit { /// @ingroup jsonpointer -/// A walker to get every JSON Pointer in a JSON document -template typename Allocator> -class GenericPointerWalker { +/// A walker to get every JSON Pointer in a JSON document. Note that no specific +/// ordering is guaranteed. If you expect any ordering, sort afterwards. +template class GenericPointerWalker { private: - using internal = - typename std::vector>; + using internal = typename std::vector; public: GenericPointerWalker(const JSON &document) { this->walk(document, {}); } @@ -27,18 +25,17 @@ class GenericPointerWalker { auto cend() const -> const_iterator { return this->pointers.cend(); }; private: - auto walk(const JSON &document, - const GenericPointer &pointer) -> void { + auto walk(const JSON &document, const PointerT &pointer) -> void { this->pointers.push_back(pointer); if (document.is_array()) { for (std::size_t index = 0; index < document.size(); index++) { - GenericPointer subpointer{pointer}; + PointerT subpointer{pointer}; subpointer.emplace_back(index); this->walk(document.at(index), subpointer); } } else if (document.is_object()) { for (const auto &pair : document.as_object()) { - GenericPointer subpointer{pointer}; + PointerT subpointer{pointer}; subpointer.emplace_back(pair.first); this->walk(pair.second, subpointer); } diff --git a/vendor/jsontoolkit/src/jsonpointer/jsonpointer.cc b/vendor/jsontoolkit/src/jsonpointer/jsonpointer.cc index 3780004b..9c98c07e 100644 --- a/vendor/jsontoolkit/src/jsonpointer/jsonpointer.cc +++ b/vendor/jsontoolkit/src/jsonpointer/jsonpointer.cc @@ -16,13 +16,10 @@ namespace { template