Disable length when taking from a lengthless range

Fix #79.
This commit is contained in:
Eugen Wissner 2018-11-13 08:29:51 +01:00
parent 9e6f5c3105
commit 0a121d9d19
3 changed files with 81 additions and 3 deletions

View File

@ -23,6 +23,7 @@ module tanya.algorithm.iteration;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation;
import tanya.range;
version (unittest) import tanya.test.range;
private struct Take(R, bool exactly)
{
@ -73,13 +74,16 @@ private struct Take(R, bool exactly)
}
else
{
return length == 0 || this.source.empty;
return this.length_ == 0 || this.source.empty;
}
}
@property size_t length()
static if (exactly || hasLength!R)
{
return this.length_;
@property size_t length()
{
return this.length_;
}
}
static if (hasAssignableElements!R)
@ -315,6 +319,19 @@ if (isInputRange!R)
assert(t.empty);
}
// length is unknown when taking from a range without length
@nogc nothrow pure @safe unittest
{
@Empty
static struct R
{
mixin InputRange;
}
auto actual = take(R(), 100);
static assert(!hasLength!(typeof(actual)));
}
/**
* Takes exactly $(D_PARAM n) elements from $(D_PARAM range).
*

View File

@ -1493,6 +1493,8 @@ if (F.length == 1)
}
/**
* Determines whether $(D_PARAM T) defines a symbol $(D_PARAM member).
*
* Params:
* T = Aggregate type.
* member = Symbol name.

59
source/tanya/test/range.d Normal file
View File

@ -0,0 +1,59 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Range generators for tests.
* Copyright: Eugene Wissner 2018.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/test/range.d,
* tanya/test/range.d)
*/
module tanya.test.range;
package(tanya) struct Empty
{
}
package(tanya) template InputRange()
{
import tanya.meta.metafunction : AliasSeq;
private alias attributes = AliasSeq!(__traits(getAttributes, typeof(this)));
static foreach (attribute; attributes)
{
static if (is(attribute == Empty))
{
@property bool empty() const @nogc nothrow pure @safe
{
return true;
}
}
}
void popFront() @nogc nothrow pure @safe
{
static foreach (attribute; attributes)
{
static if (is(attribute == Empty))
{
assert(false);
}
}
}
int front() @nogc nothrow pure @safe
{
static foreach (attribute; attributes)
{
static if (is(attribute == Empty))
{
assert(false);
}
}
}
}