|
Boost : |
From: Bob Bell (belvis_at_[hidden])
Date: 2004-12-12 15:30:55
Hi boosters-
A couple of days ago I started a thread asking about the rationale for
making filter_iterator only a forward traversal iterator. I presented
some arguments for making filter_iterator bidirectional instead. As some
people seemed to be convinced that this was OK, I took the liberty of
creating a patch.
Oddly enough, the work had almost been completed already -- all that
was needed was to make the category bidirectional. Here's the patch:
*** filter_iterator.hpp.orig Thu Aug 12 10:13:06 2004
--- filter_iterator.hpp Sun Dec 12 11:24:05 2004
***************
*** 33,39 ****
typename iterator_traversal<Iterator>::type
, bidirectional_traversal_tag
>
! , forward_traversal_tag
, use_default
>::type
> type;
--- 33,39 ----
typename iterator_traversal<Iterator>::type
, bidirectional_traversal_tag
>
! , bidirectional_traversal_tag
, use_default
>::type
> type;
Here's the test program I used to verify it:
#include <iostream>
#include <list>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/reverse_iterator.hpp>
// simple filter that returns true for even numbers:
struct filter {
typedef int argument_type;
bool operator()(argument_type iArg);
};
bool filter::operator()(argument_type iArg)
{
return (iArg & 1) == 0;
}
// Simple functions that traverse a sequence and print them:
template<typename It>
void traverse_forward(It iBegin, It iEnd)
{
while (iBegin != iEnd) {
std::cout << *iBegin << "\n";
++iBegin;
}
}
template<typename It>
void traverse_backward(It iBegin, It iEnd)
{
while (iBegin != iEnd) {
--iEnd;
std::cout << *iEnd << "\n";
}
}
// Show that boost::filter_iterator won't make a forward iterator into a
// bidirectional one.
typedef boost::filter_iterator<filter, std::istream_iterator<int> > ii;
enum {
result = boost::is_convertible<
boost::iterator_traversal<ii>::type
, boost::bidirectional_traversal_tag
>::value
};
BOOST_STATIC_ASSERT(!result);
int main (void)
{
std::list<int> l;
for (int i = 0; i < 10; ++i)
l.push_back(i);
typedef boost::filter_iterator<filter, std::list<int>::iterator> fi;
fi b, e;
b = boost::make_filter_iterator(filter(), l.begin(), l.end());
e = boost::make_filter_iterator(filter(), l.end(), l.end());
std::cout << "Using filter_iterator:\n";
std::cout << "\nEven numbers forward:\n";
traverse_forward(b, e);
std::cout << "\nEven numbers backward:\n";
traverse_backward(b, e);
// Show that filter_iterator works with reverse_iterator:
typedef boost::reverse_iterator<fi> ri;
std::cout << "\nUsing reverse_iterator with a filter_iterator:\n";
std::cout << "\nEven numbers backward:\n";
traverse_forward(ri(e), ri(b));
std::cout << "\nEven numbers forward:\n";
traverse_backward(ri(e), ri(b));
}
Here's the expected output:
Using filter_iterator:
Even numbers forward:
0
2
4
6
8
Even numbers backward:
8
6
4
2
0
Using reverse_iterator with a filter_iterator:
Even numbers backward:
8
6
4
2
0
Even numbers forward:
0
2
4
6
8
Bob
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk