PageRenderTime 44ms CodeModel.GetById 8ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/range/adaptor/adjacent_filtered.hpp

http://hadesmem.googlecode.com/
C++ Header | 238 lines | 194 code | 32 blank | 12 comment | 12 complexity | 6bed31c3358d7911d13bb4466967d540 MD5 | raw file
  1// Boost.Range library
  2//
  3//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
  4//  distribution is subject to the Boost Software License, Version
  5//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6//  http://www.boost.org/LICENSE_1_0.txt)
  7//
  8// For more information, see http://www.boost.org/libs/range/
  9//
 10
 11#ifndef BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
 12#define BOOST_RANGE_ADAPTOR_ADJACENT_FILTER_IMPL_HPP
 13
 14#include <boost/config.hpp>
 15#ifdef BOOST_MSVC
 16#pragma warning( push )
 17#pragma warning( disable : 4355 )
 18#endif
 19
 20#include <boost/range/adaptor/argument_fwd.hpp>
 21#include <boost/range/iterator_range.hpp>
 22#include <boost/range/begin.hpp>
 23#include <boost/range/end.hpp>
 24#include <boost/iterator/iterator_adaptor.hpp>
 25#include <boost/next_prior.hpp>
 26
 27
 28namespace boost
 29{
 30    namespace range_detail
 31    {
 32        template< class Iter, class Pred, bool default_pass >
 33        class skip_iterator
 34          : public boost::iterator_adaptor<
 35                    skip_iterator<Iter,Pred,default_pass>,
 36                    Iter,
 37                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
 38                    boost::forward_traversal_tag,
 39                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
 40                    BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
 41                >
 42          , private Pred
 43        {
 44        private:
 45            typedef boost::iterator_adaptor<
 46                        skip_iterator<Iter,Pred,default_pass>,
 47                        Iter,
 48                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::value_type,
 49                        boost::forward_traversal_tag,
 50                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::reference,
 51                        BOOST_DEDUCED_TYPENAME std::iterator_traits<Iter>::difference_type
 52                    > base_t;
 53
 54        public:
 55            typedef Pred pred_t;
 56            typedef Iter iter_t;
 57
 58            skip_iterator() : m_last() {}
 59
 60            skip_iterator(iter_t it, iter_t last, const Pred& pred)
 61                : base_t(it)
 62                , pred_t(pred)
 63                , m_last(last)
 64            {
 65                move_to_next_valid();
 66            }
 67
 68            template<class OtherIter>
 69            skip_iterator( const skip_iterator<OtherIter, pred_t, default_pass>& other )
 70            : base_t(other.base())
 71            , pred_t(other)
 72            , m_last(other.m_last) {}
 73
 74            void move_to_next_valid()
 75            {
 76                iter_t& it = this->base_reference();
 77                pred_t& bi_pred = *this;
 78                if (it != m_last)
 79                {
 80                    if (default_pass)
 81                    {
 82                        iter_t nxt = ::boost::next(it);
 83                        while (nxt != m_last && !bi_pred(*it, *nxt))
 84                        {
 85                            ++it;
 86                            ++nxt;
 87                        }
 88                    }
 89                    else
 90                    {
 91                        iter_t nxt = ::boost::next(it);
 92                        for(; nxt != m_last; ++it, ++nxt)
 93                        {
 94                            if (bi_pred(*it, *nxt))
 95                            {
 96                                break;
 97                            }
 98                        }
 99                        if (nxt == m_last)
100                        {
101                            it = m_last;
102                        }
103                    }
104                }
105            }
106
107            void increment()
108            {
109                iter_t& it = this->base_reference();
110                BOOST_ASSERT( it != m_last );
111                ++it;
112                move_to_next_valid();
113            }
114
115            iter_t m_last;
116        };
117
118        template< class P, class R, bool default_pass >
119        struct adjacent_filtered_range
120            : iterator_range< skip_iterator<
121                                BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
122                                P,
123                                default_pass
124                            >
125                        >
126        {
127        private:
128            typedef skip_iterator<
129                        BOOST_DEDUCED_TYPENAME range_iterator<R>::type,
130                        P,
131                        default_pass
132                     >
133                skip_iter;
134
135            typedef iterator_range<skip_iter>
136                base_range;
137
138            typedef BOOST_DEDUCED_TYPENAME range_iterator<R>::type raw_iterator;
139
140        public:
141            adjacent_filtered_range( const P& p, R& r )
142            : base_range(skip_iter(boost::begin(r), boost::end(r), p),
143                         skip_iter(boost::end(r), boost::end(r), p))
144            {
145            }
146        };
147
148        template< class T >
149        struct adjacent_holder : holder<T>
150        {
151            adjacent_holder( T r ) : holder<T>(r)
152            { }
153        };
154
155        template< class T >
156        struct adjacent_excl_holder : holder<T>
157        {
158            adjacent_excl_holder( T r ) : holder<T>(r)
159            { }
160        };
161
162        template< class ForwardRng, class BinPredicate >
163        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
164        operator|( ForwardRng& r,
165                   const adjacent_holder<BinPredicate>& f )
166        {
167            return adjacent_filtered_range<BinPredicate, ForwardRng, true>( f.val, r );
168        }
169
170        template< class ForwardRng, class BinPredicate >
171        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
172        operator|( const ForwardRng& r,
173                   const adjacent_holder<BinPredicate>& f )
174        {
175            return adjacent_filtered_range<BinPredicate,
176                                           const ForwardRng, true>( f.val, r );
177        }
178
179        template< class ForwardRng, class BinPredicate >
180        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
181        operator|( ForwardRng& r,
182                   const adjacent_excl_holder<BinPredicate>& f )
183        {
184            return adjacent_filtered_range<BinPredicate, ForwardRng, false>( f.val, r );
185        }
186
187        template< class ForwardRng, class BinPredicate >
188        inline adjacent_filtered_range<BinPredicate, ForwardRng, false>
189        operator|( const ForwardRng& r,
190                   const adjacent_excl_holder<BinPredicate>& f )
191        {
192            return adjacent_filtered_range<BinPredicate,
193                                           const ForwardRng, false>( f.val, r );
194        }
195
196    } // 'range_detail'
197
198    // Bring adjacent_filter_range into the boost namespace so that users of
199    // this library may specify the return type of the '|' operator and
200    // adjacent_filter()
201    using range_detail::adjacent_filtered_range;
202
203    namespace adaptors
204    {
205        namespace
206        {
207            const range_detail::forwarder<range_detail::adjacent_holder>
208                adjacent_filtered =
209                   range_detail::forwarder<range_detail::adjacent_holder>();
210
211            const range_detail::forwarder<range_detail::adjacent_excl_holder>
212                adjacent_filtered_excl =
213                    range_detail::forwarder<range_detail::adjacent_excl_holder>();
214        }
215
216        template<class ForwardRng, class BinPredicate>
217        inline adjacent_filtered_range<BinPredicate, ForwardRng, true>
218        adjacent_filter(ForwardRng& rng, BinPredicate filter_pred)
219        {
220            return adjacent_filtered_range<BinPredicate, ForwardRng, true>(filter_pred, rng);
221        }
222
223        template<class ForwardRng, class BinPredicate>
224        inline adjacent_filtered_range<BinPredicate, const ForwardRng, true>
225        adjacent_filter(const ForwardRng& rng, BinPredicate filter_pred)
226        {
227            return adjacent_filtered_range<BinPredicate, const ForwardRng, true>(filter_pred, rng);
228        }
229
230    } // 'adaptors'
231
232}
233
234#ifdef BOOST_MSVC
235#pragma warning( pop )
236#endif
237
238#endif