On Saturday, 6 July 2019 at 12:10:13 UTC, berni wrote:
On Saturday, 6 July 2019 at 11:48:51 UTC, a11e99z wrote:

Maybe I need to explain, what I dislike with this approach: take() calls popFront n times and drop() calls popFront another n times giving a total of 2n times (depending on the underlying range, this might cause lot's of calulcations be done twice. The first version with the foreach loop calls popFront only n times.

auto take_consuming( R )( ref R r, int cnt ) {
    import std.range.primitives : hasSlicing;
    static if (hasSlicing!R) { // without allocations
        auto tmp = r[0..cnt];
        r = r[cnt..$]; // or r.popFronN( cnt ); // O(1)
        return tmp;
    } else { // loop range once
        auto tmp = uninitializedArray!( ElementType!R[])( cnt);
        int k = 0;
for (; !r.empty && k<cnt; ++k, r.popFront) tmp[ k] = r.front;
        return tmp[ 0..k];
    }
}

Reply via email to