
I created a "bounded_iterator" concept that seems really useful. A bounded_iterator behaves just like a regular iterator, except that the termination condition can be checked by just casting the iterator to a bool. Here's an example: int array_range[] = { 1, 1, 2, 3, 5 }; for (bounded_iterator<int *> i(array_range); i; ++i) { std::fill_n(std::ostream_iterator<int>(std::cout), *i, *i); } I like it for the same reason that I like iterator_range: it frees the developer from having to worry about both a begin and an end iterator. It can be used as a wrapper for operations on a container or a sub-range. Just like iterator_range simplifies the invocation of functions for ranges, bounded_iterator simplifies the traversal of ranges. In my application I was storing lots of iterators in containers, and using bounded_iterator proved to be a better abstraction than storing iterator pairs or ranges. The main disadvantage to using a bounded_iterator is that it competes with the standard iterator concept, and it's usually more confusing to support many ways to do the same thing. Here is a simple implementation: template<typename base_iterator> class bounded_iterator : public boost::iterator_adaptor<bounded_iterator<base_iterator>, base_iterator> { base_iterator const end; typedef boost::iterator_adaptor<bounded_iterator, base_iterator> super_type; struct unspecified_bool_helper { int true_tag; }; typedef int unspecified_bool_helper::*unspecified_bool_type; public: template<typename source_iterator> bounded_iterator(source_iterator begin, source_iterator end) : super_type(begin), end(end) { } template<typename source_range> bounded_iterator(source_range &range) : super_type(boost::begin(range)), end(boost::end(range)) { } template<typename source_range> bounded_iterator(source_range const &range) : super_type(boost::begin(range)), end(boost::end(range)) { } operator unspecified_bool_type() const { return super_type::base() == end ? 0 : &unspecified_bool_helper::true_tag; } }; -- chad