• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[section:filter Filter Iterator]
2
3The filter iterator adaptor creates a view of an iterator range in
4which some elements of the range are skipped. A predicate function
5object controls which elements are skipped. When the predicate is
6applied to an element, if it returns `true` then the element is
7retained and if it returns `false` then the element is skipped
8over. When skipping over elements, it is necessary for the filter
9adaptor to know when to stop so as to avoid going past the end of the
10underlying range. A filter iterator is therefore constructed with pair
11of iterators indicating the range of elements in the unfiltered
12sequence to be traversed.
13
14[h2 Example]
15
16This example uses `filter_iterator` and then
17`make_filter_iterator` to output only the positive integers from an
18array of integers. Then `make_filter_iterator` is is used to output
19the integers greater than `-2`.
20
21    struct is_positive_number {
22      bool operator()(int x) { return 0 < x; }
23    };
24
25    int main()
26    {
27      int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
28      const int N = sizeof(numbers_)/sizeof(int);
29
30      typedef int* base_iterator;
31      base_iterator numbers(numbers_);
32
33      // Example using filter_iterator
34      typedef boost::filter_iterator<is_positive_number, base_iterator>
35        FilterIter;
36
37      is_positive_number predicate;
38      FilterIter filter_iter_first(predicate, numbers, numbers + N);
39      FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
40
41      std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
42      std::cout << std::endl;
43
44      // Example using make_filter_iterator()
45      std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
46                boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
47                std::ostream_iterator<int>(std::cout, " "));
48      std::cout << std::endl;
49
50      // Another example using make_filter_iterator()
51      std::copy(
52          boost::make_filter_iterator(
53              std::bind(std::greater<int>(), std::placeholders::_1, -2)
54            , numbers, numbers + N)
55
56        , boost::make_filter_iterator(
57              std::bind(std::greater<int>(), std::placeholders::_1, -2)
58            , numbers + N, numbers + N)
59
60        , std::ostream_iterator<int>(std::cout, " ")
61      );
62
63      std::cout << std::endl;
64
65      return boost::exit_success;
66    }
67
68
69The output is:
70
71[pre
724 5 8
734 5 8
740 -1 4 5 8
75]
76
77The source code for this example can be found [example_link filter_iterator_example.cpp..here].
78
79[h2 Reference]
80
81
82[h3 Synopsis]
83
84  template <class Predicate, class Iterator>
85  class filter_iterator
86  {
87   public:
88      typedef iterator_traits<Iterator>::value_type value_type;
89      typedef iterator_traits<Iterator>::reference reference;
90      typedef iterator_traits<Iterator>::pointer pointer;
91      typedef iterator_traits<Iterator>::difference_type difference_type;
92      typedef /* see below */ iterator_category;
93
94      filter_iterator();
95      filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
96      filter_iterator(Iterator x, Iterator end = Iterator());
97      template<class OtherIterator>
98      filter_iterator(
99          filter_iterator<Predicate, OtherIterator> const& t
100          , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
101          );
102      Predicate predicate() const;
103      Iterator end() const;
104      Iterator const& base() const;
105      reference operator*() const;
106      filter_iterator& operator++();
107  private:
108      Predicate m_pred; // exposition only
109      Iterator m_iter;  // exposition only
110      Iterator m_end;   // exposition only
111  };
112
113
114If `Iterator` models Readable Lvalue Iterator and Bidirectional Traversal
115Iterator then `iterator_category` is convertible to
116`std::bidirectional_iterator_tag`.
117Otherwise, if `Iterator` models Readable Lvalue Iterator and Forward Traversal
118Iterator then `iterator_category` is convertible to
119`std::forward_iterator_tag`.
120Otherwise `iterator_category` is
121convertible to `std::input_iterator_tag`.
122
123
124[h3 Requirements]
125
126The `Iterator` argument shall meet the requirements of Readable
127Iterator and Single Pass Iterator or it shall meet the requirements of
128Input Iterator.
129
130
131The `Predicate` argument must be Assignable, Copy Constructible, and
132the expression `p(x)` must be valid where `p` is an object of type
133`Predicate`, `x` is an object of type
134`iterator_traits<Iterator>::value_type`, and where the type of
135`p(x)` must be convertible to `bool`.
136
137
138[h3 Concepts]
139
140The concepts that `filter_iterator` models are dependent on which
141concepts the `Iterator` argument models, as specified in the
142following tables.
143
144[table Traversal
145       [[If `Iterator` models             ][then `filter_iterator` models   ]]
146       [[Single Pass Iterator             ][Single Pass Iterator            ]]
147       [[Forward Traversal Iterator       ][Forward Traversal Iterator      ]]
148       [[Bidirectional Traversal Iterator ][Bidirectional Traversal Iterator]]
149]
150
151[table Access
152       [[If `Iterator` models             ][then `filter_iterator` models   ]]
153       [[Readable Iterator][Readable Iterator]]
154       [[Writable Iterator][Writable Iterator]]
155       [[Lvalue Iterator  ][Lvalue Iterator  ]]
156]
157
158[table C++03
159       [[If `Iterator` models             ][then `filter_iterator` models   ]]
160       [[Readable Iterator, Single Pass Iterator             ][Input Iterator                ]]
161       [[Readable Lvalue Iterator, Forward Traversal Iterator][Forward Iterator              ]]
162       [[Writable Lvalue Iterator, Forward Traversal Iterator][Mutable Forward Iterator      ]]
163       [[Writable Lvalue Iterator, Bidirectional Iterator    ][Mutable Bidirectional Iterator]]
164]
165
166`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
167if and only if `X` is interoperable with `Y`.
168
169
170[h3 Operations]
171
172
173In addition to those operations required by the concepts that
174`filter_iterator` models, `filter_iterator` provides the following
175operations.
176
177
178  filter_iterator();
179
180[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.[br]
181[*Effects: ] Constructs a `filter_iterator` whose`m_pred`,  `m_iter`, and `m_end`
182  members are a default constructed.
183
184
185  filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
186
187[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
188    the first position in the range `[x,end)` such that `f(*m_iter) == true`
189    or else`m_iter == end`. The member `m_pred` is constructed from
190    `f` and `m_end` from `end`.
191
192
193
194  filter_iterator(Iterator x, Iterator end = Iterator());
195
196[*Requires: ] `Predicate` must be Default Constructible and
197  `Predicate` is a class type (not a function pointer).[br]
198[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
199    the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
200    or else`m_iter == end`. The member `m_pred` is default constructed.
201
202
203    template <class OtherIterator>
204    filter_iterator(
205        filter_iterator<Predicate, OtherIterator> const& t
206        , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
207        );
208
209[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
210[*Effects: ] Constructs a filter iterator whose members are copied from `t`.
211
212
213  Predicate predicate() const;
214
215[*Returns: ] `m_pred`
216
217
218   Ierator end() const;
219
220[*Returns: ] `m_end`
221
222
223  Iterator const& base() const;
224
225[*Returns: ] `m_iterator`
226
227
228  reference operator*() const;
229
230[*Returns: ] `*m_iter`
231
232
233  filter_iterator& operator++();
234
235[*Effects: ] Increments `m_iter` and then continues to
236  increment `m_iter` until either `m_iter == m_end`
237  or `m_pred(*m_iter) == true`.[br]
238[*Returns: ] `*this`
239
240[endsect]
241