238 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
// 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_ADJACENT_FILTER_IMPL_HPP
 | 
						|
#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_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/range/concepts.hpp>
 | 
						|
#include <boost/iterator/iterator_adaptor.hpp>
 | 
						|
#include <boost/next_prior.hpp>
 | 
						|
 | 
						|
 | 
						|
namespace boost
 | 
						|
{
 | 
						|
    namespace range_detail
 | 
						|
    {
 | 
						|
        template< class Iter, class Pred, bool default_pass >
 | 
						|
        class skip_iterator
 | 
						|
          : public boost::iterator_adaptor<
 | 
						|
                    skip_iterator<Iter,Pred,default_pass>,
 | 
						|
                    Iter,
 | 
						|
                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
 | 
						|
                    boost::forward_traversal_tag,
 | 
						|
                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
 | 
						|
                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
 | 
						|
                >
 | 
						|
          , private Pred
 | 
						|
        {
 | 
						|
        private:
 | 
						|
            typedef boost::iterator_adaptor<
 | 
						|
                        skip_iterator<Iter,Pred,default_pass>,
 | 
						|
                        Iter,
 | 
						|
                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
 | 
						|
                        boost::forward_traversal_tag,
 | 
						|
                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
 | 
						|
                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
 | 
						|
                    > base_t;
 | 
						|
 | 
						|
        public:
 | 
						|
            typedef Pred pred_t;
 | 
						|
            typedef Iter iter_t;
 | 
						|
 | 
						|
            skip_iterator() : m_last() {}
 | 
						|
 | 
						|
            skip_iterator(iter_t it, iter_t last, const Pred& pred)
 | 
						|
                : base_t(it)
 | 
						|
                , pred_t(pred)
 | 
						|
                , m_last(last)
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            template<class OtherIter>
 | 
						|
            skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
 | 
						|
            : base_t(other.base())
 | 
						|
            , pred_t(other)
 | 
						|
            , m_last(other.m_last)
 | 
						|
            {
 | 
						|
            }
 | 
						|
 | 
						|
            void increment()
 | 
						|
            {
 | 
						|
                iter_t& it = this->base_reference();
 | 
						|
                BOOST_ASSERT( it != m_last );
 | 
						|
                pred_t& bi_pred = *this;
 | 
						|
                iter_t prev = it;
 | 
						|
                ++it;
 | 
						|
                if (it != m_last)
 | 
						|
                {
 | 
						|
                    if (default_pass)
 | 
						|
                    {
 | 
						|
                        while (it != m_last && !bi_pred(*prev, *it))
 | 
						|
                        {
 | 
						|
                            ++it;
 | 
						|
                            ++prev;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        for (; it != m_last; ++it, ++prev)
 | 
						|
                        {
 | 
						|
                            if (bi_pred(*prev, *it))
 | 
						|
                            {
 | 
						|
                                break;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            iter_t m_last;
 | 
						|
        };
 | 
						|
 | 
						|
        template< class P, class R, bool default_pass >
 | 
						|
        struct adjacent_filtered_range
 | 
						|
            : iterator_range< skip_iterator<
 | 
						|
                                BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
 | 
						|
                                P,
 | 
						|
                                default_pass
 | 
						|
                            >
 | 
						|
                        >
 | 
						|
        {
 | 
						|
        private:
 | 
						|
            typedef skip_iterator<
 | 
						|
                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
 | 
						|
                        P,
 | 
						|
                        default_pass
 | 
						|
                     >
 | 
						|
                skip_iter;
 | 
						|
 | 
						|
            typedef iterator_range<skip_iter>
 | 
						|
                base_range;
 | 
						|
 | 
						|
            typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
 | 
						|
 | 
						|
        public:
 | 
						|
            adjacent_filtered_range( const P& p, R& r )
 | 
						|
            : base_range(skip_iter(boost::begin(r), boost::end(r), p),
 | 
						|
                         skip_iter(boost::end(r), boost::end(r), p))
 | 
						|
            {
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        template< class T >
 | 
						|
        struct adjacent_holder : holder<T>
 | 
						|
        {
 | 
						|
            adjacent_holder( T r ) : holder<T>(r)
 | 
						|
            { }
 | 
						|
        };
 | 
						|
 | 
						|
        template< class T >
 | 
						|
        struct adjacent_excl_holder : holder<T>
 | 
						|
        {
 | 
						|
            adjacent_excl_holder( T r ) : holder<T>(r)
 | 
						|
            { }
 | 
						|
        };
 | 
						|
 | 
						|
        template< class ForwardRng, class BinPredicate >
 | 
						|
        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
 | 
						|
        operator|( ForwardRng& r,
 | 
						|
                   const adjacent_holder<BinPredicate>& f )
 | 
						|
        {
 | 
						|
            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
 | 
						|
 | 
						|
            return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
 | 
						|
        }
 | 
						|
 | 
						|
        template< class ForwardRng, class BinPredicate >
 | 
						|
        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
 | 
						|
        operator|( const ForwardRng& r,
 | 
						|
                   const adjacent_holder<BinPredicate>& f )
 | 
						|
        {
 | 
						|
            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
 | 
						|
 | 
						|
            return adjacent_filtered_range<BinPredicate,
 | 
						|
                                           const ForwardRng, true>( f.val, r );
 | 
						|
        }
 | 
						|
 | 
						|
        template< class ForwardRng, class BinPredicate >
 | 
						|
        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
 | 
						|
        operator|( ForwardRng& r,
 | 
						|
                   const adjacent_excl_holder<BinPredicate>& f )
 | 
						|
        {
 | 
						|
            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
 | 
						|
            return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
 | 
						|
        }
 | 
						|
 | 
						|
        template< class ForwardRng, class BinPredicate >
 | 
						|
        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
 | 
						|
        operator|( const ForwardRng& r,
 | 
						|
                   const adjacent_excl_holder<BinPredicate>& f )
 | 
						|
        {
 | 
						|
            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
 | 
						|
            return adjacent_filtered_range<BinPredicate,
 | 
						|
                                           const ForwardRng, false>( f.val, r );
 | 
						|
        }
 | 
						|
 | 
						|
    } // 'range_detail'
 | 
						|
 | 
						|
    // Bring adjacent_filter_range into the boost namespace so that users of
 | 
						|
    // this library may specify the return type of the '|' operator and
 | 
						|
    // adjacent_filter()
 | 
						|
    using range_detail::adjacent_filtered_range;
 | 
						|
 | 
						|
    namespace adaptors
 | 
						|
    {
 | 
						|
        namespace
 | 
						|
        {
 | 
						|
            const range_detail::forwarder<range_detail::adjacent_holder>
 | 
						|
                adjacent_filtered =
 | 
						|
                   range_detail::forwarder<range_detail::adjacent_holder>();
 | 
						|
 | 
						|
            const range_detail::forwarder<range_detail::adjacent_excl_holder>
 | 
						|
                adjacent_filtered_excl =
 | 
						|
                    range_detail::forwarder<range_detail::adjacent_excl_holder>();
 | 
						|
        }
 | 
						|
 | 
						|
        template<class ForwardRng, class BinPredicate>
 | 
						|
        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
 | 
						|
        adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
 | 
						|
        {
 | 
						|
            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
 | 
						|
            return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
 | 
						|
        }
 | 
						|
 | 
						|
        template<class ForwardRng, class BinPredicate>
 | 
						|
        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
 | 
						|
        adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
 | 
						|
        {
 | 
						|
            BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
 | 
						|
            return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
 | 
						|
        }
 | 
						|
 | 
						|
    } // 'adaptors'
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#ifdef BOOST_MSVC
 | 
						|
#pragma warning( pop )
 | 
						|
#endif
 | 
						|
 | 
						|
#endif
 |