A toolkit for working with phylogenetic data.
v0.24.0
tree/formats/newick/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-2020 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"
38 
39 #include <iterator>
40 
41 namespace genesis {
42 namespace tree {
43 
44 // =================================================================================================
45 // Newick Input Iterator
46 // =================================================================================================
47 
77 {
78 public:
79 
80  // -------------------------------------------------------------------------
81  // Member Types
82  // -------------------------------------------------------------------------
83 
85  using iterator_category = std::input_iterator_tag;
86 
87  // -------------------------------------------------------------------------
88  // Constructors and Rule of Five
89  // -------------------------------------------------------------------------
90 
95  : input_stream_( nullptr )
96  , reader_()
97  , tree_()
98  {}
99 
103  explicit NewickInputIterator( std::shared_ptr<utils::BaseInputSource> source )
104  : input_stream_( std::make_shared<utils::InputStream>( source ))
105  , reader_()
106  , tree_()
107  {
108  // Setting so that we only read one tree at a time.
109  reader_.stop_after_semicolon( true );
110 
111  // Read first tree.
112  increment();
113  }
114 
119  NewickInputIterator( std::shared_ptr<utils::BaseInputSource> source, NewickReader const& settings )
120  : input_stream_( std::make_shared<utils::InputStream>( source ))
121  , reader_( settings )
122  , tree_()
123  {
124  // Setting so that we only read one tree at a time.
125  reader_.stop_after_semicolon( true );
126 
127  // Read first tree.
128  increment();
129  }
130 
131  ~NewickInputIterator() = default;
132 
133  NewickInputIterator( self_type const& ) = delete;
134  NewickInputIterator( self_type&& ) = default;
135 
136  self_type& operator= ( self_type const& ) = delete;
137  self_type& operator= ( self_type&& ) = default;
138 
139  // -------------------------------------------------------------------------
140  // Comparators
141  // -------------------------------------------------------------------------
142 
143  bool operator == ( self_type const& other ) const
144  {
145  return input_stream_ == other.input_stream_;
146  }
147 
148  bool operator != ( self_type const& other ) const
149  {
150  return !( *this == other );
151  }
152 
156  explicit operator bool() const
157  {
158  return good_;
159  }
160 
161  // -------------------------------------------------------------------------
162  // Accessors
163  // -------------------------------------------------------------------------
164 
165  Tree const& operator * () const
166  {
167  return dereference();
168  }
169 
170  Tree const* operator -> () const
171  {
172  return &dereference();
173  }
174 
175  Tree const& dereference() const
176  {
177  return tree_;
178  }
179 
180  // -------------------------------------------------------------------------
181  // Iteration
182  // -------------------------------------------------------------------------
183 
191  {
192  return *this;
193  }
194 
201  {
202  return self_type();
203  }
204 
206  {
207  increment();
208  return *this;
209  }
210 
211  void increment()
212  {
213  // Check whether the input stream is good (not end-of-stream) and can be read from.
214  // If not, we reached its end, so we stop reading in the next iteration.
215  if( ! input_stream_ || ! *input_stream_ ) {
216  good_ = false;
217  return;
218  }
219 
220  // Read the next tree.
221  tree_ = reader_.parse_single_tree( *input_stream_ );
222 
223  // Check whether we actually got a tree. We use empty as marker for this,
224  // which is valid, as we can never read an actual empty tree from any input
225  // (it always consists of at least the root node).
226  if( tree_.empty() ) {
227  good_ = false;
228  }
229  }
230 
231  // -------------------------------------------------------------------------
232  // Data Members
233  // -------------------------------------------------------------------------
234 
235 private:
236 
237  std::shared_ptr<utils::InputStream> input_stream_;
238 
239  bool good_ = true;
240  NewickReader reader_;
241  Tree tree_;
242 };
243 
244 } // namespace tree
245 } // namespace genesis
246 
247 #endif // include guard
bool empty() const
Return whether the Tree is empty (i.e., has no nodes, edges and links).
Definition: tree/tree.hpp:194
STL namespace.
Tree parse_single_tree(utils::InputStream &input_stream) const
Parse a single tree. Depending on stop_after_semicolon(), stop after the semicolon or continue until ...
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
NewickInputIterator()
Create a default instance, with no input.
Iterate an input stream and parse it as Newick trees.
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:97
self_type & begin()
Beginning of the iterator.
NewickInputIterator(std::shared_ptr< utils::BaseInputSource > source, NewickReader const &settings)
Create an instance that reads from an input source, using the settings of a given NewickReader...
NewickInputIterator(std::shared_ptr< utils::BaseInputSource > source)
Create an instance that reads from an input source, using a default NewickReader. ...
NewickReader & stop_after_semicolon(bool value)
Set whether reading a single tree stops after the semicolon that finishes a Newick tree...
Header of Tree class.
self_type & operator=(self_type const &)=delete