A toolkit for working with phylogenetic data.
v0.24.0
node_links.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_TREE_ITERATOR_NODE_LINKS_H_
2 #define GENESIS_TREE_ITERATOR_NODE_LINKS_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"
36 
37 #include <iterator>
38 #include <type_traits>
39 
40 namespace genesis {
41 namespace tree {
42 
43 // =================================================================================================
44 // Forward Declarations
45 // =================================================================================================
46 
47 class Tree;
48 class TreeNode;
49 class TreeEdge;
50 class TreeLink;
51 
52 // =============================================================================
53 // Iterator Node Links
54 // =============================================================================
55 
56 template< bool is_const = true >
58 {
59 
60 public:
61 
62  // -----------------------------------------------------
63  // Typedefs
64  // -----------------------------------------------------
65 
66  // Make the memer types const or not, depending on iterator type.
67  using TreeType = typename std::conditional< is_const, Tree const, Tree >::type;
68  using LinkType = typename std::conditional< is_const, TreeLink const, TreeLink >::type;
69  using NodeType = typename std::conditional< is_const, TreeNode const, TreeNode >::type;
70  using EdgeType = typename std::conditional< is_const, TreeEdge const, TreeEdge >::type;
71 
73  using iterator_category = std::forward_iterator_tag;
74  // using value_type = NodeType;
75  // using pointer = NodeType*;
76  // using reference = NodeType&;
77  // using difference_type = std::ptrdiff_t;
78 
79  // -----------------------------------------------------
80  // Constructors and Rule of Five
81  // -----------------------------------------------------
82 
84  : start_( nullptr )
85  , link_( nullptr )
86  {}
87 
89  : start_( &node.primary_link() )
90  , link_( &node.primary_link() )
91  {}
92 
94  : start_( &link )
95  , link_( &link )
96  {}
97 
98  ~IteratorNodeLinks() = default;
99 
100  IteratorNodeLinks( IteratorNodeLinks const& ) = default;
101  IteratorNodeLinks( IteratorNodeLinks&& ) = default;
102 
103  IteratorNodeLinks& operator= ( IteratorNodeLinks const& ) = default;
105 
106  // -----------------------------------------------------
107  // Operators
108  // -----------------------------------------------------
109 
111  {
112  return *this;
113  }
114 
116  {
117  link_ = &link_->next();
118  if (link_ == start_) {
119  link_ = nullptr;
120  }
121  return *this;
122  }
123 
125  {
126  self_type tmp = *this;
127  ++(*this);
128  return tmp;
129  }
130 
131  bool operator == (const self_type &other) const
132  {
133  return other.link_ == link_;
134  }
135 
136  bool operator != (const self_type &other) const
137  {
138  return !(other == *this);
139  }
140 
141  // -----------------------------------------------------
142  // Members
143  // -----------------------------------------------------
144 
145  bool is_first_iteration() const
146  {
147  return link_ == start_;
148  }
149 
150  LinkType& link() const
151  {
152  return *link_;
153  }
154 
155  NodeType& node() const
156  {
157  return link_->node();
158  }
159 
160  EdgeType& edge() const
161  {
162  return link_->edge();
163  }
164 
166  {
167  return *start_;
168  }
169 
170  // -----------------------------------------------------
171  // Data Members
172  // -----------------------------------------------------
173 
174 private:
175 
176  LinkType* const start_;
177  LinkType* link_;
178 };
179 
180 // =================================================================================================
181 // Node Links Wrapper Functions
182 // =================================================================================================
183 
184 template<typename ElementType>
186 node_links( ElementType const& element )
187 {
188  return {
189  IteratorNodeLinks< true >( element ),
191  };
192 }
193 
194 template<typename ElementType>
196 node_links( ElementType& element )
197 {
198  return {
199  IteratorNodeLinks< false >( element ),
201  };
202 }
203 
204 } // namespace tree
205 } // namespace genesis
206 
207 #endif // include guard
utils::Range< IteratorNodeLinks< true > > node_links(ElementType const &element)
Definition: node_links.hpp:186
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
Header of Tree class.
Simple wrapper for typical begin() and end() iterators, to be used in range-based for loops...
Definition: range.hpp:46