|
Boost Users : |
Subject: Re: [Boost-users] Using single-pass ranges.
From: Robert Jones (robertgbjones_at_[hidden])
Date: 2012-08-03 06:15:46
Hi All,
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?
Full source attached.
Thx, 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 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>
{
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 );
}
> ~/local/gcc-4.6.2/bin/g++ -std=c++0x -I ~/local/boost_1_48_0/include -g
-Werror -W -fno-strict-aliasing -fno-inline -Wall -Wno-uninitialized
-Wcast-align -Wwrite-strings -Wunused -Wnon-virtual-dtor -Wextra -c -o
iterate.o iterate.cpp
In file included from iterate.cpp|2| 0:
/home/rjones/local/boost_1_48_0/include/boost/iterator/iterator_facade.hpp:
In instantiation of boost::detail::postfix_increment_proxy<ThingIterator>:
/home/rjones/local/boost_1_48_0/include/boost/range/concepts.hpp|155 col
17| instantiated from
boost::range_detail::SinglePassIteratorConcept<Iterator>::~SinglePassIteratorConcept()
[with Iterator = ThingIterator]
/home/rjones/local/boost_1_48_0/include/boost/concept/detail/general.hpp|38
col 28| instantiated from static void
boost::concepts::requirement<boost::concepts::failed************
Model::************>::failed() [with Model =
boost::range_detail::SinglePassIteratorConcept<ThingIterator>]
/home/rjones/local/boost_1_48_0/include/boost/range/concepts.hpp|259 col 1|
instantiated from boost::SinglePassRangeConcept<const ThingRange>
/home/rjones/local/boost_1_48_0/include/boost/concept/detail/has_constraints.hpp|42
col 5| instantiated from const bool
boost::concepts::not_satisfied<boost::SinglePassRangeConcept<const
ThingRange> >::value
/home/rjones/local/boost_1_48_0/include/boost/concept/detail/has_constraints.hpp|45
col 31| instantiated from
boost::concepts::not_satisfied<boost::SinglePassRangeConcept<const
ThingRange> >
/home/rjones/local/boost_1_48_0/include/boost/mpl/if.hpp|67 col 11|
instantiated from
boost::mpl::if_<boost::concepts::not_satisfied<boost::SinglePassRangeConcept<const
ThingRange> >,
boost::concepts::constraint<boost::SinglePassRangeConcept<const ThingRange>
>, boost::concepts::requirement<boost::concepts::failed************
boost::SinglePassRangeConcept<const ThingRange>::************> >
/home/rjones/local/boost_1_48_0/include/boost/concept/detail/general.hpp|50
col 8| instantiated from boost::concepts::requirement_<void
(*)(boost::SinglePassRangeConcept<const ThingRange>)>
/home/rjones/local/boost_1_48_0/include/boost/range/algorithm/for_each.hpp|91
col 1| instantiated from UnaryFunction boost::range::for_each(const
SinglePassRange&, UnaryFunction) [with SinglePassRange = ThingRange,
UnaryFunction = void (*)(const AbstractThing&)]
iterate.cpp|55 col 51| instantiated from here
/home/rjones/local/boost_1_48_0/include/boost/iterator/iterator_facade.hpp|158
col 28| error: cannot declare field
boost::detail::postfix_increment_proxy<ThingIterator>::stored_value to be
of abstract type AbstractThing
iterate.cpp|7 col 8| note: because the following virtual functions are
pure within AbstractThing:
iterate.cpp|8 col 18| note: virtual char AbstractThing::get_c() const
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