ALP User Documentation  0.8.preview
Algebraic Programming User Documentation
adapter.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright 2021 Huawei Technologies Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
28 #ifndef _H_GRB_ITERATOR_ADAPTER
29 #define _H_GRB_ITERATOR_ADAPTER
30 
31 #include <utility>
32 #include <iterator>
33 #include <functional>
34 
35 #include <assert.h>
36 
37 
38 namespace grb::utils {
39 
40  namespace iterators {
41 
61  template<
62  typename SubIterT,
63  typename std::enable_if< std::is_same<
64  typename std::iterator_traits< SubIterT >::iterator_category,
65  std::random_access_iterator_tag
66  >::value, void >::type * = nullptr
67  >
68  class Adapter {
69 
70  public:
71 
72  // standard STL typedefs
73 
74  typedef typename SubIterT::iterator_category iterator_category;
75 
76  typedef typename SubIterT::difference_type difference_type;
77 
78  typedef typename SubIterT::value_type value_type;
79 
80  typedef typename SubIterT::pointer pointer;
81 
82  typedef typename SubIterT::reference reference;
83 
84 
85  protected:
86 
87  // STL-like typedefs
88 
90 
92 
94 
95  typedef const value_type & const_reference;
96 
97  typedef const value_type * const_pointer;
98 
99 
100  private:
101 
102  value_type v;
103 
104  SubIterT iter;
105 
106  SubIterT end_it;
107 
108  std::function< value_type(const value_type) > adapter_func;
109 
110 
111  public:
112 
113  // constructors
114 
115  Adapter(
116  const SubIterT iter_in, const SubIterT iter_end,
117  const std::function< value_type( const value_type ) > func_in
118  ) : iter( iter_in ), end_it( iter_end ), adapter_func( func_in ) {
119  if( iter != end_it ) {
120  v = adapter_func( *iter );
121  }
122  }
123 
124  Adapter( const self_const_reference_type &other ) :
125  v( other.v ),
126  iter( other.iter ), end_it( other.end_it ),
127  adapter_func( other.adapter_func )
128  {}
129 
130  Adapter( Adapter< SubIterT > &&other ) :
131  v( std::move( other.v ) ),
132  iter( std::move( other.iter ) ), end_it( std::move( other.end_it ) ),
133  adapter_func( std::move( other.adapter_func ) )
134  {}
135 
136  // destructor
137 
138  ~Adapter() {}
139 
140  // standard iterator interface
141 
142  const_reference operator*() const noexcept {
143  return v;
144  }
145 
146  self_reference_type operator=( self_const_reference_type other ) noexcept {
147  v = other.v;
148  iter = other.iter;
149  end_it = other.end_it;
150  adapter_func = other.adapter_func;
151  return *this;
152  }
153 
154  self_reference_type operator=(
155  Adapter< SubIterT > &&other
156  ) noexcept {
157  v = std::move( other.v );
158  iter = std::move( other.iter );
159  end_it = std::move( other.end_it );
160  adapter_func = std::move( other.adapter_func );
161  return *this;
162  }
163 
164  self_reference_type operator++() noexcept {
165  (void) iter++;
166  if( iter != end_it ) {
167  v = adapter_func( *iter );
168  }
169  return *this;
170  }
171 
172  friend void swap( self_reference_type left, self_reference_type right ) {
173  std::swap( left.v, right.v );
174  std::swap( left.iter, right.iter );
175  std::swap( left.end_it, right.end_it );
176  std::swap( left.adapter_func, right.adapter_func );
177  }
178 
179  // input iterator interface
180 
181  const_pointer operator->() const noexcept {
182  return &v;
183  }
184 
185  self_type operator++(int) noexcept {
186  self_type ret = self_type( *this );
187  (void) ++iter;
188  if( iter != end_it ) {
189  v = adapter_func( *iter );
190  }
191  return ret;
192  }
193 
194  friend bool operator==(
196  ) noexcept {
197  return left.iter == right.iter;
198  }
199 
200  friend bool operator!=(
202  ) noexcept {
203  return !(left == right);
204  }
205 
206  // bi-directional iterator interface
207 
208  self_reference_type operator--() noexcept {
209  (void) --iter;
210  if( iter != end_it ) {
211  v = adapter_func( *iter );
212  }
213  return *this;
214  }
215 
216  self_type operator--(int) noexcept {
217  self_type ret = self_type( *this );
218  (void) iter--;
219  if( iter != end_it ) {
220  v = adapter_func( *iter );
221  }
222  return ret;
223  }
224 
225  // random access iterator interface
226 
232  value_type operator[]( const size_t i ) const noexcept {
233  return adapter_func( iter[ i ] );
234  }
235 
236  friend bool operator<(
239  ) {
240  return left.iter < right.iter;
241  }
242 
243  friend bool operator>(
246  ) {
247  return left.iter > right.iter;
248  }
249 
250  friend bool operator<=(
253  ) {
254  return left.iter <= right.iter;
255  }
256 
257  friend bool operator>=(
260  ) {
261  return left.iter >= right.iter;
262  }
263 
264  self_reference_type operator+=( const size_t count ) noexcept {
265  iter += count;
266  if( iter != end_it ) {
267  v = adapter_func( *iter );
268  }
269  return *this;
270  }
271 
272  friend self_type operator+(
273  self_const_reference_type iterator,
274  const size_t count
275  ) noexcept {
276  const SubIterT subRet = iterator.iter + count;
277  return self_type( subRet, iterator.end_it, iterator.adapter_func );
278  }
279 
280  friend self_type operator+(
281  const size_t count,
283  ) noexcept {
284  const SubIterT subRet = iterator.iter + count;
285  return self_type( subRet, iterator.end_it, iterator.adapter_func );
286  }
287 
288  self_reference_type operator-=( const size_t count ) noexcept {
289  iter -= count;
290  if( iter != end_it ) {
291  v = adapter_func( *iter );
292  }
293  return *this;
294  }
295 
296  friend self_type operator-(
297  self_const_reference_type iterator,
298  const size_t count
299  ) noexcept {
300  const SubIterT subRet = iterator.iter - count;
301  return self_type( subRet, iterator.end_it, iterator.adapter_func );
302  }
303 
304  friend self_type operator-(
305  const size_t count,
307  ) noexcept {
308  const SubIterT subRet = iterator.iter - count;
309  return self_type( subRet, iterator.end_it, iterator.adapter_func );
310  }
311 
312  difference_type operator-(
314  ) const noexcept {
315  return iter - iterator.iter;
316  }
317 
318  };
319 
320  // factory
321 
348  template< typename SubIterT >
350  const SubIterT start, const SubIterT end,
351  const std::function<
352  typename SubIterT::value_type(const typename SubIterT::value_type)
353  > func
354  ) {
355  return Adapter< SubIterT >( start, end, func );
356  }
357 
358  } // end namespace grb::utils::iterators
359 
360 } // end namespace grb
361 
362 #endif // end _H_GRB_ITERATOR_ADAPTER
363 
An iterator that simply adapts the values returned by another iterator.
Definition: adapter.hpp:68
static Adapter< SubIterT > make_adapter_iterator(const SubIterT start, const SubIterT end, const std::function< typename SubIterT::value_type(const typename SubIterT::value_type) > func)
Creates an adapter of a given iterator.
Definition: adapter.hpp:349
The sequential reference implementation.
Definition: backends.hpp:55