node: has_children/has_child_recursive

This commit is contained in:
2019-02-10 08:55:31 +07:00
parent 62e86f45f4
commit f9054a9abf
3 changed files with 64 additions and 18 deletions

View File

@@ -57,7 +57,12 @@ namespace e2d
const_node_iptr parent() const noexcept;
bool has_parent() const noexcept;
bool has_parent(const const_node_iptr& parent) const noexcept;
bool has_parent_recursive(
const const_node_iptr& parent) const noexcept;
bool has_children() const noexcept;
bool has_child_recursive(
const const_node_iptr& child) const noexcept;
bool remove_from_parent() noexcept;
std::size_t remove_all_children() noexcept;

View File

@@ -115,10 +115,9 @@ namespace e2d
return !!parent_;
}
bool node::has_parent(const const_node_iptr& parent) const noexcept {
if ( !parent ) {
return has_parent();
}
bool node::has_parent_recursive(
const const_node_iptr& parent) const noexcept
{
const node* p = parent_;
while ( p && p != parent ) {
p = p->parent_;
@@ -126,6 +125,18 @@ namespace e2d
return !!p;
}
bool node::has_children() const noexcept {
return !children_.empty();
}
bool node::has_child_recursive(
const const_node_iptr& child) const noexcept
{
return child
? child->has_parent_recursive(this)
: false;
}
bool node::remove_from_parent() noexcept {
return parent_
? parent_->remove_child(this)
@@ -133,8 +144,9 @@ namespace e2d
}
std::size_t node::remove_all_children() noexcept {
const std::size_t count = children_.size();
std::size_t count = 0;
while ( !children_.empty() ) {
++count;
children_.back().remove_from_parent();
}
return count;
@@ -145,9 +157,9 @@ namespace e2d
}
std::size_t node::child_count_recursive() const noexcept {
std::size_t count = child_count();
std::size_t count = 0;
for ( const node& child : children_ ) {
count += child.child_count_recursive();
count += 1u + child.child_count_recursive();
}
return count;
}

View File

@@ -153,26 +153,55 @@ TEST_CASE("node") {
}
}
}
SECTION("has_parent") {
SECTION("has_parent/has_parent_recursive") {
auto p = node::create(w);
REQUIRE_FALSE(p->has_parent());
REQUIRE_FALSE(p->has_parent(nullptr));
REQUIRE_FALSE(p->has_parent_recursive(nullptr));
auto n = node::create(w, p);
REQUIRE_FALSE(p->has_parent());
REQUIRE_FALSE(p->has_parent_recursive(n));
REQUIRE(n->has_parent());
REQUIRE(n->has_parent(p));
REQUIRE(n->has_parent(nullptr));
REQUIRE(n->has_parent_recursive(p));
REQUIRE_FALSE(n->has_parent_recursive(nullptr));
auto pp = node::create(w);
REQUIRE_FALSE(n->has_parent(pp));
REQUIRE_FALSE(pp->has_parent(pp));
REQUIRE_FALSE(n->has_parent_recursive(pp));
REQUIRE_FALSE(pp->has_parent_recursive(pp));
pp->add_child(p);
REQUIRE(n->has_parent(p));
REQUIRE(n->has_parent(pp));
REQUIRE(n->has_parent_recursive(p));
REQUIRE(n->has_parent_recursive(pp));
REQUIRE_FALSE(n->has_parent(n));
REQUIRE_FALSE(pp->has_parent(pp));
REQUIRE_FALSE(n->has_parent_recursive(n));
REQUIRE_FALSE(pp->has_parent_recursive(pp));
}
SECTION("has_children/has_child_recursive") {
auto p = node::create(w);
REQUIRE_FALSE(p->has_children());
REQUIRE_FALSE(p->has_child_recursive(nullptr));
auto n = node::create(w, p);
REQUIRE(p->has_children());
REQUIRE(p->has_child_recursive(n));
REQUIRE_FALSE(p->has_child_recursive(nullptr));
REQUIRE_FALSE(n->has_children());
REQUIRE_FALSE(n->has_child_recursive(p));
REQUIRE_FALSE(n->has_child_recursive(nullptr));
auto pp = node::create(w);
REQUIRE_FALSE(n->has_child_recursive(pp));
REQUIRE_FALSE(pp->has_child_recursive(pp));
pp->add_child(p);
REQUIRE_FALSE(n->has_child_recursive(p));
REQUIRE_FALSE(n->has_child_recursive(pp));
REQUIRE(pp->has_child_recursive(p));
REQUIRE(pp->has_child_recursive(n));
}
SECTION("auto_remove/remove_all_children") {
{