A toolkit for working with phylogenetic data.
v0.18.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
input_iterator.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_TREE_FORMATS_NEWICK_INPUT_ITERATOR_H_
2 #define GENESIS_TREE_FORMATS_NEWICK_INPUT_ITERATOR_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2017 Lucas Czech
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 
40 namespace genesis {
41 namespace tree {
42 
43 // =================================================================================================
44 // Newick Input Iterator
45 // =================================================================================================
46 
68 {
69 public:
70 
71  // -------------------------------------------------------------------------
72  // Member Types
73  // -------------------------------------------------------------------------
74 
76  using iterator_category = std::input_iterator_tag;
77 
78  // -------------------------------------------------------------------------
79  // Constructors and Rule of Five
80  // -------------------------------------------------------------------------
81 
83  : reader_()
84  , input_stream_( nullptr )
85  , tree_()
86  {}
87 
89  : reader_()
90  , input_stream_( &in )
91  , tree_()
92  {
93  // Setting so that we only read one tree at a time.
94  reader_.stop_at_semicolon( true );
95 
96  // Read first tree.
97  increment();
98  }
99 
101  : reader_( reader )
102  , input_stream_( &in )
103  , tree_()
104  {
105  // Setting so that we only read one tree at a time.
106  reader_.stop_at_semicolon( true );
107 
108  // Read first tree.
109  increment();
110  }
111 
112  ~NewickInputIterator() = default;
113 
114  NewickInputIterator( self_type const& ) = delete;
115  NewickInputIterator( self_type&& ) = default;
116 
117  self_type& operator= ( self_type const& ) = delete;
118  self_type& operator= ( self_type&& ) = default;
119 
120  // -------------------------------------------------------------------------
121  // Comparators
122  // -------------------------------------------------------------------------
123 
124  bool operator == ( self_type const& other ) const
125  {
126  return input_stream_ == other.input_stream_;
127  }
128 
129  bool operator != ( self_type const& other ) const
130  {
131  return !( *this == other );
132  }
133 
137  explicit operator bool() const
138  {
139  return good_;
140  }
141 
142  // -------------------------------------------------------------------------
143  // Accessors
144  // -------------------------------------------------------------------------
145 
146  Tree const& operator * () const
147  {
148  return dereference();
149  }
150 
151  Tree const* operator -> () const
152  {
153  return &dereference();
154  }
155 
156  Tree const& dereference() const
157  {
158  return tree_;
159  }
160 
167  {
168  return reader_;
169  }
170 
171  // -------------------------------------------------------------------------
172  // Iteration
173  // -------------------------------------------------------------------------
174 
176  {
177  increment();
178  return *this;
179  }
180 
181  void increment()
182  {
183  // Check whether the input stream is good (not end-of-stream) and can be read from.
184  // If not, we reached its end, so we stop reading in the next iteration.
185  if( input_stream_ == nullptr || ! *input_stream_ ) {
186  good_ = false;
187  return;
188  }
189 
190  // Read the next tree.
191  tree_ = reader_.parse_single_tree( *input_stream_ );
192 
193  // Check whether we actually got a tree. We use empty as marker for this,
194  // which is valid, as we can never read an actual empty tree from any input
195  // (it always consists of at least the root node).
196  if( tree_.empty() ) {
197  good_ = false;
198  }
199  }
200 
201  // -------------------------------------------------------------------------
202  // Data Members
203  // -------------------------------------------------------------------------
204 
205 private:
206 
207  NewickReader reader_;
208  utils::InputStream* input_stream_;
209  Tree tree_;
210  bool good_ = true;
211 };
212 
213 } // namespace tree
214 } // namespace genesis
215 
216 #endif // include guard
NewickInputIterator(utils::InputStream &in, NewickReader const &reader)
NewickInputIterator(utils::InputStream &in)
std::input_iterator_tag iterator_category
Iterate an input stream and parse it as Newick trees.
Tree parse_single_tree(utils::InputStream &input_stream) const
Parse a single tree. Depending on stop_at_semicolon(), stop after the semicolon or continue until the...
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:95
bool empty() const
Return whether the Tree is empty (i.e., has no nodes, edges and links).
Definition: tree/tree.cpp:222
bool operator!=(self_type const &other) const
NewickReader & reader()
Return the NewickReader used for this iterator.
Header of Tree class.
self_type & operator=(self_type const &)=delete
NewickReader & stop_at_semicolon(bool value)
Set whether reading a single tree stops after the semicolon that finishes a Newick tree...
Stream interface for reading data from an InputSource, that keeps track of line and column counters...
bool operator==(self_type const &other) const