/**
This module is a submodule of $(MREF std, range).

It defines the bidirectional and forward range primitives for arrays:
$(LREF empty), $(LREF front), $(LREF back), $(LREF popFront), $(LREF popBack) and $(LREF save).

It provides basic range functionality by defining several templates for testing
whether a given object is a range, and what kind of range it is:

$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE ,
    $(TR $(TD $(LREF isInputRange))
        $(TD Tests if something is an $(I input range), defined to be
        something from which one can sequentially read data using the
        primitives `front`, `popFront`, and `empty`.
    ))
    $(TR $(TD $(LREF isOutputRange))
        $(TD Tests if something is an $(I output range), defined to be
        something to which one can sequentially write data using the
        $(LREF put) primitive.
    ))
    $(TR $(TD $(LREF isForwardRange))
        $(TD Tests if something is a $(I forward range), defined to be an
        input range with the additional capability that one can save one's
        current position with the `save` primitive, thus allowing one to
        iterate over the same range multiple times.
    ))
    $(TR $(TD $(LREF isBidirectionalRange))
        $(TD Tests if something is a $(I bidirectional range), that is, a
        forward range that allows reverse traversal using the primitives $(D
        back) and `popBack`.
    ))
    $(TR $(TD $(LREF isRandomAccessRange))
        $(TD Tests if something is a $(I random access range), which is a
        bidirectional range that also supports the array subscripting
        operation via the primitive `opIndex`.
    ))
))

It also provides number of templates that test for various range capabilities:

$(BOOKTABLE ,
    $(TR $(TD $(LREF hasMobileElements))
        $(TD Tests if a given range's elements can be moved around using the
        primitives `moveFront`, `moveBack`, or `moveAt`.
    ))
    $(TR $(TD $(LREF ElementType))
        $(TD Returns the element type of a given range.
    ))
    $(TR $(TD $(LREF ElementEncodingType))
        $(TD Returns the encoding element type of a given range.
    ))
    $(TR $(TD $(LREF hasSwappableElements))
        $(TD Tests if a range is a forward range with swappable elements.
    ))
    $(TR $(TD $(LREF hasAssignableElements))
        $(TD Tests if a range is a forward range with mutable elements.
    ))
    $(TR $(TD $(LREF hasLvalueElements))
        $(TD Tests if a range is a forward range with elements that can be
        passed by reference and have their address taken.
    ))
    $(TR $(TD $(LREF hasLength))
        $(TD Tests if a given range has the `length` attribute.
    ))
    $(TR $(TD $(LREF isInfinite))
        $(TD Tests if a given range is an $(I infinite range).
    ))
    $(TR $(TD $(LREF hasSlicing))
        $(TD Tests if a given range supports the array slicing operation $(D
        R[x .. y]).
    ))
)

Finally, it includes some convenience functions for manipulating ranges:

$(BOOKTABLE ,
    $(TR $(TD $(LREF popFrontN))
        $(TD Advances a given range by up to $(I n) elements.
    ))
    $(TR $(TD $(LREF popBackN))
        $(TD Advances a given bidirectional range from the right by up to
        $(I n) elements.
    ))
    $(TR $(TD $(LREF popFrontExactly))
        $(TD Advances a given range by up exactly $(I n) elements.
    ))
    $(TR $(TD $(LREF popBackExactly))
        $(TD Advances a given bidirectional range from the right by exactly
        $(I n) elements.
    ))
    $(TR $(TD $(LREF moveFront))
        $(TD Removes the front element of a range.
    ))
    $(TR $(TD $(LREF moveBack))
        $(TD Removes the back element of a bidirectional range.
    ))
    $(TR $(TD $(LREF moveAt))
        $(TD Removes the $(I i)'th element of a random-access range.
    ))
    $(TR $(TD $(LREF walkLength))
        $(TD Computes the length of any range in O(n) time.
    ))
    $(TR $(TD $(LREF put))
        $(TD Outputs element `e` to a range.
    ))
)

Source: $(PHOBOSSRC std/range/primitives.d)

License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).

Authors: $(HTTP erdani.com, Andrei Alexandrescu), David Simcha, and
         $(HTTP jmdavisprog.com, Jonathan M Davis). Credit for some of the ideas
         in building this module goes to
         $(HTTP fantascienza.net/leonardo/so/, Leonardo Maffi).
*/
module std.range.primitives;

import std.traits;

/**
Returns `true` if `R` is an input range. An input range must
define the primitives `empty`, `popFront`, and `front`. The
following code should compile for any input range.

----
R r;              // can define a range object
if (r.empty) {}   // can test for empty
r.popFront();     // can invoke popFront()
auto h = r.front; // can get the front of the range of non-void type
----

The following are rules of input ranges are assumed to hold true in all
Phobos code. These rules are not checkable at compile-time, so not conforming
to these rules when writing ranges or range based code will result in
undefined behavior.

$(UL
    $(LI `r.empty` returns `false` if and only if there is more data
    available in the range.)
    $(LI `r.empty` evaluated multiple times, without calling
    `r.popFront`, or otherwise mutating the range object or the
    underlying data, yields the same result for every evaluation.)
    $(LI `r.front` returns the current element in the range.
    It may return by value or by reference.)
    $(LI `r.front` can be legally evaluated if and only if evaluating
    `r.empty` has, or would have, equaled `false`.)
    $(LI `r.front` evaluated multiple times, without calling
    `r.popFront`, or otherwise mutating the range object or the
    underlying data, yields the same result for every evaluation.)
    $(LI `r.popFront` advances to the next element in the range.)
    $(LI `r.popFront` can be called if and only if evaluating `r.empty`
    has, or would have, equaled `false`.)
)

Also, note that Phobos code assumes that the primitives `r.front` and
`r.empty` are $(BIGOH 1) time complexity wise or "cheap" in terms of
running time. $(BIGOH) statements in the documentation of range functions
are made with this assumption.

See_Also:
    The header of $(MREF std,range) for tutorials on ranges.

Params:
    R = type to be tested
    E = if present, the elements of the range must be
        $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible)
        to this type

Returns:
    `true` if R is an input range (possibly with element type `E`), `false` if not
 */
enum bool isInputRange(R) =
    is(typeof(R.init) == R)
    && is(typeof((R r) { return r.empty; } (R.init)) == bool)
    && (is(typeof((return ref R r) => r.front)) || is(typeof(ref (return ref R r) => r.front)))
    && !is(typeof((R r) { return r.front; } (R.init)) == void)
    && is(typeof((R r) => r.popFront));

/// ditto
enum bool isInputRange(R, E) =
    .isInputRange!R && isQualifierConvertible!(ElementType!R, E);

///
@safe unittest
{
    struct A {}
    struct B
    {
        void popFront();
        @property bool empty();
        @property int front();
    }
    static assert(!isInputRange!A);
    static assert( isInputRange!B);
    static assert( isInputRange!(int[]));
    static assert( isInputRange!(char[]));
    static assert(!isInputRange!(char[4]));
    static assert( isInputRange!(inout(int)[]));
    static assert(!isInputRange!(int[], string));
    static assert( isInputRange!(int[], int));
    static assert( isInputRange!(int[], const int));
    static assert(!isInputRange!(int[], immutable int));

    static assert(!isInputRange!(const(int)[], int));
    static assert( isInputRange!(const(int)[], const int));
    static assert(!isInputRange!(const(int)[], immutable int));

    static assert(!isInputRange!(immutable(int)[], int));
    static assert( isInputRange!(immutable(int)[], const int));
    static assert( isInputRange!(immutable(int)[], immutable int));

    static struct NotDefaultConstructible
    {
        @disable this();
        void popFront();
        @property bool empty();
        @property int front();
    }
    static assert( isInputRange!NotDefaultConstructible);

    static struct NotDefaultConstructibleOrCopyable
    {
        @disable this();
        @disable this(this);
        void popFront();
        @property bool empty();
        @property int front();
    }
    static assert(isInputRange!NotDefaultConstructibleOrCopyable);

    static struct Frontless
    {
        void popFront();
        @property bool empty();
    }
    static assert(!isInputRange!Frontless);

    static struct VoidFront
    {
        void popFront();
        @property bool empty();
        void front();
    }
    static assert(!isInputRange!VoidFront);
}
// https://issues.dlang.org/show_bug.cgi?id=16034
@safe unittest
{
    struct One
    {
        int entry = 1;
        @disable this(this);
    }

    assert(isInputRange!(One[]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;

    static struct R
    {
        static struct Front
        {
            R* impl;
            @property int value() { return impl._front; }
            alias value this;
        }

        int _front;

        @property bool empty() { return _front >= 3; }
        @property auto front() { return Front(&this); }
        void popFront() { _front++; }
    }
    R r;

    static assert(isInputRange!R);
    assert(r.equal([ 0, 1, 2 ]));
}

/+
puts the whole raw element `e` into `r`. doPut will not attempt to
iterate, slice or transcode `e` in any way shape or form. It will $(B only)
call the correct primitive (`r.put(e)`,  $(D r.front = e) or
`r(e)` once.

This can be important when `e` needs to be placed in `r` unchanged.
Furthermore, it can be useful when working with `InputRange`s, as doPut
guarantees that no more than a single element will be placed.
+/
private void doPut(R, E)(ref R r, auto ref E e)
{
    static if (is(PointerTarget!R == struct))
        enum usingPut = hasMember!(PointerTarget!R, "put");
    else
        enum usingPut = hasMember!(R, "put");

    static if (usingPut)
    {
        static assert(is(typeof(r.put(e))),
            "Cannot put a " ~ E.stringof ~ " into a " ~ R.stringof ~ ".");
        r.put(e);
    }
    else static if (isNarrowString!R && is(const(E) == const(typeof(r[0]))))
    {
        // one character, we can put it
        r[0] = e;
        r = r[1 .. $];
    }
    else static if (isNarrowString!R && isNarrowString!E && is(typeof(r[] = e)))
    {
        // slice assign. Note that this is a duplicate from put, but because
        // putChar uses doPut exclusively, we have to copy it here.
        immutable len = e.length;
        r[0 .. len] = e;
        r = r[len .. $];
    }
    else static if (isInputRange!R)
    {
        static assert(is(typeof(r.front = e)),
            "Cannot put a " ~ E.stringof ~ " into a " ~ R.stringof ~ ".");
        r.front = e;
        r.popFront();
    }
    else static if (is(typeof(r(e))))
    {
        r(e);
    }
    else
    {
        static assert(false,
            "Cannot put a " ~ E.stringof ~ " into a " ~ R.stringof ~ ".");
    }
}

@safe unittest
{
    static assert(!isNativeOutputRange!(int,     int));
    static assert( isNativeOutputRange!(int[],   int));
    static assert(!isNativeOutputRange!(int[][], int));

    static assert(!isNativeOutputRange!(int,     int[]));
    static assert(!isNativeOutputRange!(int[],   int[]));
    static assert( isNativeOutputRange!(int[][], int[]));

    static assert(!isNativeOutputRange!(int,     int[][]));
    static assert(!isNativeOutputRange!(int[],   int[][]));
    static assert(!isNativeOutputRange!(int[][], int[][]));

    static assert(!isNativeOutputRange!(int[4],   int));
    static assert( isNativeOutputRange!(int[4][], int)); //Scary!
    static assert( isNativeOutputRange!(int[4][], int[4]));

    static assert( isNativeOutputRange!( char[],   char));
    static assert(!isNativeOutputRange!( char[],  dchar));
    static assert( isNativeOutputRange!(dchar[],   char));
    static assert( isNativeOutputRange!(dchar[],  dchar));

}

/++
Outputs `e` to `r`. The exact effect is dependent upon the two
types. Several cases are accepted, as described below. The code snippets
are attempted in order, and the first to compile "wins" and gets
evaluated.

In this table "doPut" is a method that places `e` into `r`, using the
correct primitive: `r.put(e)` if `R` defines `put`, $(D r.front = e)
if `r` is an input range (followed by `r.popFront()`), or `r(e)`
otherwise.

$(BOOKTABLE ,
    $(TR
        $(TH Code Snippet)
        $(TH Scenario)
    )
    $(TR
        $(TD `r.doPut(e);`)
        $(TD `R` specifically accepts an `E`.)
    )
    $(TR
        $(TD $(D r.doPut([ e ]);))
        $(TD `R` specifically accepts an `E[]`.)
    )
    $(TR
        $(TD `r.putChar(e);`)
        $(TD `R` accepts some form of string or character. put will
            transcode the character `e` accordingly.)
    )
    $(TR
        $(TD $(D for (; !e.empty; e.popFront()) put(r, e.front);))
        $(TD Copying range `E` into `R`.)
    )
)

Tip: `put` should $(I not) be used "UFCS-style", e.g. `r.put(e)`.
Doing this may call `R.put` directly, by-passing any transformation
feature provided by `Range.put`. $(D put(r, e)) is prefered.
 +/
void put(R, E)(ref R r, E e)
{
    //First level: simply straight up put.
    static if (is(typeof(doPut(r, e))))
    {
        doPut(r, e);
    }
    //Optional optimization block for straight up array to array copy.
    else static if (isDynamicArray!R &&
                    !isAutodecodableString!R &&
                    isDynamicArray!E &&
                    is(typeof(r[] = e[])))
    {
        immutable len = e.length;
        r[0 .. len] = e[];
        r = r[len .. $];
    }
    //Accepts E[] ?
    else static if (is(typeof(doPut(r, [e]))) && !isDynamicArray!R)
    {
        if (__ctfe)
        {
            E[1] arr = [e];
            doPut(r, arr[]);
        }
        else
            doPut(r, (ref e) @trusted { return (&e)[0 .. 1]; }(e));
    }
    //special case for char to string.
    else static if (isSomeChar!E && is(typeof(putChar(r, e))))
    {
        putChar(r, e);
    }
    //Extract each element from the range
    //We can use "put" here, so we can recursively test a RoR of E.
    else static if (isInputRange!E && is(typeof(put(r, e.front))))
    {
        //Special optimization: If E is a narrow string, and r accepts characters no-wider than the string's
        //Then simply feed the characters 1 by 1.
        static if (isAutodecodableString!E && !isAggregateType!E && (
            (is(E : const  char[]) && is(typeof(doPut(r,  char.max))) && !is(typeof(doPut(r, dchar.max))) &&
                !is(typeof(doPut(r, wchar.max)))) ||
            (is(E : const wchar[]) && is(typeof(doPut(r, wchar.max))) && !is(typeof(doPut(r, dchar.max)))) ) )
        {
            foreach (c; e)
                doPut(r, c);
        }
        else
        {
            for (; !e.empty; e.popFront())
                put(r, e.front);
        }
    }
    else
    {
        static assert(false, "Cannot put a " ~ E.stringof ~ " into a " ~ R.stringof ~ ".");
    }
}

/**
 * When an output range's `put` method only accepts elements of type
 * `T`, use the global `put` to handle outputting a `T[]` to the range
 * or vice-versa.
 */
@safe pure unittest
{
    import std.traits : isSomeChar;

    static struct A
    {
        string data;

        void put(C)(C c)
        if (isSomeChar!C)
        {
            data ~= c;
        }
    }
    static assert(isOutputRange!(A, char));

    auto a = A();
    put(a, "Hello");
    assert(a.data == "Hello");
}

/**
 * `put` treats dynamic arrays as array slices, and will call `popFront`
 * on the slice after an element has been copied.
 *
 * Be sure to save the position of the array before calling `put`.
 */
@safe pure nothrow unittest
{
    int[] a = [1, 2, 3], b = [10, 20];
    auto c = a;
    put(a, b);
    assert(c == [10, 20, 3]);
    // at this point, a was advanced twice, so it only contains
    // its last element while c represents the whole array
    assert(a == [3]);
}

/**
 * It's also possible to `put` any width strings or characters into narrow
 * strings -- put does the conversion for you.
 *
 * Note that putting the same width character as the target buffer type is
 * `nothrow`, but transcoding can throw a $(REF UTFException, std, utf).
 */
@safe pure unittest
{
    // the elements must be mutable, so using string or const(char)[]
    // won't compile
    char[] s1 = new char[13];
    auto r1 = s1;
    put(r1, "Hello, World!"w);
    assert(s1 == "Hello, World!");
}

@safe pure nothrow unittest
{
    // same thing, just using same character width.
    char[] s1 = new char[13];
    auto r1 = s1;
    put(r1, "Hello, World!");
    assert(s1 == "Hello, World!");
}


@safe pure nothrow @nogc unittest
{
    static struct R() { void put(scope const(char)[]) {} }
    R!() r;
    put(r, 'a');
}

//Helper function to handle chars as quickly and as elegantly as possible
//Assumes r.put(e)/r(e) has already been tested
private void putChar(R, E)(ref R r, E e)
if (isSomeChar!E)
{
    // https://issues.dlang.org/show_bug.cgi?id=9186: Can't use (E[]).init
    enum csCond = is(typeof(doPut(r, (){ ref const( char)[] cstringInit(); return cstringInit(); }())));
    enum wsCond = is(typeof(doPut(r, (){ ref const(wchar)[] wstringInit(); return wstringInit(); }())));
    enum dsCond = is(typeof(doPut(r, (){ ref const(dchar)[] dstringInit(); return dstringInit(); }())));

    //Use "max" to avoid static type demotion
    enum ccCond = is(typeof(doPut(r,  char.max)));
    enum wcCond = is(typeof(doPut(r, wchar.max)));
    //enum dcCond = is(typeof(doPut(r, dchar.max)));

    //Fast transform a narrow char into a wider string
    static if ((wsCond && E.sizeof < wchar.sizeof) || (dsCond && E.sizeof < dchar.sizeof))
    {
        enum w = wsCond && E.sizeof < wchar.sizeof;
        Select!(w, wchar, dchar) c = e;
        typeof(c)[1] arr = [c];
        doPut(r, arr[]);
    }
    //Encode a wide char into a narrower string
    else static if (wsCond || csCond)
    {
        import std.utf : encode;
        /+static+/ Select!(wsCond, wchar[2], char[4]) buf; //static prevents purity.
        doPut(r, buf[0 .. encode(buf, e)]);
    }
    //Slowly encode a wide char into a series of narrower chars
    else static if (wcCond || ccCond)
    {
        import std.encoding : encode;
        alias C = Select!(wcCond, wchar, char);
        encode!(C, R)(e, r);
    }
    else
    {
        static assert(false, "Cannot put a " ~ E.stringof ~ " into a " ~ R.stringof ~ ".");
    }
}

pure @safe unittest
{
    auto f = delegate (const(char)[]) {};
    putChar(f, cast(dchar)'a');
}


@safe pure unittest
{
    static struct R() { void put(scope const(char)[]) {} }
    R!() r;
    putChar(r, 'a');
}

@safe unittest
{
    struct A {}
    static assert(!isInputRange!(A));
    struct B
    {
        void put(int) {}
    }
    B b;
    put(b, 5);
}

@safe unittest
{
    int[] a = new int[10];
    int b;
    static assert(isInputRange!(typeof(a)));
    put(a, b);
}

@safe unittest
{
    void myprint(scope const(char)[] s) { }
    auto r = &myprint;
    put(r, 'a');
}

@safe unittest
{
    int[] a = new int[10];
    static assert(!__traits(compiles, put(a, 1.0L)));
    put(a, 1);
    assert(a.length == 9);
    /*
     * a[0] = 65;       // OK
     * a[0] = 'A';      // OK
     * a[0] = "ABC"[0]; // OK
     * put(a, "ABC");   // OK
     */
    put(a, "ABC");
    assert(a.length == 6);
}

@safe unittest
{
    char[] a = new char[10];
    static assert(!__traits(compiles, put(a, 1.0L)));
    static assert(!__traits(compiles, put(a, 1)));
    //char[] is now an output range for char, wchar, dchar, and ranges of such.
    static assert(__traits(compiles, putChar(a, 'a')));
    static assert(__traits(compiles, put(a, wchar('a'))));
    static assert(__traits(compiles, put(a, dchar('a'))));
    static assert(__traits(compiles, put(a, "ABC")));
    static assert(__traits(compiles, put(a, "ABC"w)));
    static assert(__traits(compiles, put(a, "ABC"d)));
}

@safe unittest
{
    // attempt putting into narrow strings by transcoding
    char[] a = new char[10];
    auto b = a;
    put(a, "ABC"w);
    assert(b[0 .. 3] == "ABC");
    assert(a.length == 7);

    a = b; // reset
    put(a, 'λ');
    assert(b[0 .. 2] == "λ");
    assert(a.length == 8);

    a = b; // reset
    put(a, "ABC"d);
    assert(b[0 .. 3] == "ABC");
    assert(a.length == 7);

    a = b; // reset
    put(a, '𐐷');
    assert(b[0 .. 4] == "𐐷");
    assert(a.length == 6);

    wchar[] aw = new wchar[10];
    auto bw = aw;
    put(aw, "ABC");
    assert(bw[0 .. 3] == "ABC"w);
    assert(aw.length == 7);

    aw = bw; // reset
    put(aw, 'λ');
    assert(bw[0 .. 1] == "λ"w);
    assert(aw.length == 9);

    aw = bw; // reset
    put(aw, "ABC"d);
    assert(bw[0 .. 3] == "ABC"w);
    assert(aw.length == 7);

    aw = bw; // reset
    put(aw, '𐐷');
    assert(bw[0 .. 2] == "𐐷"w);
    assert(aw.length == 8);

    aw = bw; // reset
    put(aw, "𐐷"); // try transcoding from char[]
    assert(bw[0 .. 2] == "𐐷"w);
    assert(aw.length == 8);
}

@safe unittest
{
    int[][] a = new int[][10];
    int[]   b = new int[10];
    int     c;
    put(b, c);
    assert(b.length == 9);
    put(a, b);
    assert(a.length == 9);
    static assert(!__traits(compiles, put(a, c)));
}

@safe unittest
{
    int[][] a = new int[][](3);
    int[]   b = [1];
    auto aa = a;
    put(aa, b);
    assert(aa == [[], []]);
    assert(a  == [[1], [], []]);
    int[][3] c = [2];
    aa = a;
    put(aa, c[]);
    assert(aa.empty);
    assert(a == [[2], [2], [2]]);
}

@safe unittest
{
    // Test fix for bug 7476.
    struct LockingTextWriter
    {
        void put(dchar c){}
    }
    struct RetroResult
    {
        bool end = false;
        @property bool empty() const { return end; }
        @property dchar front(){ return 'a'; }
        void popFront(){ end = true; }
    }
    LockingTextWriter w;
    RetroResult re;
    put(w, re);
}

@system unittest
{
    import std.conv : to;
    import std.meta : AliasSeq;
    import std.typecons : tuple;

    static struct PutC(C)
    {
        string result;
        void put(const(C) c) { result ~= to!string((&c)[0 .. 1]); }
    }
    static struct PutS(C)
    {
        string result;
        void put(const(C)[] s) { result ~= to!string(s); }
    }
    static struct PutSS(C)
    {
        string result;
        void put(const(C)[][] ss)
        {
            foreach (s; ss)
                result ~= to!string(s);
        }
    }

    PutS!char p;
    putChar(p, cast(dchar)'a');

    //Source Char
    static foreach (SC; AliasSeq!(char, wchar, dchar))
    {{
        SC ch = 'I';
        dchar dh = '♥';
        immutable(SC)[] s = "日本語！";
        immutable(SC)[][] ss = ["日本語", "が", "好き", "ですか", "？"];

        //Target Char
        static foreach (TC; AliasSeq!(char, wchar, dchar))
        {
            //Testing PutC and PutS
            static foreach (Type; AliasSeq!(PutC!TC, PutS!TC))
            {{
                Type type;
                auto sink = new Type();

                //Testing put and sink
                foreach (value ; tuple(type, sink))
                {
                    put(value, ch);
                    assert(value.result == "I");
                    put(value, dh);
                    assert(value.result == "I♥");
                    put(value, s);
                    assert(value.result == "I♥日本語！");
                    put(value, ss);
                    assert(value.result == "I♥日本語！日本語が好きですか？");
                }
            }}
        }
    }}
}

@safe unittest
{
    static struct CharRange
    {
        char c;
        enum empty = false;
        void popFront(){}
        ref char front() return @property
        {
            return c;
        }
    }
    CharRange c;
    put(c, cast(dchar)'H');
    put(c, "hello"d);
}

// https://issues.dlang.org/show_bug.cgi?id=9823
@system unittest
{
    const(char)[] r;
    void delegate(const(char)[]) dg = (s) { r = s; };
    put(dg, ["ABC"]);
    assert(r == "ABC");
}

// https://issues.dlang.org/show_bug.cgi?id=10571
@safe unittest
{
    import std.format.write : formattedWrite;
    string buf;
    formattedWrite((scope const(char)[] s) { buf ~= s; }, "%s", "hello");
    assert(buf == "hello");
}

@safe unittest
{
    import std.format.write : formattedWrite;
    import std.meta : AliasSeq;
    struct PutC(C)
    {
        void put(C){}
    }
    struct PutS(C)
    {
        void put(const(C)[]){}
    }
    struct CallC(C)
    {
        void opCall(C){}
    }
    struct CallS(C)
    {
        void opCall(const(C)[]){}
    }
    struct FrontC(C)
    {
        enum empty = false;
        auto front()@property{return C.init;}
        void front(C)@property{}
        void popFront(){}
    }
    struct FrontS(C)
    {
        enum empty = false;
        auto front()@property{return C[].init;}
        void front(const(C)[])@property{}
        void popFront(){}
    }
    void foo()
    {
        static foreach (C; AliasSeq!(char, wchar, dchar))
        {{
            formattedWrite((C c){},        "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            formattedWrite((const(C)[]){}, "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            formattedWrite(PutC!C(),       "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            formattedWrite(PutS!C(),       "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            CallC!C callC;
            CallS!C callS;
            formattedWrite(callC,          "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            formattedWrite(callS,          "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            formattedWrite(FrontC!C(),     "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
            formattedWrite(FrontS!C(),     "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
        }}
        formattedWrite((dchar[]).init,     "", 1, 'a', cast(wchar)'a', cast(dchar)'a', "a"c, "a"w, "a"d);
    }
}

/+
Returns `true` if `R` is a native output range for elements of type
`E`. An output range is defined functionally as a range that
supports the operation $(D doPut(r, e)) as defined above. if $(D doPut(r, e))
is valid, then `put(r,e)` will have the same behavior.

The two guarantees isNativeOutputRange gives over the larger `isOutputRange`
are:
1: `e` is $(B exactly) what will be placed (not `[e]`, for example).
2: if `E` is a non $(empty) `InputRange`, then placing `e` is
guaranteed to not overflow the range.
 +/
package(std) enum bool isNativeOutputRange(R, E) =
    is(typeof(doPut(lvalueOf!R, lvalueOf!E)));

@safe unittest
{
    int[] r = new int[](4);
    static assert(isInputRange!(int[]));
    static assert( isNativeOutputRange!(int[], int));
    static assert(!isNativeOutputRange!(int[], int[]));
    static assert( isOutputRange!(int[], int[]));

    if (!r.empty)
        put(r, 1); //guaranteed to succeed
    if (!r.empty)
        put(r, [1, 2]); //May actually error out.
}

/++
Returns `true` if `R` is an output range for elements of type
`E`. An output range is defined functionally as a range that
supports the operation $(D put(r, e)) as defined above.

See_Also:
    The header of $(MREF std,range) for tutorials on ranges.
 +/
enum bool isOutputRange(R, E) =
    is(typeof(put(lvalueOf!R, lvalueOf!E)));

///
@safe unittest
{
    void myprint(scope const(char)[] s) { }
    static assert(isOutputRange!(typeof(&myprint), char));

    static assert( isOutputRange!(char[], char));
    static assert( isOutputRange!(dchar[], wchar));
    static assert( isOutputRange!(dchar[], dchar));
}

@safe unittest
{
    import std.array;
    import std.stdio : writeln;

    auto app = appender!string();
    string s;
    static assert( isOutputRange!(Appender!string, string));
    static assert( isOutputRange!(Appender!string*, string));
    static assert(!isOutputRange!(Appender!string, int));
    static assert( isOutputRange!(wchar[], wchar));
    static assert( isOutputRange!(dchar[], char));
    static assert( isOutputRange!(dchar[], string));
    static assert( isOutputRange!(dchar[], wstring));
    static assert( isOutputRange!(dchar[], dstring));

    static assert(!isOutputRange!(const(int)[], int));
    static assert(!isOutputRange!(inout(int)[], int));
}


/**
Returns `true` if `R` is a forward range. A forward range is an
input range `r` that can save "checkpoints" by saving `r.save`
to another value of type `R`. Notable examples of input ranges that
are $(I not) forward ranges are file/socket ranges; copying such a
range will not save the position in the stream, and they most likely
reuse an internal buffer as the entire stream does not sit in
memory. Subsequently, advancing either the original or the copy will
advance the stream, so the copies are not independent.

The following code should compile for any forward range.

----
static assert(isInputRange!R);
R r1;
auto s1 = r1.save;
static assert(is(typeof(s1) == R));
----

Saving a range is not duplicating it; in the example above, `r1`
and `r2` still refer to the same underlying data. They just
navigate that data independently.

The semantics of a forward range (not checkable during compilation)
are the same as for an input range, with the additional requirement
that backtracking must be possible by saving a copy of the range
object with `save` and using it later.

`save` behaves in many ways like a copy constructor, and its
implementation typically is done using copy construction.

The existence of a copy constructor, however, does not imply
the range is a forward range. For example, a range that reads
from a TTY consumes its input and cannot save its place and
read it again, and so cannot be a forward range and cannot
have a `save` function.


See_Also:
    The header of $(MREF std,range) for tutorials on ranges.

Params:
    R = type to be tested
    E = if present, the elements of the range must be
        $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible)
        to this type

Returns:
    `true` if R is a forward range (possibly with element type `E`), `false` if not
 */
enum bool isForwardRange(R) = isInputRange!R
    && is(typeof((R r) { return r.save; } (R.init)) == R);

/// ditto
enum bool isForwardRange(R, E) =
    .isForwardRange!R && isQualifierConvertible!(ElementType!R, E);

///
@safe unittest
{
    static assert(!isForwardRange!(int));
    static assert( isForwardRange!(int[]));
    static assert( isForwardRange!(inout(int)[]));

    static assert( isForwardRange!(int[], const int));
    static assert(!isForwardRange!(int[], immutable int));

    static assert(!isForwardRange!(const(int)[], int));
    static assert( isForwardRange!(const(int)[], const int));
    static assert(!isForwardRange!(const(int)[], immutable int));

    static assert(!isForwardRange!(immutable(int)[], int));
    static assert( isForwardRange!(immutable(int)[], const int));
    static assert( isForwardRange!(immutable(int)[], immutable int));
}

@safe unittest
{
    // BUG 14544
    struct R14544
    {
        int front() { return 0;}
        void popFront() {}
        bool empty() { return false; }
        R14544 save() {return this;}
    }

    static assert( isForwardRange!R14544 );
}

/**
Returns `true` if `R` is a bidirectional range. A bidirectional
range is a forward range that also offers the primitives `back` and
`popBack`. The following code should compile for any bidirectional
range.

The semantics of a bidirectional range (not checkable during
compilation) are assumed to be the following (`r` is an object of
type `R`):

$(UL $(LI `r.back` returns (possibly a reference to) the last
element in the range. Calling `r.back` is allowed only if calling
`r.empty` has, or would have, returned `false`.))

See_Also:
    The header of $(MREF std,range) for tutorials on ranges.

Params:
    R = type to be tested
    E = if present, the elements of the range must be
        $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible)
        to this type

Returns:
    `true` if R is a bidirectional range (possibly with element type `E`), `false` if not
 */
enum bool isBidirectionalRange(R) = isForwardRange!R
    && is(typeof((R r) => r.popBack))
    && (is(typeof((return ref R r) => r.back)) || is(typeof(ref (return ref R r) => r.back)))
    && is(typeof(R.init.back.init) == ElementType!R);

/// ditto
enum bool isBidirectionalRange(R, E) =
    .isBidirectionalRange!R && isQualifierConvertible!(ElementType!R, E);

///
@safe unittest
{
    alias R = int[];
    R r = [0,1];
    static assert(isForwardRange!R);           // is forward range
    r.popBack();                               // can invoke popBack
    auto t = r.back;                           // can get the back of the range
    auto w = r.front;
    static assert(is(typeof(t) == typeof(w))); // same type for front and back

    // Checking the element type
    static assert( isBidirectionalRange!(int[], const int));
    static assert(!isBidirectionalRange!(int[], immutable int));

    static assert(!isBidirectionalRange!(const(int)[], int));
    static assert( isBidirectionalRange!(const(int)[], const int));
    static assert(!isBidirectionalRange!(const(int)[], immutable int));

    static assert(!isBidirectionalRange!(immutable(int)[], int));
    static assert( isBidirectionalRange!(immutable(int)[], const int));
    static assert( isBidirectionalRange!(immutable(int)[], immutable int));
}

@safe unittest
{
    struct A {}
    struct B
    {
        void popFront();
        @property bool empty();
        @property int front();
    }
    struct C
    {
        @property bool empty();
        @property C save();
        void popFront();
        @property int front();
        void popBack();
        @property int back();
    }
    static assert(!isBidirectionalRange!(A));
    static assert(!isBidirectionalRange!(B));
    static assert( isBidirectionalRange!(C));
    static assert( isBidirectionalRange!(int[]));
    static assert( isBidirectionalRange!(char[]));
    static assert( isBidirectionalRange!(inout(int)[]));
}

/**
Returns `true` if `R` is a random-access range. A random-access
range is a bidirectional range that also offers the primitive $(D
opIndex), OR an infinite forward range that offers `opIndex`. In
either case, the range must either offer `length` or be
infinite. The following code should compile for any random-access
range.

The semantics of a random-access range (not checkable during
compilation) are assumed to be the following (`r` is an object of
type `R`): $(UL $(LI `r.opIndex(n)` returns a reference to the
`n`th element in the range.))

Although `char[]` and `wchar[]` (as well as their qualified
versions including `string` and `wstring`) are arrays, $(D
isRandomAccessRange) yields `false` for them because they use
variable-length encodings (UTF-8 and UTF-16 respectively). These types
are bidirectional ranges only.

See_Also:
    The header of $(MREF std,range) for tutorials on ranges.

Params:
    R = type to be tested
    E = if present, the elements of the range must be
        $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible)
        to this type

Returns:
    `true` if R is a random-access range (possibly with element type `E`), `false` if not
 */
enum bool isRandomAccessRange(R) =
    is(typeof(lvalueOf!R[1]) == ElementType!R)
    && !(isAutodecodableString!R && !isAggregateType!R)
    && isForwardRange!R
    && (isBidirectionalRange!R || isInfinite!R)
    && (hasLength!R || isInfinite!R)
    && (isInfinite!R || !is(typeof(lvalueOf!R[$ - 1]))
        || is(typeof(lvalueOf!R[$ - 1]) == ElementType!R));

/// ditto
enum bool isRandomAccessRange(R, E) =
    .isRandomAccessRange!R && isQualifierConvertible!(ElementType!R, E);

///
@safe unittest
{
    import std.traits : isAggregateType, isAutodecodableString;

    alias R = int[];

    // range is finite and bidirectional or infinite and forward.
    static assert(isBidirectionalRange!R ||
                  isForwardRange!R && isInfinite!R);

    R r = [0,1];
    auto e = r[1]; // can index
    auto f = r.front;
    static assert(is(typeof(e) == typeof(f))); // same type for indexed and front
    static assert(!(isAutodecodableString!R && !isAggregateType!R)); // narrow strings cannot be indexed as ranges
    static assert(hasLength!R || isInfinite!R); // must have length or be infinite

    // $ must work as it does with arrays if opIndex works with $
    static if (is(typeof(r[$])))
    {
        static assert(is(typeof(f) == typeof(r[$])));

        // $ - 1 doesn't make sense with infinite ranges but needs to work
        // with finite ones.
        static if (!isInfinite!R)
            static assert(is(typeof(f) == typeof(r[$ - 1])));
    }

    // Checking the element type
    static assert( isRandomAccessRange!(int[], const int));
    static assert(!isRandomAccessRange!(int[], immutable int));

    static assert(!isRandomAccessRange!(const(int)[], int));
    static assert( isRandomAccessRange!(const(int)[], const int));
    static assert(!isRandomAccessRange!(const(int)[], immutable int));

    static assert(!isRandomAccessRange!(immutable(int)[], int));
    static assert( isRandomAccessRange!(immutable(int)[], const int));
    static assert( isRandomAccessRange!(immutable(int)[], immutable int));
}

@safe unittest
{
    struct A {}
    struct B
    {
        void popFront();
        @property bool empty();
        @property int front();
    }
    struct C
    {
        void popFront();
        @property bool empty();
        @property int front();
        void popBack();
        @property int back();
    }
    struct D
    {
        @property bool empty();
        @property D save();
        @property int front();
        void popFront();
        @property int back();
        void popBack();
        ref int opIndex(uint);
        @property size_t length();
        alias opDollar = length;
        //int opSlice(uint, uint);
    }
    struct E
    {
        bool empty();
        E save();
        int front();
        void popFront();
        int back();
        void popBack();
        ref int opIndex(uint);
        size_t length();
        alias opDollar = length;
        //int opSlice(uint, uint);
    }
    static assert(!isRandomAccessRange!(A));
    static assert(!isRandomAccessRange!(B));
    static assert(!isRandomAccessRange!(C));
    static assert( isRandomAccessRange!(D));
    static assert( isRandomAccessRange!(E));
    static assert( isRandomAccessRange!(int[]));
    static assert( isRandomAccessRange!(inout(int)[]));
}

@safe unittest
{
    // Test fix for bug 6935.
    struct R
    {
        @disable this();

        @property bool empty() const { return false; }
        @property int front() const { return 0; }
        void popFront() {}

        @property R save() { return this; }

        @property int back() const { return 0; }
        void popBack(){}

        int opIndex(size_t n) const { return 0; }
        @property size_t length() const { return 0; }
        alias opDollar = length;

        void put(int e){  }
    }
    static assert(isInputRange!R);
    static assert(isForwardRange!R);
    static assert(isBidirectionalRange!R);
    static assert(isRandomAccessRange!R);
    static assert(isOutputRange!(R, int));
}

/**
Returns `true` iff `R` is an input range that supports the
`moveFront` primitive, as well as `moveBack` and `moveAt` if it's a
bidirectional or random access range. These may be explicitly implemented, or
may work via the default behavior of the module level functions `moveFront`
and friends. The following code should compile for any range
with mobile elements.

----
alias E = ElementType!R;
R r;
static assert(isInputRange!R);
static assert(is(typeof(moveFront(r)) == E));
static if (isBidirectionalRange!R)
    static assert(is(typeof(moveBack(r)) == E));
static if (isRandomAccessRange!R)
    static assert(is(typeof(moveAt(r, 0)) == E));
----
 */
enum bool hasMobileElements(R) =
    isInputRange!R
    && is(typeof(moveFront(lvalueOf!R)) == ElementType!R)
    && (!isBidirectionalRange!R
        || is(typeof(moveBack(lvalueOf!R)) == ElementType!R))
    && (!isRandomAccessRange!R
        || is(typeof(moveAt(lvalueOf!R, 0)) == ElementType!R));

///
@safe unittest
{
    import std.algorithm.iteration : map;
    import std.range : iota, repeat;

    static struct HasPostblit
    {
        this(this) {}
    }

    auto nonMobile = map!"a"(repeat(HasPostblit.init));
    static assert(!hasMobileElements!(typeof(nonMobile)));
    static assert( hasMobileElements!(int[]));
    static assert( hasMobileElements!(inout(int)[]));
    static assert( hasMobileElements!(typeof(iota(1000))));

    static assert( hasMobileElements!( string));
    static assert( hasMobileElements!(dstring));
    static assert( hasMobileElements!( char[]));
    static assert( hasMobileElements!(dchar[]));
}

/**
The element type of `R`. `R` does not have to be a range. The
element type is determined as the type yielded by `r.front` for an
object `r` of type `R`. For example, `ElementType!(T[])` is
`T` if `T[]` isn't a narrow string; if it is, the element type is
`dchar`. If `R` doesn't have `front`, `ElementType!R` is
`void`.
 */
template ElementType(R)
{
    static if (is(typeof(R.init.front.init) T))
        alias ElementType = T;
    else
        alias ElementType = void;
}

///
@safe unittest
{
    import std.range : iota;

    // Standard arrays: returns the type of the elements of the array
    static assert(is(ElementType!(int[]) == int));

    // Accessing .front retrieves the decoded dchar
    static assert(is(ElementType!(char[])  == dchar)); // rvalue
    static assert(is(ElementType!(dchar[]) == dchar)); // lvalue

    // Ditto
    static assert(is(ElementType!(string) == dchar));
    static assert(is(ElementType!(dstring) == immutable(dchar)));

    // For ranges it gets the type of .front.
    auto range = iota(0, 10);
    static assert(is(ElementType!(typeof(range)) == int));
}

@safe unittest
{
    static assert(is(ElementType!(byte[]) == byte));
    static assert(is(ElementType!(wchar[]) == dchar)); // rvalue
    static assert(is(ElementType!(wstring) == dchar));
}

@safe unittest
{
    enum XYZ : string { a = "foo" }
    auto x = XYZ.a.front;
    immutable char[3] a = "abc";
    int[] i;
    void[] buf;
    static assert(is(ElementType!(XYZ) == dchar));
    static assert(is(ElementType!(typeof(a)) == dchar));
    static assert(is(ElementType!(typeof(i)) == int));
    static assert(is(ElementType!(typeof(buf)) == void));
    static assert(is(ElementType!(inout(int)[]) == inout(int)));
    static assert(is(ElementType!(inout(int[])) == inout(int)));
}

@safe unittest
{
    static assert(is(ElementType!(int[5]) == int));
    static assert(is(ElementType!(int[0]) == int));
    static assert(is(ElementType!(char[5]) == dchar));
    static assert(is(ElementType!(char[0]) == dchar));
}

// https://issues.dlang.org/show_bug.cgi?id=11336
@safe unittest
{
    static struct S
    {
        this(this) @disable;
    }
    static assert(is(ElementType!(S[]) == S));
}

// https://issues.dlang.org/show_bug.cgi?id=11401
@safe unittest
{
    // ElementType should also work for non-@propety 'front'
    struct E { ushort id; }
    struct R
    {
        E front() { return E.init; }
    }
    static assert(is(ElementType!R == E));
}

/**
The encoding element type of `R`. For narrow strings (`char[]`,
`wchar[]` and their qualified variants including `string` and
`wstring`), `ElementEncodingType` is the character type of the
string. For all other types, `ElementEncodingType` is the same as
`ElementType`.
 */
template ElementEncodingType(R)
{
    static if (is(StringTypeOf!R) && is(R : E[], E))
        alias ElementEncodingType = E;
    else
        alias ElementEncodingType = ElementType!R;
}

///
@safe unittest
{
    import std.range : iota;
    // internally the range stores the encoded type
    static assert(is(ElementEncodingType!(char[])  == char));

    static assert(is(ElementEncodingType!(wstring) == immutable(wchar)));

    static assert(is(ElementEncodingType!(byte[]) == byte));

    auto range = iota(0, 10);
    static assert(is(ElementEncodingType!(typeof(range)) == int));
}

@safe unittest
{
    static assert(is(ElementEncodingType!(wchar[]) == wchar));
    static assert(is(ElementEncodingType!(dchar[]) == dchar));
    static assert(is(ElementEncodingType!(string)  == immutable(char)));
    static assert(is(ElementEncodingType!(dstring) == immutable(dchar)));
    static assert(is(ElementEncodingType!(int[])  == int));
}

@safe unittest
{
    enum XYZ : string { a = "foo" }
    auto x = XYZ.a.front;
    immutable char[3] a = "abc";
    int[] i;
    void[] buf;
    static assert(is(ElementType!(XYZ) : dchar));
    static assert(is(ElementEncodingType!(char[]) == char));
    static assert(is(ElementEncodingType!(string) == immutable char));
    static assert(is(ElementType!(typeof(a)) : dchar));
    static assert(is(ElementType!(typeof(i)) == int));
    static assert(is(ElementEncodingType!(typeof(i)) == int));
    static assert(is(ElementType!(typeof(buf)) : void));

    static assert(is(ElementEncodingType!(inout char[]) : inout(char)));
}

@safe unittest
{
    static assert(is(ElementEncodingType!(int[5]) == int));
    static assert(is(ElementEncodingType!(int[0]) == int));
    static assert(is(ElementEncodingType!(char[5]) == char));
    static assert(is(ElementEncodingType!(char[0]) == char));
}

/**
Returns `true` if `R` is an input range and has swappable
elements. The following code should compile for any range
with swappable elements.

----
R r;
static assert(isInputRange!R);
swap(r.front, r.front);
static if (isBidirectionalRange!R) swap(r.back, r.front);
static if (isRandomAccessRange!R) swap(r[0], r.front);
----
 */
template hasSwappableElements(R)
{
    import std.algorithm.mutation : swap;
    enum bool hasSwappableElements = isInputRange!R
        && is(typeof((ref R r) => swap(r.front, r.front)))
        && (!isBidirectionalRange!R
            || is(typeof((ref R r) => swap(r.back, r.front))))
        && (!isRandomAccessRange!R
            || is(typeof((ref R r) => swap(r[0], r.front))));
}

///
@safe unittest
{
    static assert(!hasSwappableElements!(const int[]));
    static assert(!hasSwappableElements!(const(int)[]));
    static assert(!hasSwappableElements!(inout(int)[]));
    static assert( hasSwappableElements!(int[]));

    static assert(!hasSwappableElements!( string));
    static assert(!hasSwappableElements!(dstring));
    static assert(!hasSwappableElements!( char[]));
    static assert( hasSwappableElements!(dchar[]));
}

/**
Returns `true` if `R` is an input range and has mutable
elements. The following code should compile for any range
with assignable elements.

----
R r;
static assert(isInputRange!R);
r.front = r.front;
static if (isBidirectionalRange!R) r.back = r.front;
static if (isRandomAccessRange!R) r[0] = r.front;
----
 */
enum bool hasAssignableElements(R) = isInputRange!R
    && is(typeof(lvalueOf!R.front = lvalueOf!R.front))
    && (!isBidirectionalRange!R
        || is(typeof(lvalueOf!R.back = lvalueOf!R.back)))
    && (!isRandomAccessRange!R
        || is(typeof(lvalueOf!R[0] = lvalueOf!R.front)));

///
@safe unittest
{
    static assert(!hasAssignableElements!(const int[]));
    static assert(!hasAssignableElements!(const(int)[]));
    static assert( hasAssignableElements!(int[]));
    static assert(!hasAssignableElements!(inout(int)[]));

    static assert(!hasAssignableElements!( string));
    static assert(!hasAssignableElements!(dstring));
    static assert(!hasAssignableElements!( char[]));
    static assert( hasAssignableElements!(dchar[]));
}

/**
Tests whether the range `R` has lvalue elements. These are defined as
elements that can be passed by reference and have their address taken.
The following code should compile for any range with lvalue elements.
----
void passByRef(ref ElementType!R stuff);
...
static assert(isInputRange!R);
passByRef(r.front);
static if (isBidirectionalRange!R) passByRef(r.back);
static if (isRandomAccessRange!R) passByRef(r[0]);
----
*/
enum bool hasLvalueElements(R) = isInputRange!R
    && is(typeof(isLvalue(lvalueOf!R.front)))
    && (!isBidirectionalRange!R
        || is(typeof(isLvalue(lvalueOf!R.back))))
    && (!isRandomAccessRange!R
        || is(typeof(isLvalue(lvalueOf!R[0]))));

/* Compile successfully if argument of type T is an lvalue
 */
private void isLvalue(T)(T)
if (0);

private void isLvalue(T)(ref T)
if (1);

///
@safe unittest
{
    import std.range : iota, chain;

    static assert( hasLvalueElements!(int[]));
    static assert( hasLvalueElements!(const(int)[]));
    static assert( hasLvalueElements!(inout(int)[]));
    static assert( hasLvalueElements!(immutable(int)[]));
    static assert(!hasLvalueElements!(typeof(iota(3))));

    static assert(!hasLvalueElements!( string));
    static assert( hasLvalueElements!(dstring));
    static assert(!hasLvalueElements!( char[]));
    static assert( hasLvalueElements!(dchar[]));

    auto c = chain([1, 2, 3], [4, 5, 6]);
    static assert( hasLvalueElements!(typeof(c)));
}

@safe unittest
{
    // bugfix 6336
    struct S { immutable int value; }
    static assert( isInputRange!(S[]));
    static assert( hasLvalueElements!(S[]));
}

/**
Yields `true` if `R` has a `length` member that returns a value of `size_t`
type. `R` does not have to be a range. If `R` is a range, algorithms in the
standard library are only guaranteed to support `length` with type `size_t`.

Note that `length` is an optional primitive as no range must implement it. Some
ranges do not store their length explicitly, some cannot compute it without
actually exhausting the range (e.g. socket streams), and some other ranges may
be infinite.

Although narrow string types (`char[]`, `wchar[]`, and their qualified
derivatives) do define a `length` property, `hasLength` yields `false` for them.
This is because a narrow string's length does not reflect the number of
characters, but instead the number of encoding units, and as such is not useful
with range-oriented algorithms. To use strings as random-access ranges with
length, use $(REF representation, std, string) or $(REF byCodeUnit, std, utf).
*/
template hasLength(R)
{
    static if (is(typeof(((R* r) => r.length)(null)) Length))
        enum bool hasLength = is(Length == size_t) &&
                              !(isAutodecodableString!R && !isAggregateType!R);
    else
        enum bool hasLength = false;
}

///
@safe unittest
{
    static assert(!hasLength!(char[]));
    static assert( hasLength!(int[]));
    static assert( hasLength!(inout(int)[]));

    struct A { size_t length() { return 0; } }
    struct B { @property size_t length() { return 0; } }
    static assert( hasLength!(A));
    static assert( hasLength!(B));
}

// test combinations which are invalid on some platforms
@safe unittest
{
    struct A { ulong length; }
    struct B { @property uint length() { return 0; } }

    static if (is(size_t == uint))
    {
        static assert(!hasLength!(A));
        static assert(hasLength!(B));
    }
    else static if (is(size_t == ulong))
    {
        static assert(hasLength!(A));
        static assert(!hasLength!(B));
    }
}

// test combinations which are invalid on all platforms
@safe unittest
{
    struct A { long length; }
    struct B { int length; }
    struct C { ubyte length; }
    struct D { char length; }
    static assert(!hasLength!(A));
    static assert(!hasLength!(B));
    static assert(!hasLength!(C));
    static assert(!hasLength!(D));
}

/**
Returns `true` if `R` is an infinite input range. An
infinite input range is an input range that has a statically-defined
enumerated member called `empty` that is always `false`,
for example:

----
struct MyInfiniteRange
{
    enum bool empty = false;
    ...
}
----
 */

template isInfinite(R)
{
    static if (isInputRange!R && __traits(compiles, { enum e = R.empty; }))
        enum bool isInfinite = !R.empty;
    else
        enum bool isInfinite = false;
}

///
@safe unittest
{
    import std.range : Repeat;
    static assert(!isInfinite!(int[]));
    static assert( isInfinite!(Repeat!(int)));
}

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

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 $(I not) using `opDollar`, the result of `opSlice`
may be a forward range of any type. However, when using `opDollar`, the result
of `opSlice` must be of the same type as the original range type.

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

----
    isForwardRange!R
    && !(isAutodecodableString!R && !isAggregateType!R)
    && is(typeof((R r) { return r[1 .. 1].length; } (R.init)) == 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])));
    }));
----
 */
enum bool hasSlicing(R) = isForwardRange!R
    && !(isAutodecodableString!R && !isAggregateType!R)
    && is(typeof((R r) { return r[1 .. 1].length; } (R.init)) == 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])));
    }));

///
@safe unittest
{
    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);
}

// https://issues.dlang.org/show_bug.cgi?id=24348
@safe unittest
{
    static struct Slice
    {
        size_t length;
        bool empty() => length == 0;
        int front() => 0;
        void popFront() { --length; }
        Slice save() => this;
    }

    static struct InfZeros
    {
        enum empty = false;
        int front() => 0;
        void popFront() {}
        InfZeros save() => this;

        Slice opIndex(size_t[2] bounds)
        {
            size_t i = bounds[0], j = bounds[1];
            size_t length = i <= j ? j - i : 0;
            return Slice(length);
        }

        size_t[2] opSlice(size_t dim : 0)(size_t i, size_t j) => [i, j];
    }

    static assert(hasSlicing!InfZeros);
}

/**
This is a best-effort implementation of `length` for any kind of
range.

If `hasLength!Range`, simply returns `range.length` without
checking `upTo` (when specified).

Otherwise, walks the range through its length and returns the number
of elements seen. Performes $(BIGOH n) evaluations of `range.empty`
and `range.popFront()`, where `n` is the effective length of $(D
range).

The `upTo` parameter is useful to "cut the losses" in case
the interest is in seeing whether the range has at least some number
of elements. If the parameter `upTo` is specified, stops if $(D
upTo) steps have been taken and returns `upTo`.

Infinite ranges are compatible, provided the parameter `upTo` is
specified, in which case the implementation simply returns upTo.
 */
auto walkLength(Range)(Range range)
if (isInputRange!Range && !isInfinite!Range)
{
    static if (hasLength!Range)
        return range.length;
    else
    {
        size_t result;
        static if (autodecodeStrings && isNarrowString!Range)
        {
            import std.utf : codeUnitLimit;
            result = range.length;
            foreach (const i, const c; range)
            {
                if (c >= codeUnitLimit!Range)
                {
                    result = i;
                    break;
                }
            }
            range = range[result .. $];
        }
        for ( ; !range.empty ; range.popFront() )
            ++result;
        return result;
    }
}
/// ditto
auto walkLength(Range)(Range range, const size_t upTo)
if (isInputRange!Range)
{
    static if (hasLength!Range)
        return range.length;
    else static if (isInfinite!Range)
        return upTo;
    else
    {
        size_t result;
        static if (autodecodeStrings && isNarrowString!Range)
        {
            import std.utf : codeUnitLimit;
            result = upTo > range.length ? range.length : upTo;
            foreach (const i, const c; range[0 .. result])
            {
                if (c >= codeUnitLimit!Range)
                {
                    result = i;
                    break;
                }
            }
            range = range[result .. $];
        }
        for ( ; result < upTo && !range.empty ; range.popFront() )
            ++result;
        return result;
    }
}

///
@safe unittest
{
    import std.range : iota;

    assert(10.iota.walkLength == 10);
    // iota has a length function, and therefore the
    // doesn't have to be walked, and the upTo
    // parameter is ignored
    assert(10.iota.walkLength(5) == 10);
}

@safe unittest
{
    import std.algorithm.iteration : filter;
    import std.range : recurrence, take;

    //hasLength Range
    int[] a = [ 1, 2, 3 ];
    assert(walkLength(a) == 3);
    assert(walkLength(a, 0) == 3);
    assert(walkLength(a, 2) == 3);
    assert(walkLength(a, 4) == 3);

    //Forward Range
    auto b = filter!"true"([1, 2, 3, 4]);
    assert(b.walkLength() == 4);
    assert(b.walkLength(0) == 0);
    assert(b.walkLength(2) == 2);
    assert(b.walkLength(4) == 4);
    assert(b.walkLength(6) == 4);

    //Infinite Range
    auto fibs = recurrence!"a[n-1] + a[n-2]"(1, 1);
    assert(!__traits(compiles, fibs.walkLength()));
    assert(fibs.take(10).walkLength() == 10);
    assert(fibs.walkLength(55) == 55);
}

/**
    `popFrontN` eagerly advances `r` itself (not a copy) up to `n` times
    (by calling `r.popFront`). `popFrontN` takes `r` by `ref`,
    so it mutates the original range. Completes in $(BIGOH 1) steps for ranges
    that support slicing and have length.
    Completes in $(BIGOH n) time for all other ranges.

    `popBackN` behaves the same as `popFrontN` but instead removes
    elements from the back of the (bidirectional) range instead of the front.

    Returns:
    How much `r` was actually advanced, which may be less than `n` if
    `r` did not have at least `n` elements.

    See_Also: $(REF drop, std, range), $(REF dropBack, std, range)
*/
size_t popFrontN(Range)(ref Range r, size_t n)
if (isInputRange!Range)
{
    static if (hasLength!Range)
    {
        n = cast(size_t) (n < r.length ? n : r.length);
    }

    static if (hasSlicing!Range && is(typeof(r = r[n .. $])))
    {
        r = r[n .. $];
    }
    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.
    {
        r = r[n .. r.length];
    }
    else
    {
        static if (hasLength!Range)
        {
            foreach (i; 0 .. n)
                r.popFront();
        }
        else
        {
            foreach (i; 0 .. n)
            {
                if (r.empty) return i;
                r.popFront();
            }
        }
    }
    return n;
}

/// ditto
size_t popBackN(Range)(ref Range r, size_t n)
if (isBidirectionalRange!Range)
{
    static if (hasLength!Range)
    {
        n = cast(size_t) (n < r.length ? n : r.length);
    }

    static if (hasSlicing!Range && is(typeof(r = r[0 .. $ - n])))
    {
        r = r[0 .. $ - n];
    }
    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.
    {
        r = r[0 .. r.length - n];
    }
    else
    {
        static if (hasLength!Range)
        {
            foreach (i; 0 .. n)
                r.popBack();
        }
        else
        {
            foreach (i; 0 .. n)
            {
                if (r.empty) return i;
                r.popBack();
            }
        }
    }
    return n;
}

///
@safe unittest
{
    int[] a = [ 1, 2, 3, 4, 5 ];
    a.popFrontN(2);
    assert(a == [ 3, 4, 5 ]);
    a.popFrontN(7);
    assert(a == [ ]);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : iota;
    auto LL = iota(1L, 7L);
    auto r = popFrontN(LL, 2);
    assert(equal(LL, [3L, 4L, 5L, 6L]));
    assert(r == 2);
}

///
@safe unittest
{
    int[] a = [ 1, 2, 3, 4, 5 ];
    a.popBackN(2);
    assert(a == [ 1, 2, 3 ]);
    a.popBackN(7);
    assert(a == [ ]);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : iota;
    auto LL = iota(1L, 7L);
    auto r = popBackN(LL, 2);
    assert(equal(LL, [1L, 2L, 3L, 4L]));
    assert(r == 2);
}

/**
    Eagerly advances `r` itself (not a copy) exactly `n` times (by
    calling `r.popFront`). `popFrontExactly` takes `r` by `ref`,
    so it mutates the original range. Completes in $(BIGOH 1) steps for ranges
    that support slicing, and have either length or are infinite.
    Completes in $(BIGOH n) time for all other ranges.

    Note: Unlike $(LREF popFrontN), `popFrontExactly` will assume that the
    range holds at least `n` elements. This makes `popFrontExactly`
    faster than `popFrontN`, but it also means that if `range` does
    not contain at least `n` elements, it will attempt to call `popFront`
    on an empty range, which is undefined behavior. So, only use
    `popFrontExactly` when it is guaranteed that `range` holds at least
    `n` elements.

    `popBackExactly` will behave the same but instead removes elements from
    the back of the (bidirectional) range instead of the front.

    See_Also: $(REF dropExactly, std, range), $(REF dropBackExactly, std, range)
*/
void popFrontExactly(Range)(ref Range r, size_t n)
if (isInputRange!Range)
{
    static if (hasLength!Range)
        assert(n <= r.length, "range is smaller than amount of items to pop");

    static if (hasSlicing!Range && is(typeof(r = r[n .. $])))
        r = r[n .. $];
    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.
        r = r[n .. r.length];
    else
        foreach (i; 0 .. n)
            r.popFront();
}

/// ditto
void popBackExactly(Range)(ref Range r, size_t n)
if (isBidirectionalRange!Range)
{
    static if (hasLength!Range)
        assert(n <= r.length, "range is smaller than amount of items to pop");

    static if (hasSlicing!Range && is(typeof(r = r[0 .. $ - n])))
        r = r[0 .. $ - n];
    else static if (hasSlicing!Range && hasLength!Range) //TODO: Remove once hasSlicing forces opDollar.
        r = r[0 .. r.length - n];
    else
        foreach (i; 0 .. n)
            r.popBack();
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filterBidirectional;

    auto a = [1, 2, 3];
    a.popFrontExactly(1);
    assert(a == [2, 3]);
    a.popBackExactly(1);
    assert(a == [2]);

    string s = "日本語";
    s.popFrontExactly(1);
    assert(s == "本語");
    s.popBackExactly(1);
    assert(s == "本");

    auto bd = filterBidirectional!"true"([1, 2, 3]);
    bd.popFrontExactly(1);
    assert(bd.equal([2, 3]));
    bd.popBackExactly(1);
    assert(bd.equal([2]));
}

/**
   Moves the front of `r` out and returns it.

   If `r.front` is a struct with a destructor or copy constructor defined, it
   is reset to its `.init` value after its value is moved. Otherwise, it is
   left unchanged.

   In either case, `r.front` is left in a destroyable state that does not
   allocate any resources.
*/
ElementType!R moveFront(R)(R r)
{
    static if (is(typeof(&r.moveFront)))
    {
        return r.moveFront();
    }
    else static if (!hasElaborateCopyConstructor!(ElementType!R))
    {
        return r.front;
    }
    else static if (is(typeof(&(r.front())) == ElementType!R*))
    {
        import std.algorithm.mutation : move;
        return move(r.front);
    }
    else
    {
        static assert(0,
                "Cannot move front of a range with a postblit and an rvalue front.");
    }
}

///
@safe unittest
{
    auto a = [ 1, 2, 3 ];
    assert(moveFront(a) == 1);
    assert(a.length == 3);

    // define a perfunctory input range
    struct InputRange
    {
        enum bool empty = false;
        enum int front = 7;
        void popFront() {}
        int moveFront() { return 43; }
    }
    InputRange r;
    // calls r.moveFront
    assert(moveFront(r) == 43);
}

@safe unittest
{
    struct R
    {
        @property ref int front() { static int x = 42; return x; }
        this(this){}
    }
    R r;
    assert(moveFront(r) == 42);
}

/**
   Moves the back of `r` out and returns it. Leaves `r.back` in a
   destroyable state that does not allocate any resources (usually equal
   to its `.init` value).
*/
ElementType!R moveBack(R)(R r)
{
    static if (is(typeof(&r.moveBack)))
    {
        return r.moveBack();
    }
    else static if (!hasElaborateCopyConstructor!(ElementType!R))
    {
        return r.back;
    }
    else static if (is(typeof(&(r.back())) == ElementType!R*))
    {
        import std.algorithm.mutation : move;
        return move(r.back);
    }
    else
    {
        static assert(0,
                "Cannot move back of a range with a postblit and an rvalue back.");
    }
}

///
@safe unittest
{
    struct TestRange
    {
        int payload = 5;
        @property bool empty() { return false; }
        @property TestRange save() { return this; }
        @property ref int front() return { return payload; }
        @property ref int back() return { return payload; }
        void popFront() { }
        void popBack() { }
    }
    static assert(isBidirectionalRange!TestRange);
    TestRange r;
    auto x = moveBack(r);
    assert(x == 5);
}

/**
   Moves element at index `i` of `r` out and returns it. Leaves $(D
   r[i]) in a destroyable state that does not allocate any resources
   (usually equal to its `.init` value).
*/
ElementType!R moveAt(R)(R r, size_t i)
{
    static if (is(typeof(&r.moveAt)))
    {
        return r.moveAt(i);
    }
    else static if (!hasElaborateCopyConstructor!(ElementType!(R)))
    {
        return r[i];
    }
    else static if (is(typeof(&r[i]) == ElementType!R*))
    {
        import std.algorithm.mutation : move;
        return move(r[i]);
    }
    else
    {
        static assert(0,
                "Cannot move element of a range with a postblit and rvalue elements.");
    }
}

///
@safe unittest
{
    auto a = [1,2,3,4];
    foreach (idx, it; a)
    {
        assert(it == moveAt(a, idx));
    }
}

@safe unittest
{
    import std.internal.test.dummyrange;

    foreach (DummyType; AllDummyRanges)
    {
        auto d = DummyType.init;
        assert(moveFront(d) == 1);

        static if (isBidirectionalRange!DummyType)
        {
            assert(moveBack(d) == 10);
        }

        static if (isRandomAccessRange!DummyType)
        {
            assert(moveAt(d, 2) == 3);
        }
    }
}

/**
Implements the range interface primitive `empty` for types that
obey $(LREF hasLength) property and for narrow strings. Due to the
fact that nonmember functions can be called with the first argument
using the dot notation, `a.empty` is equivalent to `empty(a)`.
 */
@property bool empty(T)(auto ref scope T a)
if (is(typeof(a.length) : size_t))
{
    return !a.length;
}

///
@safe pure nothrow unittest
{
    auto a = [ 1, 2, 3 ];
    assert(!a.empty);
    assert(a[3 .. $].empty);

    int[string] b;
    assert(b.empty);
    b["zero"] = 0;
    assert(!b.empty);
}

/**
Implements the range interface primitive `save` for built-in
arrays. Due to the fact that nonmember functions can be called with
the first argument using the dot notation, `array.save` is
equivalent to `save(array)`. The function does not duplicate the
content of the array, it simply returns its argument.
 */
@property inout(T)[] save(T)(return scope inout(T)[] a) @safe pure nothrow @nogc
{
    return a;
}

///
@safe pure nothrow unittest
{
    auto a = [ 1, 2, 3 ];
    auto b = a.save;
    assert(b is a);
}

/**
Implements the range interface primitive `popFront` for built-in
arrays. Due to the fact that nonmember functions can be called with
the first argument using the dot notation, `array.popFront` is
equivalent to `popFront(array)`. For $(GLOSSARY narrow strings),
`popFront` automatically advances to the next $(GLOSSARY code
point).
*/
void popFront(T)(scope ref inout(T)[] a) @safe pure nothrow @nogc
if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{
    assert(a.length, "Attempting to popFront() past the end of an array of " ~ T.stringof);
    a = a[1 .. $];
}

///
@safe pure nothrow unittest
{
    auto a = [ 1, 2, 3 ];
    a.popFront();
    assert(a == [ 2, 3 ]);
}

@safe unittest
{
    static assert(!is(typeof({          int[4] a; popFront(a); })));
    static assert(!is(typeof({ immutable int[] a; popFront(a); })));
    static assert(!is(typeof({          void[] a; popFront(a); })));
}

/// ditto
void popFront(C)(scope ref inout(C)[] str) @trusted pure nothrow
if (isAutodecodableString!(C[]))
{
    import std.algorithm.comparison : min;

    assert(str.length, "Attempting to popFront() past the end of an array of " ~ C.stringof);

    static if (is(immutable C == immutable char))
    {
        static immutable ubyte[] charWidthTab = [
            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
            4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
        ];

        immutable c = str[0];
        immutable charWidth = c < 192 ? 1 : charWidthTab.ptr[c - 192];
        str = str.ptr[min(str.length, charWidth) .. str.length];
    }
    else static if (is(immutable C == immutable wchar))
    {
        immutable u = str[0];
        immutable seqLen = 1 + (u >= 0xD800 && u <= 0xDBFF);
        str = str.ptr[min(seqLen, str.length) .. str.length];
    }
    else static assert(0, "Bad template constraint.");
}

@safe pure unittest
{
    import std.meta : AliasSeq;

    static foreach (S; AliasSeq!(string, wstring, dstring))
    {{
        S s = "\xC2\xA9hello";
        s.popFront();
        assert(s == "hello");

        S str = "hello\U00010143\u0100\U00010143";
        foreach (dchar c; ['h', 'e', 'l', 'l', 'o', '\U00010143', '\u0100', '\U00010143'])
        {
            assert(str.front == c);
            str.popFront();
        }
        assert(str.empty);

        static assert(!is(typeof({          immutable S a; popFront(a); })));
        static assert(!is(typeof({ typeof(S.init[0])[4] a; popFront(a); })));
    }}

    C[] _eatString(C)(C[] str)
    {
        while (!str.empty)
            str.popFront();

        return str;
    }
    enum checkCTFE = _eatString("ウェブサイト@La_Verité.com");
    static assert(checkCTFE.empty);
    enum checkCTFEW = _eatString("ウェブサイト@La_Verité.com"w);
    static assert(checkCTFEW.empty);
}

// https://issues.dlang.org/show_bug.cgi?id=16090
@safe unittest
{
    string s = "\u00E4";
    assert(s.length == 2);
    s = s[0 .. 1];
    assert(s.length == 1);
    s.popFront;
    assert(s.empty);
}

@safe unittest
{
    wstring s = "\U00010000";
    assert(s.length == 2);
    s = s[0 .. 1];
    assert(s.length == 1);
    s.popFront;
    assert(s.empty);
}

/**
Implements the range interface primitive `popBack` for built-in
arrays. Due to the fact that nonmember functions can be called with
the first argument using the dot notation, `array.popBack` is
equivalent to `popBack(array)`. For $(GLOSSARY narrow strings), $(D
popFront) automatically eliminates the last $(GLOSSARY code point).
*/
void popBack(T)(scope ref inout(T)[] a) @safe pure nothrow @nogc
if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{
    assert(a.length);
    a = a[0 .. $ - 1];
}

///
@safe pure nothrow unittest
{
    auto a = [ 1, 2, 3 ];
    a.popBack();
    assert(a == [ 1, 2 ]);
}

@safe unittest
{
    static assert(!is(typeof({ immutable int[] a; popBack(a); })));
    static assert(!is(typeof({          int[4] a; popBack(a); })));
    static assert(!is(typeof({          void[] a; popBack(a); })));
}

/// ditto
void popBack(T)(scope ref inout(T)[] a) @safe pure
if (isAutodecodableString!(T[]))
{
    import std.utf : strideBack;
    assert(a.length, "Attempting to popBack() past the front of an array of " ~ T.stringof);
    a = a[0 .. $ - strideBack(a, $)];
}

@safe pure unittest
{
    import std.meta : AliasSeq;

    static foreach (S; AliasSeq!(string, wstring, dstring))
    {{
        S s = "hello\xE2\x89\xA0";
        s.popBack();
        assert(s == "hello");
        S s3 = "\xE2\x89\xA0";
        auto c = s3.back;
        assert(c == cast(dchar)'\u2260');
        s3.popBack();
        assert(s3 == "");

        S str = "\U00010143\u0100\U00010143hello";
        foreach (dchar ch; ['o', 'l', 'l', 'e', 'h', '\U00010143', '\u0100', '\U00010143'])
        {
            assert(str.back == ch);
            str.popBack();
        }
        assert(str.empty);

        static assert(!is(typeof({          immutable S a; popBack(a); })));
        static assert(!is(typeof({ typeof(S.init[0])[4] a; popBack(a); })));
    }}
}

/**
EXPERIMENTAL: to try out removing autodecoding, set the version
`NoAutodecodeStrings`. Most things are expected to fail with this version
currently.
*/
version (NoAutodecodeStrings)
{
    enum autodecodeStrings = false;
}
else
{
    ///
    enum autodecodeStrings = true;
}

/**
Implements the range interface primitive `front` for built-in
arrays. Due to the fact that nonmember functions can be called with
the first argument using the dot notation, `array.front` is
equivalent to `front(array)`. For $(GLOSSARY narrow strings), $(D
front) automatically returns the first $(GLOSSARY code point) as _a $(D
dchar).
*/
@property ref inout(T) front(T)(return scope inout(T)[] a) @safe pure nothrow @nogc
if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{
    assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
    return a[0];
}

///
@safe pure nothrow unittest
{
    int[] a = [ 1, 2, 3 ];
    assert(a.front == 1);
}

@safe pure nothrow unittest
{
    auto a = [ 1, 2 ];
    a.front = 4;
    assert(a.front == 4);
    assert(a == [ 4, 2 ]);

    immutable b = [ 1, 2 ];
    assert(b.front == 1);

    int[2] c = [ 1, 2 ];
    assert(c.front == 1);
}

/// ditto
@property dchar front(T)(scope const(T)[] a) @safe pure
if (isAutodecodableString!(T[]))
{
    import std.utf : decode;
    assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
    size_t i = 0;
    return decode(a, i);
}

/**
Implements the range interface primitive `back` for built-in
arrays. Due to the fact that nonmember functions can be called with
the first argument using the dot notation, `array.back` is
equivalent to `back(array)`. For $(GLOSSARY narrow strings), $(D
back) automatically returns the last $(GLOSSARY code point) as _a $(D
dchar).
*/
@property ref inout(T) back(T)(return scope inout(T)[] a) @safe pure nothrow @nogc
if (!isAutodecodableString!(T[]) && !is(T[] == void[]))
{
    assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof);
    return a[$ - 1];
}

///
@safe pure nothrow unittest
{
    int[] a = [ 1, 2, 3 ];
    assert(a.back == 3);
    a.back += 4;
    assert(a.back == 7);
}

@safe pure nothrow unittest
{
    immutable b = [ 1, 2, 3 ];
    assert(b.back == 3);

    int[3] c = [ 1, 2, 3 ];
    assert(c.back == 3);
}

/// ditto
// Specialization for strings
@property dchar back(T)(scope const(T)[] a) @safe pure
if (isAutodecodableString!(T[]))
{
    import std.utf : decode, strideBack;
    assert(a.length, "Attempting to fetch the back of an empty array of " ~ T.stringof);
    size_t i = a.length - strideBack(a, a.length);
    return decode(a, i);
}

/*
Implements `length` for a range by forwarding it to `member`.
*/
package(std) mixin template ImplementLength(alias member)
{
    static if (hasLength!(typeof(member)))
    {
        @property auto length()
        {
            return member.length;
        }
        alias opDollar = length;
    }
}

@safe unittest
{
    import std.meta : AliasSeq;

    foreach (alias E; AliasSeq!(noreturn, const(noreturn), immutable(noreturn) ))
    {
        alias R = E[];

        static assert(isInputRange!R);
        static assert(isForwardRange!R);
        static assert(isBidirectionalRange!R);
        static assert(isRandomAccessRange!R);
    }

    static assert(isOutputRange!(noreturn[], noreturn));
}
