From e88cff6172c1afad69952b77969885061cf8f534 Mon Sep 17 00:00:00 2001 From: Daniel Parker Date: Tue, 7 Nov 2023 18:39:09 -0500 Subject: [PATCH] path_node w string_view --- include/jsoncons_ext/jsonpath/expression.hpp | 4 +- .../jsoncons_ext/jsonpath/json_location.hpp | 66 +++++++++++++++---- .../jsonpath/jsonpath_selector.hpp | 14 ++-- test/jsonpath/src/json_location_tests.cpp | 9 ++- .../src/jsonpath_make_expression_tests.cpp | 2 +- 5 files changed, 67 insertions(+), 28 deletions(-) diff --git a/include/jsoncons_ext/jsonpath/expression.hpp b/include/jsoncons_ext/jsonpath/expression.hpp index 1298052ae0..5c623616cb 100644 --- a/include/jsoncons_ext/jsonpath/expression.hpp +++ b/include/jsoncons_ext/jsonpath/expression.hpp @@ -2271,13 +2271,13 @@ namespace detail { const path_node_type& root_path_node() const { - static path_node_type root(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "$"), alloc_}); + static path_node_type root('$'); return root; } const path_node_type& current_path_node() const { - static path_node_type root(string_type{JSONCONS_CSTRING_CONSTANT(char_type, "@"), alloc_}); + static path_node_type root('@'); return root; } diff --git a/include/jsoncons_ext/jsonpath/json_location.hpp b/include/jsoncons_ext/jsonpath/json_location.hpp index 4215e70c19..da5bff3b4f 100644 --- a/include/jsoncons_ext/jsonpath/json_location.hpp +++ b/include/jsoncons_ext/jsonpath/json_location.hpp @@ -30,30 +30,70 @@ namespace jsonpath { { friend class json_location; public: - using string_type = typename Json::string_type; - using char_type = typename string_type::value_type; + using string_view_type = typename Json::string_view_type; + using char_type = typename string_view_type::value_type; private: + char_type root_; const path_node* parent_; path_node_kind node_kind_; - jsoncons::optional name_; + string_view_type name_; std::size_t index_; + public: - path_node(string_type&& name) - : parent_(nullptr), + path_node(char_type root) + : root_{root}, parent_(nullptr), node_kind_(path_node_kind::root), - name_(std::move(name)), index_(0) + name_(&root_,1), index_(0) { } - path_node(const path_node* parent, const string_type& name) - : parent_(parent), node_kind_(path_node_kind::name), name_(name), index_(0) + path_node(const path_node* parent, const string_view_type& name) + : root_(0), parent_(parent), node_kind_(path_node_kind::name), name_(name), index_(0) { } path_node(const path_node* parent, std::size_t index) - : parent_(parent), node_kind_(path_node_kind::index), index_(index) + : root_(0), parent_(parent), node_kind_(path_node_kind::index), index_(index) + { + } + + path_node(const path_node& other) + : root_(other.root_), + parent_(other.parent_), + node_kind_(other.node_kind_), + name_(other.node_kind_ == path_node_kind::root ? string_view_type(&root_, 1) : other.name_), + index_(other.index_) + { + } + + path_node(path_node&& other) + : root_(other.root_), + parent_(other.parent_), + node_kind_(other.node_kind_), + name_(other.node_kind_ == path_node_kind::root ? string_view_type(&root_, 1) : other.name_), + index_(other.index_) + { + } + + path_node& operator=(const path_node& other) + { + root_ = other.root_; + parent_ = other.parent_; + node_kind_ = other.node_kind_; + index_ = other.index_; + name_ = other.node_kind_ == path_node_kind::root ? string_view_type(&root_, 1) : other.name_; + return *this; + } + + path_node& operator=(path_node&& other) { + root_ = other.root_; + parent_ = other.parent_; + node_kind_ = other.node_kind_; + index_ = other.index_; + name_ = other.node_kind_ == path_node_kind::root ? string_view_type(&root_, 1) : other.name_; + return *this; } const path_node* parent() const { return parent_;} @@ -63,9 +103,9 @@ namespace jsonpath { return node_kind_; } - const string_type& name() const + const string_view_type& name() const { - return *name_; + return name_; } std::size_t index() const @@ -85,7 +125,7 @@ namespace jsonpath { std::size_t node_hash() const { - std::size_t h = node_kind_ == path_node_kind::index ? std::hash{}(index_) : std::hash{}(*name_); + std::size_t h = node_kind_ == path_node_kind::index ? std::hash{}(index_) : std::hash{}(name_); return h; } @@ -103,7 +143,7 @@ namespace jsonpath { { case path_node_kind::root: case path_node_kind::name: - diff = (*name_).compare(*(other.name_)); + diff = name_.compare(other.name_); break; case path_node_kind::index: diff = index_ < other.index_ ? -1 : index_ > other.index_ ? 1 : 0; diff --git a/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp b/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp index caee3d300a..3bc76bc621 100644 --- a/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +++ b/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp @@ -138,9 +138,9 @@ namespace detail { using path_node_type = path_node; static const path_node_type& generate(dynamic_resources& resources, - const path_node_type& last, - std::size_t index, - result_options options) + const path_node_type& last, + std::size_t index, + result_options options) { const result_options require_path = result_options::path | result_options::nodups | result_options::sort; if ((options & require_path) != result_options()) @@ -154,9 +154,9 @@ namespace detail { } static const path_node_type& generate(dynamic_resources& resources, - const path_node_type& last, - const string_type& identifier, - result_options options) + const path_node_type& last, + const string_view_type& identifier, + result_options options) { const result_options require_path = result_options::path | result_options::nodups | result_options::sort; if ((options & require_path) != result_options()) @@ -1101,7 +1101,7 @@ namespace detail { { auto sv = j.as_string_view(); this->tail_select(resources, root, - path_generator_type::generate(resources, last, string_type(sv.begin(),sv.end(), resources.get_allocator()), options), + path_generator_type::generate(resources, last, sv, options), current.at(j.as_string_view()), receiver, options); } } diff --git a/test/jsonpath/src/json_location_tests.cpp b/test/jsonpath/src/json_location_tests.cpp index 6763269184..ff21dd4796 100644 --- a/test/jsonpath/src/json_location_tests.cpp +++ b/test/jsonpath/src/json_location_tests.cpp @@ -14,12 +14,12 @@ using json_location = jsoncons::jsonpath::json_location; TEST_CASE("test json_location equals") { - path_node component1("$"); + path_node component1('$'); path_node component2(&component1,"foo"); path_node component3(&component2,"bar"); path_node component4(&component3,0); - path_node component11("$"); + path_node component11('$'); path_node component12(&component11,"foo"); path_node component13(&component12,"bar"); path_node component14(&component13,0); @@ -32,7 +32,7 @@ TEST_CASE("test json_location equals") TEST_CASE("test json_location to_string") { - path_node component1("$"); + path_node component1('$'); path_node component2(&component1,"foo"); path_node component3(&component2,"bar"); path_node component4(&component3,0); @@ -44,7 +44,7 @@ TEST_CASE("test json_location to_string") TEST_CASE("test json_location with solidus to_string") { - path_node component1("$"); + path_node component1('$'); path_node component2(&component1,"foo's"); path_node component3(&component2,"bar"); path_node component4(&component3,0); @@ -54,4 +54,3 @@ TEST_CASE("test json_location with solidus to_string") CHECK(path1.to_string() == std::string(R"($['foo\'s']['bar'][0])")); } - diff --git a/test/jsonpath/src/jsonpath_make_expression_tests.cpp b/test/jsonpath/src/jsonpath_make_expression_tests.cpp index 96c249685b..c37e278613 100644 --- a/test/jsonpath/src/jsonpath_make_expression_tests.cpp +++ b/test/jsonpath/src/jsonpath_make_expression_tests.cpp @@ -98,7 +98,7 @@ TEST_CASE("jsonpath make_expression test") } }; - expr.evaluate(doc, callback1); + expr.select_nodes(doc, callback1); CHECK(count == 1);