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