Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
Tree.hpp
1// Copyright 2021 Arnaud Becheler <abechele@umich.edu>
2
10
11#ifndef TREE_H_INCLUDED
12#define TREE_H_INCLUDED
13
14#include <vector>
15
16namespace quetzal
17{
18namespace coalescence
19{
20namespace container
21{
28template <class CellT> class Tree
29{
30 private:
31 Tree<CellT> *m_parent;
32 CellT m_cell;
33 std::vector<Tree<CellT>> m_children;
34
35 public:
41 Tree();
49 Tree(const CellT &cell);
57 Tree(CellT &&cell) noexcept;
65 Tree(const Tree<CellT> &other);
73 Tree(Tree<CellT> &&other) noexcept;
82 Tree(CellT &&cell, std::vector<Tree<CellT>> &&children) noexcept;
88 Tree<CellT> &operator=(const Tree<CellT> &other);
94 Tree<CellT> &operator=(Tree<CellT> &&other) noexcept;
102 const CellT &cell() const;
110 CellT &cell();
118 Tree<CellT> &add_child(const Tree<CellT> &subtree);
126 Tree<CellT> &add_child(Tree<CellT> &&subtree) noexcept;
134 Tree<CellT> &add_child(CellT &&cell) noexcept;
140 bool has_parent() const
141 {
142 return m_parent != nullptr;
143 }
149 bool has_children() const;
158 template <typename UnaryOperation> void visit_cells_by_pre_order_DFS(UnaryOperation op) const
159 {
160 op(this->cell());
161 for (auto const &child : this->m_children)
162 {
163 child.visit_cells_by_pre_order_DFS(op);
164 }
165 }
174 template <class UnaryOperation> void visit_subtrees_by_pre_order_DFS(UnaryOperation op)
175 {
176 op(*this);
177 for (auto &child : this->m_children)
178 {
179 child.visit_subtrees_by_pre_order_DFS(op);
180 }
181 }
182
183 template <typename Op1, typename Op2, typename Op3>
184 void visit_subtrees_by_generic_DFS(Op1 preorder, Op2 inorder, Op3 postorder)
185 {
186 preorder(*this);
187 for (auto &child : this->m_children)
188 {
189 child.visit_subtrees_by_generic_DFS(preorder, inorder, postorder);
190 inorder(*this);
191 }
192 postorder(*this);
193 }
194
195 auto &parent()
196 {
197 assert(has_parent());
198 return *m_parent;
199 }
200
201 auto const &parent() const
202 {
203 assert(has_parent());
204 return *m_parent;
205 }
206
207 unsigned int nb_children() const
208 {
209 return m_children.size();
210 }
218 template <typename UnaryOperation> void visit_leaves_cells_by_DFS(UnaryOperation op) const
219 {
220 if (has_children())
221 {
222 for (auto const &child : this->m_children)
223 {
224 child.visit_leaves_cells_by_DFS(op);
225 }
226 }
227 else
228 {
229 op(this->cell());
230 }
231 }
232}; // end class Tree
233
234template <typename CellT> Tree<CellT>::Tree() : m_parent(nullptr), m_cell(), m_children()
235{
236}
237
238template <typename CellT> Tree<CellT>::Tree(const CellT &cell) : m_parent(nullptr), m_cell(cell), m_children()
239{
240}
241
242template <typename CellT>
243Tree<CellT>::Tree(CellT &&cell) noexcept : m_parent(nullptr), m_cell(std::move(cell)), m_children()
244{
245}
246
247template <class CellT>
248Tree<CellT>::Tree(const Tree<CellT> &other) : m_parent(nullptr), m_cell(other.m_cell), m_children(other.m_children)
249{
250 for (Tree<CellT> &child : m_children)
251 child.m_parent = this;
252}
253
254template <class CellT>
256 : m_parent(nullptr), m_cell(std::move(other.m_cell)), m_children(std::move(other.m_children))
257{
258 for (Tree<CellT> &child : m_children)
259 child.m_parent = this;
260}
261
262template <class CellT>
263Tree<CellT>::Tree(CellT &&cell, std::vector<Tree<CellT>> &&children) noexcept
264 : m_parent(nullptr), m_cell(std::move(cell)), m_children(std::move(children))
265{
266 for (Tree<CellT> &child : m_children)
267 child.m_parent = this;
268}
269
270template <class CellT> Tree<CellT> &Tree<CellT>::operator=(const Tree<CellT> &other)
271{
272 Tree<CellT> otherCopy(other);
273 *this = std::move(otherCopy);
274 return *this;
275}
276
277template <class CellT> Tree<CellT> &Tree<CellT>::operator=(Tree<CellT> &&other) noexcept
278{
279 m_cell = std::move(other.m_cell);
280 m_children = std::move(other.m_children);
281 for (Tree<CellT> &child : m_children)
282 child.m_parent = this;
283 return *this;
284}
285
286template <class CellT> const CellT &Tree<CellT>::cell() const
287{
288 return m_cell;
289}
290
291template <class CellT> CellT &Tree<CellT>::cell()
292{
293 return m_cell;
294}
295
296template <class CellT> Tree<CellT> &Tree<CellT>::add_child(const Tree<CellT> &subtree)
297{
298 Tree<CellT> otherCopy(subtree);
299 otherCopy.m_parent = this;
300 m_children.push_back(std::move(otherCopy));
301 return *this;
302}
303
304template <class CellT> Tree<CellT> &Tree<CellT>::add_child(Tree<CellT> &&subtree) noexcept
305{
306 subtree.m_parent = this;
307 m_children.push_back(std::move(subtree));
308 return *this;
309}
310
311template <class CellT> Tree<CellT> &Tree<CellT>::add_child(CellT &&cell) noexcept
312{
313 Tree<CellT> subtree(std::move(cell));
314 subtree.m_parent = this;
315 m_children.push_back(std::move(subtree));
316 return m_children.back();
317}
318
319template <class CellT> bool Tree<CellT>::has_children() const
320{
321 return !m_children.empty();
322}
323} // end namespace container
324} // end namespace coalescence
325} // end namespace quetzal
326
327#endif
Data structure for representing tree topologies where each node contains a data field.
Definition Tree.hpp:29
Tree< CellT > & add_child(const Tree< CellT > &subtree)
Add a subtree to the children list of the tree.
Definition Tree.hpp:296
const CellT & cell() const
Cell accessor.
Definition Tree.hpp:286
void visit_subtrees_by_pre_order_DFS(UnaryOperation op)
Applies a function object to each node encountered in a depth first search algorithm.
Definition Tree.hpp:174
bool has_children() const
Checks whether the tree has one or more child.
Definition Tree.hpp:319
Tree()
Default constructor.
Definition Tree.hpp:234
Tree< CellT > & operator=(const Tree< CellT > &other)
Copy assignment operator.
Definition Tree.hpp:270
void visit_leaves_cells_by_DFS(UnaryOperation op) const
Applies a function object to each leave encountered in a depth first search algorithm.
Definition Tree.hpp:218
bool has_parent() const
Checks whether the tree has a parent.
Definition Tree.hpp:140
void visit_cells_by_pre_order_DFS(UnaryOperation op) const
Applies a function object to each node encountered in a depth first search algorithm.
Definition Tree.hpp:158
Simulation of coalescence-based models of molecular evolution.
Definition coalescence.hpp:21