|
Boost Users : |
Subject: Re: [Boost-users] Using single-pass ranges.
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2012-07-25 00:13:54
>> I have a class that hands out a sequence of Things through a
>> getNextThing() interface, ie.,
>>
>> struct Thing { };
>>
>> struct ThingFeed
>> {
>> Thing * getNextThing( );
>> };
>>
>> returning null when there's no more things. I'd like to be
>> able to feed this into the Boost range-based algorithms, something
>> like
>
> Since we are not in a position to offer range primitives, there is more
> work required than one would like. To maximize interoperability with
> algorithms and existing C++ code the ranges in Boost.Range are limited
> to being implemented on top of iterators. Therefore the getNextThing()
> would need to be part of an increment operator / operators upon a
> forward traversal iterator. This is not difficult to implement using
> Boost.Iterator.
Here's how you might do such a thing (untested):
class ThingIterator : public boost::iterator_facade<ThingIterator, Thing, boost::single_pass_traversal_tag>
{
public:
// Public interface
ThingIterator(ThingFeed& feed, Thing* cur = NULL) : m_feed(feed), m_cur(cur) {}
private:
// Interface to boost::iterator_facade
void increment() { m_cur = m_feed.getNextThing(); }
Thing& dereference() const { return *m_cur; }
bool equal(const ThingIterator& other) const { return m_cur == other.m_cur; }
private:
// Implementation
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))
{}
};
...
ThingFeed feed;
...
boost::for_each( ThingRange(feed) | filter( someCondition ), doSomething );
Regards,
Nate
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