Browse Source

Test: PityTest - PityTree addNew() as abstract factory with perfect forwarding

master
heck 4 years ago
parent
commit
ab0a743ad2
  1. 15
      src/PityTree.hh
  2. 53
      src/PityTree.hxx

15
src/PityTree.hh

@ -36,13 +36,16 @@ namespace pEp {
virtual PityTree* clone() = 0; virtual PityTree* clone() = 0;
// Append // Append
T& addRef(T& node); // creates a new instance of CT, add the new instance as child and returns a ref to it
template<typename CT, typename... Args>
template<typename... Args> CT& addNew(Args&&... args);
T& addNew(Args&&... args);
// Creates a copy, add the copy as child and returns a ref to it
template<typename CT> template<typename CT>
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 // Query
T* getParent() const; T* getParent() const;
@ -66,7 +69,7 @@ namespace pEp {
void setParent(T* const parent); void setParent(T* const parent);
private: private:
void _cloneChildRefs(const PityTree<T>& rhs); void _copyChildRefs(const PityTree<T>& rhs);
// Fields // Fields
std::string _nodename; std::string _nodename;
T& _self; T& _self;

53
src/PityTree.hxx

@ -44,49 +44,49 @@ namespace pEp {
{ {
_nodename = rhs._nodename; _nodename = rhs._nodename;
_parent = nullptr; _parent = nullptr;
_cloneChildRefs(rhs); _copyChildRefs(rhs);
} }
template<class T> template<class T>
PityTree<T>& PityTree<T>::operator=(const PityTree<T>& rhs) { PityTree<T>& PityTree<T>::operator=(const PityTree<T>& rhs)
{
_nodename = rhs._nodename; _nodename = rhs._nodename;
_parent = nullptr; _parent = nullptr;
_cloneChildRefs(rhs); _copyChildRefs(rhs);
return *this; return *this;
} }
template<class T>
T& PityTree<T>::addRef(T& node)
{
node.setParent(&_self);
_childrefs.insert(ChildRef(node.getName(), node));
return node;
}
template<typename T> template<typename T>
template<typename... Args> template<typename CT, typename... Args>
T& PityTree<T>::addNew(Args&&... args) CT& PityTree<T>::addNew(Args&&... args)
{ {
_childobjs.push_back(ChildObj(new T(std::forward<Args>(args)...))); static_assert(std::is_base_of<T, CT>::value, "T must be base of CT");
T& ret = *_childobjs.back().get(); std::shared_ptr<CT> tmp = std::make_shared<CT>(std::forward<Args>(args)...);
addRef(ret); _childobjs.push_back(tmp);
return ret; addRef(*tmp.get());
return *tmp.get();
} }
template<typename T> template<typename T>
template<typename CT> template<typename CT>
T& PityTree<T>::addCopy(const CT&& t, const std::string& new_name) CT& PityTree<T>::addCopy(const CT&& child, const std::string& new_name)
{ {
static_assert(std::is_base_of<T, CT>::value, "PityTree<T> must be a base of T"); static_assert(std::is_base_of<T, CT>::value, "PityTree<T> must be a base of T");
_childobjs.push_back(ChildObj(new CT(t))); CT* tmpraw = new CT(child);
T& ret = *_childobjs.back().get(); _childobjs.push_back(ChildObj(tmpraw));
if (new_name != "") { if (new_name != "") {
ret.setName(new_name); tmpraw->setName(new_name);
} }
addRef(ret); addRef(*tmpraw);
return ret; return *tmpraw;
}
template<class T>
T& PityTree<T>::addRef(T& child)
{
child.setParent(&_self);
_childrefs.insert(ChildRef(child.getName(), child));
return child;
} }
template<class T> template<class T>
@ -203,7 +203,8 @@ namespace pEp {
// When you copy a treenode, you need to create a copy of all children // When you copy a treenode, you need to create a copy of all children
// and take ownership // and take ownership
template<class T> template<class T>
void PityTree<T>::_cloneChildRefs(const PityTree<T>& rhs) { void PityTree<T>::_copyChildRefs(const PityTree<T>& rhs)
{
for (const ChildRef& cr : rhs.getChildRefs()) { for (const ChildRef& cr : rhs.getChildRefs()) {
_childobjs.push_back(ChildObj(cr.second.clone())); _childobjs.push_back(ChildObj(cr.second.clone()));
T& ret = *_childobjs.back().get(); T& ret = *_childobjs.back().get();

Loading…
Cancel
Save