On Monday 14 July 2014 07:10:23 Vladimir Batov wrote:
boost::iterator_range is a great concept/class but it does not seem to play efficiently with certain input sequences and seem to be too strong a requirement for certain algorithms. I have an old-fashioned C string in mind (I am sure there are other examples) and traversing algorithms.
When I tried deploying boost::iterator_range for string-to-int conversion purposes, I quickly realized that I was traversing the string twice -- first to find the end and second to do the work.
Not sure why would you need to find the end - it can be found in the parsing process (that is assuming the integer may not be the whole string; otherwise the end iterator is already provided by the range).
What I think is missing is the "parent" concept of a "sequence". Say,
template
struct sequence { iterator_type begin(); sentry_type sentry(); }; Then "range" would implement and refine the "sequence" concept by
template
struct range : sequence { iterator_type begin(); iterator_type end(); sentry_type sentry() { return end; } } I.e., as "range" implements/is the "sequence", the boost::iterator_range will have one additional "useless" sentry() method.
That way all the old code (using and/or needing end()) would still work but traversing algorithms might gradually adapt to only require "sequences" instead of "ranges":
template
Function for_each(Iterator beg, Sentry sentry, Function fun) { for (; beg != sentry; ++beg) fun(*beg); return fun; } That means that now all "open-ended" (with no known "end") "ranges" (they are not even "ranges" in the strict meaning of the word but rather "sequences") can be handled efficiently.
I don't see much difference with the current ranges, where end iterators are singular. Can you provide a strong motivating example for the sentry() method?