xxxxxxxxxx
import std.stdio;
import std.array;
import std.typecons;
import std.range.primitives;
void main(string[] args)
{
auto a = [1,2,3,4,5,6,7,8,9];
auto b = mytake(a,5);
writeln(b[0]);
writeln(b[1]);
}
auto mytake(T)(ref T range, int c)
{
class Take
{
private T* take_range;
int count;
ElementType!T[] save = null;
this(T* range, int c)
{
this.take_range = range;
this.count = c;
}
bool empty()
{
if (count>0) return false;
if (save is null) return true;
return save.empty;
}
auto front()
{
if (count>0) return (*take_range).front;
return save.front;
}
void popFront()
{
if (count>0)
{
(*take_range).popFront();
--count;
}
else save.popFront();
}
T* get_range()
{
save = new ElementType!T[](0);
while (count>0) { save~=front; popFront(); }
return take_range;
}
}
class Rest
{
private Take take;
private T* rest_range;
this(Take take)
{
this.take = take;
}
bool empty()
{
get_range();
return rest_range.empty;
}
auto front()
{
get_range();
return (*rest_range).front;
}
void popFront()
{
get_range();
(*rest_range).popFront();
}
void get_range()
{
if (rest_range !is null) return;
rest_range = take.get_range();
}
}
auto take = new Take(&range,c);
return tuple(take,new Rest(take));
}