Lumiera  0.pre.03
»edit your freedom«
iter-adapter-ptr-deref.hpp
Go to the documentation of this file.
1 /*
2  ITER-ADAPTER-PTR-DEREF.hpp - wrapping iterator to dereference pointers automatically
3 
4  Copyright (C) Lumiera.org
5  2015, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
45 #ifndef LIB_ITER_ADAPTER_PTR_DEREF_H
46 #define LIB_ITER_ADAPTER_PTR_DEREF_H
47 
48 
49 #include "lib/iter-adapter.hpp"
50 
51 #include <type_traits>
52 
53 
54 namespace lib {
55 
56 
64  template<class IT>
66  {
67  IT i_;
68 
69 
70  public:
72  using pointer = typename meta::ValueTypeBinding<IT>::value_type;
73  static_assert(std::is_pointer_v<pointer>);
74 
75  using value_type = typename std::remove_pointer_t<pointer>;
76  using reference = value_type&;
77 
78 
79  ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (PtrDerefIter);
80 
81 
82  // the purpose of the following typedefs is to support building a correct "const iterator"
83 
84  using ValueTypeBase = typename std::remove_const_t<value_type>; // value_type without const
85 
86  using WrappedIterType = typename IterType<IT>::template SimilarIter< ValueTypeBase* * >::Type;
87  using WrappedConstIterType = typename IterType<IT>::template SimilarIter<const ValueTypeBase* * >::Type;
88 
91 
92 
93 
97  explicit
98  PtrDerefIter (IT srcIter)
99  : i_{srcIter}
100  { }
101 
102  PtrDerefIter()
103  : i_{}
104  { }
105 
106 
118  : i_(reinterpret_cast<IT const&> (oIter.getBase()))
119  { }
120 
121  PtrDerefIter&
122  operator= (PtrDerefIter<WrappedIterType> const& ref)
123  {
124  i_ = reinterpret_cast<IT const&> (ref.getBase());
125  return *this;
126  }
127 
128  explicit
129  operator bool() const
130  {
131  return isValid();
132  }
133 
134 
135 
142  static PtrDerefIter
143  build_by_cast (WrappedIterType const& srcIter)
144  {
145  return PtrDerefIter (reinterpret_cast<IT const&> (srcIter));
146  }
147 
148  static PtrDerefIter
149  nil()
150  {
151  return PtrDerefIter (IT());
152  }
153 
154 
155 
156 
157 
158 
159  /* === lumiera forward iterator concept === */
160 
161  reference
162  operator*() const
163  {
164  return *(*i_);
165  }
166 
167  pointer
168  operator->() const
169  {
170  return *i_;
171  }
172 
173  PtrDerefIter&
174  operator++()
175  {
176  ++i_;
177  return *this;
178  }
179 
180  bool
181  isValid () const
182  {
183  return bool(i_);
184  }
185 
186  bool
187  empty () const
188  {
189  return not isValid();
190  }
191 
192 
194  IT const&
195  getBase() const
196  {
197  return i_;
198  }
199  };
200 
201 
203  template<class I1, class I2>
204  bool operator== (PtrDerefIter<I1> const& il, PtrDerefIter<I2> const& ir) { return il.getBase() == ir.getBase(); }
205 
206  template<class I1, class I2>
207  bool operator!= (PtrDerefIter<I1> const& il, PtrDerefIter<I2> const& ir) { return not (il == ir); }
208 
209 
211  template<class IT>
212  auto
214  {
215  return PtrDerefIter<IT>{iter};
216  }
217 
218 
219 
220 
229  template<class IT>
231  {
232  typedef typename IT::pointer _Ptr;
233 
234  IT i_;
235 
236  mutable _Ptr currPtr_;
237 
238 
239  void
240  takeAddress()
241  {
242  if (i_.isValid())
243  currPtr_ = & (*i_);
244  else
245  currPtr_ = nullptr;
246  }
247 
248 
249  public:
250  typedef typename IT::pointer const* pointer;
251  typedef typename IT::pointer const& reference;
252  typedef typename IT::pointer const value_type;
253 
255 
256 
260  explicit
261  AddressExposingIter (IT srcIter)
262  : i_(srcIter)
263  {
264  takeAddress();
265  }
266 
267  explicit
268  operator bool() const
269  {
270  return isValid();
271  }
272 
273 
274 
275 
276  /* === lumiera forward iterator concept === */
277 
283  reference
284  operator*() const
285  {
286  return currPtr_;
287  }
288 
289  _Ptr
290  operator->() const
291  {
292  return currPtr_;
293  }
294 
296  operator++()
297  {
298  ++i_;
299  takeAddress();
300  return *this;
301  }
302 
303  bool
304  isValid () const
305  {
306  return bool(i_);
307  }
308 
309  bool
310  empty () const
311  {
312  return not isValid();
313  }
314 
315 
317  IT const&
318  getBase() const
319  {
320  return i_;
321  }
322  };
323 
324 
326  template<class I1, class I2>
327  bool operator== (AddressExposingIter<I1> const& il, AddressExposingIter<I2> const& ir) { return il.getBase() == ir.getBase(); }
328 
329  template<class I1, class I2>
330  bool operator!= (AddressExposingIter<I1> const& il, AddressExposingIter<I2> const& ir) { return not (il == ir); }
331 
332 
333 
334 
335 
336 
337 }// namespace lib
338 #endif /*LIB_ITER_ADAPTER_PTR_DEREF_H*/
wrapper for an existing Iterator type, automatically dereferencing the output of the former...
typename meta::ValueTypeBinding< IT >::value_type pointer
this iterator adapter is meant to wrap an iterator yielding pointer values
IT i_
nested source iterator
Helper template(s) for creating Lumiera Forward Iterators.
IT const & getBase() const
access the wrapped implementation iterator
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
#define ENABLE_USE_IN_STD_RANGE_FOR_LOOPS(ITER)
use a given Lumiera Forward Iterator in standard "range for loops"
Implementation namespace for support and library code.
PtrDerefIter(PtrDerefIter< WrappedIterType > const &oIter)
allow copy initialisation also when the wrapped iterator is based on some variation of a pointer...
IT const & getBase() const
access the wrapped implementation iterator
static PtrDerefIter build_by_cast(WrappedIterType const &srcIter)
explicit builder to allow creating a const variant from the basic srcIter type.
wrapper for an existing Iterator type to expose the address of each value yielded.
AddressExposingIter(IT srcIter)
AddressExposingIter is always created by wrapping an existing iterator.
IT i_
nested source iterator
auto ptrDeref(IT iter)
Convenience shortcut to dereference pointers yielded from the wrapped iterator.
PtrDerefIter(IT srcIter)
PtrDerefIter is always created by wrapping an existing iterator.