25 #ifndef BOLT_ITERATOR_FACADE_H
26 #define BOLT_ITERATOR_FACADE_H
28 #include <type_traits>
29 #include <bolt/cl/iterator/iterator_categories.h>
30 #include <bolt/cl/iterator/facade_iterator_category.h>
47 template <
class T,
class U>
64 bolt::cl::detail::or_<
65 std::is_convertible<Facade1, Facade2>
66 , std::is_convertible<Facade2, Facade1>
72 template<
typename Facade1,
typename Facade2>
74 : bolt::cl::detail::eval_if<
75 std::is_convertible<Facade2,Facade1>,
76 identity_<typename Facade1::difference_type>,
77 identity_<typename Facade2::difference_type>
87 template <
class Iterator>
92 typedef typename Iterator::reference reference;
93 typedef typename Iterator::value_type value_type;
100 operator reference()
const
118 template <
class I1,
class I2>
120 : bolt::cl::detail::eval_if<
121 std::is_convertible<I2,I1>
122 , bolt::cl::iterator_difference<I1>
123 , bolt::cl::iterator_difference<I2>
131 # define BOLT_ITERATOR_FACADE_INTEROP_HEAD(prefix, op) \
133 class Derived1, class V1, class TC1, class Reference1, class Difference1 \
134 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
138 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
139 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
153 template <
class I,
class V,
class TC,
class R,
class D>
friend class iterator_facade;
155 # define BOLT_ITERATOR_FACADE_RELATION(op) \
156 BOLT_ITERATOR_FACADE_INTEROP_HEAD(friend,op);
158 BOLT_ITERATOR_FACADE_RELATION(==)
159 BOLT_ITERATOR_FACADE_RELATION(!=)
161 BOLT_ITERATOR_FACADE_RELATION(<)
162 BOLT_ITERATOR_FACADE_RELATION(>)
163 BOLT_ITERATOR_FACADE_RELATION(<=)
164 BOLT_ITERATOR_FACADE_RELATION(>=)
165 # undef BOLT_ITERATOR_FACADE_RELATION
168 class Derived1,
class V1,
class TC1,
class Reference1,
class Difference1
169 ,
class Derived2,
class V2,
class TC2,
class Reference2,
class Difference2
180 template <
class Derived,
class V,
class TC,
class R,
class D>
182 ,
typename Derived::difference_type);
184 template <
class Derived,
class V,
class TC,
class R,
class D>
185 friend inline Derived operator+ (
typename Derived::difference_type
188 template <
class Facade>
189 static typename Facade::reference dereference(Facade
const& f)
191 return f.dereference();
194 template <
class Facade>
195 static void increment(Facade& f)
200 template <
class Facade>
201 static void decrement(Facade& f)
206 template <
class Facade1,
class Facade2>
207 static bool equal(Facade1
const& f1, Facade2
const& f2)
212 template <
class Facade1,
class Facade2>
213 static bool equal(Facade1
const& f1, Facade2
const& f2, std::true_type)
218 template <
class Facade1,
class Facade2>
219 static bool equal(Facade1
const& f1, Facade2
const& f2, std::false_type)
224 template <
class Facade>
225 static void advance(Facade& f,
typename Facade::difference_type n)
230 template <
class Facade1,
class Facade2>
231 static typename Facade1::difference_type distance_from(
232 Facade1
const& f1, Facade2
const& f2, std::true_type)
234 return -f1.distance_to(f2);
237 template <
class Facade1,
class Facade2>
238 static typename Facade2::difference_type distance_from(
239 Facade1
const& f1, Facade2
const& f2, std::false_type)
241 return f2.distance_to(f1);
247 template <
class I,
class V,
class TC,
class R,
class D>
250 return *
static_cast<I*
>(&facade);
253 template <
class I,
class V,
class TC,
class R,
class D>
256 return *
static_cast<I const*
>(&facade);
271 ,
class CategoryOrTraversal
272 ,
class Reference = Value&
273 ,
class Difference = std::ptrdiff_t
283 return *
static_cast<Derived*
>(
this);
286 Derived
const& derived()
const
288 return *
static_cast<Derived const*
>(
this);
297 typedef typename std::remove_const<Value>::type value_type;
298 typedef Reference reference;
299 typedef Difference difference_type;
300 typedef typename std::add_pointer<value_type>::type pointer;
304 reference operator*()
const
306 return iterator_core_access::dereference(this->derived());
309 pointer operator->()
const
311 return this->derived();
315 operator[](difference_type n)
const
317 return *(this->derived() + n);
320 Derived& operator++()
322 iterator_core_access::increment(this->derived());
323 return this->derived();
329 Derived tmp(this->derived());
334 Derived& operator--()
336 iterator_core_access::decrement(this->derived());
337 return this->derived();
340 Derived operator--(
int)
342 Derived tmp(this->derived());
347 Derived& operator+=(difference_type n)
349 iterator_core_access::advance(this->derived(), n);
350 return this->derived();
353 Derived& operator-=(difference_type n)
355 iterator_core_access::advance(this->derived(), -n);
356 return this->derived();
359 Derived operator-(difference_type x)
const
361 Derived result(this->derived());
435 # define BOLT_ITERATOR_FACADE_INTEROP(op, return_prefix, base_op) \
436 BOLT_ITERATOR_FACADE_INTEROP_HEAD(inline, op) \
439 return_prefix iterator_core_access::base_op( \
440 *static_cast<Derived1 const*>(&lhs) \
441 , *static_cast<Derived2 const*>(&rhs) \
442 , std::is_convertible<Derived2,Derived1>() \
446 # define BOLT_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
447 BOLT_ITERATOR_FACADE_INTEROP( \
453 BOLT_ITERATOR_FACADE_RELATION(==,
return, equal);
454 BOLT_ITERATOR_FACADE_RELATION(!=,
return !, equal);
455 BOLT_ITERATOR_FACADE_RELATION(<,
return 0 >, distance_from);
456 BOLT_ITERATOR_FACADE_RELATION(>,
return 0 <, distance_from);
457 BOLT_ITERATOR_FACADE_RELATION(<=,
return 0 >=, distance_from);
458 BOLT_ITERATOR_FACADE_RELATION(>=,
return 0 <=, distance_from);
460 # undef BOLT_ITERATOR_FACADE_RELATION
464 class Derived1,
class V1,
class TC1,
class Reference1,
class Difference1
465 ,
class Derived2,
class V2,
class TC2,
class Reference2,
class Difference2
475 return iterator_core_access::distance_from(
476 *static_cast<Derived1 const*>(&lhs)
477 , *static_cast<Derived2 const*>(&rhs)
478 , std::is_convertible<Derived2,Derived1>()
482 # undef BOLT_ITERATOR_FACADE_INTEROP
483 # undef BOLT_ITERATOR_FACADE_INTEROP_HEAD
485 template <
class Derived,
class V,
class TC,
class R,
class D>
487 typename Derived::difference_type n )
489 Derived tmp(static_cast<Derived const&>(i));
493 template <
class Derived,
class V,
class TC,
class R,
class D> \
494 inline Derived operator+ (
typename Derived::difference_type n,
497 Derived tmp(static_cast<Derived const&>(i));
505 #endif // BOLT_ITERATOR_FACADE_H