• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
5 
6 #ifndef BOOST_SHADOW_ITERATOR_HPP
7 #define BOOST_SHADOW_ITERATOR_HPP
8 
9 #include <boost/iterator_adaptors.hpp>
10 #include <boost/operators.hpp>
11 
12 namespace boost
13 {
14 
15 namespace detail
16 {
17 
18     template < class A, class B, class D >
19     class shadow_proxy : boost::operators< shadow_proxy< A, B, D > >
20     {
21         typedef shadow_proxy self;
22 
23     public:
shadow_proxy(A aa,B bb)24         inline shadow_proxy(A aa, B bb) : a(aa), b(bb) {}
shadow_proxy(const self & x)25         inline shadow_proxy(const self& x) : a(x.a), b(x.b) {}
shadow_proxy(Self x)26         template < class Self > inline shadow_proxy(Self x) : a(x.a), b(x.b) {}
operator =(const self & x)27         inline self& operator=(const self& x)
28         {
29             a = x.a;
30             b = x.b;
31             return *this;
32         }
operator ++()33         inline self& operator++()
34         {
35             ++a;
36             return *this;
37         }
operator --()38         inline self& operator--()
39         {
40             --a;
41             return *this;
42         }
operator +=(const self & x)43         inline self& operator+=(const self& x)
44         {
45             a += x.a;
46             return *this;
47         }
operator -=(const self & x)48         inline self& operator-=(const self& x)
49         {
50             a -= x.a;
51             return *this;
52         }
operator *=(const self & x)53         inline self& operator*=(const self& x)
54         {
55             a *= x.a;
56             return *this;
57         }
operator /=(const self & x)58         inline self& operator/=(const self& x)
59         {
60             a /= x.a;
61             return *this;
62         }
operator %=(const self & x)63         inline self& operator%=(const self& x) { return *this; } // JGS
operator &=(const self & x)64         inline self& operator&=(const self& x) { return *this; } // JGS
operator |=(const self & x)65         inline self& operator|=(const self& x) { return *this; } // JGS
operator ^=(const self & x)66         inline self& operator^=(const self& x) { return *this; } // JGS
operator -(const self & x,const self & y)67         inline friend D operator-(const self& x, const self& y)
68         {
69             return x.a - y.a;
70         }
operator ==(const self & x) const71         inline bool operator==(const self& x) const { return a == x.a; }
operator <(const self & x) const72         inline bool operator<(const self& x) const { return a < x.a; }
73         //  protected:
74         A a;
75         B b;
76     };
77 
78     struct shadow_iterator_policies
79     {
initializeboost::detail::shadow_iterator_policies80         template < typename iter_pair > void initialize(const iter_pair&) {}
81 
82         template < typename Iter >
dereferenceboost::detail::shadow_iterator_policies83         typename Iter::reference dereference(const Iter& i) const
84         {
85             typedef typename Iter::reference R;
86             return R(*i.base().first, *i.base().second);
87         }
88         template < typename Iter >
equalboost::detail::shadow_iterator_policies89         bool equal(const Iter& p1, const Iter& p2) const
90         {
91             return p1.base().first == p2.base().first;
92         }
incrementboost::detail::shadow_iterator_policies93         template < typename Iter > void increment(Iter& i)
94         {
95             ++i.base().first;
96             ++i.base().second;
97         }
98 
decrementboost::detail::shadow_iterator_policies99         template < typename Iter > void decrement(Iter& i)
100         {
101             --i.base().first;
102             --i.base().second;
103         }
104 
lessboost::detail::shadow_iterator_policies105         template < typename Iter > bool less(const Iter& x, const Iter& y) const
106         {
107             return x.base().first < y.base().first;
108         }
109         template < typename Iter >
distanceboost::detail::shadow_iterator_policies110         typename Iter::difference_type distance(
111             const Iter& x, const Iter& y) const
112         {
113             return y.base().first - x.base().first;
114         }
advanceboost::detail::shadow_iterator_policies115         template < typename D, typename Iter > void advance(Iter& p, D n)
116         {
117             p.base().first += n;
118             p.base().second += n;
119         }
120     };
121 
122 } // namespace detail
123 
124 template < typename IterA, typename IterB > struct shadow_iterator_generator
125 {
126 
127     // To use the iterator_adaptor we can't derive from
128     // random_access_iterator because we don't have a real reference.
129     // However, we want the STL algorithms to treat the shadow
130     // iterator like a random access iterator.
131     struct shadow_iterator_tag : public std::input_iterator_tag
132     {
operator std::random_access_iterator_tagboost::shadow_iterator_generator::shadow_iterator_tag133         operator std::random_access_iterator_tag()
134         {
135             return std::random_access_iterator_tag();
136         };
137     };
138     typedef typename std::iterator_traits< IterA >::value_type Aval;
139     typedef typename std::iterator_traits< IterB >::value_type Bval;
140     typedef typename std::iterator_traits< IterA >::reference Aref;
141     typedef typename std::iterator_traits< IterB >::reference Bref;
142     typedef typename std::iterator_traits< IterA >::difference_type D;
143     typedef detail::shadow_proxy< Aval, Bval, Aval > V;
144     typedef detail::shadow_proxy< Aref, Bref, Aval > R;
145     typedef iterator_adaptor< std::pair< IterA, IterB >,
146         detail::shadow_iterator_policies, V, R, V*, shadow_iterator_tag, D >
147         type;
148 };
149 
150 // short cut for creating a shadow iterator
151 template < class IterA, class IterB >
152 inline typename shadow_iterator_generator< IterA, IterB >::type
make_shadow_iter(IterA a,IterB b)153 make_shadow_iter(IterA a, IterB b)
154 {
155     typedef typename shadow_iterator_generator< IterA, IterB >::type Iter;
156     return Iter(std::make_pair(a, b));
157 }
158 
159 template < class Cmp > struct shadow_cmp
160 {
shadow_cmpboost::shadow_cmp161     inline shadow_cmp(const Cmp& c) : cmp(c) {}
162     template < class ShadowProxy1, class ShadowProxy2 >
operator ()boost::shadow_cmp163     inline bool operator()(const ShadowProxy1& x, const ShadowProxy2& y) const
164     {
165         return cmp(x.a, y.a);
166     }
167     Cmp cmp;
168 };
169 
170 } // namespace boost
171 
172 namespace std
173 {
174 template < class A1, class B1, class D1, class A2, class B2, class D2 >
swap(boost::detail::shadow_proxy<A1 &,B1 &,D1> x,boost::detail::shadow_proxy<A2 &,B2 &,D2> y)175 void swap(boost::detail::shadow_proxy< A1&, B1&, D1 > x,
176     boost::detail::shadow_proxy< A2&, B2&, D2 > y)
177 {
178     std::swap(x.a, y.a);
179     std::swap(x.b, y.b);
180 }
181 }
182 
183 #endif // BOOST_SHADOW_ITERATOR_HPP
184