protocol for using InputRanges

w0rp devw0rp at gmail.com
Mon Mar 24 06:11:18 PDT 2014


On Sunday, 23 March 2014 at 09:38:43 UTC, Szymon Gatner wrote:
> On Sunday, 23 March 2014 at 09:26:53 UTC, w0rp wrote:
>> I understand it like this.
>>
>> * empty - Are there no more values?
>> * front - Get me the current value.
>> * popFront - Advance to the next value.
>
> That is correct.
>
>>
>> In terms of how I implement an InputRange in general, I 
>> typically end up with this.
>>
>> * empty - Advance and cache "current value," return true if we 
>> ran out of values.
>> * front - enforce(!empty), which in turn caches the current 
>> value, which we then return.
>> * popFront - enforce(!empty), clear the cached value so we can 
>> later advance.
>>
>> So .front gives you the same thing again and again until you 
>> call popFront, you could indeed call .front before .empty, but 
>> you may get an exception. This obviously isn't how I implement 
>> all InputRanges, as there are better ways to write other 
>> ranges, such as ranges which operate on sets of integers or 
>> wrap arrays. This is just my last resort general case 
>> InputRange implementation.
>>
>> .front assignment obviously replaces the cached value.
>
> That is not consistent with the first part of your reply and is 
> incorrect imho. Calling empty() twice should not destroy 
> anything, even according to your understanding. Neither should 
> front(). User should be able to call them as many times as he 
> wishes getting same value every time. Only popFront() mutate 
> the range.

You read wrong. Say you have this sequence of three numbers and 
'x' represents the cached value being empty, for a range 'r.'

---
1 2 3
x

r.empty

1 2 3
^

r.empty

1 2 3
^

r.front == 1

r.popFront()

1 2 3
   x

r.empty

1 2 3
   ^
---

front and popFront each enforce(!empty) first, so this works, etc.

---
1 2 3
x

r.popFront()

# enforce(!empty);

1 2 3
^

# Clear the cached value.

1 2 3
   x

---

So it works for any sequence of values, and you can call .empty 
and .front as much as you want without changing the result. It 
just so happens that it's actually .empty which does the work of 
actually fetching the next value. There are better ways to 
implement this for certain ranges, but this works for anything.


More information about the Digitalmars-d mailing list