Decouple isRandomAccessRange from isForwardRange and isBidirectionalRange

This commit is contained in:
Nathan Sashihara 2018-02-26 03:21:56 -05:00
parent 9bf8754711
commit 467335460e

View File

@ -633,8 +633,8 @@ template isBidirectionalRange(R)
* *
* A random-access range is a range that allows random access to its * A random-access range is a range that allows random access to its
* elements by index using $(D_INLINECODE [])-operator (defined with * elements by index using $(D_INLINECODE [])-operator (defined with
* $(D_INLINECODE opIndex())). Further a random access range should be a * $(D_INLINECODE opIndex())). Further a random access range should
* bidirectional range that also has a length or an infinite forward range. * have a length or be infinite.
* *
* Params: * Params:
* R = The type to be tested. * R = The type to be tested.
@ -642,19 +642,21 @@ template isBidirectionalRange(R)
* Returns: $(D_KEYWORD true) if $(D_PARAM R) is a random-access range, * Returns: $(D_KEYWORD true) if $(D_PARAM R) is a random-access range,
* $(D_KEYWORD false) otherwise. * $(D_KEYWORD false) otherwise.
* *
* See_Also: $(D_PSYMBOL isBidirectionalRange), * See_Also: $(D_PSYMBOL isInfinite),
* $(D_PSYMBOL isForwardRange),
* $(D_PSYMBOL isInfinite),
* $(D_PSYMBOL hasLength). * $(D_PSYMBOL hasLength).
*
* Note: This definition differs from `std.range.primitives.isRandomAccessRange`
* in the D standard library in that it does not also require $(D_PARAM R) to
* be a forward range and a bidirectional range. Those properties may be tested
* separately with $(D_PSYMBOL isForwardRange) and
* $(D_PSYMBOL isBidirectionalRange).
*/ */
template isRandomAccessRange(R) template isRandomAccessRange(R)
{ {
static if (is(ReturnType!((R r) => r.opIndex(size_t.init)) U)) static if (is(ReturnType!((R r) => r.opIndex(size_t.init)) U))
{ {
private enum bool isBidirectional = isBidirectionalRange!R enum bool isRandomAccessRange = isInputRange!R
&& hasLength!R; && (hasLength!R || isInfinite!R)
private enum bool isForward = isInfinite!R && isForwardRange!R;
enum bool isRandomAccessRange = (isBidirectional || isForward)
&& is(U == ReturnType!((R r) => r.front())); && is(U == ReturnType!((R r) => r.front()));
} }
else else