| // Boost.Range library |
| // |
| // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and |
| // distribution is subject to the Boost Software License, Version |
| // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // For more information, see http://www.boost.org/libs/range/ |
| // |
| |
| #ifndef BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP |
| #define BOOST_RANGE_ADAPTOR_INDEXED_IMPL_HPP |
| |
| #include <boost/config.hpp> |
| #ifdef BOOST_MSVC |
| #pragma warning( push ) |
| #pragma warning( disable : 4355 ) |
| #endif |
| |
| #include <boost/range/adaptor/argument_fwd.hpp> |
| #include <boost/range/iterator_range.hpp> |
| #include <boost/range/begin.hpp> |
| #include <boost/range/end.hpp> |
| #include <boost/iterator/iterator_adaptor.hpp> |
| |
| |
| |
| namespace boost |
| { |
| namespace adaptors |
| { |
| // This structure exists to carry the parameters from the '|' operator |
| // to the index adapter. The expression rng | indexed(1) instantiates |
| // this structure and passes it as the right-hand operand to the |
| // '|' operator. |
| struct indexed |
| { |
| explicit indexed(std::size_t x) : val(x) {} |
| std::size_t val; |
| }; |
| } |
| |
| namespace range_detail |
| { |
| template< class Iter > |
| class indexed_iterator |
| : public boost::iterator_adaptor< indexed_iterator<Iter>, Iter > |
| { |
| private: |
| typedef boost::iterator_adaptor< indexed_iterator<Iter>, Iter > |
| base; |
| |
| typedef BOOST_DEDUCED_TYPENAME base::difference_type index_type; |
| |
| index_type m_index; |
| |
| public: |
| explicit indexed_iterator( Iter i, index_type index ) |
| : base(i), m_index(index) |
| { |
| BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" ); |
| } |
| |
| index_type index() const |
| { |
| return m_index; |
| } |
| |
| private: |
| friend class boost::iterator_core_access; |
| |
| void increment() |
| { |
| ++m_index; |
| ++(this->base_reference()); |
| } |
| |
| |
| void decrement() |
| { |
| BOOST_ASSERT( m_index > 0 && "Indexed Iterator out of bounds" ); |
| --m_index; |
| --(this->base_reference()); |
| } |
| |
| void advance( index_type n ) |
| { |
| m_index += n; |
| BOOST_ASSERT( m_index >= 0 && "Indexed Iterator out of bounds" ); |
| this->base_reference() += n; |
| } |
| }; |
| |
| template< class Rng > |
| struct indexed_range : |
| iterator_range< indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> > |
| { |
| private: |
| typedef indexed_iterator<BOOST_DEDUCED_TYPENAME range_iterator<Rng>::type> |
| iter_type; |
| typedef iterator_range<iter_type> |
| base; |
| public: |
| template< class Index > |
| indexed_range( Index i, Rng& r ) |
| : base( iter_type(boost::begin(r), i), iter_type(boost::end(r),i) ) |
| { } |
| }; |
| |
| } // 'range_detail' |
| |
| // Make this available to users of this library. It will sometimes be |
| // required since it is the return type of operator '|' and |
| // index(). |
| using range_detail::indexed_range; |
| |
| namespace adaptors |
| { |
| template< class SinglePassRange > |
| inline indexed_range<SinglePassRange> |
| operator|( SinglePassRange& r, |
| const indexed& f ) |
| { |
| return indexed_range<SinglePassRange>( f.val, r ); |
| } |
| |
| template< class SinglePassRange > |
| inline indexed_range<const SinglePassRange> |
| operator|( const SinglePassRange& r, |
| const indexed& f ) |
| { |
| return indexed_range<const SinglePassRange>( f.val, r ); |
| } |
| |
| template<class SinglePassRange, class Index> |
| inline indexed_range<SinglePassRange> |
| index(SinglePassRange& rng, Index index_value) |
| { |
| return indexed_range<SinglePassRange>(index_value, rng); |
| } |
| |
| template<class SinglePassRange, class Index> |
| inline indexed_range<const SinglePassRange> |
| index(const SinglePassRange& rng, Index index_value) |
| { |
| return indexed_range<const SinglePassRange>(index_value, rng); |
| } |
| } // 'adaptors' |
| |
| } |
| |
| #ifdef BOOST_MSVC |
| #pragma warning( pop ) |
| #endif |
| |
| #endif |