Is there something like a consuming take?

berni someone at somewhere.com
Tue Jul 9 13:47:38 UTC 2019


On Sunday, 7 July 2019 at 21:55:17 UTC, Jonathan M Davis wrote:
> Having one range know about the other isn't enough. That just 
> means that the take range would tell the other range that it 
> had popped an element off, and then the other would know that 
> it had to pop an element off. That still involves popping the 
> same element on different ranges twice.

Sounds like you didn't understand what I meant. So I tried to 
implement what I had in mind and I have to confess, that there is 
something about ranges that I do not understand yet:

>import std.stdio;
>import std.array;
>
>void main()
>{
>    auto a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
>
>    call(a,5);
>}
>
>void call(T)(ref T range, int c)
>{
>    struct Take
>    {
>        T* take_range;
>        int count;
>
>        @property bool empty=false;
>        @property auto front() { return (*take_range).front; }
>        void popFront()
>        {
>            (*take_range).popFront();
>            if (--count<=0) empty=true;
>        }
>
>        T* get_range()
>        {
>            assert(count==0);
>            while (!empty) popFront();
>            return take_range;
>        }
>    }
>
>    auto take = Take(&range,c);
>
>//    writeln(take);
>    while (!take.empty) { write(take.front); take.popFront(); }
>
>    auto original_range = take.get_range();
>
>    writeln(*original_range);
>}

Running this program leads to
>12345[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
as expected.

But when I replace that loop at the bottom by writeln(take) the 
assertion in get_range fails (count==5). As all the functions are 
called in the same order by both the loop and writeln, I confess, 
that writeln somehow manages to use a copy of "take" although 
this isn't a ForwardRange and copying should therefore not be 
possible.

> You can try mucking around with your own implemention of take 
> if you want, but I'd suggest that you're just better off taking 
> the approach that it's expected that if you use take,

I't not about improving or doing things different. It's just 
about me understanding, what happens.





More information about the Digitalmars-d-learn mailing list