View source code
Display the source code in std/range/primitives.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

Enum member std.range.primitives.hasSlicing

Returns true if R offers a slicing operator with integral boundaries that returns a forward range type.

enum hasSlicing(R) = isForwardRange!R && !isNarrowString!R && is(ReturnType!((R r) => r[1..1].length) == size_t) && (is(typeof(lvalueOf!R[1..1]) == R) || isInfinite!R) && (!is(typeof(lvalueOf!R[0..__dollar])) || is(typeof(lvalueOf!R[0..__dollar]) == R)) && (!is(typeof(lvalueOf!R[0..__dollar])) || isInfinite!R || is(typeof(lvalueOf!R[0..__dollar - 1]) == R)) && is(typeof((ref R r) { static assert(isForwardRange!(typeof(r[1..2]))); } ));

For finite ranges, the result of opSlice must be of the same type as the original range type. If the range defines opDollar, then it must support subtraction.

For infinite ranges, when not using opDollar, the result of opSlice must be the result of take or takeExactly on the original range (they both return the same type for infinite ranges). However, when using opDollar, the result of opSlice must be that of the original range type.

The following expression must be true for hasSlicing to be true:

isForwardRange!R
&& !isNarrowString!R
&& is(ReturnType!((R r) => r[1 .. 1].length) == size_t)
&& (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R)
&& (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R))
&& (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R
    || is(typeof(lvalueOf!R[0 .. $ - 1]) == R))
&& is(typeof((ref R r)
{
    static assert(isForwardRange!(typeof(r[1 .. 2])));
}));

Example

import std.range : takeExactly;
static assert( hasSlicing!(int[]));
static assert( hasSlicing!(const(int)[]));
static assert(!hasSlicing!(const int[]));
static assert( hasSlicing!(inout(int)[]));
static assert(!hasSlicing!(inout int []));
static assert( hasSlicing!(immutable(int)[]));
static assert(!hasSlicing!(immutable int[]));
static assert(!hasSlicing!string);
static assert( hasSlicing!dstring);

enum rangeFuncs = "@property int front();" ~
                  "void popFront();" ~
                  "@property bool empty();" ~
                  "@property auto save() { return this; }" ~
                  "@property size_t length();";

struct A { mixin(rangeFuncs); int opSlice(size_t, size_t); }
struct B { mixin(rangeFuncs); B opSlice(size_t, size_t); }
struct C { mixin(rangeFuncs); @disable this(); C opSlice(size_t, size_t); }
struct D { mixin(rangeFuncs); int[] opSlice(size_t, size_t); }
static assert(!hasSlicing!(A));
static assert( hasSlicing!(B));
static assert( hasSlicing!(C));
static assert(!hasSlicing!(D));

struct InfOnes
{
    enum empty = false;
    void popFront() {}
    @property int front() { return 1; }
    @property InfOnes save() { return this; }
    auto opSlice(size_t i, size_t j) { return takeExactly(this, j - i); }
    auto opSlice(size_t i, Dollar d) { return this; }

    struct Dollar {}
    Dollar opDollar() const { return Dollar.init; }
}

static assert(hasSlicing!InfOnes);

Authors

Andrei Alexandrescu, David Simcha, and Jonathan M Davis. Credit for some of the ideas in building this module goes to Leonardo Maffi.

License

Boost License 1.0.