1// (C) Copyright David Abrahams 2002.
2// (C) Copyright Jeremy Siek 2002.
3// (C) Copyright Thomas Witt 2002.
4// Distributed under the Boost Software License, Version 1.0. (See
5// accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
8#define BOOST_FILTER_ITERATOR_23022003THW_HPP
9
10#include <boost/iterator.hpp>
11#include <boost/iterator/iterator_adaptor.hpp>
12#include <boost/iterator/iterator_categories.hpp>
13
14#include <boost/type_traits/is_class.hpp>
15#include <boost/static_assert.hpp>
16
17namespace boost {
18namespace iterators {
19
20 template <class Predicate, class Iterator>
21 class filter_iterator;
22
23 namespace detail
24 {
25 template <class Predicate, class Iterator>
26 struct filter_iterator_base
27 {
28 typedef iterator_adaptor<
29 filter_iterator<Predicate, Iterator>
30 , Iterator
31 , use_default
32 , typename mpl::if_<
33 is_convertible<
34 typename iterator_traversal<Iterator>::type
35 , random_access_traversal_tag
36 >
37 , bidirectional_traversal_tag
38 , use_default
39 >::type
40 > type;
41 };
42 }
43
44 template <class Predicate, class Iterator>
45 class filter_iterator
46 : public detail::filter_iterator_base<Predicate, Iterator>::type
47 {
48 typedef typename detail::filter_iterator_base<
49 Predicate, Iterator
50 >::type super_t;
51
52 friend class iterator_core_access;
53
54 public:
55 filter_iterator() { }
56
57 filter_iterator(Predicate f, Iterator x, Iterator end_ = Iterator())
58 : super_t(x), m_predicate(f), m_end(end_)
59 {
60 satisfy_predicate();
61 }
62
63 filter_iterator(Iterator x, Iterator end_ = Iterator())
64 : super_t(x), m_predicate(), m_end(end_)
65 {
66 // Pro8 is a little too aggressive about instantiating the
67 // body of this function.
68#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
69 // Don't allow use of this constructor if Predicate is a
70 // function pointer type, since it will be 0.
71 BOOST_STATIC_ASSERT(is_class<Predicate>::value);
72#endif
73 satisfy_predicate();
74 }
75
76 template<class OtherIterator>
77 filter_iterator(
78 filter_iterator<Predicate, OtherIterator> const& t
79 , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
80 )
81 : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
82
83 Predicate predicate() const { return m_predicate; }
84
85 Iterator end() const { return m_end; }
86
87 private:
88 void increment()
89 {
90 ++(this->base_reference());
91 satisfy_predicate();
92 }
93
94 void decrement()
95 {
96 while(!this->m_predicate(*--(this->base_reference()))){};
97 }
98
99 void satisfy_predicate()
100 {
101 while (this->base() != this->m_end && !this->m_predicate(*this->base()))
102 ++(this->base_reference());
103 }
104
105 // Probably should be the initial base class so it can be
106 // optimized away via EBO if it is an empty class.
107 Predicate m_predicate;
108 Iterator m_end;
109 };
110
111 template <class Predicate, class Iterator>
112 inline filter_iterator<Predicate,Iterator>
113 make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
114 {
115 return filter_iterator<Predicate,Iterator>(f,x,end);
116 }
117
118 template <class Predicate, class Iterator>
119 inline filter_iterator<Predicate,Iterator>
120 make_filter_iterator(
121 typename iterators::enable_if<
122 is_class<Predicate>
123 , Iterator
124 >::type x
125 , Iterator end = Iterator())
126 {
127 return filter_iterator<Predicate,Iterator>(x,end);
128 }
129
130} // namespace iterators
131
132using iterators::filter_iterator;
133using iterators::make_filter_iterator;
134
135} // namespace boost
136
137#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
138

source code of boost/boost/iterator/filter_iterator.hpp