1 // Boost.Range library 2 // 3 // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and 4 // distribution is subject to the Boost Software License, Version 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // For more information, see http://www.boost.org/libs/range/ 9 // 10 11 #ifndef BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP 12 #define BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP 13 14 #include <boost/config.hpp> 15 #ifdef BOOST_MSVC 16 #pragma warning( push ) 17 #pragma warning( disable : 4355 ) 18 #endif 19 20 #include <boost/range/adaptor/argument_fwd.hpp> 21 #include <boost/range/iterator_range.hpp> 22 #include <boost/range/begin.hpp> 23 #include <boost/range/end.hpp> 24 #include <boost/iterator/iterator_adaptor.hpp> 25 26 27 28 namespace boost 29 { 30 namespace adaptors 31 { 32 // This structure exists to carry the parameters from the '|' operator 33 // to the index adapter. The expression rng | indexed(1) instantiates 34 // this structure and passes it as the right-hand operand to the 35 // '|' operator. 36 struct indexed 37 { indexedboost::adaptors::indexed38 explicit indexed(std::size_t x) : val(x) {} 39 std::size_t val; 40 }; 41 } 42 43 namespace range_detail 44 { 45 template< class Iter > 46 class indexed_iterator 47 : public boost::iterator_adaptor< indexed_iterator<Iter>, Iter > 48 { 49 private: 50 typedef boost::iterator_adaptor< indexed_iterator<Iter>, Iter > 51 base; 52 53 typedef BOOST_DEDUCED_TYPENAME base::difference_type index_type; 54 55 index_type m_index; 56 57 public: indexed_iterator(Iter i,index_type index)58 explicit indexed_iterator( Iter i, index_type index ) 59 : base(i), m_index(index) 60 { 61 BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" ); 62 } 63 index() const64 index_type index() const 65 { 66 return m_index; 67 } 68 69 private: 70 friend class boost::iterator_core_access; 71 increment()72 void increment() 73 { 74 ++m_index; 75 ++(this->base_reference()); 76 } 77 78 decrement()79 void decrement() 80 { 81 BOOST_ASSERT( m_index > 0 && "Indexed Iterator out of bounds" ); 82 --m_index; 83 --(this->base_reference()); 84 } 85 advance(index_type n)86 void advance( index_type n ) 87 { 88 m_index += n; 89 BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" ); 90 this->base_reference() += n; 91 } 92 }; 93 94 template< class Rng > 95 struct indexed_range : 96 iterator_range< indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> > 97 { 98 private: 99 typedef indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> 100 iter_type; 101 typedef iterator_range<iter_type> 102 base; 103 public: 104 template< class Index > indexed_rangeboost::range_detail::indexed_range105 indexed_range( Index i, Rng& r ) 106 : base( iter_type(boost::begin(r), i), iter_type(boost::end(r),i) ) 107 { } 108 }; 109 110 } // 'range_detail' 111 112 // Make this available to users of this library. It will sometimes be 113 // required since it is the return type of operator '|' and 114 // index(). 115 using range_detail::indexed_range; 116 117 namespace adaptors 118 { 119 template< class SinglePassRange > 120 inline indexed_range<SinglePassRange> operator |(SinglePassRange & r,const indexed & f)121 operator|( SinglePassRange& r, 122 const indexed& f ) 123 { 124 return indexed_range<SinglePassRange>( f.val, r ); 125 } 126 127 template< class SinglePassRange > 128 inline indexed_range<const SinglePassRange> operator |(const SinglePassRange & r,const indexed & f)129 operator|( const SinglePassRange& r, 130 const indexed& f ) 131 { 132 return indexed_range<const SinglePassRange>( f.val, r ); 133 } 134 135 template<class SinglePassRange, class Index> 136 inline indexed_range<SinglePassRange> index(SinglePassRange & rng,Index index_value)137 index(SinglePassRange& rng, Index index_value) 138 { 139 return indexed_range<SinglePassRange>(index_value, rng); 140 } 141 142 template<class SinglePassRange, class Index> 143 inline indexed_range<const SinglePassRange> index(const SinglePassRange & rng,Index index_value)144 index(const SinglePassRange& rng, Index index_value) 145 { 146 return indexed_range<const SinglePassRange>(index_value, rng); 147 } 148 } // 'adaptors' 149 150 } 151 152 #ifdef BOOST_MSVC 153 #pragma warning( pop ) 154 #endif 155 156 #endif 157