Imported Upstream version 0.8~alpha1
[platform/upstream/syncevolution.git] / src / boost / iterator / filter_iterator.hpp
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
17 namespace boost
18 {
19   template <class Predicate, class Iterator>
20   class filter_iterator;
21
22   namespace detail
23   {
24     template <class Predicate, class Iterator>
25     struct filter_iterator_base
26     {
27         typedef iterator_adaptor<
28             filter_iterator<Predicate, Iterator>
29           , Iterator
30           , use_default
31           , typename mpl::if_<
32                 is_convertible<
33                     typename iterator_traversal<Iterator>::type
34                   , random_access_traversal_tag
35                 >
36               , bidirectional_traversal_tag
37               , use_default
38             >::type
39         > type;
40     };
41   }
42   
43   template <class Predicate, class Iterator>
44   class filter_iterator
45     : public detail::filter_iterator_base<Predicate, Iterator>::type
46   {
47       typedef typename detail::filter_iterator_base<
48           Predicate, Iterator
49       >::type super_t;
50
51       friend class iterator_core_access;
52
53    public:
54       filter_iterator() { }
55
56       filter_iterator(Predicate f, Iterator x, Iterator end_ = Iterator())
57           : super_t(x), m_predicate(f), m_end(end_)
58       {
59           satisfy_predicate();
60       }
61
62       filter_iterator(Iterator x, Iterator end_ = Iterator())
63         : super_t(x), m_predicate(), m_end(end_)
64       {
65         // Pro8 is a little too aggressive about instantiating the
66         // body of this function.
67 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
68           // Don't allow use of this constructor if Predicate is a
69           // function pointer type, since it will be 0.
70           BOOST_STATIC_ASSERT(is_class<Predicate>::value);
71 #endif 
72           satisfy_predicate();
73       }
74
75       template<class OtherIterator>
76       filter_iterator(
77           filter_iterator<Predicate, OtherIterator> const& t
78           , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
79           )
80           : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
81
82       Predicate predicate() const { return m_predicate; }
83
84       Iterator end() const { return m_end; }
85
86    private:
87       void increment()
88       {
89           ++(this->base_reference());
90           satisfy_predicate();
91       }
92
93       void decrement()
94       {
95         while(!this->m_predicate(*--(this->base_reference()))){};
96       }
97
98       void satisfy_predicate()
99       {
100           while (this->base() != this->m_end && !this->m_predicate(*this->base()))
101               ++(this->base_reference());
102       }
103
104       // Probably should be the initial base class so it can be
105       // optimized away via EBO if it is an empty class.
106       Predicate m_predicate;
107       Iterator m_end;
108   };
109
110   template <class Predicate, class Iterator>
111   filter_iterator<Predicate,Iterator>
112   make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
113   {
114       return filter_iterator<Predicate,Iterator>(f,x,end);
115   }
116
117   template <class Predicate, class Iterator>
118   filter_iterator<Predicate,Iterator>
119   make_filter_iterator(
120       typename iterators::enable_if<
121           is_class<Predicate>
122         , Iterator
123       >::type x
124     , Iterator end = Iterator()
125 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
126     , Predicate* = 0
127 #endif 
128   )
129   {
130       return filter_iterator<Predicate,Iterator>(x,end);
131   }
132
133 } // namespace boost
134
135 #endif // BOOST_FILTER_ITERATOR_23022003THW_HPP