|
Boost Users : |
Subject: Re: [Boost-users] Using single-pass ranges.
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2012-08-03 13:07:38
> When a range is constructed from a 'getNextThing()' sort of interface,
> it seems quite
> reasonable for that interface to return references to an abstract type.
> However that doesn't
> seem to be supported by Boost.IteratorFacade. I guess this only comes
> up in this context,
> as you couldn't construct a container of abstract objects, but is this
> a know limitation of
> iterator_facade?
I'm not sure whether this can be done with iterator_facade. If not,
Boost.Iterator could probably use a new utility (abstract_iterator_facade?)
that makes this possible.
As a workaround, though, you can make ThingRange be a range of pointers
instead. See code below.
Regards,
Nate
#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 AbstractThing {
virtual char get_c( ) const = 0;
virtual ~AbstractThing( ) { }
};
struct Thing : AbstractThing {
Thing( char c ) : c( c ) { }
char get_c( ) const { return c; }
private:
char c;
};
struct ThingFeed
{
ThingFeed( const char * thing_values ) : m_current_value( thing_values ) { }
AbstractThing * getNextThing( ) { return * m_current_value ? new Thing( * m_current_value ++ ) : 0; }
private:
const char * m_current_value;
};
struct ThingIterator : public boost::iterator_facade<ThingIterator, AbstractThing *, boost::single_pass_traversal_tag, AbstractThing *>
{
ThingIterator( ThingFeed & feed, AbstractThing * 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( ); }
AbstractThing * dereference( ) const { return m_cur; }
private:
ThingFeed & m_feed;
AbstractThing * m_cur;
};
struct ThingRange : public boost::iterator_range<ThingIterator>
{
ThingRange( ThingFeed & feed )
: boost::iterator_range<ThingIterator>(
ThingIterator( feed, feed.getNextThing( ) ),
ThingIterator( feed ) )
{}
};
void printThing( const AbstractThing * thing ) { std::cout << thing->get_c( ) << "\n"; }
int main( )
{
ThingFeed feed( "abcd" );
boost::for_each( ThingRange(feed), printThing );
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net