
Neil Groves wrote:
I have to confess I'm still studying the proposals to have different iterator types for begin and end, and I have yet to fully understand the impact.
There is a probably a design that would allow to keep compatibility with older Boost.Range-based code. If the end type is convertible to the begin type, it should probably be enough. iterator_range could take an optional second parameter, and the range_end_iterator meta-function would give the real type of the end iterator while range_iterator would still give the type of the begin one. The only fundamental thing that would change behavior is boost::end, since it could potentially return a different type, but it being convertible should be enough not to break compatibility. So it's not too much work: - Add range_end_iterator meta-function, which by default is the same as range_iterator - Update pair<T1, T2> to provide that meta-function - Change end to return the type defined by range_end_iterator - Update iterator_range and potentially sub_range (I don't know how the latter is implemented) so that they take into account a possible different type for the end, define range_end_iterator correctly, and make them use compressed_pair in case the end is empty. Then you can go and optimize the various algorithms and Boost.Foreach, albeit they would still work without being modified. What would be really interesting, however, is a mechanism similar to that of iterator_facade to define ranges with an empty end iterator painlessly.