Is there something like a consuming take?

a11e99z black80 at bk.ru
Sat Jul 6 12:55:48 UTC 2019


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];
     }
}



More information about the Digitalmars-d-learn mailing list