// 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 #ifdef BOOST_MSVC #pragma warning( push ) #pragma warning( disable : 4355 ) #endif #include #include #include #include #include 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 > { private: typedef boost::iterator_adaptor< indexed_iterator, 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::type> > { private: typedef indexed_iterator::type> iter_type; typedef iterator_range 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 operator|( SinglePassRange& r, const indexed& f ) { return indexed_range( f.val, r ); } template< class SinglePassRange > inline indexed_range operator|( const SinglePassRange& r, const indexed& f ) { return indexed_range( f.val, r ); } template inline indexed_range index(SinglePassRange& rng, Index index_value) { return indexed_range(index_value, rng); } template inline indexed_range index(const SinglePassRange& rng, Index index_value) { return indexed_range(index_value, rng); } } // 'adaptors' } #ifdef BOOST_MSVC #pragma warning( pop ) #endif #endif