#pragma once #include namespace Stats { namespace Base { class TreeImpl { public: struct Top { TreeImpl * head = nullptr; TreeImpl * tail = nullptr; void append(TreeImpl * node) { if(!head) { head = node; } else { tail->next = node;} tail = node; } }; virtual void print(std::ostream &) = 0; const std::string name; TreeImpl(const std::string & name) : name(name) {} protected: virtual ~TreeImpl() = default; TreeImpl * next = nullptr; Top children; template friend void ForAll(TreeImpl::Top & range, size_t level, func_t func, bool destroy = false); }; template inline void ForAll(TreeImpl::Top & range, size_t level, func_t func, bool destroy) { auto it = range.head; while(it) { auto next = it->next; func(it, level); ForAll(it->children, level + 1, func); if(destroy) delete it; it = next; } } template class Tree : public TreeImpl { public: Tree(const std::string & name) : TreeImpl{name} { top.append(this); } Tree(const std::string & name, Tree * parent) : TreeImpl{name} { parent->children.append(this); } protected: virtual ~Tree() = default; }; } }