Skip to content

Commit

Permalink
path_node comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Nov 13, 2023
1 parent 68ae13b commit 58cd5c6
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 1 deletion.
96 changes: 95 additions & 1 deletion include/jsoncons_ext/jsonpath/json_location.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ namespace jsonpath {

return h;
}

int compare_node(const basic_path_node& other) const
{
int diff = 0;
Expand All @@ -165,6 +164,101 @@ namespace jsonpath {
}
return diff;
}

friend bool operator<(const basic_path_node& lhs, const basic_path_node& rhs)
{
std::size_t len = (std::min)(lhs.size(),rhs.size());

const basic_path_node* p_lhs = std::addressof(lhs);
const basic_path_node* p_rhs = std::addressof(rhs);

bool is_less = false;
while (p_lhs->size() > len)
{
p_lhs = p_lhs->parent_;
is_less = false;
}
while (p_rhs->size() > len)
{
p_rhs = p_rhs->parent_;
is_less = true;
}
while (p_lhs != nullptr)
{
int diff = 0;
if (p_lhs->node_kind_ != p_rhs->node_kind_)
{
diff = static_cast<int>(p_lhs->node_kind_) - static_cast<int>(p_rhs->node_kind_);
}
else
{
switch (p_lhs->node_kind_)
{
case path_node_kind::root:
case path_node_kind::name:
diff = p_lhs->name_.compare(p_rhs->name_);
break;
case path_node_kind::index:
diff = static_cast<int>(p_lhs->index_) - static_cast<int>(p_rhs->index_);
break;
default:
break;
}
}
if (diff < 0)
{
is_less = true;
}
else if (diff > 0)
{
is_less = false;
}

p_lhs = p_lhs->parent_;
p_rhs = p_rhs->parent_;
}

return is_less;
}

friend bool operator==(const basic_path_node& lhs, const basic_path_node& rhs)
{
if (lhs.size() != rhs.size())
{
return false;
}

const basic_path_node* p_lhs = std::addressof(lhs);
const basic_path_node* p_rhs = std::addressof(rhs);

bool is_equal = true;
while (p_lhs != nullptr && is_equal)
{
if (p_lhs->node_kind_ != p_rhs->node_kind_)
{
is_equal = false;
}
else
{
switch (p_lhs->node_kind_)
{
case path_node_kind::root:
case path_node_kind::name:
is_equal = p_lhs->name_ == p_rhs->name_;
break;
case path_node_kind::index:
is_equal = p_lhs->index_ == p_rhs->index_;
break;
default:
break;
}
}
p_lhs = p_lhs->parent_;
p_rhs = p_rhs->parent_;
}

return is_equal;
}
};

template <class CharT>
Expand Down
83 changes: 83 additions & 0 deletions test/jsonpath/src/json_location_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,86 @@ TEST_CASE("test json_location with solidus to_string")
CHECK(path1.to_string() == std::string(R"($['foo\'s']['bar'][0])"));
}

TEST_CASE("test path_node less")
{
SECTION("test rhs < lhs")
{
basic_path_node a1('$');
basic_path_node a2(&a1,"foo");
basic_path_node a3(&a2,"bar");
basic_path_node a4(&a3,0);

basic_path_node b1('$');
basic_path_node b2(&b1,"baz");
basic_path_node b3(&b2,"bar");
basic_path_node b4(&b3,0);

CHECK_FALSE(b4 == a4);

CHECK(b4 < a4);
CHECK_FALSE(a4 < b4);

CHECK(b3 < a4);
CHECK_FALSE(a4 < b3);

CHECK(b2 < a4);
CHECK_FALSE(a4 < b2);
}

SECTION("test rhs < lhs 2")
{
basic_path_node a1('$');
basic_path_node a2(&a1,"foo");
basic_path_node a3(&a2,"bar");
basic_path_node a4(&a3,0);

basic_path_node b1('$');
basic_path_node b2(&b1,"baz");
basic_path_node b3(&b2,"g");
basic_path_node b4(&b3,0);

CHECK_FALSE(b4 == a4);

CHECK(b4 < a4);
CHECK_FALSE(a4 < b4);

CHECK(b3 < a4);
CHECK_FALSE(a4 < b3);

CHECK(b2 < a4);
CHECK_FALSE(a4 < b2);
}

SECTION("test rhs == lhs")
{
basic_path_node a1('$');
basic_path_node a2(&a1,"foo");
basic_path_node a3(&a2,"bar");
basic_path_node a4(&a3,0);

basic_path_node b1('$');
basic_path_node b2(&b1,"foo");
basic_path_node b3(&b2,"bar");
basic_path_node b4(&b3,0);

CHECK(a1 == b1);
CHECK(a2 == b2);
CHECK(a3 == b3);
CHECK(a4 == b4);
CHECK(b1 == a1);
CHECK(b2 == a2);
CHECK(b3 == a3);
CHECK(b4 == a4);

CHECK_FALSE(b4 < a4);
CHECK_FALSE(a4 < b4);

CHECK(b3 < a4);
CHECK_FALSE(a4 < b3);

CHECK(b2 < a4);
CHECK_FALSE(a4 < b2);
}

}

0 comments on commit 58cd5c6

Please sign in to comment.