shadow_iterator.hpp 5.4 KB

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