
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