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)
5  2015, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
36 #ifndef LIB_ITER_ADAPTER_PTR_DEREF_H
37 #define LIB_ITER_ADAPTER_PTR_DEREF_H
38 
39 
40 #include "lib/iter-adapter.hpp"
41 
42 #include <type_traits>
43 
44 
45 namespace lib {
46 
47 
55  template<class IT>
57  {
58  IT i_;
59 
60 
61  public:
63  using pointer = typename meta::ValueTypeBinding<IT>::value_type;
64  static_assert(std::is_pointer_v<pointer>);
65 
66  using value_type = typename std::remove_pointer_t<pointer>;
67  using reference = value_type&;
68 
69 
70  ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (PtrDerefIter);
71 
72 
73  // the purpose of the following typedefs is to support building a correct "const iterator"
74 
75  using ValueTypeBase = typename std::remove_const_t<value_type>; // value_type without const
76 
77  using WrappedIterType = typename IterType<IT>::template SimilarIter< ValueTypeBase* * >::Type;
78  using WrappedConstIterType = typename IterType<IT>::template SimilarIter<const ValueTypeBase* * >::Type;
79 
82 
83 
84 
88  explicit
89  PtrDerefIter (IT srcIter)
90  : i_{srcIter}
91  { }
92 
93  PtrDerefIter()
94  : i_{}
95  { }
96 
97 
109  : i_(reinterpret_cast<IT const&> (oIter.getBase()))
110  { }
111 
112  PtrDerefIter&
113  operator= (PtrDerefIter<WrappedIterType> const& ref)
114  {
115  i_ = reinterpret_cast<IT const&> (ref.getBase());
116  return *this;
117  }
118 
119  explicit
120  operator bool() const
121  {
122  return isValid();
123  }
124 
125 
126 
133  static PtrDerefIter
134  build_by_cast (WrappedIterType const& srcIter)
135  {
136  return PtrDerefIter (reinterpret_cast<IT const&> (srcIter));
137  }
138 
139  static PtrDerefIter
140  nil()
141  {
142  return PtrDerefIter (IT());
143  }
144 
145 
146 
147 
148 
149 
150  /* === lumiera forward iterator concept === */
151 
152  reference
153  operator*() const
154  {
155  return *(*i_);
156  }
157 
158  pointer
159  operator->() const
160  {
161  return *i_;
162  }
163 
164  PtrDerefIter&
165  operator++()
166  {
167  ++i_;
168  return *this;
169  }
170 
171  bool
172  isValid () const
173  {
174  return bool(i_);
175  }
176 
177  bool
178  empty () const
179  {
180  return not isValid();
181  }
182 
183 
185  IT const&
186  getBase() const
187  {
188  return i_;
189  }
190  };
191 
192 
194  template<class I1, class I2>
195  bool operator== (PtrDerefIter<I1> const& il, PtrDerefIter<I2> const& ir) { return il.getBase() == ir.getBase(); }
196 
197  template<class I1, class I2>
198  bool operator!= (PtrDerefIter<I1> const& il, PtrDerefIter<I2> const& ir) { return not (il == ir); }
199 
200 
202  template<class IT>
203  auto
205  {
206  return PtrDerefIter<IT>{iter};
207  }
208 
209 
210 
211 
220  template<class IT>
222  {
223  typedef typename IT::pointer _Ptr;
224 
225  IT i_;
226 
227  mutable _Ptr currPtr_;
228 
229 
230  void
231  takeAddress()
232  {
233  if (i_.isValid())
234  currPtr_ = & (*i_);
235  else
236  currPtr_ = nullptr;
237  }
238 
239 
240  public:
241  typedef typename IT::pointer const* pointer;
242  typedef typename IT::pointer const& reference;
243  typedef typename IT::pointer const value_type;
244 
246 
247 
251  explicit
252  AddressExposingIter (IT srcIter)
253  : i_(srcIter)
254  {
255  takeAddress();
256  }
257 
258  explicit
259  operator bool() const
260  {
261  return isValid();
262  }
263 
264 
265 
266 
267  /* === lumiera forward iterator concept === */
268 
274  reference
275  operator*() const
276  {
277  return currPtr_;
278  }
279 
280  _Ptr
281  operator->() const
282  {
283  return currPtr_;
284  }
285 
287  operator++()
288  {
289  ++i_;
290  takeAddress();
291  return *this;
292  }
293 
294  bool
295  isValid () const
296  {
297  return bool(i_);
298  }
299 
300  bool
301  empty () const
302  {
303  return not isValid();
304  }
305 
306 
308  IT const&
309  getBase() const
310  {
311  return i_;
312  }
313  };
314 
315 
317  template<class I1, class I2>
318  bool operator== (AddressExposingIter<I1> const& il, AddressExposingIter<I2> const& ir) { return il.getBase() == ir.getBase(); }
319 
320  template<class I1, class I2>
321  bool operator!= (AddressExposingIter<I1> const& il, AddressExposingIter<I2> const& ir) { return not (il == ir); }
322 
323 
324 
325 
326 
327 
328 }// namespace lib
329 #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.