Skip to content

Commit

Permalink
Short circuit type for takeExactly(takeExactly(r, n))
Browse files Browse the repository at this point in the history
  • Loading branch information
andralex committed Jan 25, 2011
1 parent 6f81c57 commit b91689d
Showing 1 changed file with 31 additions and 15 deletions.
46 changes: 31 additions & 15 deletions std/range.d
Expand Up @@ -2384,25 +2384,35 @@ is an input range with length. Finally, if $(D R) is a forward range
auto takeExactly(R)(R range, size_t n)
if (isInputRange!R && !isRandomAccessRange!R)
{
static struct Result
static if (is(typeof(takeExactly(range._input, n)) == R))
{
private R _input;
private size_t _n;

@property bool empty() const { return !_n; }
@property auto ref front()
// takeExactly(takeExactly(r, n1), n2) has the same type as
// takeExactly(r, n1) and simply returns takeExactly(r, n2)
range._n = n;
return range;
}
else
{
static struct Result
{
assert(_n > 0, "front() on an empty " ~ Result.stringof);
return _input.front();
}
void popFront() { _input.popFront(); --_n; }
size_t length() const { return _n; }
R _input;
private size_t _n;

@property bool empty() const { return !_n; }
@property auto ref front()
{
assert(_n > 0, "front() on an empty " ~ Result.stringof);
return _input.front();
}
void popFront() { _input.popFront(); --_n; }
size_t length() const { return _n; }

static if (isForwardRange!R)
auto save() { return this; }
static if (isForwardRange!R)
auto save() { return this; }
}

return Result(range, n);
}

return Result(range, n);
}

auto takeExactly(R)(R range, size_t n)
Expand All @@ -2416,6 +2426,12 @@ unittest
auto a = [ 1, 2, 3, 4, 5 ];
auto b = takeExactly(a, 3);
assert(equal(b, [1, 2, 3]));
auto c = takeExactly(b, 2);

auto d = filter!"a > 0"(a);
auto e = takeExactly(d, 3);
assert(equal(e, [1, 2, 3]));
assert(equal(takeExactly(e, 4), [1, 2, 3, 4]));
// assert(b.length == 3);
// assert(b.front == 1);
// assert(b.back == 3);
Expand Down

0 comments on commit b91689d

Please sign in to comment.