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