A library for working with phylogenetic and population genetic data.
v0.27.0
base_window_iterator.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_POPULATION_WINDOW_BASE_WINDOW_ITERATOR_H_
2 #define GENESIS_POPULATION_WINDOW_BASE_WINDOW_ITERATOR_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2022 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 <lczech@carnegiescience.edu>
23  Department of Plant Biology, Carnegie Institution For Science
24  260 Panama Street, Stanford, CA 94305, USA
25 */
26 
37 
38 #include <cassert>
39 #include <functional>
40 #include <memory>
41 #include <stdexcept>
42 #include <string>
43 #include <type_traits>
44 #include <utility>
45 
46 namespace genesis {
47 namespace population {
48 
49 // =================================================================================================
50 // Base Window Iterator
51 // =================================================================================================
52 
105 template<class ForwardIterator, class DataType = typename ForwardIterator::value_type>
107 {
108 public:
109 
110  // -------------------------------------------------------------------------
111  // Typedefs and Enums
112  // -------------------------------------------------------------------------
113 
115 
117  using Entry = typename Window::Entry;
118  using InputType = typename ForwardIterator::value_type;
119 
120  using iterator_category = std::input_iterator_tag;
122  using pointer = value_type*;
124  using const_reference = value_type const&;
125 
126  // -------------------------------------------------------------------------
127  // Public Functors
128  // -------------------------------------------------------------------------
129 
134  std::function<DataType( InputType const& )> entry_input_function;
135 
139  std::function<std::string( InputType const& )> chromosome_function;
140 
145  std::function<size_t( InputType const& )> position_function;
146 
147  // ======================================================================================
148  // Internal Public Iterator
149  // ======================================================================================
150 
151 protected:
152 
153  // Forward Declaration.
154  class BaseIterator;
155 
156 public:
157 
173  class Iterator
174  {
175  public:
176 
177  // -------------------------------------------------------------------------
178  // Constructors and Rule of Five
179  // -------------------------------------------------------------------------
180 
182 
184  using Entry = typename Window::Entry;
185  using InputType = typename ForwardIterator::value_type;
186 
187  using iterator_category = std::input_iterator_tag;
189  using pointer = value_type*;
191  using const_reference = value_type const&;
192 
193  protected:
194 
195  Iterator() = delete;
196 
197  Iterator( std::unique_ptr<BaseIterator> base_iterator )
198  : pimpl_( std::move( base_iterator ))
199  {}
200 
201  public:
202 
203  ~Iterator() = default;
204 
205  Iterator( self_type const& ) = default;
206  Iterator( self_type&& ) = default;
207 
208  Iterator& operator= ( self_type const& ) = default;
209  Iterator& operator= ( self_type&& ) = default;
210 
212 
213  // -------------------------------------------------------------------------
214  // Properties
215  // -------------------------------------------------------------------------
216 
227  bool is_first_window() const
228  {
229  assert( pimpl_ );
230  return pimpl_->is_first_window_;
231  }
232 
243  bool is_last_window() const
244  {
245  assert( pimpl_ );
246  return pimpl_->is_last_window_;
247  }
248 
249  // -------------------------------------------------------------------------
250  // Accessors
251  // -------------------------------------------------------------------------
252 
253  value_type const & operator*() const
254  {
255  assert( pimpl_ );
256  return pimpl_->get_current_window_();
257  }
258 
260  {
261  assert( pimpl_ );
262  return pimpl_->get_current_window_();
263  }
264 
265  value_type const * operator->() const
266  {
267  assert( pimpl_ );
268  return &( pimpl_->get_current_window_() );
269  }
270 
272  {
273  assert( pimpl_ );
274  return &( pimpl_->get_current_window_() );
275  }
276 
277  // -------------------------------------------------------------------------
278  // Iteration
279  // -------------------------------------------------------------------------
280 
282  {
283  assert( pimpl_ );
284  pimpl_->increment_();
285  return *this;
286  }
287 
288  // self_type operator ++(int)
289  // {
290  // auto cpy = *this;
291  // increment_();
292  // return cpy;
293  // }
294 
304  bool operator==( self_type const& other ) const
305  {
306  assert( pimpl_ );
307  assert( other.pimpl_ );
308 
309  // We compare the parents as a baseline - two past-the-end iterator shall
310  // always compare equal. If only one of them is past-the-end, they will compare false.
311  return pimpl_->get_parent_() == other.pimpl_->get_parent_();
312  }
313 
314  bool operator!=( self_type const& other ) const
315  {
316  return !(*this == other);
317  }
318 
319  // -------------------------------------------------------------------------
320  // PIMPL-like Implementation Abstraction
321  // -------------------------------------------------------------------------
322 
323  private:
324 
325  std::unique_ptr<BaseIterator> pimpl_;
326 
327  };
328 
329  // ======================================================================================
330  // Internal Base Iterator for PIMPL-like Abstraction
331  // ======================================================================================
332 
333 protected:
334 
343  {
344  public:
345 
346  // -------------------------------------------------------------------------
347  // Constructors and Rule of Five
348  // -------------------------------------------------------------------------
349 
351 
353  using Entry = typename Window::Entry;
354  using InputType = typename ForwardIterator::value_type;
355 
356  using iterator_category = std::input_iterator_tag;
358  using pointer = value_type*;
360  using const_reference = value_type const&;
361 
362  protected:
363 
364  // BaseIterator() = default;
365 
371  {
372  init_( parent );
373  }
374 
375  public:
376 
377  ~BaseIterator() = default;
378 
379  BaseIterator( self_type const& ) = default;
380  BaseIterator( self_type&& ) = default;
381 
382  BaseIterator& operator= ( self_type const& ) = default;
383  BaseIterator& operator= ( self_type&& ) = default;
384 
386  friend Iterator;
387 
388  // -------------------------------------------------------------------------
389  // Internal Members
390  // -------------------------------------------------------------------------
391 
392  protected:
393 
397  void init_( BaseWindowIterator const* parent )
398  {
399  // We use the parent as a check if this Iterator is intended to be a begin()
400  // or end() iterator. If its the former, init. If the latter, we are done here.
401  // After we are done iterating the input (for which we do need _its_ begin and end
402  // iterators), we then set the parent_ to nullptr, as a sign that we are done.
403  // This allows us also to know if we reached end() (of the window iteration;
404  // not of the underlying data iterator) without having to store the end() iterator
405  // when using this class.
406  if( ! parent ) {
407  return;
408  }
409 
410  // Check that the functors are set up.
411  if( ! parent->entry_input_function ) {
412  throw std::runtime_error(
413  "Need to set BaseWindowIterator::entry_input_function "
414  "before iterating over Windows with a Window Iterator."
415  );
416  }
417  if( ! parent->chromosome_function ) {
418  throw std::runtime_error(
419  "Need to set BaseWindowIterator::chromosome_function "
420  "before iterating over Windows with a Window Iterator."
421  );
422  }
423  if( ! parent->position_function ) {
424  throw std::runtime_error(
425  "Need to set BaseWindowIterator::position_function "
426  "before iterating over Windows with a Window Iterator."
427  );
428  }
429 
430  // Copy over the underlying data iterator.
431  current_ = parent->begin_;
432  end_ = parent->end_;
433  }
434 
435  // -------------------------------------------------------------------------
436  // Virtual Members
437  // -------------------------------------------------------------------------
438 
439  protected:
440 
444  virtual void increment_() = 0;
445 
449  virtual value_type& get_current_window_() const = 0;
450 
457  virtual BaseWindowIterator const* get_parent_() const = 0;
458 
459  protected:
460 
461  // Need to manually keep track of those...
462  bool is_first_window_ = true;
463  bool is_last_window_ = false;
464 
465  // Underlying iterator
466  ForwardIterator current_;
467  ForwardIterator end_;
468 
469  };
470 
471  // ======================================================================================
472  // Main Class
473  // ======================================================================================
474 
475 public:
476 
477  // -------------------------------------------------------------------------
478  // Constructors and Rule of Five
479  // -------------------------------------------------------------------------
480 
482  ForwardIterator begin, ForwardIterator end
483  )
484  : begin_(begin)
485  , end_(end)
486  {}
487 
488  ~BaseWindowIterator() = default;
489 
490  BaseWindowIterator( BaseWindowIterator const& ) = default;
491  BaseWindowIterator( BaseWindowIterator&& ) = default;
492 
493  BaseWindowIterator& operator= ( BaseWindowIterator const& ) = default;
495 
496  friend Iterator;
497 
498  // -------------------------------------------------------------------------
499  // Iteration
500  // -------------------------------------------------------------------------
501 
503  {
504  return Iterator( get_begin_iterator_() );
505  }
506 
508  {
509  return Iterator( get_end_iterator_() );
510  }
511 
512  // -------------------------------------------------------------------------
513  // Virtual Members
514  // -------------------------------------------------------------------------
515 
516 protected:
517 
518  virtual std::unique_ptr<BaseIterator> get_begin_iterator_() = 0;
519  virtual std::unique_ptr<BaseIterator> get_end_iterator_() = 0;
520 
521  // -------------------------------------------------------------------------
522  // Data Members
523  // -------------------------------------------------------------------------
524 
525 private:
526 
527  // Underlying iterator to the data that we want to put in windows.
528  ForwardIterator begin_;
529  ForwardIterator end_;
530 
531 };
532 
533 } // namespace population
534 } // namespace genesis
535 
536 #endif // include guard
genesis::population::BaseWindowIterator::BaseWindowIterator
BaseWindowIterator(ForwardIterator begin, ForwardIterator end)
Definition: base_window_iterator.hpp:481
genesis::population::BaseWindowIterator::Iterator::operator!=
bool operator!=(self_type const &other) const
Definition: base_window_iterator.hpp:314
genesis::population::BaseWindowIterator::BaseIterator::BaseWindowIterator
friend BaseWindowIterator
Definition: base_window_iterator.hpp:385
genesis::population::BaseWindowIterator::BaseIterator::get_current_window_
virtual value_type & get_current_window_() const =0
Get the current window that the iterator shall return when dereferenced.
genesis::population::BaseWindowIterator::Window
::genesis::population::Window< DataType > Window
Definition: base_window_iterator.hpp:116
genesis::population::BaseWindowIterator::BaseIterator::increment_
virtual void increment_()=0
Advance in the iteration. This function is called from operator++.
genesis::population::BaseWindowIterator
Base iterator class for Windows over the chromosomes of a genome.
Definition: base_window_iterator.hpp:106
genesis::population::BaseWindowIterator::Iterator::operator*
const value_type & operator*() const
Definition: base_window_iterator.hpp:253
genesis::population::BaseWindowIterator::Iterator::operator=
Iterator & operator=(self_type const &)=default
genesis::population::BaseWindowIterator::operator=
BaseWindowIterator & operator=(BaseWindowIterator const &)=default
genesis::population::BaseWindowIterator::BaseIterator::BaseIterator
BaseIterator(BaseWindowIterator const *parent)
Construct the base class, which does initialization checks on its member variables to ensure that the...
Definition: base_window_iterator.hpp:370
genesis::population::Window
Window over the chromosomes of a genome.
Definition: window.hpp:104
genesis::population::BaseWindowIterator::BaseIterator
Internal PIMPL-like implementation of the iterator that produces Windows.
Definition: base_window_iterator.hpp:342
genesis::population::BaseWindowIterator::get_begin_iterator_
virtual std::unique_ptr< BaseIterator > get_begin_iterator_()=0
genesis::population::BaseWindowIterator::Iterator::const_reference
value_type const & const_reference
Definition: base_window_iterator.hpp:191
genesis::population::BaseWindowIterator::BaseIterator::is_last_window_
bool is_last_window_
Definition: base_window_iterator.hpp:463
genesis::population::BaseWindowIterator::Iterator::InputType
typename ForwardIterator::value_type InputType
Definition: base_window_iterator.hpp:185
genesis::population::BaseWindowIterator::Iterator::Iterator
Iterator(std::unique_ptr< BaseIterator > base_iterator)
Definition: base_window_iterator.hpp:197
genesis::population::BaseWindowIterator::Iterator::is_first_window
bool is_first_window() const
Return whether the current iteration is the first of the current chromosome.
Definition: base_window_iterator.hpp:227
genesis::population::BaseWindowIterator::BaseIterator::current_
ForwardIterator current_
Definition: base_window_iterator.hpp:466
genesis::population::BaseWindowIterator::BaseIterator::is_first_window_
bool is_first_window_
Definition: base_window_iterator.hpp:462
std.hpp
Provides some valuable additions to STD.
genesis::population::BaseWindowIterator< ForwardIterator, typename ForwardIterator::value_type >::const_reference
value_type const & const_reference
Definition: base_window_iterator.hpp:124
genesis::population::BaseWindowIterator::Iterator::operator->
value_type * operator->()
Definition: base_window_iterator.hpp:271
genesis::population::BaseWindowIterator::BaseIterator::Window
::genesis::population::Window< DataType > Window
Definition: base_window_iterator.hpp:352
genesis::population::BaseWindowIterator::BaseIterator::iterator_category
std::input_iterator_tag iterator_category
Definition: base_window_iterator.hpp:356
genesis::population::BaseWindowIterator::entry_input_function
std::function< DataType(InputType const &)> entry_input_function
Functor to convert from the underlying input iterator that provides the data to fill the windows to t...
Definition: base_window_iterator.hpp:134
genesis::population::BaseWindowIterator::chromosome_function
std::function< std::string(InputType const &)> chromosome_function
Functor that yields the current chromosome, given the input iterator data.
Definition: base_window_iterator.hpp:139
genesis::population::BaseWindowIterator::Iterator
Internal public iterator that produces Windows.
Definition: base_window_iterator.hpp:173
range.hpp
genesis::population::BaseWindowIterator::begin
Iterator begin()
Definition: base_window_iterator.hpp:502
genesis::population::BaseWindowIterator::Iterator::Window
::genesis::population::Window< DataType > Window
Definition: base_window_iterator.hpp:183
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::population::BaseWindowIterator< ForwardIterator, typename ForwardIterator::value_type >::Entry
typename Window::Entry Entry
Definition: base_window_iterator.hpp:117
genesis::population::BaseWindowIterator::position_function
std::function< size_t(InputType const &)> position_function
Functor that yields the current position on the chromosome, given the input iterator data.
Definition: base_window_iterator.hpp:145
genesis::population::Window::Entry
Data that is stored per entry that was enqueued in a window.
Definition: window.hpp:124
genesis::population::BaseWindowIterator::Iterator::operator->
const value_type * operator->() const
Definition: base_window_iterator.hpp:265
genesis::population::BaseWindowIterator::Iterator::operator*
value_type & operator*()
Definition: base_window_iterator.hpp:259
window.hpp
genesis::population::BaseWindowIterator::BaseIterator::end_
ForwardIterator end_
Definition: base_window_iterator.hpp:467
genesis::population::BaseWindowIterator::Iterator::BaseWindowIterator
friend BaseWindowIterator
Definition: base_window_iterator.hpp:211
genesis::population::BaseWindowIterator::BaseIterator::const_reference
value_type const & const_reference
Definition: base_window_iterator.hpp:360
genesis::population::BaseWindowIterator::BaseIterator::Iterator
friend Iterator
Definition: base_window_iterator.hpp:386
genesis::population::BaseWindowIterator::Iterator::operator++
self_type & operator++()
Definition: base_window_iterator.hpp:281
genesis::population::BaseWindowIterator::BaseIterator::~BaseIterator
~BaseIterator()=default
genesis::population::BaseWindowIterator::BaseIterator::init_
void init_(BaseWindowIterator const *parent)
Initialize the base iterator class and check that it is set up correctly.
Definition: base_window_iterator.hpp:397
genesis::population::BaseWindowIterator::Iterator::Iterator
Iterator()=delete
genesis::population::BaseWindowIterator::Iterator::Entry
typename Window::Entry Entry
Definition: base_window_iterator.hpp:184
genesis::population::BaseWindowIterator::Iterator::iterator_category
std::input_iterator_tag iterator_category
Definition: base_window_iterator.hpp:187
genesis::population::BaseWindowIterator::get_end_iterator_
virtual std::unique_ptr< BaseIterator > get_end_iterator_()=0
genesis::population::BaseWindowIterator< ForwardIterator, typename ForwardIterator::value_type >::InputType
typename ForwardIterator::value_type InputType
Definition: base_window_iterator.hpp:118
genesis::population::BaseWindowIterator::BaseIterator::operator=
BaseIterator & operator=(self_type const &)=default
genesis::population::BaseWindowIterator::BaseIterator::Entry
typename Window::Entry Entry
Definition: base_window_iterator.hpp:353
genesis::population::BaseWindowIterator::Iterator::~Iterator
~Iterator()=default
genesis::population::BaseWindowIterator::end
Iterator end()
Definition: base_window_iterator.hpp:507
genesis::population::BaseWindowIterator::Iterator
friend Iterator
Definition: base_window_iterator.hpp:496
genesis::population::BaseWindowIterator::BaseIterator::InputType
typename ForwardIterator::value_type InputType
Definition: base_window_iterator.hpp:354
genesis::population::BaseWindowIterator< ForwardIterator, typename ForwardIterator::value_type >::iterator_category
std::input_iterator_tag iterator_category
Definition: base_window_iterator.hpp:120
genesis::population::BaseWindowIterator::BaseIterator::get_parent_
virtual BaseWindowIterator const * get_parent_() const =0
Get a pointer to the base class parent.
genesis::population::BaseWindowIterator::Iterator::is_last_window
bool is_last_window() const
Return whether the current iteration is the last of the current chromosome.
Definition: base_window_iterator.hpp:243
genesis::population::BaseWindowIterator::Iterator::operator==
bool operator==(self_type const &other) const
Compare two iterators for equality.
Definition: base_window_iterator.hpp:304
genesis::population::BaseWindowIterator::~BaseWindowIterator
~BaseWindowIterator()=default