trsl logo
persistent_filter_iterator.hpp
Go to the documentation of this file.
1 // (C) Copyright David Abrahams 2002.
2 // (C) Copyright Jeremy Siek 2002.
3 // (C) Copyright Thomas Witt 2002.
4 // (C) Copyright Renaud Detry 2007-2011.
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 // This file is a near copy of boost/iterator/filter_iterator.hpp.
10 // Conceptual modifications to boost/iterator/filter_iterator.hpp
11 // are reported /* - */ and /* + */
12 // Doxygen comments are not part of filter_iterator.hpp.
13 // Name changes are not reported.
14 
17 #ifndef TRSL_PERSISTENT_FILTER_ITERATOR_23022003THW_HPP
18 #define TRSL_PERSISTENT_FILTER_ITERATOR_23022003THW_HPP
19 
20 #include <boost/iterator.hpp>
21 #include <boost/iterator/iterator_adaptor.hpp>
22 #include <boost/iterator/iterator_categories.hpp>
23 
24 #include <boost/type_traits/is_class.hpp>
25 #include <boost/static_assert.hpp>
26 
27 namespace trsl
28 {
29  template <class Predicate, class Iterator>
31 
32  namespace detail
33  {
35  template <class Predicate, class Iterator>
37  {
38  typedef boost::iterator_adaptor<
40  , Iterator
41  , boost::use_default
42  , typename boost::mpl::if_<
43  boost::is_convertible<
44  typename boost::iterator_traversal<Iterator>::type
45  , boost::random_access_traversal_tag
46  >
47 /* - , bidirectional_traversal_tag*/
48  , boost::forward_traversal_tag/* + */
49 /* - , use_default*/
50  , boost::forward_traversal_tag/* + */
51  >::type
52  > type;
53  };
54  }
55 
92  template <class Predicate, class Iterator>
94  : public detail::persistent_filter_iterator_base<Predicate, Iterator>::type
95  {
97  Predicate, Iterator
98  >::type super_t;
99 
100  friend class boost::iterator_core_access;
101 
102  public:
104 
105  persistent_filter_iterator(Predicate f, Iterator x, Iterator end_ = Iterator())
106  : super_t(x), m_predicate(f), m_end(end_)
107  {
108  satisfy_predicate();
109  }
110 
111  persistent_filter_iterator(Iterator x, Iterator end_ = Iterator())
112  : super_t(x), m_predicate(), m_end(end_)
113  {
114  // Pro8 is a little too aggressive about instantiating the
115  // body of this function.
116 #if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
117  // Don't allow use of this constructor if Predicate is a
118  // function pointer type, since it will be 0.
119  BOOST_STATIC_ASSERT(boost::is_class<Predicate>::value);
120 #endif
121  satisfy_predicate();
122  }
123 
124  template<class OtherIterator>
125  persistent_filter_iterator(
126  persistent_filter_iterator<Predicate, OtherIterator> const& t
127  , typename boost::enable_if_convertible<OtherIterator, Iterator>::type* = 0
128  )
129  : super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
130 
131  Predicate predicate() const { return m_predicate; }
132 
133  Iterator end() const { return m_end; }
134 
135  private:
136  void increment()
137  {
138 /* - ++(this->base_reference());*/
139  satisfy_predicate();
140  }
141 
142 /* - void decrement()*/
143 /* - {*/
144 /* - while(!this->m_predicate(*--(this->base_reference()))){};*/
145 /* - }*/
146 
147  void satisfy_predicate()
148  {
149  while (this->base() != this->m_end && !this->m_predicate(*this->base()))
150  ++(this->base_reference());
151  }
152 
153  template<class OtherIterator>/* + */
154  bool equal(/* + */
155  persistent_filter_iterator<Predicate, OtherIterator> const& t/* + */
156  , typename boost::enable_if_convertible<OtherIterator, Iterator>::type* = 0/* + */
157  ) const/* + */
158  {/* + */
159  return (this->base() == t.base()) &&/* + */
160  // There is always at most one end iterator/* + */
161  ((this->base() == m_end) ||/* + */
162  (this->predicate() == t.predicate()));/* + */
163  }/* + */
164 
165  // Probably should be the initial base class so it can be
166  // optimized away via EBO if it is an empty class.
167  Predicate m_predicate;
168  Iterator m_end;
169  };
170 
171  template <class Predicate, class Iterator>
172  persistent_filter_iterator<Predicate,Iterator>
173  make_persistent_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
174  {
175  return persistent_filter_iterator<Predicate,Iterator>(f,x,end);
176  }
177 
178  template <class Predicate, class Iterator>
179  persistent_filter_iterator<Predicate,Iterator>
180  make_persistent_filter_iterator(
181  typename boost::iterators::enable_if<
182  boost::is_class<Predicate>
183  , Iterator
184  >::type x
185  , Iterator end = Iterator()
186 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
187  , Predicate* = 0
188 #endif
189  )
190  {
191  return persistent_filter_iterator<Predicate,Iterator>(x,end);
192  }
193 
194 } // namespace trsl
195 
196 #endif // TRSL_PERSISTENT_FILTER_ITERATOR_23022003THW_HPP
trsl::detail::persistent_filter_iterator_base
Used internally.
Definition: persistent_filter_iterator.hpp:36
trsl
Public namespace.
Definition: common.hpp:29
trsl::persistent_filter_iterator
Adaptation of boost::filter_iterator to allow an element to be selected multiple times.
Definition: persistent_filter_iterator.hpp:30
© Copyright 2007-2011 Renaud Detry.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt.)
Revised Wed Jan 8 2020 14:43:31.