A toolkit for working with phylogenetic data.
v0.22.1
eulertour.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_TREE_ITERATOR_EULERTOUR_H_
2 #define GENESIS_TREE_ITERATOR_EULERTOUR_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
34 #include "genesis/tree/tree.hpp"
37 
38 #include <iterator>
39 #include <type_traits>
40 
41 namespace genesis {
42 namespace tree {
43 
44 // =================================================================================================
45 // Forward Declarations
46 // =================================================================================================
47 
48 class Tree;
49 class TreeNode;
50 class TreeEdge;
51 class TreeLink;
52 class Subtree;
53 
54 // =================================================================================================
55 // Euler Tour Iterator
56 // =================================================================================================
57 
58 template< bool is_const = true >
60 {
61 
62 public:
63 
64  // -----------------------------------------------------
65  // Typedefs
66  // -----------------------------------------------------
67 
68  // Make the memer types const or not, depending on iterator type.
69  using TreeType = typename std::conditional< is_const, Tree const, Tree >::type;
70  using LinkType = typename std::conditional< is_const, TreeLink const, TreeLink >::type;
71  using NodeType = typename std::conditional< is_const, TreeNode const, TreeNode >::type;
72  using EdgeType = typename std::conditional< is_const, TreeEdge const, TreeEdge >::type;
73 
75  using iterator_category = std::forward_iterator_tag;
76  // using value_type = NodeType;
77  // using pointer = NodeType*;
78  // using reference = NodeType&;
79  // using difference_type = std::ptrdiff_t;
80 
81  // -----------------------------------------------------
82  // Constructors and Rule of Five
83  // -----------------------------------------------------
84 
86  : link_( nullptr )
87  , start_( nullptr )
88  {}
89 
90  explicit IteratorEulertour( TreeType& tree )
91  : link_( &tree.root_link() )
92  , start_( &tree.root_link() )
93  {}
94 
96  : link_( &node.primary_link() )
97  , start_( &node.primary_link() )
98  {}
99 
101  : link_( &link )
102  , start_( &link )
103  {}
104 
105  explicit IteratorEulertour( Subtree const& subtree )
106  // We need to consider the edge case of a subtree that is only a leaf.
107  // In that case, the start_ is set to the one that is visited after,
108  // so that we iterate only the leaf itself.
109  : link_( &(subtree.link().next()) )
110  , start_( (link_ == &link_->next()) ? &(subtree.link().outer().next()) : &(subtree.link()) )
111  {}
112 
113  ~IteratorEulertour() = default;
114 
115  IteratorEulertour( IteratorEulertour const& ) = default;
116  IteratorEulertour( IteratorEulertour&& ) = default;
117 
118  IteratorEulertour& operator= ( IteratorEulertour const& ) = default;
120 
121  // -----------------------------------------------------
122  // Operators
123  // -----------------------------------------------------
124 
126  {
127  return *this;
128  }
129 
131  {
132  link_ = &link_->outer().next();
133  if( link_ == start_ ) {
134  link_ = nullptr;
135  }
136  return *this;
137  }
138 
140  {
141  self_type tmp = *this;
142  ++(*this);
143  return tmp;
144  }
145 
146  bool operator == (const self_type &other) const
147  {
148  return other.link_ == link_;
149  }
150 
151  bool operator != (const self_type &other) const
152  {
153  return !(other == *this);
154  }
155 
156  // -----------------------------------------------------
157  // Members
158  // -----------------------------------------------------
159 
160  bool is_first_iteration() const
161  {
162  return link_ == start_;
163  }
164 
165  LinkType& link() const
166  {
167  return *link_;
168  }
169 
170  NodeType& node() const
171  {
172  return link_->node();
173  }
174 
175  EdgeType& edge() const
176  {
177  return link_->edge();
178  }
179 
181  {
182  return *start_;
183  }
184 
186  {
187  return start_->node();
188  }
189 
190  // -----------------------------------------------------
191  // Data Members
192  // -----------------------------------------------------
193 
194 private:
195 
196  LinkType* link_;
197  LinkType* const start_;
198 };
199 
200 // =================================================================================================
201 // Euler Tour Wrapper Functions
202 // =================================================================================================
203 
204 template<typename ElementType>
206 eulertour( ElementType const& element )
207 {
208  return {
209  IteratorEulertour< true >( element ),
211  };
212 }
213 
214 template<typename ElementType>
216 eulertour( ElementType& element )
217 {
218  return {
219  IteratorEulertour< false >( element ),
221  };
222 }
223 
224 } // namespace tree
225 } // namespace genesis
226 
227 #endif // include guard
typename std::conditional< is_const, TreeLink const, TreeLink >::type LinkType
Definition: eulertour.hpp:70
IteratorEulertour & operator=(IteratorEulertour const &)=default
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
typename std::conditional< is_const, TreeEdge const, TreeEdge >::type EdgeType
Definition: eulertour.hpp:72
IteratorEulertour(NodeType &node)
Definition: eulertour.hpp:95
Reference to a subtree of a Tree.
Definition: subtree.hpp:69
utils::Range< IteratorEulertour< true > > eulertour(ElementType const &element)
Definition: eulertour.hpp:206
bool operator!=(const self_type &other) const
Definition: eulertour.hpp:151
IteratorEulertour(Subtree const &subtree)
Definition: eulertour.hpp:105
IteratorEulertour(TreeType &tree)
Definition: eulertour.hpp:90
bool operator==(const self_type &other) const
Definition: eulertour.hpp:146
typename std::conditional< is_const, TreeNode const, TreeNode >::type NodeType
Definition: eulertour.hpp:71
LinkType & start_link() const
Definition: eulertour.hpp:180
Header of Tree class.
Simple wrapper for typical begin() and end() iterators, to be used in range-based for loops...
Definition: range.hpp:46
typename std::conditional< is_const, Tree const, Tree >::type TreeType
Definition: eulertour.hpp:69
NodeType & start_node() const
Definition: eulertour.hpp:185
std::forward_iterator_tag iterator_category
Definition: eulertour.hpp:75