A library for working with phylogenetic and population genetic data.
v0.32.0
window_view.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_POPULATION_WINDOW_WINDOW_VIEW_H_
2 #define GENESIS_POPULATION_WINDOW_WINDOW_VIEW_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2024 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@sund.ku.dk>
23  University of Copenhagen, Globe Institute, Section for GeoGenetics
24  Oster Voldgade 5-7, 1350 Copenhagen K, Denmark
25 */
26 
36 
37 #include <cassert>
38 #include <functional>
39 #include <stdexcept>
40 #include <string>
41 #include <vector>
42 
43 namespace genesis {
44 namespace population {
45 
46 // =================================================================================================
47 // Genomic Window View
48 // =================================================================================================
49 
75 template<class D>
76 class WindowView final : public BaseWindow<D>
77 {
78 public:
79 
80  // -------------------------------------------------------------------------
81  // Typedefs and Enums
82  // -------------------------------------------------------------------------
83 
84  using Data = D;
86 
87  using iterator_category = std::input_iterator_tag;
88 
89  using value_type = Data;
91  using const_reference = value_type const&;
92 
93  class Iterator;
94  friend Iterator;
95 
96  // =========================================================================
97  // Genomic Window View
98  // =========================================================================
99 
100  class Iterator
101  {
102  public:
103 
104  // -------------------------------------------------------------------------
105  // Constructors and Rule of Five
106  // -------------------------------------------------------------------------
107 
108  using Data = D;
110 
111  using value_type = Data;
112  using pointer = value_type const*;
114  using const_reference = value_type const&;
115  using difference_type = std::ptrdiff_t;
116  using iterator_category = std::input_iterator_tag;
117 
121  Iterator() = default;
122 
126  Iterator( WindowView const* parent )
127  : parent_( parent )
128  {
129  // Either we have no parent, or a valid one. This is checked in the begin() function.
130  assert( ! parent_ || parent_->get_element );
131 
132  // If there is a parent, this is not an end iterator.
133  // Then, we need to read the first element, and check if there is any.
134  if( parent_ ) {
135  assert( parent_->get_element );
136  current_element_ = parent_->get_element();
137  if( ! current_element_ ) {
138  parent_ = nullptr;
139  }
140  }
141  }
142 
143  ~Iterator() = default;
144 
145  Iterator( self_type const& ) = default;
146  Iterator( self_type&& ) = default;
147 
148  Iterator& operator= ( self_type const& ) = default;
149  Iterator& operator= ( self_type&& ) = default;
150 
151  // -------------------------------------------------------------------------
152  // Accessors
153  // -------------------------------------------------------------------------
154 
155  value_type const * operator->() const
156  {
157  assert( parent_ );
158  assert( current_element_ );
159  return current_element_;
160  }
161 
163  {
164  assert( parent_ );
165  assert( current_element_ );
166  return current_element_;
167  }
168 
169  value_type const & operator*() const
170  {
171  assert( parent_ );
172  assert( current_element_ );
173  return *current_element_;
174  }
175 
177  {
178  assert( parent_ );
179  assert( current_element_ );
180  return *current_element_;
181  }
182 
183  // -------------------------------------------------------------------------
184  // Iteration
185  // -------------------------------------------------------------------------
186 
188  {
189  assert( parent_ );
190  assert( parent_->get_element );
191 
192  current_element_ = parent_->get_element();
193  if( ! current_element_ ) {
194  parent_ = nullptr;
195  }
196  return *this;
197  }
198 
199  // No post increment, to keep it simple, fast, and consistent.
200  // self_type operator ++(int)
201  // {}
202 
210  bool operator==( self_type const& other ) const
211  {
212  // We compare the parents as a baseline - two past-the-end iterator shall
213  // always compare equal. If only one of them is past-the-end, they will compare false.
214  return parent_ == other.parent_;
215  }
216 
217  bool operator!=( self_type const& other ) const
218  {
219  return !(*this == other);
220  }
221 
222  // -------------------------------------------------------------------------
223  // Internal Members
224  // -------------------------------------------------------------------------
225 
226  private:
227 
228  Data* current_element_ = nullptr;
229  WindowView const* parent_ = nullptr;
230 
231  };
232 
233  // =========================================================================
234  // Main Class
235  // =========================================================================
236 
237  // -------------------------------------------------------------------------
238  // Constructors and Rule of Five
239  // -------------------------------------------------------------------------
240 
241  WindowView() = default;
242 
252  WindowView( Window<Data> const& window )
253  // Set the chromosome and positions
254  : BaseWindow<Data>( static_cast<BaseWindow<Data> const&>( window ))
255  {
256  size_t index = 0;
257  get_element = [ index, &window ]() mutable -> Data const* {
258  if( index >= window.size() ) {
259  return nullptr;
260  }
261  return &window[index++].data;
262  };
263  }
264 
269  // Set the chromosome and positions
270  : BaseWindow<Data>( static_cast<BaseWindow<Data> const&>( window ))
271  {
272  size_t index = 0;
273  get_element = [ index, &window ]() mutable -> Data* {
274  if( index >= window.size() ) {
275  return nullptr;
276  }
277  return &window[index++].data;
278  };
279  }
280 
281  virtual ~WindowView() override = default;
282 
283  WindowView( WindowView const& ) = default;
284  WindowView( WindowView&& ) = default;
285 
286  WindowView& operator= ( WindowView const& ) = default;
287  WindowView& operator= ( WindowView&& ) = default;
288 
289  // -------------------------------------------------------------------------
290  // Data Accessors
291  // -------------------------------------------------------------------------
292 
293  Iterator begin() const
294  {
295  if( ! get_element ) {
296  throw std::runtime_error(
297  "WindowView begin() has been called without setting "
298  "the get_element function first."
299  );
300  }
301  if( started_ ) {
302  throw std::runtime_error(
303  "WindowView is an input iterator (single pass), "
304  "but begin() has been called multiple times."
305  );
306  }
307  started_ = true;
308  return Iterator( this );
309  }
310 
311  Iterator end() const
312  {
313  return Iterator( nullptr );
314  }
315 
316  // -------------------------------------------------------------------------
317  // Data Members
318  // -------------------------------------------------------------------------
319 
320 public:
321 
330  std::function<Data*()> get_element;
331 
332 private:
333 
334  mutable bool started_ = false;
335 
336 };
337 
338 } // namespace population
339 } // namespace genesis
340 
341 #endif // include guard
genesis::population::WindowView::Iterator::Iterator
Iterator()=default
Default constructor for empty (past-the-end) data.
genesis::population::WindowView< DataType >::value_type
Data value_type
Definition: window_view.hpp:89
genesis::population::WindowView::Iterator::reference
value_type & reference
Definition: window_view.hpp:113
genesis::population::WindowView::Iterator::operator->
value_type * operator->()
Definition: window_view.hpp:162
genesis::population::WindowView< DataType >::iterator_category
std::input_iterator_tag iterator_category
Definition: window_view.hpp:87
genesis::population::WindowView::Iterator::operator++
self_type & operator++()
Definition: window_view.hpp:187
base_window.hpp
genesis::population::WindowView::~WindowView
virtual ~WindowView() override=default
genesis::population::WindowView::Iterator
friend Iterator
Definition: window_view.hpp:93
genesis::population::Window
Window over the chromosomes of a genome.
Definition: window.hpp:105
genesis::population::WindowView::Iterator::operator=
Iterator & operator=(self_type const &)=default
genesis::population::WindowView::Iterator::const_reference
value_type const & const_reference
Definition: window_view.hpp:114
genesis::population::WindowView::operator=
WindowView & operator=(WindowView const &)=default
genesis::population::WindowView::Iterator::operator==
bool operator==(self_type const &other) const
Compare two iterators for equality.
Definition: window_view.hpp:210
genesis::population::WindowView::Iterator::operator*
value_type & operator*()
Definition: window_view.hpp:176
genesis::population::WindowView::Iterator::pointer
value_type const * pointer
Definition: window_view.hpp:112
genesis::population::Window::size
size_t size() const
Get the number of D/Data Entries that are stored in the Window.
Definition: window.hpp:237
genesis::population::WindowView::Iterator::Data
D Data
Definition: window_view.hpp:108
genesis::population::WindowView::end
Iterator end() const
Definition: window_view.hpp:311
genesis::population::WindowView::WindowView
WindowView()=default
genesis::population::BaseWindow< DataType >::Data
DataType Data
Definition: base_window.hpp:68
genesis::population::WindowView::Iterator::operator->
const value_type * operator->() const
Definition: window_view.hpp:155
genesis::population::WindowView::Iterator::Iterator
Iterator(WindowView const *parent)
Constructor for data iteration.
Definition: window_view.hpp:126
genesis::population::WindowView::Iterator::difference_type
std::ptrdiff_t difference_type
Definition: window_view.hpp:115
genesis::population::WindowView::Iterator
Definition: window_view.hpp:100
genesis::population::WindowView
Proxy view over window-like regions of a genome.
Definition: window_view.hpp:76
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::WindowView::Data
D Data
Definition: window_view.hpp:84
genesis::population::WindowView::Iterator::operator*
const value_type & operator*() const
Definition: window_view.hpp:169
genesis::population::WindowView::Iterator::~Iterator
~Iterator()=default
genesis::population::WindowView::WindowView
WindowView(Window< Data > &window)
Constructor that takes a Window window and creates a view into it.
Definition: window_view.hpp:268
genesis::population::WindowView< DataType >::const_reference
value_type const & const_reference
Definition: window_view.hpp:91
window.hpp
genesis::population::WindowView::WindowView
WindowView(Window< Data > const &window)
Constructor that takes a Window window and creates a view into it.
Definition: window_view.hpp:252
genesis::population::WindowView::begin
Iterator begin() const
Definition: window_view.hpp:293
genesis::population::WindowView::Iterator::iterator_category
std::input_iterator_tag iterator_category
Definition: window_view.hpp:116
genesis::population::WindowView::get_element
std::function< Data *()> get_element
Function to read the next element from some input source.
Definition: window_view.hpp:330
genesis::population::BaseWindow
Base class for Window and WindowView, to share common functionality.
Definition: base_window.hpp:60
genesis::population::WindowView::Iterator::operator!=
bool operator!=(self_type const &other) const
Definition: window_view.hpp:217
genesis::population::WindowView< DataType >::reference
value_type & reference
Definition: window_view.hpp:90
genesis::population::WindowView::Iterator::value_type
Data value_type
Definition: window_view.hpp:111