From f9054a9abf0c23a767cdce3b5de96ffd9ae6ab94 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 10 Feb 2019 08:55:31 +0700 Subject: [PATCH] node: has_children/has_child_recursive --- headers/enduro2d/high/node.hpp | 7 +++- sources/enduro2d/high/node.cpp | 26 ++++++++++---- untests/sources/untests_high/node.cpp | 49 +++++++++++++++++++++------ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/headers/enduro2d/high/node.hpp b/headers/enduro2d/high/node.hpp index 62b053e2..839f9158 100644 --- a/headers/enduro2d/high/node.hpp +++ b/headers/enduro2d/high/node.hpp @@ -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; diff --git a/sources/enduro2d/high/node.cpp b/sources/enduro2d/high/node.cpp index 8cec5c4b..c8c01906 100644 --- a/sources/enduro2d/high/node.cpp +++ b/sources/enduro2d/high/node.cpp @@ -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; } diff --git a/untests/sources/untests_high/node.cpp b/untests/sources/untests_high/node.cpp index 1f9a5f9a..054ded70 100644 --- a/untests/sources/untests_high/node.cpp +++ b/untests/sources/untests_high/node.cpp @@ -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") { {