protocol for using InputRanges

monarch_dodra monarchdodra at gmail.com
Fri Mar 28 00:25:53 PDT 2014


On Friday, 28 March 2014 at 02:14:40 UTC, H. S. Teoh wrote:
> I'm with Walter on this one. Generic code should NOT assume 
> anything
> about a range it was given, and therefore it should call .empty 
> before
> calling .front or .popFront. If you "know" that a particular 
> range
> doesn't require calling .empty beforehand, then by definition 
> your code
> is no longer generic, and you just have to live with the 
> consequences of
> that. Nothing stops you, for example, from exposing a .get 
> function or
> whatever else, *in addition* to the standard range API. Then 
> code that
> knows how to deal with .get will use it, and your range remains 
> usable
> with other generic code.

It's not that *you* know a particular range doesn't need "empty" 
called, it's that the algorithm you are using has already 
previously validated there are elements in it.

For example, the splitter algorithm will first save a copy of its 
range, and then walk it, searching for the "splitting" elements. 
It then realizes it has walked N elements.

 From there, it takes the original range, and packs it into a 
"takeExactly(N)" of the original range. Iterating that 
"takeExactly(N)" is faster than a raw "take", *because* 
"takeExactly" was already promised that the range holds N 
elements, and as such, *doesn't* check for empty.

Ditto for "findSplit".

And again, there are functions, such as "copy", then simply 
*require* that a certain range have at least a certain amount of 
elements. Why check for it, if not providing it is a violation of 
its interface.

On Thursday, 27 March 2014 at 23:52:46 UTC, Walter Bright wrote:
> I know that you want to get rid of empty. But getting rid of 
> empty means that front may fail. This is why there is an empty, 
> and any generic code MUST respect that.

Front only fails *if* the range is empty. Not if you fail to call 
empty. Generic code respects that.

> What you can do is, in your range:
>
>     enum empty = true;

That's not the same. That's making the assumption your range will 
*never* be empty, which is a whole other concept (infinite 
ranges).


More information about the Digitalmars-d mailing list