Full code attached, built with Boost 1.47 and gcc-4.6.2, many thanks.
Rob.
#include <iostream>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/adaptor/filtered.hpp>
struct Thing { Thing( char c ) : c( c ) { } char c; };
std::ostream & operator << ( std::ostream & ostrm, const Thing & thing ) { return ostrm << thing.c; }
struct ThingFeed
{
ThingFeed( const char * thing_values ) : m_current_value( thing_values ) { }
Thing * getNextThing( ) { return * m_current_value ? new Thing( * m_current_value ++ ) : 0; }
private:
const char * m_current_value;
};
struct ThingIterator : public boost::iterator_facade<ThingIterator, Thing, boost::single_pass_traversal_tag>
{
ThingIterator(ThingFeed& feed, Thing* cur = NULL) : m_feed(feed), m_cur(cur) {}
bool equal(const ThingIterator& other) const { return m_cur == other.m_cur; }
void increment() { m_cur = m_feed.getNextThing(); }
Thing& dereference() const { return *m_cur; }
private:
ThingFeed& m_feed;
Thing* m_cur;
};
class ThingRange : public boost::iterator_range<ThingIterator>
{
public:
ThingRange(ThingFeed& feed)
: boost::iterator_range<ThingIterator>(
ThingIterator(feed, feed.getNextThing()),
ThingIterator(feed))
{}
};
void printThing( const Thing & thing ) { std::cout << thing << "\n"; }
bool thingFilter( const Thing & thing ) { return thing.c != 'c'; }
int main( )
{
ThingFeed feed( "abcd" );
boost::for_each( ThingRange(feed) | boost::adaptors::filtered( thingFilter ), printThing );
}