From ab0a743ad249a3415a95479b09b28882bc87c630 Mon Sep 17 00:00:00 2001 From: heck Date: Thu, 8 Jul 2021 16:42:06 +0200 Subject: [PATCH] Test: PityTest - PityTree addNew() as abstract factory with perfect forwarding --- src/PityTree.hh | 15 ++++++++------ src/PityTree.hxx | 53 ++++++++++++++++++++++++------------------------ 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/PityTree.hh b/src/PityTree.hh index 3644e7e..74960c8 100644 --- a/src/PityTree.hh +++ b/src/PityTree.hh @@ -36,13 +36,16 @@ namespace pEp { virtual PityTree* clone() = 0; // Append - T& addRef(T& node); - - template - T& addNew(Args&&... args); + // creates a new instance of CT, add the new instance as child and returns a ref to it + template + CT& addNew(Args&&... args); + // Creates a copy, add the copy as child and returns a ref to it template - T& addCopy(const CT&& t, const std::string& new_name = ""); + CT& addCopy(const CT&& child, const std::string& new_name = ""); + + // Just adds child as a non-owned reference. + T& addRef(T& child); // Query T* getParent() const; @@ -66,7 +69,7 @@ namespace pEp { void setParent(T* const parent); private: - void _cloneChildRefs(const PityTree& rhs); + void _copyChildRefs(const PityTree& rhs); // Fields std::string _nodename; T& _self; diff --git a/src/PityTree.hxx b/src/PityTree.hxx index 7b9fcb6..411471a 100644 --- a/src/PityTree.hxx +++ b/src/PityTree.hxx @@ -44,49 +44,49 @@ namespace pEp { { _nodename = rhs._nodename; _parent = nullptr; - _cloneChildRefs(rhs); + _copyChildRefs(rhs); } template - PityTree& PityTree::operator=(const PityTree& rhs) { + PityTree& PityTree::operator=(const PityTree& rhs) + { _nodename = rhs._nodename; _parent = nullptr; - _cloneChildRefs(rhs); + _copyChildRefs(rhs); return *this; } - template - T& PityTree::addRef(T& node) - { - node.setParent(&_self); - _childrefs.insert(ChildRef(node.getName(), node)); - return node; - } - - template - template - T& PityTree::addNew(Args&&... args) + template + CT& PityTree::addNew(Args&&... args) { - _childobjs.push_back(ChildObj(new T(std::forward(args)...))); - T& ret = *_childobjs.back().get(); - addRef(ret); - return ret; + static_assert(std::is_base_of::value, "T must be base of CT"); + std::shared_ptr tmp = std::make_shared(std::forward(args)...); + _childobjs.push_back(tmp); + addRef(*tmp.get()); + return *tmp.get(); } - template template - T& PityTree::addCopy(const CT&& t, const std::string& new_name) + CT& PityTree::addCopy(const CT&& child, const std::string& new_name) { static_assert(std::is_base_of::value, "PityTree must be a base of T"); - _childobjs.push_back(ChildObj(new CT(t))); - T& ret = *_childobjs.back().get(); + CT* tmpraw = new CT(child); + _childobjs.push_back(ChildObj(tmpraw)); if (new_name != "") { - ret.setName(new_name); + tmpraw->setName(new_name); } - addRef(ret); - return ret; + addRef(*tmpraw); + return *tmpraw; + } + + template + T& PityTree::addRef(T& child) + { + child.setParent(&_self); + _childrefs.insert(ChildRef(child.getName(), child)); + return child; } template @@ -203,7 +203,8 @@ namespace pEp { // When you copy a treenode, you need to create a copy of all children // and take ownership template - void PityTree::_cloneChildRefs(const PityTree& rhs) { + void PityTree::_copyChildRefs(const PityTree& rhs) + { for (const ChildRef& cr : rhs.getChildRefs()) { _childobjs.push_back(ChildObj(cr.second.clone())); T& ret = *_childobjs.back().get();