A library for working with phylogenetic data.
v0.25.0
lambda_iterator.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_CONTAINERS_LAMBDA_ITERATOR_H_
2 #define GENESIS_UTILS_CONTAINERS_LAMBDA_ITERATOR_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2021 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 
27 #include <functional>
28 #include <memory>
29 
30 namespace genesis {
31 namespace utils {
32 
33 // =================================================================================================
34 // Lambda Iterator
35 // =================================================================================================
36 
86 template<class T>
88 {
89 public:
90 
91  // -------------------------------------------------------------------------
92  // Member Types
93  // -------------------------------------------------------------------------
94 
96  using value_type = T;
97  using pointer = value_type const*;
98  using reference = value_type const&;
99  using difference_type = std::ptrdiff_t;
100  using iterator_category = std::input_iterator_tag;
101 
102  // -------------------------------------------------------------------------
103  // Iterator
104  // -------------------------------------------------------------------------
105 
107  {
108  public:
109 
110  // -------------------------------------------------------------------------
111  // Constructors and Rule of Five
112  // -------------------------------------------------------------------------
113 
115 
116  // LambdaIterator() = default;
117 
119  LambdaIteratorGenerator* generator,
120  std::shared_ptr<T> current_element
121  )
122  : generator_(generator)
123  , current_element_(current_element)
124  {}
125 
126  ~LambdaIterator() = default;
127 
128  LambdaIterator( self_type const& ) = default;
129  LambdaIterator( self_type&& ) = default;
130 
131  LambdaIterator& operator= ( self_type const& ) = default;
132  LambdaIterator& operator= ( self_type&& ) = default;
133 
134  // friend LambdaIteratorGenerator;
135 
136  // -------------------------------------------------------------------------
137  // Accessors
138  // -------------------------------------------------------------------------
139 
140  T const& operator*() const
141  {
142  return *current_element_;
143  }
144 
145  // T operator*()
146  // {
147  // return *current_element_;
148  // }
149 
150  // -------------------------------------------------------------------------
151  // Iteration
152  // -------------------------------------------------------------------------
153 
155  {
156  current_element_ = generator_->get_element_();
157  return *this;
158  }
159 
161  {
162  auto cpy = *this;
163  current_element_ = generator_->get_element_();
164  return cpy;
165  }
166 
167  bool operator==( self_type const& it ) const
168  {
169  return current_element_ == it.current_element_;
170  }
171 
172  bool operator!=( self_type const& it ) const
173  {
174  return !(*this == it);
175  }
176 
177  private:
178 
179  LambdaIteratorGenerator* generator_;
180  std::shared_ptr<T> current_element_;
181 
182  };
183 
184  // -------------------------------------------------------------------------
185  // Constructors and Rule of Five
186  // -------------------------------------------------------------------------
187 
188  LambdaIteratorGenerator() = default;
189 
191  std::function<std::shared_ptr<value_type>()> get_element
192  )
193  : get_element_(get_element)
194  {}
195 
196  ~LambdaIteratorGenerator() = default;
197 
198  LambdaIteratorGenerator( self_type const& ) = default;
199  LambdaIteratorGenerator( self_type&& ) = default;
200 
201  self_type& operator= ( self_type const& ) = default;
202  self_type& operator= ( self_type&& ) = default;
203 
205 
206  // -------------------------------------------------------------------------
207  // Data Members
208  // -------------------------------------------------------------------------
209 
211  {
212  return LambdaIterator( this, get_element_() );
213  }
214 
216  {
217  return LambdaIterator( this, nullptr );
218  }
219 
224  operator bool() const
225  {
226  return static_cast<bool>( get_element_ );
227  }
228 
229  // -------------------------------------------------------------------------
230  // Data Members
231  // -------------------------------------------------------------------------
232 
233 private:
234 
235  std::function<std::shared_ptr<value_type>()> get_element_;
236 
237 };
238 
242 template<class T>
244 
245 } // namespace utils
246 } // namespace genesis
247 
248 #endif // include guard
genesis::utils::LambdaIteratorGenerator
Type erasure for iterators, using std::function to get rid of the underlying input type.
Definition: lambda_iterator.hpp:87
genesis::utils::LambdaIteratorGenerator::LambdaIterator::operator==
bool operator==(self_type const &it) const
Definition: lambda_iterator.hpp:167
genesis::utils::LambdaIteratorGenerator::LambdaIterator::operator*
T const & operator*() const
Definition: lambda_iterator.hpp:140
genesis::utils::LambdaIteratorGenerator::LambdaIterator
friend LambdaIterator
Definition: lambda_iterator.hpp:204
genesis::utils::LambdaIteratorGenerator::~LambdaIteratorGenerator
~LambdaIteratorGenerator()=default
genesis::utils::LambdaIteratorGenerator::operator=
self_type & operator=(self_type const &)=default
genesis::utils::LambdaIteratorGenerator::end
LambdaIterator end()
Definition: lambda_iterator.hpp:215
genesis::utils::LambdaIteratorGenerator::LambdaIterator::operator++
self_type & operator++()
Definition: lambda_iterator.hpp:154
genesis::utils::LambdaIteratorGenerator::LambdaIterator
Definition: lambda_iterator.hpp:106
genesis::utils::LambdaIteratorGenerator::reference
value_type const & reference
Definition: lambda_iterator.hpp:98
genesis::utils::LambdaIteratorGenerator::difference_type
std::ptrdiff_t difference_type
Definition: lambda_iterator.hpp:99
genesis::utils::LambdaIteratorGenerator::LambdaIterator::operator=
LambdaIterator & operator=(self_type const &)=default
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::utils::LambdaIteratorGenerator::LambdaIterator::operator!=
bool operator!=(self_type const &it) const
Definition: lambda_iterator.hpp:172
genesis::utils::LambdaIteratorGenerator::LambdaIteratorGenerator
LambdaIteratorGenerator()=default
genesis::utils::LambdaIteratorGenerator::value_type
T value_type
Definition: lambda_iterator.hpp:96
genesis::utils::LambdaIterator
typename LambdaIteratorGenerator< T >::LambdaIterator LambdaIterator
Alias for the internal iterator of a LambdaIteratorGenerator for easier usage.
Definition: lambda_iterator.hpp:243
genesis::utils::LambdaIteratorGenerator::begin
LambdaIterator begin()
Definition: lambda_iterator.hpp:210
genesis::utils::LambdaIteratorGenerator::LambdaIteratorGenerator
LambdaIteratorGenerator(std::function< std::shared_ptr< value_type >()> get_element)
Definition: lambda_iterator.hpp:190
genesis::utils::LambdaIteratorGenerator::iterator_category
std::input_iterator_tag iterator_category
Definition: lambda_iterator.hpp:100
genesis::utils::LambdaIteratorGenerator::LambdaIterator::~LambdaIterator
~LambdaIterator()=default
genesis::utils::LambdaIteratorGenerator::self_type
LambdaIteratorGenerator self_type
Definition: lambda_iterator.hpp:95
genesis::utils::LambdaIteratorGenerator::pointer
value_type const * pointer
Definition: lambda_iterator.hpp:97
genesis::utils::LambdaIteratorGenerator::LambdaIterator::LambdaIterator
LambdaIterator(LambdaIteratorGenerator *generator, std::shared_ptr< T > current_element)
Definition: lambda_iterator.hpp:118