1 // (C) Copyright Jeremy Siek 2001.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_SHADOW_ITERATOR_HPP
7 #define BOOST_SHADOW_ITERATOR_HPP
9 #include <boost/iterator_adaptors.hpp>
10 #include <boost/operators.hpp>
16 template <class A
, class B
, class D
>
18 : boost::operators
< shadow_proxy
<A
,B
,D
> >
20 typedef shadow_proxy self
;
22 inline shadow_proxy(A aa
, B bb
) : a(aa
), b(bb
) { }
23 inline shadow_proxy(const self
& x
) : a(x
.a
), b(x
.b
) { }
25 inline shadow_proxy(Self x
) : a(x
.a
), b(x
.b
) { }
26 inline self
& operator=(const self
& x
) { a
= x
.a
; b
= x
.b
; return *this; }
27 inline self
& operator++() { ++a
; return *this; }
28 inline self
& operator--() { --a
; return *this; }
29 inline self
& operator+=(const self
& x
) { a
+= x
.a
; return *this; }
30 inline self
& operator-=(const self
& x
) { a
-= x
.a
; return *this; }
31 inline self
& operator*=(const self
& x
) { a
*= x
.a
; return *this; }
32 inline self
& operator/=(const self
& x
) { a
/= x
.a
; return *this; }
33 inline self
& operator%=(const self
& x
) { return *this; } // JGS
34 inline self
& operator&=(const self
& x
) { return *this; } // JGS
35 inline self
& operator|=(const self
& x
) { return *this; } // JGS
36 inline self
& operator^=(const self
& x
) { return *this; } // JGS
37 inline friend D
operator-(const self
& x
, const self
& y
) {
40 inline bool operator==(const self
& x
) const { return a
== x
.a
; }
41 inline bool operator<(const self
& x
) const { return a
< x
.a
; }
47 struct shadow_iterator_policies
49 template <typename iter_pair
>
50 void initialize(const iter_pair
&) { }
52 template <typename Iter
>
53 typename
Iter::reference
dereference(const Iter
& i
) const {
54 typedef typename
Iter::reference R
;
55 return R(*i
.base().first
, *i
.base().second
);
57 template <typename Iter
>
58 bool equal(const Iter
& p1
, const Iter
& p2
) const {
59 return p1
.base().first
== p2
.base().first
;
61 template <typename Iter
>
62 void increment(Iter
& i
) { ++i
.base().first
; ++i
.base().second
; }
64 template <typename Iter
>
65 void decrement(Iter
& i
) { --i
.base().first
; --i
.base().second
; }
67 template <typename Iter
>
68 bool less(const Iter
& x
, const Iter
& y
) const {
69 return x
.base().first
< y
.base().first
;
71 template <typename Iter
>
72 typename
Iter::difference_type
73 distance(const Iter
& x
, const Iter
& y
) const {
74 return y
.base().first
- x
.base().first
;
76 template <typename D
, typename Iter
>
77 void advance(Iter
& p
, D n
) { p
.base().first
+= n
; p
.base().second
+= n
; }
82 template <typename IterA
, typename IterB
>
83 struct shadow_iterator_generator
{
85 // To use the iterator_adaptor we can't derive from
86 // random_access_iterator because we don't have a real reference.
87 // However, we want the STL algorithms to treat the shadow
88 // iterator like a random access iterator.
89 struct shadow_iterator_tag
: public std::input_iterator_tag
{
90 operator std::random_access_iterator_tag() {
91 return std::random_access_iterator_tag();
94 typedef typename
std::iterator_traits
<IterA
>::value_type Aval
;
95 typedef typename
std::iterator_traits
<IterB
>::value_type Bval
;
96 typedef typename
std::iterator_traits
<IterA
>::reference Aref
;
97 typedef typename
std::iterator_traits
<IterB
>::reference Bref
;
98 typedef typename
std::iterator_traits
<IterA
>::difference_type D
;
99 typedef detail::shadow_proxy
<Aval
,Bval
,Aval
> V
;
100 typedef detail::shadow_proxy
<Aref
,Bref
,Aval
> R
;
101 typedef iterator_adaptor
< std::pair
<IterA
, IterB
>,
102 detail::shadow_iterator_policies
,
103 V
, R
, V
*, shadow_iterator_tag
,
107 // short cut for creating a shadow iterator
108 template <class IterA
, class IterB
>
109 inline typename shadow_iterator_generator
<IterA
,IterB
>::type
110 make_shadow_iter(IterA a
, IterB b
) {
111 typedef typename shadow_iterator_generator
<IterA
,IterB
>::type Iter
;
112 return Iter(std::make_pair(a
,b
));
117 inline shadow_cmp(const Cmp
& c
) : cmp(c
) { }
118 template <class ShadowProxy1
, class ShadowProxy2
>
119 inline bool operator()(const ShadowProxy1
& x
, const ShadowProxy2
& y
) const
121 return cmp(x
.a
, y
.a
);
129 template <class A1
, class B1
, class D1
,
130 class A2
, class B2
, class D2
>
131 void swap(boost::detail::shadow_proxy
<A1
&,B1
&,D1
> x
,
132 boost::detail::shadow_proxy
<A2
&,B2
&,D2
> y
)
139 #endif // BOOST_SHADOW_ITERATOR_HPP