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_FILTERED_HPP 12 #define BOOST_RANGE_ADAPTOR_FILTERED_HPP 13 14 #include <boost/range/adaptor/argument_fwd.hpp> 15 #include <boost/range/detail/default_constructible_unary_fn.hpp> 16 #include <boost/range/iterator_range.hpp> 17 #include <boost/range/concepts.hpp> 18 #include <boost/iterator/filter_iterator.hpp> 19 20 namespace boost 21 { 22 namespace range_detail 23 { 24 template< class P, class R > 25 struct filtered_range : 26 boost::iterator_range< 27 boost::filter_iterator< 28 typename default_constructible_unary_fn_gen<P, bool>::type, 29 typename range_iterator<R>::type 30 > 31 > 32 { 33 private: 34 typedef boost::iterator_range< 35 boost::filter_iterator< 36 typename default_constructible_unary_fn_gen<P, bool>::type, 37 typename range_iterator<R>::type 38 > 39 > base; 40 public: 41 typedef typename default_constructible_unary_fn_gen<P, bool>::type 42 pred_t; 43 filtered_rangeboost::range_detail::filtered_range44 filtered_range(P p, R& r) 45 : base(make_filter_iterator(pred_t(p), 46 boost::begin(r), boost::end(r)), 47 make_filter_iterator(pred_t(p), 48 boost::end(r), boost::end(r))) 49 { } 50 }; 51 52 template< class T > 53 struct filter_holder : holder<T> 54 { filter_holderboost::range_detail::filter_holder55 filter_holder( T r ) : holder<T>(r) 56 { } 57 }; 58 59 template< class SinglePassRange, class Predicate > 60 inline filtered_range<Predicate, SinglePassRange> operator |(SinglePassRange & r,const filter_holder<Predicate> & f)61 operator|(SinglePassRange& r, 62 const filter_holder<Predicate>& f) 63 { 64 BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>)); 65 return filtered_range<Predicate, SinglePassRange>( f.val, r ); 66 } 67 68 template< class SinglePassRange, class Predicate > 69 inline filtered_range<Predicate, const SinglePassRange> operator |(const SinglePassRange & r,const filter_holder<Predicate> & f)70 operator|(const SinglePassRange& r, 71 const filter_holder<Predicate>& f ) 72 { 73 BOOST_RANGE_CONCEPT_ASSERT(( 74 SinglePassRangeConcept<const SinglePassRange>)); 75 return filtered_range<Predicate, const SinglePassRange>( f.val, r ); 76 } 77 78 } // 'range_detail' 79 80 // Unusual use of 'using' is intended to bring filter_range into the boost namespace 81 // while leaving the mechanics of the '|' operator in range_detail and maintain 82 // argument dependent lookup. 83 // filter_range logically needs to be in the boost namespace to allow user of 84 // the library to define the return type for filter() 85 using range_detail::filtered_range; 86 87 namespace adaptors 88 { 89 namespace 90 { 91 const range_detail::forwarder<range_detail::filter_holder> 92 filtered = 93 range_detail::forwarder<range_detail::filter_holder>(); 94 } 95 96 template<class SinglePassRange, class Predicate> 97 inline filtered_range<Predicate, SinglePassRange> filter(SinglePassRange & rng,Predicate filter_pred)98 filter(SinglePassRange& rng, Predicate filter_pred) 99 { 100 BOOST_RANGE_CONCEPT_ASSERT(( 101 SinglePassRangeConcept<SinglePassRange>)); 102 103 return range_detail::filtered_range< 104 Predicate, SinglePassRange>( filter_pred, rng ); 105 } 106 107 template<class SinglePassRange, class Predicate> 108 inline filtered_range<Predicate, const SinglePassRange> filter(const SinglePassRange & rng,Predicate filter_pred)109 filter(const SinglePassRange& rng, Predicate filter_pred) 110 { 111 BOOST_RANGE_CONCEPT_ASSERT(( 112 SinglePassRangeConcept<const SinglePassRange>)); 113 114 return range_detail::filtered_range< 115 Predicate, const SinglePassRange>( filter_pred, rng ); 116 } 117 } // 'adaptors' 118 119 } 120 121 #endif 122