// 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 |