indexed.hpp 4.55 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
// 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