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