// Written in the D programming language.

/**
This module defines the notion of a range. Ranges generalize the concept of
arrays, lists, or anything that involves sequential access. This abstraction
enables the same set of algorithms (see $(MREF std, algorithm)) to be used
with a vast variety of different concrete types. For example,
a linear search algorithm such as $(REF find, std, algorithm, searching)
works not just for arrays, but for linked-lists, input files,
incoming network data, etc.

Guides:

There are many articles available that can bolster understanding ranges:

$(UL
    $(LI Ali Çehreli's $(HTTP ddili.org/ders/d.en/ranges.html, tutorial on ranges)
        for the basics of working with and creating range-based code.)
    $(LI Jonathan M. Davis $(LINK2 http://dconf.org/2015/talks/davis.html, $(I Introduction to Ranges))
        talk at DConf 2015 a vivid introduction from its core constructs to practical advice.)
    $(LI The DLang Tour's $(LINK2 http://tour.dlang.org/tour/en/basics/ranges, chapter on ranges)
        for an interactive introduction.)
    $(LI H. S. Teoh's $(LINK2 http://wiki.dlang.org/Component_programming_with_ranges, tutorial on
        component programming with ranges) for a real-world showcase of the influence
        of range-based programming on complex algorithms.)
    $(LI Andrei Alexandrescu's article
        $(LINK2 http://www.informit.com/articles/printerfriendly.aspx?p=1407357$(AMP)rll=1,
        $(I On Iteration)) for conceptual aspect of ranges and the motivation
    )
)

Submodules:

This module has two submodules:

The $(MREF std, range, primitives) submodule
provides basic range functionality. It defines several templates for testing
whether a given object is a range, what kind of range it is, and provides
some common range operations.

The $(MREF std, range, interfaces) submodule
provides object-based interfaces for working with ranges via runtime
polymorphism.

The remainder of this module provides a rich set of range creation and
composition templates that let you construct new ranges out of existing ranges:


$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE ,
    $(TR $(TD $(LREF chain))
        $(TD Concatenates several ranges into a single range.
    ))
    $(TR $(TD $(LREF choose))
        $(TD Chooses one of two ranges at runtime based on a boolean condition.
    ))
    $(TR $(TD $(LREF chooseAmong))
        $(TD Chooses one of several ranges at runtime based on an index.
    ))
    $(TR $(TD $(LREF chunks))
        $(TD Creates a range that returns fixed-size chunks of the original
        range.
    ))
    $(TR $(TD $(LREF cycle))
        $(TD Creates an infinite range that repeats the given forward range
        indefinitely. Good for implementing circular buffers.
    ))
    $(TR $(TD $(LREF drop))
        $(TD Creates the range that results from discarding the first $(I n)
        elements from the given range.
    ))
    $(TR $(TD $(LREF dropBack))
        $(TD Creates the range that results from discarding the last $(I n)
        elements from the given range.
    ))
    $(TR $(TD $(LREF dropExactly))
        $(TD Creates the range that results from discarding exactly $(I n)
        of the first elements from the given range.
    ))
    $(TR $(TD $(LREF dropBackExactly))
        $(TD Creates the range that results from discarding exactly $(I n)
        of the last elements from the given range.
    ))
    $(TR $(TD $(LREF dropOne))
        $(TD Creates the range that results from discarding
        the first element from the given range.
    ))
    $(TR $(TD $(D $(LREF dropBackOne)))
        $(TD Creates the range that results from discarding
        the last element from the given range.
    ))
    $(TR $(TD $(LREF enumerate))
        $(TD Iterates a range with an attached index variable.
    ))
    $(TR $(TD $(LREF evenChunks))
        $(TD Creates a range that returns a number of chunks of
        approximately equal length from the original range.
    ))
    $(TR $(TD $(LREF frontTransversal))
        $(TD Creates a range that iterates over the first elements of the
        given ranges.
    ))
    $(TR $(TD $(LREF generate))
        $(TD Creates a range by successive calls to a given function. This
        allows to create ranges as a single delegate.
    ))
    $(TR $(TD $(LREF indexed))
        $(TD Creates a range that offers a view of a given range as though
        its elements were reordered according to a given range of indices.
    ))
    $(TR $(TD $(LREF iota))
        $(TD Creates a range consisting of numbers between a starting point
        and ending point, spaced apart by a given interval.
    ))
    $(TR $(TD $(LREF lockstep))
        $(TD Iterates $(I n) ranges in lockstep, for use in a `foreach`
        loop. Similar to `zip`, except that `lockstep` is designed
        especially for `foreach` loops.
    ))
    $(TR $(TD $(LREF nullSink))
        $(TD An output range that discards the data it receives.
    ))
    $(TR $(TD $(LREF only))
        $(TD Creates a range that iterates over the given arguments.
    ))
    $(TR $(TD $(LREF padLeft))
        $(TD Pads a range to a specified length by adding a given element to
        the front of the range. Is lazy if the range has a known length.
    ))
    $(TR $(TD $(LREF padRight))
        $(TD Lazily pads a range to a specified length by adding a given element to
        the back of the range.
    ))
    $(TR $(TD $(LREF radial))
        $(TD Given a random-access range and a starting point, creates a
        range that alternately returns the next left and next right element to
        the starting point.
    ))
    $(TR $(TD $(LREF recurrence))
        $(TD Creates a forward range whose values are defined by a
        mathematical recurrence relation.
    ))
    $(TR $(TD $(LREF refRange))
        $(TD Pass a range by reference. Both the original range and the RefRange
        will always have the exact same elements.
        Any operation done on one will affect the other.
    ))
    $(TR $(TD $(LREF repeat))
        $(TD Creates a range that consists of a single element repeated $(I n)
        times, or an infinite range repeating that element indefinitely.
    ))
    $(TR $(TD $(LREF retro))
        $(TD Iterates a bidirectional range backwards.
    ))
    $(TR $(TD $(LREF roundRobin))
        $(TD Given $(I n) ranges, creates a new range that return the $(I n)
        first elements of each range, in turn, then the second element of each
        range, and so on, in a round-robin fashion.
    ))
    $(TR $(TD $(LREF sequence))
        $(TD Similar to `recurrence`, except that a random-access range is
        created.
    ))
    $(TR $(TD $(D $(LREF slide)))
        $(TD Creates a range that returns a fixed-size sliding window
        over the original range. Unlike chunks,
        it advances a configurable number of items at a time,
        not one chunk at a time.
    ))
    $(TR $(TD $(LREF stride))
        $(TD Iterates a range with stride $(I n).
    ))
    $(TR $(TD $(LREF tail))
        $(TD Return a range advanced to within `n` elements of the end of
        the given range.
    ))
    $(TR $(TD $(LREF take))
        $(TD Creates a sub-range consisting of only up to the first $(I n)
        elements of the given range.
    ))
    $(TR $(TD $(LREF takeExactly))
        $(TD Like `take`, but assumes the given range actually has $(I n)
        elements, and therefore also defines the `length` property.
    ))
    $(TR $(TD $(LREF takeNone))
        $(TD Creates a random-access range consisting of zero elements of the
        given range.
    ))
    $(TR $(TD $(LREF takeOne))
        $(TD Creates a random-access range consisting of exactly the first
        element of the given range.
    ))
    $(TR $(TD $(LREF tee))
        $(TD Creates a range that wraps a given range, forwarding along
        its elements while also calling a provided function with each element.
    ))
    $(TR $(TD $(LREF transposed))
        $(TD Transposes a range of ranges.
    ))
    $(TR $(TD $(LREF transversal))
        $(TD Creates a range that iterates over the $(I n)'th elements of the
        given random-access ranges.
    ))
    $(TR $(TD $(LREF zip))
        $(TD Given $(I n) ranges, creates a range that successively returns a
        tuple of all the first elements, a tuple of all the second elements,
        etc.
    ))
))

Sortedness:

Ranges whose elements are sorted afford better efficiency with certain
operations. For this, the $(LREF assumeSorted) function can be used to
construct a $(LREF SortedRange) from a pre-sorted range. The $(REF
sort, std, algorithm, sorting) function also conveniently
returns a $(LREF SortedRange). $(LREF SortedRange) objects provide some additional
range operations that take advantage of the fact that the range is sorted.

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

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

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

public import std.array;
public import std.range.interfaces;
public import std.range.primitives;
public import std.typecons : Flag, Yes, No, Rebindable, rebindable;

import std.internal.attributes : betterC;
import std.meta : aliasSeqOf, allSatisfy, anySatisfy, staticMap;
import std.traits : CommonType, isCallable, isFloatingPoint, isIntegral,
    isPointer, isSomeFunction, isStaticArray, Unqual, isInstanceOf;


/**
Iterates a bidirectional range backwards. The original range can be
accessed by using the `source` property. Applying retro twice to
the same range yields the original range.

Params:
    r = the bidirectional range to iterate backwards

Returns:
    A bidirectional range with length if `r` also provides a length. Or,
    if `r` is a random access range, then the return value will be random
    access as well.
See_Also:
    $(REF reverse, std,algorithm,mutation) for mutating the source range directly.
 */
auto retro(Range)(Range r)
if (isBidirectionalRange!(Unqual!Range))
{
    // Check for retro(retro(r)) and just return r in that case
    static if (is(typeof(retro(r.source)) == Range))
    {
        return r.source;
    }
    else
    {
        static struct Result()
        {
            private alias R = Unqual!Range;

            // User code can get and set source, too
            R source;

            static if (hasLength!R)
            {
                size_t retroIndex(size_t n)
                {
                    return source.length - n - 1;
                }
            }

        public:
            alias Source = R;

            @property bool empty() { return source.empty; }
            @property auto save()
            {
                return Result(source.save);
            }
            @property auto ref front() { return source.back; }
            void popFront() { source.popBack(); }
            @property auto ref back() { return source.front; }
            void popBack() { source.popFront(); }

            static if (is(typeof(source.moveBack())))
            {
                ElementType!R moveFront()
                {
                    return source.moveBack();
                }
            }

            static if (is(typeof(source.moveFront())))
            {
                ElementType!R moveBack()
                {
                    return source.moveFront();
                }
            }

            static if (hasAssignableElements!R)
            {
                @property void front(ElementType!R val)
                {
                    import core.lifetime : forward;

                    // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                    source.back = __ctfe ? val : forward!val;
                }

                @property void back(ElementType!R val)
                {
                    import core.lifetime : forward;

                    // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                    source.front = __ctfe ? val : forward!val;
                }
            }

            static if (isRandomAccessRange!(R) && hasLength!(R))
            {
                auto ref opIndex(size_t n) { return source[retroIndex(n)]; }

                static if (hasAssignableElements!R)
                {
                    void opIndexAssign(ElementType!R val, size_t n)
                    {
                        import core.lifetime : forward;

                        // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                        source[retroIndex(n)] = __ctfe ? val : forward!val;
                    }
                }

                static if (is(typeof(source.moveAt(0))))
                {
                    ElementType!R moveAt(size_t index)
                    {
                        return source.moveAt(retroIndex(index));
                    }
                }

                static if (hasSlicing!R)
                    typeof(this) opSlice(size_t a, size_t b)
                    {
                        return typeof(this)(source[source.length - b .. source.length - a]);
                    }
            }

            mixin ImplementLength!source;
        }

        return Result!()(r);
    }
}


///
pure @safe nothrow @nogc unittest
{
    import std.algorithm.comparison : equal;
    int[5] a = [ 1, 2, 3, 4, 5 ];
    int[5] b = [ 5, 4, 3, 2, 1 ];
    assert(equal(retro(a[]), b[]));
    assert(retro(a[]).source is a[]);
    assert(retro(retro(a[])) is a[]);
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    static assert(isBidirectionalRange!(typeof(retro("hello"))));
    int[] a;
    static assert(is(typeof(a) == typeof(retro(retro(a)))));
    assert(retro(retro(a)) is a);
    static assert(isRandomAccessRange!(typeof(retro([1, 2, 3]))));
    void test(int[] input, int[] witness)
    {
        auto r = retro(input);
        assert(r.front == witness.front);
        assert(r.back == witness.back);
        assert(equal(r, witness));
    }
    test([ 1 ], [ 1 ]);
    test([ 1, 2 ], [ 2, 1 ]);
    test([ 1, 2, 3 ], [ 3, 2, 1 ]);
    test([ 1, 2, 3, 4 ], [ 4, 3, 2, 1 ]);
    test([ 1, 2, 3, 4, 5 ], [ 5, 4, 3, 2, 1 ]);
    test([ 1, 2, 3, 4, 5, 6 ], [ 6, 5, 4, 3, 2, 1 ]);

    immutable foo = [1,2,3].idup;
    auto r = retro(foo);
    assert(equal(r, [3, 2, 1]));
}

pure @safe nothrow unittest
{
    import std.internal.test.dummyrange : AllDummyRanges, propagatesRangeType,
        ReturnBy;

    foreach (DummyType; AllDummyRanges)
    {
        static if (!isBidirectionalRange!DummyType)
        {
            static assert(!__traits(compiles, Retro!DummyType));
        }
        else
        {
            DummyType dummyRange;
            dummyRange.reinit();

            auto myRetro = retro(dummyRange);
            static assert(propagatesRangeType!(typeof(myRetro), DummyType));
            assert(myRetro.front == 10);
            assert(myRetro.back == 1);
            assert(myRetro.moveFront() == 10);
            assert(myRetro.moveBack() == 1);

            static if (isRandomAccessRange!DummyType && hasLength!DummyType)
            {
                assert(myRetro[0] == myRetro.front);
                assert(myRetro.moveAt(2) == 8);

                static if (DummyType.r == ReturnBy.Reference)
                {
                    {
                        myRetro[9]++;
                        scope(exit) myRetro[9]--;
                        assert(dummyRange[0] == 2);
                        myRetro.front++;
                        scope(exit) myRetro.front--;
                        assert(myRetro.front == 11);
                        myRetro.back++;
                        scope(exit) myRetro.back--;
                        assert(myRetro.back == 3);
                    }

                    {
                        myRetro.front = 0xFF;
                        scope(exit) myRetro.front = 10;
                        assert(dummyRange.back == 0xFF);

                        myRetro.back = 0xBB;
                        scope(exit) myRetro.back = 1;
                        assert(dummyRange.front == 0xBB);

                        myRetro[1] = 11;
                        scope(exit) myRetro[1] = 8;
                        assert(dummyRange[8] == 11);
                    }
                }
            }
        }
    }
}

pure @safe nothrow @nogc unittest
{
    import std.algorithm.comparison : equal;
    auto LL = iota(1L, 4L);
    auto r = retro(LL);
    long[3] excepted = [3, 2, 1];
    assert(equal(r, excepted[]));
}

// https://issues.dlang.org/show_bug.cgi?id=12662
pure @safe nothrow @nogc unittest
{
    int[3] src = [1,2,3];
    int[] data = src[];
    foreach_reverse (x; data) {}
    foreach (x; data.retro) {}
}

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

    static struct S {
        int v;
        @disable this(this);
    }

    immutable foo = [S(1), S(2), S(3)];
    auto r = retro(foo);
    assert(equal(r, [S(3), S(2), S(1)]));
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)];
    auto range = arr[].retro();

    called = false;
    range.front = Handle(42);
    assert(called);

    called = false;
    range.back = Handle(42);
    assert(called);

    called = false;
    range[2] = Handle(42);
    assert(called);
}

/**
Iterates range `r` with stride `n`. If the range is a
random-access range, moves by indexing into the range; otherwise,
moves by successive calls to `popFront`. Applying stride twice to
the same range results in a stride with a step that is the
product of the two applications. It is an error for `n` to be 0.

Params:
    r = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to stride over
    n = the number of elements to skip over

Returns:
    At minimum, an input range. The resulting range will adopt the
    range primitives of the underlying range as long as
    $(REF hasLength, std,range,primitives) is `true`.
 */
auto stride(Range)(Range r, size_t n)
if (isInputRange!(Unqual!Range))
in
{
    assert(n != 0, "stride cannot have step zero.");
}
do
{
    import std.algorithm.comparison : min;

    static if (is(typeof(stride(r.source, n)) == Range))
    {
        // stride(stride(r, n1), n2) is stride(r, n1 * n2)
        return stride(r.source, r._n * n);
    }
    else
    {
        static struct Result
        {
            private alias R = Unqual!Range;
            public R source;
            private size_t _n;

            // Chop off the slack elements at the end
            static if (hasLength!R &&
                    (isRandomAccessRange!R && hasSlicing!R
                            || isBidirectionalRange!R))
                private void eliminateSlackElements()
                {
                    auto slack = source.length % _n;

                    if (slack)
                    {
                        slack--;
                    }
                    else if (!source.empty)
                    {
                        slack = min(_n, source.length) - 1;
                    }
                    else
                    {
                        slack = 0;
                    }
                    if (!slack) return;
                    static if (isRandomAccessRange!R && hasLength!R && hasSlicing!R)
                    {
                        source = source[0 .. source.length - slack];
                    }
                    else static if (isBidirectionalRange!R)
                    {
                        foreach (i; 0 .. slack)
                        {
                            source.popBack();
                        }
                    }
                }

            static if (isForwardRange!R)
            {
                @property auto save()
                {
                    return Result(source.save, _n);
                }
            }

            static if (isInfinite!R)
            {
                enum bool empty = false;
            }
            else
            {
                @property bool empty()
                {
                    return source.empty;
                }
            }

            @property auto ref front()
            {
                return source.front;
            }

            static if (is(typeof(.moveFront(source))))
            {
                ElementType!R moveFront()
                {
                    return source.moveFront();
                }
            }

            static if (hasAssignableElements!R)
            {
                @property void front(ElementType!R val)
                {
                    import core.lifetime : forward;

                    // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                    source.front = __ctfe ? val : forward!val;
                }
            }

            void popFront()
            {
                source.popFrontN(_n);
            }

            static if (isBidirectionalRange!R && hasLength!R)
            {
                void popBack()
                {
                    popBackN(source, _n);
                }

                @property auto ref back()
                {
                    eliminateSlackElements();
                    return source.back;
                }

                static if (is(typeof(.moveBack(source))))
                {
                    ElementType!R moveBack()
                    {
                        eliminateSlackElements();
                        return source.moveBack();
                    }
                }

                static if (hasAssignableElements!R)
                {
                    @property void back(ElementType!R val)
                    {
                        eliminateSlackElements();
                        source.back = val;
                    }
                }
            }

            static if (isRandomAccessRange!R && hasLength!R)
            {
                auto ref opIndex(size_t n)
                {
                    return source[_n * n];
                }

                /**
                   Forwards to $(D moveAt(source, n)).
                */
                static if (is(typeof(source.moveAt(0))))
                {
                    ElementType!R moveAt(size_t n)
                    {
                        return source.moveAt(_n * n);
                    }
                }

                static if (hasAssignableElements!R)
                {
                    void opIndexAssign(ElementType!R val, size_t n)
                    {
                        source[_n * n] = val;
                    }
                }
            }

            static if (hasSlicing!R && hasLength!R)
                typeof(this) opSlice(size_t lower, size_t upper)
                {
                    assert(upper >= lower && upper <= length,
                        "Attempt to get out-of-bounds slice of `stride` range");
                    immutable translatedUpper = (upper == 0) ? 0 :
                        (upper * _n - (_n - 1));
                    immutable translatedLower = min(lower * _n, translatedUpper);

                    assert(translatedLower <= translatedUpper,
                        "Overflow when calculating slice of `stride` range");

                    return typeof(this)(source[translatedLower .. translatedUpper], _n);
                }

            static if (hasLength!R)
            {
                @property auto length()
                {
                    return (source.length + _n - 1) / _n;
                }

                alias opDollar = length;
            }
        }
        return Result(r, n);
    }
}

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

    int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
    assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][]));
    assert(stride(stride(a, 2), 3) == stride(a, 6));
}

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

    int[4] testArr = [1,2,3,4];
    static immutable result = [1, 3];
    assert(equal(testArr[].stride(2), result));
}

debug pure nothrow @system unittest
{//check the contract
    int[4] testArr = [1,2,3,4];
    bool passed = false;
    scope (success) assert(passed);
    import core.exception : AssertError;
    //std.exception.assertThrown won't do because it can't infer nothrow
    // https://issues.dlang.org/show_bug.cgi?id=12647
    try
    {
        auto unused = testArr[].stride(0);
    }
    catch (AssertError unused)
    {
        passed = true;
    }
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges, propagatesRangeType,
        ReturnBy;

    static assert(isRandomAccessRange!(typeof(stride([1, 2, 3], 2))));
    void test(size_t n, int[] input, int[] witness)
    {
        assert(equal(stride(input, n), witness));
    }
    test(1, [], []);
    int[] arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    assert(stride(stride(arr, 2), 3) is stride(arr, 6));
    test(1, arr, arr);
    test(2, arr, [1, 3, 5, 7, 9]);
    test(3, arr, [1, 4, 7, 10]);
    test(4, arr, [1, 5, 9]);

    // Test slicing.
    auto s1 = stride(arr, 1);
    assert(equal(s1[1 .. 4], [2, 3, 4]));
    assert(s1[1 .. 4].length == 3);
    assert(equal(s1[1 .. 5], [2, 3, 4, 5]));
    assert(s1[1 .. 5].length == 4);
    assert(s1[0 .. 0].empty);
    assert(s1[3 .. 3].empty);
    // assert(s1[$ .. $].empty);
    assert(s1[s1.opDollar .. s1.opDollar].empty);

    auto s2 = stride(arr, 2);
    assert(equal(s2[0 .. 2], [1,3]));
    assert(s2[0 .. 2].length == 2);
    assert(equal(s2[1 .. 5], [3, 5, 7, 9]));
    assert(s2[1 .. 5].length == 4);
    assert(s2[0 .. 0].empty);
    assert(s2[3 .. 3].empty);
    // assert(s2[$ .. $].empty);
    assert(s2[s2.opDollar .. s2.opDollar].empty);

    // Test fix for https://issues.dlang.org/show_bug.cgi?id=5035
    auto m = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]; // 3 rows, 4 columns
    auto col = stride(m, 4);
    assert(equal(col, [1, 1, 1]));
    assert(equal(retro(col), [1, 1, 1]));

    immutable int[] immi = [ 1, 2, 3 ];
    static assert(isRandomAccessRange!(typeof(stride(immi, 1))));

    // Check for infiniteness propagation.
    static assert(isInfinite!(typeof(stride(repeat(1), 3))));

    foreach (DummyType; AllDummyRanges)
    {
        DummyType dummyRange;
        dummyRange.reinit();

        auto myStride = stride(dummyRange, 4);

        // Should fail if no length and bidirectional b/c there's no way
        // to know how much slack we have.
        static if (hasLength!DummyType || !isBidirectionalRange!DummyType)
        {
            static assert(propagatesRangeType!(typeof(myStride), DummyType));
        }
        assert(myStride.front == 1);
        assert(myStride.moveFront() == 1);
        assert(equal(myStride, [1, 5, 9]));

        static if (hasLength!DummyType)
        {
            assert(myStride.length == 3);
        }

        static if (isBidirectionalRange!DummyType && hasLength!DummyType)
        {
            assert(myStride.back == 9);
            assert(myStride.moveBack() == 9);
        }

        static if (isRandomAccessRange!DummyType && hasLength!DummyType)
        {
            assert(myStride[0] == 1);
            assert(myStride[1] == 5);
            assert(myStride.moveAt(1) == 5);
            assert(myStride[2] == 9);

            static assert(hasSlicing!(typeof(myStride)));
        }

        static if (DummyType.r == ReturnBy.Reference)
        {
            // Make sure reference is propagated.

            {
                myStride.front++;
                scope(exit) myStride.front--;
                assert(dummyRange.front == 2);
            }
            {
                myStride.front = 4;
                scope(exit) myStride.front = 1;
                assert(dummyRange.front == 4);
            }

            static if (isBidirectionalRange!DummyType && hasLength!DummyType)
            {
                {
                    myStride.back++;
                    scope(exit) myStride.back--;
                    assert(myStride.back == 10);
                }
                {
                    myStride.back = 111;
                    scope(exit) myStride.back = 9;
                    assert(myStride.back == 111);
                }

                static if (isRandomAccessRange!DummyType)
                {
                    {
                        myStride[1]++;
                        scope(exit) myStride[1]--;
                        assert(dummyRange[4] == 6);
                    }
                    {
                        myStride[1] = 55;
                        scope(exit) myStride[1] = 5;
                        assert(dummyRange[4] == 55);
                    }
                }
            }
        }
    }
}

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

    auto LL = iota(1L, 10L);
    auto s = stride(LL, 3);
    assert(equal(s, [1L, 4L, 7L]));
}

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

    static struct S {
        int v;
        @disable this(this);
    }

    immutable foo = [S(1), S(2), S(3), S(4), S(5)];
    auto r = stride(foo, 3);
    assert(equal(r, [S(1), S(4)]));
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)];
    auto range = arr[].stride(2);

    called = false;
    range.front = Handle(42);
    assert(called);
}

/**
Spans multiple ranges in sequence. The function `chain` takes any
number of ranges and returns a $(D Chain!(R1, R2,...)) object. The
ranges may be different, but they must have the same element type. The
result is a range that offers the `front`, `popFront`, and $(D
empty) primitives. If all input ranges offer random access and $(D
length), `Chain` offers them as well.

Note that repeated random access of the resulting range is likely
to perform somewhat badly since lengths of the ranges in the chain have to be
added up for each random access operation. Random access to elements of
the first remaining range is still efficient.

If only one range is offered to `Chain` or `chain`, the $(D
Chain) type exits the picture by aliasing itself directly to that
range's type.

Params:
    rs = the $(REF_ALTTEXT input ranges, isInputRange, std,range,primitives) to chain together

Returns:
    An input range at minimum. If all of the ranges in `rs` provide
    a range primitive, the returned range will also provide that range
    primitive.

See_Also: $(LREF only) to chain values to a range
 */
auto chain(Ranges...)(Ranges rs)
if (Ranges.length > 0 &&
    allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) &&
    !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void))
{
    static if (Ranges.length == 1)
    {
        return rs[0];
    }
    else
    {
        static struct Result
        {
        private:
            alias R = staticMap!(Unqual, Ranges);
            alias RvalueElementType = CommonType!(staticMap!(.ElementType, R));
            template sameET(A)
            {
                enum sameET = is(.ElementType!A == RvalueElementType);
            }

            enum bool allSameType = allSatisfy!(sameET, R),
                bidirectional = allSatisfy!(isBidirectionalRange, R),
                mobileElements = allSatisfy!(hasMobileElements, R),
                assignableElements = allSameType
                    && allSatisfy!(hasAssignableElements, R);

            alias ElementType = RvalueElementType;

            static if (allSameType && allSatisfy!(hasLvalueElements, R))
            {
                static ref RvalueElementType fixRef(ref RvalueElementType val)
                {
                    return val;
                }
            }
            else
            {
                static RvalueElementType fixRef(RvalueElementType val)
                {
                    return val;
                }
            }

            R source;
            size_t frontIndex;
            // Always points to index one past the last non-empty range,
            // because otherwise decrementing while pointing to first range
            // would overflow to size_t.max.
            static if (bidirectional) size_t backIndex;
            else enum backIndex = source.length;

            this(typeof(Result.tupleof) fields)
            {
                this.tupleof = fields;
            }

        public:
            this(R input)
            {
                frontIndex = source.length;
                static if (bidirectional) backIndex = 0;

                foreach (i, ref v; input) source[i] = v;

                // We do this separately to avoid invoking `empty` needlessly.
                // While not recommended, a range may depend on side effects of
                // `empty` call.
                foreach (i, ref v; source) if (!v.empty)
                {
                    frontIndex = i;
                    static if (bidirectional) backIndex = i+1;
                    break;
                }

                // backIndex is already set in the first loop to
                // as frontIndex+1, so we'll use that if we don't find a
                // non-empty range here.
                static if (bidirectional)
                    static foreach_reverse (i; 1 .. R.length + 1)
                {
                    if (i <= frontIndex + 1) return;
                    if (!source[i-1].empty)
                    {
                        backIndex = i;
                        return;
                    }
                }
            }

            import std.meta : anySatisfy;

            static if (anySatisfy!(isInfinite, R))
            {
                // Propagate infiniteness.
                enum bool empty = false;
            }
            else
            {
                @property bool empty()
                {
                    if (frontIndex == 0)
                    {
                        // special handling: we might be in Range.init state!
                        // For instance, `format!"%s"` uses Range.init to ensure
                        // that formatting is possible.
                        // In that case, we must still behave in an internally consistent way.
                        return source[0].empty;
                    }
                    return frontIndex >= backIndex;
                }
            }

            static if (allSatisfy!(isForwardRange, R))
            {
                @property auto save()
                {
                    auto saveI(size_t i)() => source[i].save;

                    // TODO: this has the constructor needlessly refind
                    // frontIndex and backIndex. It'd be better to just copy
                    // those from `.this`.
                    auto saveResult =
                        Result(staticMap!(saveI, aliasSeqOf!(R.length.iota)));

                    return saveResult;
                }
            }

            void popFront()
            {
                sw1: switch (frontIndex)
                {
                    static foreach (i; 0 .. R.length)
                    {
                    case i:
                        source[i].popFront();
                        break sw1;
                    }

                case R.length:
                    assert(0, "Attempt to `popFront` of empty `chain` range");

                default:
                    assert(0, "Internal library error. Please report it.");
                }

                sw2: switch (frontIndex)
                {
                    static foreach (i; 0 .. R.length)
                    {
                    case i:
                        if (source[i].empty)
                        {
                            frontIndex++;
                            goto case;
                        }
                        else break sw2;
                    }

                // Only possible to reach from goto of previous case.
                case R.length:
                    break;

                default:
                    assert(0, "Internal library error. Please report it.");
                }
            }

            @property auto ref front()
            {
                switch (frontIndex)
                {
                    static foreach (i; 0 .. R.length)
                    {
                    case i:
                        return fixRef(source[i].front);
                    }

                case R.length:
                    assert(0, "Attempt to get `front` of empty `chain` range");

                default:
                    assert(0, "Internal library error. Please report it.");
                }
            }

            static if (assignableElements)
            {
                // @@@BUG@@@
                //@property void front(T)(T v) if (is(T : RvalueElementType))

                @property void front(RvalueElementType v)
                {
                    import core.lifetime : forward;

                    sw: switch (frontIndex)
                    {
                        static foreach (i; 0 .. R.length)
                        {
                        case i:
                            // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                            source[i].front = __ctfe ? v : forward!v;
                            break sw;
                        }

                    case R.length:
                        assert(0, "Attempt to set `front` of empty `chain` range");

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }
                }
            }

            static if (mobileElements)
            {
                RvalueElementType moveFront()
                {
                    switch (frontIndex)
                    {
                        static foreach (i; 0 .. R.length)
                        {
                        case i:
                            return source[i].moveFront();
                        }

                    case R.length:
                        assert(0, "Attempt to `moveFront` of empty `chain` range");

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }
                }
            }

            static if (bidirectional)
            {
                @property auto ref back()
                {
                    switch (backIndex)
                    {
                        static foreach_reverse (i; 1 .. R.length + 1)
                        {
                        case i:
                            return fixRef(source[i-1].back);
                        }

                    case 0:
                        assert(0, "Attempt to get `back` of empty `chain` range");

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }
                }

                void popBack()
                {
                    sw1: switch (backIndex)
                    {
                        static foreach_reverse (i; 1 .. R.length + 1)
                        {
                        case i:
                            source[i-1].popBack();
                            break sw1;
                        }

                    case 0:
                        assert(0, "Attempt to `popFront` of empty `chain` range");

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }

                    sw2: switch (backIndex)
                    {
                        static foreach_reverse (i; 1 .. R.length + 1)
                        {
                        case i:
                            if (source[i-1].empty)
                            {
                                backIndex--;
                                goto case;
                            }
                            else break sw2;
                        }

                    // Only possible to reach from goto of previous case.
                    case 0:
                        break;

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }
                }

                static if (mobileElements)
                {
                    RvalueElementType moveBack()
                    {
                        switch (backIndex)
                        {
                            static foreach_reverse (i; 1 .. R.length + 1)
                            {
                            case i:
                                return source[i-1].moveBack();
                            }

                        case 0:
                            assert(0, "Attempt to `moveBack` of empty `chain` range");

                        default:
                            assert(0, "Internal library error. Please report it.");
                        }
                    }
                }

                static if (allSameType && allSatisfy!(hasAssignableElements, R))
                {
                    @property void back(RvalueElementType v)
                    {
                        import core.lifetime : forward;

                        sw: switch (backIndex)
                        {
                            static foreach_reverse (i; 1 .. R.length + 1)
                            {
                            case i:
                                // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                                source[i - 1].back = __ctfe ? v : forward!v;
                                break sw;
                            }

                        case 0:
                            assert(0, "Attempt to set `back` of empty `chain` range");

                        default:
                            assert(0, "Internal library error. Please report it.");
                        }
                    }
                }
            }

            static if (allSatisfy!(hasLength, R))
            {
                @property size_t length()
                {
                    size_t result = 0;
                    sw: switch (frontIndex)
                    {
                        static foreach (i; 0 .. R.length)
                        {
                        case i:
                            result += source[i].length;
                            if (backIndex == i+1) break sw;
                            else goto case;
                        }

                    case R.length:
                        break;

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }

                    return result;
                }

                alias opDollar = length;
            }

            static if (allSatisfy!(isRandomAccessRange, R))
            {
                auto ref opIndex(size_t index)
                {
                    switch (frontIndex)
                    {
                        static foreach (i; 0 .. R.length)
                        {
                        case i:
                            static if (!isInfinite!(R[i]))
                            {
                                immutable length = source[i].length;
                                if (index >= length)
                                {
                                    index -= length;
                                    goto case;
                                }
                            }

                            return fixRef(source[i][index]);
                        }

                    case R.length:
                        assert(0, "Attempt to access out-of-bounds index of `chain` range");

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }
                }

                static if (mobileElements)
                {
                    RvalueElementType moveAt(size_t index)
                    {
                        switch (frontIndex)
                        {
                            static foreach (i; 0 .. R.length)
                            {
                            case i:
                                static if (!isInfinite!(R[i]))
                                {
                                    immutable length = source[i].length;
                                    if (index >= length)
                                    {
                                        index -= length;
                                        goto case;
                                    }
                                }

                                return source[i].moveAt(index);
                            }

                        case R.length:
                            assert(0, "Attempt to move out-of-bounds index of `chain` range");

                        default:
                            assert(0, "Internal library error. Please report it.");
                        }
                    }
                }

                static if (allSameType && allSatisfy!(hasAssignableElements, R))
                    void opIndexAssign(ElementType v, size_t index)
                    {
                        import core.lifetime : forward;

                        sw: switch (frontIndex)
                        {
                            static foreach (i; 0 .. R.length)
                            {
                            case i:
                                static if (!isInfinite!(R[i]))
                                {
                                    immutable length = source[i].length;
                                    if (index >= length)
                                    {
                                        index -= length;
                                        goto case;
                                    }
                                }

                                // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                                source[i][index] = __ctfe ? v : forward!v;
                                break sw;
                            }

                        case R.length:
                            assert(0, "Attempt to write out-of-bounds index of `chain` range");

                        default:
                            assert(0, "Internal library error. Please report it.");
                        }
                    }
            }

            static if (allSatisfy!(hasLength, R) && allSatisfy!(hasSlicing, R))
                auto opSlice(size_t begin, size_t end) return scope
                {
                    // force staticMap type conversion to Rebindable
                    static struct ResultRanges
                    {
                        staticMap!(Rebindable, typeof(source)) fields;
                    }
                    auto sourceI(size_t i)() => rebindable(this.source[i]);
                    auto resultRanges = ResultRanges(staticMap!(sourceI, aliasSeqOf!(R.length.iota))).fields;
                    size_t resultFrontIndex = this.frontIndex;
                    static if (bidirectional)
                        size_t resultBackIndex = this.backIndex;

                    sw: switch (frontIndex)
                    {
                        static foreach (i; 0 .. R.length)
                        {
                        case i:
                            immutable len = resultRanges[i].length;
                            if (len <= begin)
                            {
                                resultRanges[i] = resultRanges[i]
                                    [len .. len];
                                begin -= len;
                                resultFrontIndex++;
                                goto case;
                            }
                            else
                            {
                                resultRanges[i] = resultRanges[i]
                                    [begin .. len];
                                break sw;
                            }
                        }

                    case R.length:
                        assert(begin == 0,
                            "Attempt to access out-of-bounds slice of `chain` range");
                        break;

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }

                    // Overflow intentional if end index too big.
                    // This will trigger the bounds check failure below.
                    auto cut = length - end;

                    sw2: switch (backIndex)
                    {
                        static foreach_reverse (i; 1 .. R.length + 1)
                        {
                        case i:
                            immutable len = resultRanges[i-1].length;
                            if (len <= cut)
                            {
                                resultRanges[i-1] = resultRanges[i-1]
                                    [0 .. 0];
                                cut -= len;
                                resultBackIndex--;
                                goto case;
                            }
                            else
                            {
                                resultRanges[i-1] = resultRanges[i-1]
                                    [0 .. len - cut];
                                break sw2;
                            }
                        }

                    case 0:
                        assert(cut == 0, end > length?
                            "Attempt to access out-of-bounds slice of `chain` range":
                            "Attempt to access negative length slice of `chain` range");
                        break sw2;

                    default:
                        assert(0, "Internal library error. Please report it.");
                    }

                    static if (bidirectional)
                        return Result(resultRanges, resultFrontIndex, resultBackIndex);
                    else
                        return Result(resultRanges, resultFrontIndex);
                }
        }
        return Result(rs);
    }
}

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

    int[] arr1 = [ 1, 2, 3, 4 ];
    int[] arr2 = [ 5, 6 ];
    int[] arr3 = [ 7 ];
    auto s = chain(arr1, arr2, arr3);
    assert(s.length == 7);
    assert(s[5] == 6);
    assert(equal(s, [1, 2, 3, 4, 5, 6, 7][]));
}

/**
 * Range primitives are carried over to the returned range if
 * all of the ranges provide them
 */
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.sorting : sort;

    int[] arr1 = [5, 2, 8];
    int[] arr2 = [3, 7, 9];
    int[] arr3 = [1, 4, 6];

    // in-place sorting across all of the arrays
    auto s = arr1.chain(arr2, arr3).sort;

    assert(s.equal([1, 2, 3, 4, 5, 6, 7, 8, 9]));
    assert(arr1.equal([1, 2, 3]));
    assert(arr2.equal([4, 5, 6]));
    assert(arr3.equal([7, 8, 9]));
}

/**
Due to safe type promotion in D, chaining together different
character ranges results in a `uint` range.

Use $(REF_ALTTEXT byChar, byChar,std,utf), $(REF_ALTTEXT byWchar, byWchar,std,utf),
and $(REF_ALTTEXT byDchar, byDchar,std,utf) on the ranges
to get the type you need.
 */
pure @safe nothrow unittest
{
    import std.utf : byChar, byCodeUnit;

    auto s1 = "string one";
    auto s2 = "string two";
    // s1 and s2 front is dchar because of auto-decoding
    static assert(is(typeof(s1.front) == dchar) && is(typeof(s2.front) == dchar));

    auto r1 = s1.chain(s2);
    // chains of ranges of the same character type give that same type
    static assert(is(typeof(r1.front) == dchar));

    auto s3 = "string three".byCodeUnit;
    static assert(is(typeof(s3.front) == immutable char));
    auto r2 = s1.chain(s3);
    // chaining ranges of mixed character types gives `dchar`
    static assert(is(typeof(r2.front) == dchar));

    // use byChar on character ranges to correctly convert them to UTF-8
    auto r3 = s1.byChar.chain(s3);
    static assert(is(typeof(r3.front) == immutable char));
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges, dummyLength,
                                          propagatesRangeType;

    {
        int[] arr1 = [ 1, 2, 3, 4 ];
        int[] arr2 = [ 5, 6 ];
        int[] arr3 = [ 7 ];
        int[] witness = [ 1, 2, 3, 4, 5, 6, 7 ];
        auto s1 = chain(arr1);
        static assert(isRandomAccessRange!(typeof(s1)));
        auto s2 = chain(arr1, arr2);
        static assert(isBidirectionalRange!(typeof(s2)));
        static assert(isRandomAccessRange!(typeof(s2)));
        s2.front = 1;
        auto s = chain(arr1, arr2, arr3);
        assert(s[5] == 6);
        assert(equal(s, witness));
        assert(s[4 .. 6].equal(arr2));
        assert(s[2 .. 5].equal([3, 4, 5]));
        assert(s[0 .. 0].empty);
        assert(s[7 .. $].empty);
        assert(s[5] == 6);
    }
    {
        int[] arr1 = [ 1, 2, 3, 4 ];
        int[] witness = [ 1, 2, 3, 4 ];
        assert(equal(chain(arr1), witness));
    }
    {
        uint[] foo = [1,2,3,4,5];
        uint[] bar = [1,2,3,4,5];
        auto c = chain(foo, bar);
        c[3] = 42;
        assert(c[3] == 42);
        assert(c.moveFront() == 1);
        assert(c.moveBack() == 5);
        assert(c.moveAt(4) == 5);
        assert(c.moveAt(5) == 1);
    }


    // Make sure https://issues.dlang.org/show_bug.cgi?id=3311 is fixed.
    // elements are mutable.
    assert(equal(chain(iota(0, 3), iota(0, 3)), [0, 1, 2, 0, 1, 2]));

    // Test the case where infinite ranges are present.
    auto inf = chain([0,1,2][], cycle([4,5,6][]), [7,8,9][]); // infinite range
    assert(inf[0] == 0);
    assert(inf[3] == 4);
    assert(inf[6] == 4);
    assert(inf[7] == 5);
    static assert(isInfinite!(typeof(inf)));

    immutable int[] immi = [ 1, 2, 3 ];
    immutable float[] immf = [ 1, 2, 3 ];
    static assert(is(typeof(chain(immi, immf))));

    // Check that chain at least instantiates and compiles with every possible
    // pair of DummyRange types, in either order.

    foreach (DummyType1; AllDummyRanges)
    (){ // workaround slow optimizations for large functions
        // https://issues.dlang.org/show_bug.cgi?id=2396
        DummyType1 dummy1;
        foreach (DummyType2; AllDummyRanges)
        {
            DummyType2 dummy2;
            auto myChain = chain(dummy1, dummy2);

            static assert(
                propagatesRangeType!(typeof(myChain), DummyType1, DummyType2)
            );

            assert(myChain.front == 1);
            foreach (i; 0 .. dummyLength)
            {
                myChain.popFront();
            }
            assert(myChain.front == 1);

            static if (isBidirectionalRange!DummyType1 &&
                      isBidirectionalRange!DummyType2) {
                assert(myChain.back == 10);
            }

            static if (isRandomAccessRange!DummyType1 &&
                      isRandomAccessRange!DummyType2) {
                assert(myChain[0] == 1);
            }

            static if (hasLvalueElements!DummyType1 && hasLvalueElements!DummyType2)
            {
                static assert(hasLvalueElements!(typeof(myChain)));
            }
            else
            {
                static assert(!hasLvalueElements!(typeof(myChain)));
            }
        }
    }();
}

pure @safe nothrow @nogc unittest
{
    class Foo{}
    immutable(Foo)[] a;
    immutable(Foo)[] b;
    assert(chain(a, b).empty);
}

// https://issues.dlang.org/show_bug.cgi?id=18657
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    string s = "foo";
    auto r = refRange(&s).chain("bar");
    assert(equal(r.save, "foobar"));
    assert(equal(r, "foobar"));
}

// https://issues.dlang.org/show_bug.cgi?id=23844
pure @safe unittest
{
    struct S
    {
        immutable int value;
    }

    auto range = chain(only(S(5)), only(S(6)));
    assert(range.array == [S(5), S(6)]);
}

// https://issues.dlang.org/show_bug.cgi?id=24064
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Nullable;

    immutable Nullable!string foo = "b";
    string[] bar = ["a"];
    assert(chain(bar, foo).equal(["a", "b"]));
}

pure @safe nothrow @nogc unittest
{
    // support non-copyable items

    static struct S {
        int v;
        @disable this(this);
    }

    S[2] s0, s1;
    foreach (ref el; chain(s0[], s1[]))
    {
        int n = el.v;
    }

    S[] s2, s3;
    foreach (ref el; chain(s2, s3))
    {
        int n = el.v;
    }
}

// https://issues.dlang.org/show_bug.cgi?id=24243
pure @safe nothrow unittest
{
    import std.algorithm.iteration : filter;

    auto range = chain([2], [3].filter!"a");

    // This might happen in format!"%s"(range), for instance.
    assert(typeof(range).init.empty);
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)];
    auto range = arr[0 .. 2].chain(arr[4 .. 5]);

    called = false;
    range.front = Handle(42);
    assert(called);

    called = false;
    range.back = Handle(42);
    assert(called);

    called = false;
    range[2] = Handle(42);
    assert(called);
}

/**
Choose one of two ranges at runtime depending on a Boolean condition.

The ranges may be different, but they must have compatible element types (i.e.
`CommonType` must exist for the two element types). The result is a range
that offers the weakest capabilities of the two (e.g. `ForwardRange` if $(D
R1) is a random-access range and `R2` is a forward range).

Params:
    condition = which range to choose: `r1` if `true`, `r2` otherwise
    r1 = the "true" range
    r2 = the "false" range

Returns:
    A range type dependent on `R1` and `R2`.
 */
auto choose(R1, R2)(bool condition, return scope R1 r1, return scope R2 r2)
if (isInputRange!(Unqual!R1) && isInputRange!(Unqual!R2) &&
    !is(CommonType!(ElementType!(Unqual!R1), ElementType!(Unqual!R2)) == void))
{
    size_t choice = condition? 0: 1;
    return ChooseResult!(R1, R2)(choice, r1, r2);
}

///
@safe nothrow pure @nogc unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter, map;

    auto data1 = only(1, 2, 3, 4).filter!(a => a != 3);
    auto data2 = only(5, 6, 7, 8).map!(a => a + 1);

    // choose() is primarily useful when you need to select one of two ranges
    // with different types at runtime.
    static assert(!is(typeof(data1) == typeof(data2)));

    auto chooseRange(bool pickFirst)
    {
        // The returned range is a common wrapper type that can be used for
        // returning or storing either range without running into a type error.
        return choose(pickFirst, data1, data2);

        // Simply returning the chosen range without using choose() does not
        // work, because map() and filter() return different types.
        //return pickFirst ? data1 : data2; // does not compile
    }

    auto result = chooseRange(true);
    assert(result.equal(only(1, 2, 4)));

    result = chooseRange(false);
    assert(result.equal(only(6, 7, 8, 9)));
}


private struct ChooseResult(Ranges...)
{
    import std.meta : aliasSeqOf, ApplyLeft;
    import std.traits : hasElaborateCopyConstructor, hasElaborateDestructor,
        lvalueOf;

    private union
    {
        Ranges rs;
    }
    private size_t chosenI;

    private static auto ref actOnChosen(alias foo, ExtraArgs ...)
        (ref ChooseResult r, auto ref ExtraArgs extraArgs)
    {
        ref getI(size_t i)(return ref ChooseResult r) @trusted { return r.rs[i]; }

        switch (r.chosenI)
        {
            static foreach (candI; 0 .. rs.length)
            {
                case candI: return foo(getI!candI(r), extraArgs);
            }

            default: assert(false);
        }
    }

    // @trusted because of assignment of r which overlap each other
    this(size_t chosen, return scope Ranges rs) @trusted
    {
        import core.lifetime : emplace;

        // This should be the only place chosenI is ever assigned
        // independently
        this.chosenI = chosen;

        // Otherwise the compiler will complain about skipping these fields
        static foreach (i; 0 .. rs.length)
        {
            this.rs[i] = Ranges[i].init;
        }

        // The relevant field needs to be initialized last so it will overwrite
        // the other initializations and not the other way around.
        sw: switch (chosenI)
        {
            static foreach (i; 0 .. rs.length)
            {
                case i:
                emplace(&this.rs[i], rs[i]);
                break sw;
            }

            default: assert(false);
        }
    }

    // Some legacy code may still call this with typeof(choose(/*...*/))(/*...*/)
    // without this overload the regular constructor would invert the meaning of
    // the boolean
    static if (rs.length == 2)
    pragma(inline, true)
    deprecated("Call with size_t (0 = first), or use the choose function")
    this(bool firstChosen, Ranges rs)
    {
        import core.lifetime : move;
        this(cast(size_t)(firstChosen? 0: 1), rs[0].move, rs[1].move);
    }

    void opAssign(ChooseResult r)
    {
        ref getI(size_t i)(return ref ChooseResult r) @trusted { return r.rs[i]; }

        static if (anySatisfy!(hasElaborateDestructor, Ranges))
            if (chosenI != r.chosenI)
        {
            // destroy the current item
            actOnChosen!((ref r) => destroy(r))(this);
        }
        chosenI = r.chosenI;

        sw: switch (chosenI)
        {
            static foreach (candI; 0 .. rs.length)
            {
                case candI: getI!candI(this) = getI!candI(r);
                break sw;
            }

            default: assert(false);
        }
    }

    // Carefully defined postblit to postblit the appropriate range
    static if (anySatisfy!(hasElaborateCopyConstructor, Ranges))
    this(this)
    {
        actOnChosen!((ref r) {
                static if (hasElaborateCopyConstructor!(typeof(r))) r.__xpostblit();
            })(this);
    }

    static if (anySatisfy!(hasElaborateDestructor, Ranges))
    ~this()
    {
        actOnChosen!((ref r) => destroy(r))(this);
    }

    // Propagate infiniteness.
    static if (allSatisfy!(isInfinite, Ranges)) enum bool empty = false;
    else @property bool empty()
    {
        return actOnChosen!(r => r.empty)(this);
    }

    @property auto ref front()
    {
        static auto ref getFront(R)(ref R r) { return r.front; }
        return actOnChosen!getFront(this);
    }

    void popFront()
    {
        return actOnChosen!((ref r) { r.popFront; })(this);
    }

    static if (allSatisfy!(isForwardRange, Ranges))
    @property auto save() // return scope inferred
    {
        auto saveOrInit(size_t i)()
        {
            ref getI() @trusted { return rs[i]; }
            if (i == chosenI) return getI().save;
            else return Ranges[i].init;
        }

        return typeof(this)(chosenI, staticMap!(saveOrInit,
            aliasSeqOf!(rs.length.iota)));
    }

    template front(T)
    {
        private enum overloadValidFor(alias r) = is(typeof(r.front = T.init));

        static if (allSatisfy!(overloadValidFor, rs))
        void front(T v)
        {
            actOnChosen!((ref r, T v) { r.front = v; })(this, v);
        }
    }

    static if (allSatisfy!(hasMobileElements, Ranges))
    auto moveFront()
    {
        return actOnChosen!((ref r) => r.moveFront)(this);
    }

    static if (allSatisfy!(isBidirectionalRange, Ranges))
    {
        @property auto ref back()
        {
            static auto ref getBack(R)(ref R r) { return r.back; }
            return actOnChosen!getBack(this);
        }

        void popBack()
        {
            actOnChosen!((ref r) { r.popBack; })(this);
        }

        static if (allSatisfy!(hasMobileElements, Ranges))
        auto moveBack()
        {
            return actOnChosen!((ref r) => r.moveBack)(this);
        }

        template back(T)
        {
            private enum overloadValidFor(alias r) = is(typeof(r.back = T.init));

            static if (allSatisfy!(overloadValidFor, rs))
            void back(T v)
            {
                actOnChosen!((ref r, T v) { r.back = v; })(this, v);
            }
        }
    }

    static if (allSatisfy!(hasLength, Ranges))
    {
        @property size_t length()
        {
            return actOnChosen!(r => r.length)(this);
        }
        alias opDollar = length;
    }

    static if (allSatisfy!(isRandomAccessRange, Ranges))
    {
        auto ref opIndex(size_t index)
        {
            static auto ref get(R)(ref R r, size_t index) { return r[index]; }
            return actOnChosen!get(this, index);
        }

        static if (allSatisfy!(hasMobileElements, Ranges))
            auto moveAt(size_t index)
            {
                return actOnChosen!((ref r, size_t index) => r.moveAt(index))
                    (this, index);
            }

        private enum indexAssignable(T, R) = is(typeof(lvalueOf!R[1] = T.init));

        template opIndexAssign(T)
        if (allSatisfy!(ApplyLeft!(indexAssignable, T), Ranges))
        {
            void opIndexAssign(T v, size_t index)
            {
                return actOnChosen!((ref r, size_t index, T v) { r[index] = v; })
                    (this, index, v);
            }
        }
    }

    static if (allSatisfy!(hasSlicing, Ranges))
    auto opSlice(size_t begin, size_t end)
    {
        alias Slice(R) = typeof(R.init[0 .. 1]);
        alias Slices = staticMap!(Slice, Ranges);

        auto sliceOrInit(size_t i)()
        {
            ref getI() @trusted { return rs[i]; }
            return i == chosenI? getI()[begin .. end]: Slices[i].init;
        }

        return chooseAmong(chosenI, staticMap!(sliceOrInit,
            aliasSeqOf!(rs.length.iota)));
    }
}

// https://issues.dlang.org/show_bug.cgi?id=18657
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    string s = "foo";
    auto r = choose(true, refRange(&s), "bar");
    assert(equal(r.save, "foo"));
    assert(equal(r, "foo"));
}

@safe unittest
{
    static void* p;
    static struct R
    {
        void* q;
        int front;
        bool empty;
        void popFront() {}
        // `p = q;` is only there to prevent inference of `scope return`.
        @property @safe R save() { p = q; return this; }

    }
    R r;
    choose(true, r, r).save;
}

// Make sure ChooseResult.save doesn't trust @system user code.
@system unittest // copy is @system
{
    static struct R
    {
        int front;
        bool empty;
        void popFront() {}
        this(this) @system {}
        @property R save() { return R(front, empty); }
    }
    choose(true, R(), R()).save;
    choose(true, [0], R()).save;
    choose(true, R(), [0]).save;
}

@safe unittest // copy is @system
{
    static struct R
    {
        int front;
        bool empty;
        void popFront() {}
        this(this) @system {}
        @property R save() { return R(front, empty); }
    }
    static assert(!__traits(compiles, choose(true, R(), R()).save));
    static assert(!__traits(compiles, choose(true, [0], R()).save));
    static assert(!__traits(compiles, choose(true, R(), [0]).save));
}

@system unittest // .save is @system
{
    static struct R
    {
        int front;
        bool empty;
        void popFront() {}
        @property R save() @system { return this; }
    }
    choose(true, R(), R()).save;
    choose(true, [0], R()).save;
    choose(true, R(), [0]).save;
}

@safe unittest // .save is @system
{
    static struct R
    {
        int front;
        bool empty;
        void popFront() {}
        @property R save() @system { return this; }
    }
    static assert(!__traits(compiles, choose(true, R(), R()).save));
    static assert(!__traits(compiles, choose(true, [0], R()).save));
    static assert(!__traits(compiles, choose(true, R(), [0]).save));
}

//https://issues.dlang.org/show_bug.cgi?id=19738
@safe nothrow pure @nogc unittest
{
    static struct EvilRange
    {
        enum empty = true;
        int front;
        void popFront() @safe {}
        auto opAssign(const ref EvilRange other)
        {
            *(cast(uint*) 0xcafebabe) = 0xdeadbeef;
            return this;
        }
    }

    static assert(!__traits(compiles, () @safe
    {
        auto c1 = choose(true, EvilRange(), EvilRange());
        auto c2 = c1;
        c1 = c2;
    }));
}


// https://issues.dlang.org/show_bug.cgi?id=20495
@safe unittest
{
    static struct KillableRange
    {
        int *item;
        ref int front() { return *item; }
        bool empty() { return *item > 10; }
        void popFront() { ++(*item); }
        this(this)
        {
            assert(item is null || cast(size_t) item > 1000);
            item = new int(*item);
        }
        KillableRange save() { return this; }
    }

    auto kr = KillableRange(new int(1));
    int[] x = [1,2,3,4,5]; // length is first

    auto chosen = choose(true, x, kr);
    auto chosen2 = chosen.save;
}

pure @safe nothrow unittest
{
    static struct S {
        int v;
        @disable this(this);
    }

    auto a = [S(1), S(2), S(3)];
    auto b = [S(4), S(5), S(6)];

    auto chosen = choose(true, a, b);
    assert(chosen.front.v == 1);

    auto chosen2 = choose(false, a, b);
    assert(chosen2.front.v == 4);
}

// https://issues.dlang.org/show_bug.cgi?id=15708
@safe unittest
{
    static struct HasPostblit
    {
        this(this) {}
    }

    static struct Range
    {
        bool empty;
        int front;
        void popFront() {}
        HasPostblit member;
    }

    Range range;
    int[] arr;

    auto chosen = choose(true, range, arr);
    auto copy = chosen;
}

/**
Choose one of multiple ranges at runtime.

The ranges may be different, but they must have compatible element types. The
result is a range that offers the weakest capabilities of all `Ranges`.

Params:
    index = which range to choose, must be less than the number of ranges
    rs = two or more ranges

Returns:
    The indexed range. If rs consists of only one range, the return type is an
    alias of that range's type.
 */
auto chooseAmong(Ranges...)(size_t index, return scope Ranges rs)
if (Ranges.length >= 2
        && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))
        && !is(CommonType!(staticMap!(ElementType, Ranges)) == void))
{
        return ChooseResult!Ranges(index, rs);
}

///
@safe nothrow pure @nogc unittest
{
    auto test()
    {
        import std.algorithm.comparison : equal;

        int[4] sarr1 = [1, 2, 3, 4];
        int[2] sarr2 = [5, 6];
        int[1] sarr3 = [7];
        auto arr1 = sarr1[];
        auto arr2 = sarr2[];
        auto arr3 = sarr3[];

        {
            auto s = chooseAmong(0, arr1, arr2, arr3);
            auto t = s.save;
            assert(s.length == 4);
            assert(s[2] == 3);
            s.popFront();
            assert(equal(t, only(1, 2, 3, 4)));
        }
        {
            auto s = chooseAmong(1, arr1, arr2, arr3);
            assert(s.length == 2);
            s.front = 8;
            assert(equal(s, only(8, 6)));
        }
        {
            auto s = chooseAmong(1, arr1, arr2, arr3);
            assert(s.length == 2);
            s[1] = 9;
            assert(equal(s, only(8, 9)));
        }
        {
            auto s = chooseAmong(1, arr2, arr1, arr3)[1 .. 3];
            assert(s.length == 2);
            assert(equal(s, only(2, 3)));
        }
        {
            auto s = chooseAmong(0, arr1, arr2, arr3);
            assert(s.length == 4);
            assert(s.back == 4);
            s.popBack();
            s.back = 5;
            assert(equal(s, only(1, 2, 5)));
            s.back = 3;
            assert(equal(s, only(1, 2, 3)));
        }
        {
            uint[5] foo = [1, 2, 3, 4, 5];
            uint[5] bar = [6, 7, 8, 9, 10];
            auto c = chooseAmong(1, foo[], bar[]);
            assert(c[3] == 9);
            c[3] = 42;
            assert(c[3] == 42);
            assert(c.moveFront() == 6);
            assert(c.moveBack() == 10);
            assert(c.moveAt(4) == 10);
        }
        {
            import std.range : cycle;
            auto s = chooseAmong(0, cycle(arr2), cycle(arr3));
            assert(isInfinite!(typeof(s)));
            assert(!s.empty);
            assert(s[100] == 8);
            assert(s[101] == 9);
            assert(s[0 .. 3].equal(only(8, 9, 8)));
        }
        return 0;
    }
    // works at runtime
    auto a = test();
    // and at compile time
    static b = test();
}

@safe nothrow pure @nogc unittest
{
    int[3] a = [1, 2, 3];
    long[3] b = [4, 5, 6];
    auto c = chooseAmong(0, a[], b[]);
    c[0] = 42;
    assert(c[0] == 42);
}

@safe nothrow pure @nogc unittest
{
    static struct RefAccessRange
    {
        int[] r;
        ref front() @property { return r[0]; }
        ref back() @property { return r[$ - 1]; }
        void popFront() { r = r[1 .. $]; }
        void popBack() { r = r[0 .. $ - 1]; }
        auto empty() @property { return r.empty; }
        ref opIndex(size_t i) { return r[i]; }
        auto length() @property { return r.length; }
        alias opDollar = length;
        auto save() { return this; }
    }
    static assert(isRandomAccessRange!RefAccessRange);
    static assert(isRandomAccessRange!RefAccessRange);
    int[4] a = [4, 3, 2, 1];
    int[2] b = [6, 5];
    auto c = chooseAmong(0, RefAccessRange(a[]), RefAccessRange(b[]));

    void refFunc(ref int a, int target) { assert(a == target); }

    refFunc(c[2], 2);
    refFunc(c.front, 4);
    refFunc(c.back, 1);
}


/**
$(D roundRobin(r1, r2, r3)) yields `r1.front`, then `r2.front`,
then `r3.front`, after which it pops off one element from each and
continues again from `r1`. For example, if two ranges are involved,
it alternately yields elements off the two ranges. `roundRobin`
stops after it has consumed all ranges (skipping over the ones that
finish early).
 */
auto roundRobin(Rs...)(Rs rs)
if (Rs.length > 1 && allSatisfy!(isInputRange, staticMap!(Unqual, Rs)))
{
    struct Result
    {
        import std.conv : to;

        public Rs source;
        private size_t _current = size_t.max;

        @property bool empty()
        {
            foreach (i, Unused; Rs)
            {
                if (!source[i].empty) return false;
            }
            return true;
        }

        @property auto ref front()
        {
            final switch (_current)
            {
                foreach (i, R; Rs)
                {
                    case i:
                        assert(
                            !source[i].empty,
                            "Attempting to fetch the front of an empty roundRobin"
                        );
                        return source[i].front;
                }
            }
            assert(0);
        }

        void popFront()
        {
            final switch (_current)
            {
                foreach (i, R; Rs)
                {
                    case i:
                        source[i].popFront();
                        break;
                }
            }

            auto next = _current == (Rs.length - 1) ? 0 : (_current + 1);
            final switch (next)
            {
                foreach (i, R; Rs)
                {
                    case i:
                        if (!source[i].empty)
                        {
                            _current = i;
                            return;
                        }
                        if (i == _current)
                        {
                            _current = _current.max;
                            return;
                        }
                        goto case (i + 1) % Rs.length;
                }
            }
        }

        static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs)))
            @property auto save()
            {
                auto saveSource(size_t len)()
                {
                    import std.typecons : tuple;
                    static assert(len > 0);
                    static if (len == 1)
                    {
                        return tuple(source[0].save);
                    }
                    else
                    {
                        return saveSource!(len - 1)() ~
                            tuple(source[len - 1].save);
                    }
                }
                return Result(saveSource!(Rs.length).expand, _current);
            }

        static if (allSatisfy!(hasLength, Rs))
        {
            @property size_t length()
            {
                size_t result;
                foreach (i, R; Rs)
                {
                    result += source[i].length;
                }
                return result;
            }

            alias opDollar = length;
        }
    }

    size_t firstNonEmpty = size_t.max;
    static foreach (i; 0 .. Rs.length)
    {
        if (firstNonEmpty == size_t.max && !rs[i].empty)
            firstNonEmpty = i;
    }

    return Result(rs, firstNonEmpty);
}

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

    int[] a = [ 1, 2, 3 ];
    int[] b = [ 10, 20, 30, 40 ];
    auto r = roundRobin(a, b);
    assert(equal(r, [ 1, 10, 2, 20, 3, 30, 40 ]));
}

/**
 * roundRobin can be used to create "interleave" functionality which inserts
 * an element between each element in a range.
 */
@safe unittest
{
    import std.algorithm.comparison : equal;

    auto interleave(R, E)(R range, E element)
    if ((isInputRange!R && hasLength!R) || isForwardRange!R)
    {
        static if (hasLength!R)
            immutable len = range.length;
        else
            immutable len = range.save.walkLength;

        return roundRobin(
            range,
            element.repeat(len - 1)
        );
    }

    assert(interleave([1, 2, 3], 0).equal([1, 0, 2, 0, 3]));
}

pure @safe unittest
{
    import std.algorithm.comparison : equal;
    string f = "foo", b = "bar";
    auto r = roundRobin(refRange(&f), refRange(&b));
    assert(equal(r.save, "fboaor"));
    assert(equal(r.save, "fboaor"));
}
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;

    static struct S {
        int v;
        @disable this(this);
    }

    S[] a = [ S(1), S(2) ];
    S[] b = [ S(10), S(20) ];
    auto r = roundRobin(a, b);
    assert(equal(r, [ S(1), S(10), S(2), S(20) ]));
}

// https://issues.dlang.org/show_bug.cgi?id=24384
@safe unittest
{
    auto r = roundRobin("", "a");
    assert(!r.empty);
    auto e = r.front;
}

/**
Iterates a random-access range starting from a given point and
progressively extending left and right from that point. If no initial
point is given, iteration starts from the middle of the
range. Iteration spans the entire range.

When `startingIndex` is 0 the range will be fully iterated in order
and in reverse order when `r.length` is given.

Params:
    r = a random access range with length and slicing
    startingIndex = the index to begin iteration from

Returns:
    A forward range with length
 */
auto radial(Range, I)(Range r, I startingIndex)
if (isRandomAccessRange!(Unqual!Range) && hasLength!(Unqual!Range) && hasSlicing!(Unqual!Range) && isIntegral!I)
{
    if (startingIndex != r.length) ++startingIndex;
    return roundRobin(retro(r[0 .. startingIndex]), r[startingIndex .. r.length]);
}

/// Ditto
auto radial(R)(R r)
if (isRandomAccessRange!(Unqual!R) && hasLength!(Unqual!R) && hasSlicing!(Unqual!R))
{
    return .radial(r, (r.length - !r.empty) / 2);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    int[] a = [ 1, 2, 3, 4, 5 ];
    assert(equal(radial(a), [ 3, 4, 2, 5, 1 ]));
    a = [ 1, 2, 3, 4 ];
    assert(equal(radial(a), [ 2, 3, 1, 4 ]));

    // If the left end is reached first, the remaining elements on the right
    // are concatenated in order:
    a = [ 0, 1, 2, 3, 4, 5 ];
    assert(equal(radial(a, 1), [ 1, 2, 0, 3, 4, 5 ]));

    // If the right end is reached first, the remaining elements on the left
    // are concatenated in reverse order:
    assert(equal(radial(a, 4), [ 4, 5, 3, 2, 1, 0 ]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.conv : text;
    import std.exception : enforce;
    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;

    void test(int[] input, int[] witness)
    {
        enforce(equal(radial(input), witness),
                text(radial(input), " vs. ", witness));
    }
    test([], []);
    test([ 1 ], [ 1 ]);
    test([ 1, 2 ], [ 1, 2 ]);
    test([ 1, 2, 3 ], [ 2, 3, 1 ]);
    test([ 1, 2, 3, 4 ], [ 2, 3, 1, 4 ]);
    test([ 1, 2, 3, 4, 5 ], [ 3, 4, 2, 5, 1 ]);
    test([ 1, 2, 3, 4, 5, 6 ], [ 3, 4, 2, 5, 1, 6 ]);

    int[] a = [ 1, 2, 3, 4, 5 ];
    assert(equal(radial(a, 1), [ 2, 3, 1, 4, 5 ]));
    assert(equal(radial(a, 0), [ 1, 2, 3, 4, 5 ])); // only right subrange
    assert(equal(radial(a, a.length), [ 5, 4, 3, 2, 1 ])); // only left subrange
    static assert(isForwardRange!(typeof(radial(a, 1))));

    auto r = radial([1,2,3,4,5]);
    for (auto rr = r.save; !rr.empty; rr.popFront())
    {
        assert(rr.front == moveFront(rr));
    }
    r.front = 5;
    assert(r.front == 5);

    // Test instantiation without lvalue elements.
    DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random) dummy;
    assert(equal(radial(dummy, 4), [5, 6, 4, 7, 3, 8, 2, 9, 1, 10]));

    // immutable int[] immi = [ 1, 2 ];
    // static assert(is(typeof(radial(immi))));
}

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

    auto LL = iota(1L, 6L);
    auto r = radial(LL);
    assert(equal(r, [3L, 4L, 2L, 5L, 1L]));
}

/**
Lazily takes only up to `n` elements of a range. This is
particularly useful when using with infinite ranges.

Unlike $(LREF takeExactly), `take` does not require that there
are `n` or more elements in `input`. As a consequence, length
information is not applied to the result unless `input` also has
length information.

Params:
    input = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    to iterate over up to `n` times
    n = the number of elements to take

Returns:
    At minimum, an input range. If the range offers random access
    and `length`, `take` offers them as well.
 */
Take!R take(R)(R input, size_t n)
if (isInputRange!(Unqual!R))
{
    alias U = Unqual!R;
    static if (is(R T == Take!T))
    {
        import std.algorithm.comparison : min;
        return R(input.source, min(n, input._maxAvailable));
    }
    else static if (!isInfinite!U && hasSlicing!U)
    {
        import std.algorithm.comparison : min;
        return input[0 .. min(n, input.length)];
    }
    else
    {
        return Take!R(input, n);
    }
}

/// ditto
struct Take(Range)
if (isInputRange!(Unqual!Range) &&
    //take _cannot_ test hasSlicing on infinite ranges, because hasSlicing uses
    //take for slicing infinite ranges.
    !((!isInfinite!(Unqual!Range) && hasSlicing!(Unqual!Range)) || is(Range T == Take!T)))
{
    private alias R = Unqual!Range;

    /// User accessible in read and write
    public R source;

    private size_t _maxAvailable;

    alias Source = R;

    /// Range primitives
    @property bool empty()
    {
        return _maxAvailable == 0 || source.empty;
    }

    /// ditto
    @property auto ref front()
    {
        assert(!empty,
            "Attempting to fetch the front of an empty "
            ~ Take.stringof);
        return source.front;
    }

    /// ditto
    void popFront()
    {
        assert(!empty,
            "Attempting to popFront() past the end of a "
            ~ Take.stringof);
        source.popFront();
        --_maxAvailable;
    }

    static if (isForwardRange!R)
        /// ditto
        @property Take save()
        {
            return Take(source.save, _maxAvailable);
        }

    static if (hasAssignableElements!R)
        /// ditto
        @property void front(ElementType!R v)
        {
            import core.lifetime : forward;

            assert(!empty,
                "Attempting to assign to the front of an empty "
                ~ Take.stringof);

            // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
            source.front = __ctfe ? v : forward!v;
        }

    static if (hasMobileElements!R)
    {
        /// ditto
        auto moveFront()
        {
            assert(!empty,
                "Attempting to move the front of an empty "
                ~ Take.stringof);
            return source.moveFront();
        }
    }

    static if (isInfinite!R)
    {
        /// ditto
        @property size_t length() const
        {
            return _maxAvailable;
        }

        /// ditto
        alias opDollar = length;

        //Note: Due to Take/hasSlicing circular dependency,
        //This needs to be a restrained template.
        /// ditto
        auto opSlice()(size_t i, size_t j)
        if (hasSlicing!R)
        {
            assert(i <= j, "Invalid slice bounds");
            assert(j <= length, "Attempting to slice past the end of a "
                ~ Take.stringof);
            return source[i .. j];
        }
    }
    else static if (hasLength!R)
    {
        /// ditto
        @property size_t length()
        {
            import std.algorithm.comparison : min;
            return min(_maxAvailable, source.length);
        }

        alias opDollar = length;
    }

    static if (isRandomAccessRange!R)
    {
        /// ditto
        void popBack()
        {
            assert(!empty,
                "Attempting to popBack() past the beginning of a "
                ~ Take.stringof);
            --_maxAvailable;
        }

        /// ditto
        @property auto ref back()
        {
            assert(!empty,
                "Attempting to fetch the back of an empty "
                ~ Take.stringof);
            return source[this.length - 1];
        }

        /// ditto
        auto ref opIndex(size_t index)
        {
            assert(index < length,
                "Attempting to index out of the bounds of a "
                ~ Take.stringof);
            return source[index];
        }

        static if (hasAssignableElements!R)
        {
            /// ditto
            @property void back(ElementType!R v)
            {
                // This has to return auto instead of void because of
                // https://issues.dlang.org/show_bug.cgi?id=4706
                assert(!empty,
                    "Attempting to assign to the back of an empty "
                    ~ Take.stringof);
                source[this.length - 1] = v;
            }

            /// ditto
            void opIndexAssign(ElementType!R v, size_t index)
            {
                assert(index < length,
                    "Attempting to index out of the bounds of a "
                    ~ Take.stringof);
                source[index] = v;
            }
        }

        static if (hasMobileElements!R)
        {
            /// ditto
            auto moveBack()
            {
                assert(!empty,
                    "Attempting to move the back of an empty "
                    ~ Take.stringof);
                return source.moveAt(this.length - 1);
            }

            /// ditto
            auto moveAt(size_t index)
            {
                assert(index < length,
                    "Attempting to index out of the bounds of a "
                    ~ Take.stringof);
                return source.moveAt(index);
            }
        }
    }

    /**
    Access to maximal length of the range.
    Note: the actual length of the range depends on the underlying range.
    If it has fewer elements, it will stop before maxLength is reached.
    */
    @property size_t maxLength() const
    {
        return _maxAvailable;
    }
}

/// ditto
template Take(R)
if (isInputRange!(Unqual!R) &&
    ((!isInfinite!(Unqual!R) && hasSlicing!(Unqual!R)) || is(R T == Take!T)))
{
    alias Take = R;
}

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

    int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    auto s = take(arr1, 5);
    assert(s.length == 5);
    assert(s[4] == 5);
    assert(equal(s, [ 1, 2, 3, 4, 5 ][]));
}

/**
 * If the range runs out before `n` elements, `take` simply returns the entire
 * range (unlike $(LREF takeExactly), which will cause an assertion failure if
 * the range ends prematurely):
 */
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;

    int[] arr2 = [ 1, 2, 3 ];
    auto t = take(arr2, 5);
    assert(t.length == 3);
    assert(equal(t, [ 1, 2, 3 ]));
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;

    int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    auto s = take(arr1, 5);
    assert(s.length == 5);
    assert(s[4] == 5);
    assert(equal(s, [ 1, 2, 3, 4, 5 ][]));
    assert(equal(retro(s), [ 5, 4, 3, 2, 1 ][]));

    // Test fix for bug 4464.
    static assert(is(typeof(s) == Take!(int[])));
    static assert(is(typeof(s) == int[]));

    // Test using narrow strings.
    import std.exception : assumeWontThrow;

    auto myStr = "This is a string.";
    auto takeMyStr = take(myStr, 7);
    assert(assumeWontThrow(equal(takeMyStr, "This is")));
    // Test fix for bug 5052.
    auto takeMyStrAgain = take(takeMyStr, 4);
    assert(assumeWontThrow(equal(takeMyStrAgain, "This")));
    static assert(is (typeof(takeMyStrAgain) == typeof(takeMyStr)));
    takeMyStrAgain = take(takeMyStr, 10);
    assert(assumeWontThrow(equal(takeMyStrAgain, "This is")));

    foreach (DummyType; AllDummyRanges)
    {
        DummyType dummy;
        auto t = take(dummy, 5);
        alias T = typeof(t);

        static if (isRandomAccessRange!DummyType)
        {
            static assert(isRandomAccessRange!T);
            assert(t[4] == 5);

            assert(moveAt(t, 1) == t[1]);
            assert(t.back == moveBack(t));
        }
        else static if (isForwardRange!DummyType)
        {
            static assert(isForwardRange!T);
        }

        for (auto tt = t; !tt.empty; tt.popFront())
        {
            assert(tt.front == moveFront(tt));
        }

        // Bidirectional ranges can't be propagated properly if they don't
        // also have random access.

        assert(equal(t, [1,2,3,4,5]));

        //Test that take doesn't wrap the result of take.
        assert(take(t, 4) == take(dummy, 4));
    }

    immutable myRepeat = repeat(1);
    static assert(is(Take!(typeof(myRepeat))));
}

pure @safe nothrow @nogc unittest
{
    //check for correct slicing of Take on an infinite range
    import std.algorithm.comparison : equal;
    foreach (start; 0 .. 4)
        foreach (stop; start .. 4)
            assert(iota(4).cycle.take(4)[start .. stop]
                .equal(iota(start, stop)));
}

pure @safe nothrow @nogc unittest
{
    // Check that one can declare variables of all Take types,
    // and that they match the return type of the corresponding
    // take().
    // See https://issues.dlang.org/show_bug.cgi?id=4464
    int[] r1;
    Take!(int[]) t1;
    t1 = take(r1, 1);
    assert(t1.empty);

    string r2;
    Take!string t2;
    t2 = take(r2, 1);
    assert(t2.empty);

    Take!(Take!string) t3;
    t3 = take(t2, 1);
    assert(t3.empty);
}

pure @safe nothrow @nogc unittest
{
    alias R1 = typeof(repeat(1));
    alias R2 = typeof(cycle([1]));
    alias TR1 = Take!R1;
    alias TR2 = Take!R2;
    static assert(isBidirectionalRange!TR1);
    static assert(isBidirectionalRange!TR2);
}

// https://issues.dlang.org/show_bug.cgi?id=12731
pure @safe nothrow @nogc unittest
{
    auto a = repeat(1);
    auto s = a[1 .. 5];
    s = s[1 .. 3];
    assert(s.length == 2);
    assert(s[0] == 1);
    assert(s[1] == 1);
}

// https://issues.dlang.org/show_bug.cgi?id=13151
pure @safe nothrow @nogc unittest
{
    import std.algorithm.comparison : equal;

    auto r = take(repeat(1, 4), 3);
    assert(r.take(2).equal(repeat(1, 2)));
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    import std.algorithm.iteration : filter;

    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)];
    auto range = arr[].filter!(a => true)().take(3);

    called = false;
    range.front = Handle(42);
    assert(called);
}

/**
Similar to $(LREF take), but assumes that `range` has at least $(D
n) elements. Consequently, the result of $(D takeExactly(range, n))
always defines the `length` property (and initializes it to `n`)
even when `range` itself does not define `length`.

The result of `takeExactly` is identical to that of $(LREF take) in
cases where the original range defines `length` or is infinite.

Unlike $(LREF take), however, it is illegal to pass a range with less than
`n` elements to `takeExactly`; this will cause an assertion failure.
 */
auto takeExactly(R)(R range, size_t n)
if (isInputRange!R)
{
    static if (is(typeof(takeExactly(range._input, n)) == R))
    {
        assert(n <= range._n,
               "Attempted to take more than the length of the range with takeExactly.");
        // takeExactly(takeExactly(r, n1), n2) has the same type as
        // takeExactly(r, n1) and simply returns takeExactly(r, n2)
        range._n = n;
        return range;
    }
    //Also covers hasSlicing!R for finite ranges.
    else static if (hasLength!R)
    {
        assert(n <= range.length,
               "Attempted to take more than the length of the range with takeExactly.");
        return take(range, n);
    }
    else static if (isInfinite!R)
        return Take!R(range, n);
    else
    {
        static struct Result
        {
            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; }
            @property size_t length() const { return _n; }
            alias opDollar = length;

            @property auto _takeExactly_Result_asTake()
            {
                return take(_input, _n);
            }

            alias _takeExactly_Result_asTake this;

            static if (isForwardRange!R)
                @property auto save()
                {
                    return Result(_input.save, _n);
                }

            static if (hasMobileElements!R)
            {
                auto moveFront()
                {
                    assert(!empty,
                        "Attempting to move the front of an empty "
                        ~ typeof(this).stringof);
                    return _input.moveFront();
                }
            }

            static if (hasAssignableElements!R)
            {
                @property auto ref front(ElementType!R v)
                {
                    import core.lifetime : forward;

                    assert(!empty,
                        "Attempting to assign to the front of an empty "
                        ~ typeof(this).stringof);

                    // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                    return _input.front = __ctfe ? v : forward!v;
                }
            }
        }

        return Result(range, n);
    }
}

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

    auto a = [ 1, 2, 3, 4, 5 ];

    auto b = takeExactly(a, 3);
    assert(equal(b, [1, 2, 3]));
    static assert(is(typeof(b.length) == size_t));
    assert(b.length == 3);
    assert(b.front == 1);
    assert(b.back == 3);
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter;

    auto a = [ 1, 2, 3, 4, 5 ];
    auto b = takeExactly(a, 3);
    assert(equal(b, [1, 2, 3]));
    auto c = takeExactly(b, 2);
    assert(equal(c, [1, 2]));



    auto d = filter!"a > 2"(a);
    auto e = takeExactly(d, 3);
    assert(equal(e, [3, 4, 5]));
    static assert(is(typeof(e.length) == size_t));
    assert(e.length == 3);
    assert(e.front == 3);

    assert(equal(takeExactly(e, 3), [3, 4, 5]));
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;

    auto a = [ 1, 2, 3, 4, 5 ];
    //Test that take and takeExactly are the same for ranges which define length
    //but aren't sliceable.
    struct L
    {
        @property auto front() { return _arr[0]; }
        @property bool empty() { return _arr.empty; }
        void popFront() { _arr.popFront(); }
        @property size_t length() { return _arr.length; }
        int[] _arr;
    }
    static assert(is(typeof(take(L(a), 3)) == typeof(takeExactly(L(a), 3))));
    assert(take(L(a), 3) == takeExactly(L(a), 3));

    //Test that take and takeExactly are the same for ranges which are sliceable.
    static assert(is(typeof(take(a, 3)) == typeof(takeExactly(a, 3))));
    assert(take(a, 3) == takeExactly(a, 3));

    //Test that take and takeExactly are the same for infinite ranges.
    auto inf = repeat(1);
    static assert(is(typeof(take(inf, 5)) == Take!(typeof(inf))));
    assert(take(inf, 5) == takeExactly(inf, 5));

    //Test that take and takeExactly are _not_ the same for ranges which don't
    //define length.
    static assert(!is(typeof(take(filter!"true"(a), 3)) == typeof(takeExactly(filter!"true"(a), 3))));

    foreach (DummyType; AllDummyRanges)
    {
        {
            DummyType dummy;
            auto t = takeExactly(dummy, 5);

            //Test that takeExactly doesn't wrap the result of takeExactly.
            assert(takeExactly(t, 4) == takeExactly(dummy, 4));
        }

        static if (hasMobileElements!DummyType)
        {
            {
                auto t = takeExactly(DummyType.init, 4);
                assert(t.moveFront() == 1);
                assert(equal(t, [1, 2, 3, 4]));
            }
        }

        static if (hasAssignableElements!DummyType)
        {
            {
                auto t = takeExactly(DummyType.init, 4);
                t.front = 9;
                assert(equal(t, [9, 2, 3, 4]));
            }
        }
    }
}

pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;

    alias DummyType = DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward);
    auto te = takeExactly(DummyType(), 5);
    Take!DummyType t = te;
    assert(equal(t, [1, 2, 3, 4, 5]));
    assert(equal(t, te));
}

// https://issues.dlang.org/show_bug.cgi?id=18092
// can't combine take and takeExactly
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;

    static foreach (Range; AllDummyRanges)
    {{
        Range r;
        assert(r.take(6).takeExactly(2).equal([1, 2]));
        assert(r.takeExactly(6).takeExactly(2).equal([1, 2]));
        assert(r.takeExactly(6).take(2).equal([1, 2]));
    }}
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    import std.algorithm.iteration : filter;

    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[5] arr = [Handle(0), Handle(1), Handle(2), Handle(3), Handle(4)];
    auto range = arr[].filter!(a => true)().takeExactly(3);

    called = false;
    range.front = Handle(42);
    assert(called);
}

/**
Returns a range with at most one element; for example, $(D
takeOne([42, 43, 44])) returns a range consisting of the integer $(D
42). Calling `popFront()` off that range renders it empty.

In effect `takeOne(r)` is somewhat equivalent to $(D take(r, 1)) but in
certain interfaces it is important to know statically that the range may only
have at most one element.

The type returned by `takeOne` is a random-access range with length
regardless of `R`'s capabilities, as long as it is a forward range.
(another feature that distinguishes `takeOne` from `take`). If
(D R) is an input range but not a forward range, return type is an input
range with all random-access capabilities except save.
 */
auto takeOne(R)(R source)
if (isInputRange!R)
{
    static if (hasSlicing!R)
    {
        return source[0 .. !source.empty];
    }
    else
    {
        static struct Result
        {
            private R _source;
            private bool _empty = true;
            @property bool empty() const { return _empty; }
            @property auto ref front()
            {
                assert(!empty, "Attempting to fetch the front of an empty takeOne");
                return _source.front;
            }
            void popFront()
            {
                assert(!empty, "Attempting to popFront an empty takeOne");
                _source.popFront();
                _empty = true;
            }
            void popBack()
            {
                assert(!empty, "Attempting to popBack an empty takeOne");
                _source.popFront();
                _empty = true;
            }
            static if (isForwardRange!(Unqual!R))
            {
                @property auto save() { return Result(_source.save, empty); }
            }
            @property auto ref back()
            {
                assert(!empty, "Attempting to fetch the back of an empty takeOne");
                return _source.front;
            }
            @property size_t length() const { return !empty; }
            alias opDollar = length;
            auto ref opIndex(size_t n)
            {
                assert(n < length, "Attempting to index a takeOne out of bounds");
                return _source.front;
            }
            auto opSlice(size_t m, size_t n)
            {
                assert(
                    m <= n,
                    "Attempting to slice a takeOne range with a larger first argument than the second."
                );
                assert(
                    n <= length,
                    "Attempting to slice using an out of bounds index on a takeOne range."
                    );
                return n > m ? this : Result(_source, true);
            }
            // Non-standard property
            @property R source() { return _source; }
        }

        return Result(source, source.empty);
    }
}

///
pure @safe nothrow unittest
{
    auto s = takeOne([42, 43, 44]);
    static assert(isRandomAccessRange!(typeof(s)));
    assert(s.length == 1);
    assert(!s.empty);
    assert(s.front == 42);
    s.front = 43;
    assert(s.front == 43);
    assert(s.back == 43);
    assert(s[0] == 43);
    s.popFront();
    assert(s.length == 0);
    assert(s.empty);
}

pure @safe nothrow @nogc unittest
{
    struct NonForwardRange
    {
        enum empty = false;
        int front() { return 42; }
        void popFront() {}
    }

    static assert(!isForwardRange!NonForwardRange);

    auto s = takeOne(NonForwardRange());
    assert(s.length == 1);
    assert(!s.empty);
    assert(s.front == 42);
    assert(s.back == 42);
    assert(s[0] == 42);

    auto t = s[0 .. 0];
    assert(t.empty);
    assert(t.length == 0);

    auto u = s[1 .. 1];
    assert(u.empty);
    assert(u.length == 0);

    auto v = s[0 .. 1];
    s.popFront();
    assert(s.length == 0);
    assert(s.empty);
    assert(!v.empty);
    assert(v.front == 42);
    v.popBack();
    assert(v.empty);
    assert(v.length == 0);
}

pure @safe nothrow @nogc unittest
{
    struct NonSlicingForwardRange
    {
        enum empty = false;
        int front() { return 42; }
        void popFront() {}
        @property auto save() { return this; }
    }

    static assert(isForwardRange!NonSlicingForwardRange);
    static assert(!hasSlicing!NonSlicingForwardRange);

    auto s = takeOne(NonSlicingForwardRange());
    assert(s.length == 1);
    assert(!s.empty);
    assert(s.front == 42);
    assert(s.back == 42);
    assert(s[0] == 42);
    auto t = s.save;
    s.popFront();
    assert(s.length == 0);
    assert(s.empty);
    assert(!t.empty);
    assert(t.front == 42);
    t.popBack();
    assert(t.empty);
    assert(t.length == 0);
}

// Test that asserts trigger correctly
@system unittest
{
    import std.exception : assertThrown;
    import core.exception : AssertError;

    struct NonForwardRange
    {
        enum empty = false;
        int front() { return 42; }
        void popFront() {}
    }

    auto s = takeOne(NonForwardRange());

    assertThrown!AssertError(s[1]);
    assertThrown!AssertError(s[0 .. 2]);

    size_t one = 1;     // Avoid style warnings triggered by literals
    size_t zero = 0;
    assertThrown!AssertError(s[one .. zero]);

    s.popFront;
    assert(s.empty);
    assertThrown!AssertError(s.front);
    assertThrown!AssertError(s.back);
    assertThrown!AssertError(s.popFront);
    assertThrown!AssertError(s.popBack);
}

// https://issues.dlang.org/show_bug.cgi?id=16999
pure @safe unittest
{
    auto myIota = new class
    {
        int front = 0;
        @safe void popFront(){front++;}
        enum empty = false;
    };
    auto iotaPart = myIota.takeOne;
    int sum;
    foreach (var; chain(iotaPart, iotaPart, iotaPart))
    {
        sum += var;
    }
    assert(sum == 3);
    assert(iotaPart.front == 3);
}

/++
    Returns an empty range which is statically known to be empty and is
    guaranteed to have `length` and be random access regardless of `R`'s
    capabilities.
  +/
auto takeNone(R)()
if (isInputRange!R)
{
    return typeof(takeOne(R.init)).init;
}

///
pure @safe nothrow @nogc unittest
{
    auto range = takeNone!(int[])();
    assert(range.length == 0);
    assert(range.empty);
}

pure @safe nothrow @nogc unittest
{
    enum ctfe = takeNone!(int[])();
    static assert(ctfe.length == 0);
    static assert(ctfe.empty);
}


/++
    Creates an empty range from the given range in $(BIGOH 1). If it can, it
    will return the same range type. If not, it will return
    $(D takeExactly(range, 0)).
  +/
auto takeNone(R)(R range)
if (isInputRange!R)
{
    import std.traits : isDynamicArray;
    //Makes it so that calls to takeNone which don't use UFCS still work with a
    //member version if it's defined.
    static if (is(typeof(R.takeNone)))
        auto retval = range.takeNone();
    // https://issues.dlang.org/show_bug.cgi?id=8339
    else static if (isDynamicArray!R)/+ ||
                   (is(R == struct) && __traits(compiles, {auto r = R.init;}) && R.init.empty))+/
    {
        auto retval = R.init;
    }
    //An infinite range sliced at [0 .. 0] would likely still not be empty...
    else static if (hasSlicing!R && !isInfinite!R)
        auto retval = range[0 .. 0];
    else
        auto retval = takeExactly(range, 0);

    // https://issues.dlang.org/show_bug.cgi?id=7892 prevents this from being
    // done in an out block.
    assert(retval.empty);
    return retval;
}

///
pure @safe nothrow unittest
{
    import std.algorithm.iteration : filter;
    assert(takeNone([42, 27, 19]).empty);
    assert(takeNone("dlang.org").empty);
    assert(takeNone(filter!"true"([42, 27, 19])).empty);
}

@safe unittest
{
    import std.algorithm.iteration : filter;
    import std.meta : AliasSeq;

    struct Dummy
    {
        mixin template genInput()
        {
        @safe:
            @property bool empty() { return _arr.empty; }
            @property auto front() { return _arr.front; }
            void popFront() { _arr.popFront(); }
            static assert(isInputRange!(typeof(this)));
        }
    }
    alias genInput = Dummy.genInput;

    static struct NormalStruct
    {
        //Disabled to make sure that the takeExactly version is used.
        @disable this();
        this(int[] arr) { _arr = arr; }
        mixin genInput;
        int[] _arr;
    }

    static struct SliceStruct
    {
        @disable this();
        this(int[] arr) { _arr = arr; }
        mixin genInput;
        @property auto save() { return this; }
        auto opSlice(size_t i, size_t j) { return typeof(this)(_arr[i .. j]); }
        @property size_t length() { return _arr.length; }
        int[] _arr;
    }

    static struct InitStruct
    {
        mixin genInput;
        int[] _arr;
    }

    static struct TakeNoneStruct
    {
        this(int[] arr) { _arr = arr; }
        @disable this();
        mixin genInput;
        auto takeNone() { return typeof(this)(null); }
        int[] _arr;
    }

    static class NormalClass
    {
        this(int[] arr) {_arr = arr;}
        mixin genInput;
        int[] _arr;
    }

    static class SliceClass
    {
    @safe:
        this(int[] arr) { _arr = arr; }
        mixin genInput;
        @property auto save() { return new typeof(this)(_arr); }
        auto opSlice(size_t i, size_t j) { return new typeof(this)(_arr[i .. j]); }
        @property size_t length() { return _arr.length; }
        int[] _arr;
    }

    static class TakeNoneClass
    {
    @safe:
        this(int[] arr) { _arr = arr; }
        mixin genInput;
        auto takeNone() { return new typeof(this)(null); }
        int[] _arr;
    }

    import std.format : format;

    static foreach (range; AliasSeq!([1, 2, 3, 4, 5],
                             "hello world",
                             "hello world"w,
                             "hello world"d,
                             SliceStruct([1, 2, 3]),
                             // https://issues.dlang.org/show_bug.cgi?id=8339
                             // forces this to be takeExactly `InitStruct([1, 2, 3]),
                             TakeNoneStruct([1, 2, 3])))
    {
        static assert(takeNone(range).empty, typeof(range).stringof);
        assert(takeNone(range).empty);
        static assert(is(typeof(range) == typeof(takeNone(range))), typeof(range).stringof);
    }

    static foreach (range; AliasSeq!(NormalStruct([1, 2, 3]),
                             InitStruct([1, 2, 3])))
    {
        static assert(takeNone(range).empty, typeof(range).stringof);
        assert(takeNone(range).empty);
        static assert(is(typeof(takeExactly(range, 0)) == typeof(takeNone(range))), typeof(range).stringof);
    }

    //Don't work in CTFE.
    auto normal = new NormalClass([1, 2, 3]);
    assert(takeNone(normal).empty);
    static assert(is(typeof(takeExactly(normal, 0)) == typeof(takeNone(normal))), typeof(normal).stringof);

    auto slice = new SliceClass([1, 2, 3]);
    assert(takeNone(slice).empty);
    static assert(is(SliceClass == typeof(takeNone(slice))), typeof(slice).stringof);

    auto taken = new TakeNoneClass([1, 2, 3]);
    assert(takeNone(taken).empty);
    static assert(is(TakeNoneClass == typeof(takeNone(taken))), typeof(taken).stringof);

    auto filtered = filter!"true"([1, 2, 3, 4, 5]);
    assert(takeNone(filtered).empty);
    // https://issues.dlang.org/show_bug.cgi?id=8339 and
    // https://issues.dlang.org/show_bug.cgi?id=5941 force this to be takeExactly
    //static assert(is(typeof(filtered) == typeof(takeNone(filtered))), typeof(filtered).stringof);
}

/++
 + Return a range advanced to within `_n` elements of the end of
 + `range`.
 +
 + Intended as the range equivalent of the Unix
 + $(HTTP en.wikipedia.org/wiki/Tail_%28Unix%29, _tail) utility. When the length
 + of `range` is less than or equal to `_n`, `range` is returned
 + as-is.
 +
 + Completes in $(BIGOH 1) steps for ranges that support slicing and have
 + length. Completes in $(BIGOH range.length) time for all other ranges.
 +
 + Params:
 +    range = range to get _tail of
 +    n = maximum number of elements to include in _tail
 +
 + Returns:
 +    Returns the _tail of `range` augmented with length information
 +/
auto tail(Range)(Range range, size_t n)
if (isInputRange!Range && !isInfinite!Range &&
    (hasLength!Range || isForwardRange!Range))
{
    static if (hasLength!Range)
    {
        immutable length = range.length;
        if (n >= length)
            return range.takeExactly(length);
        else
            return range.drop(length - n).takeExactly(n);
    }
    else
    {
        Range scout = range.save;
        foreach (immutable i; 0 .. n)
        {
            if (scout.empty)
                return range.takeExactly(i);
            scout.popFront();
        }

        auto tail = range.save;
        while (!scout.empty)
        {
            assert(!tail.empty);
            scout.popFront();
            tail.popFront();
        }

        return tail.takeExactly(n);
    }
}

///
pure @safe nothrow unittest
{
    // tail -c n
    assert([1, 2, 3].tail(1) == [3]);
    assert([1, 2, 3].tail(2) == [2, 3]);
    assert([1, 2, 3].tail(3) == [1, 2, 3]);
    assert([1, 2, 3].tail(4) == [1, 2, 3]);
    assert([1, 2, 3].tail(0).length == 0);

    // tail --lines=n
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : joiner;
    import std.exception : assumeWontThrow;
    import std.string : lineSplitter;
    assert("one\ntwo\nthree"
        .lineSplitter
        .tail(2)
        .joiner("\n")
        .equal("two\nthree")
        .assumeWontThrow);
}

// @nogc prevented by https://issues.dlang.org/show_bug.cgi?id=15408
pure nothrow @safe /+@nogc+/ unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges, DummyRange, Length,
        RangeType, ReturnBy;

    static immutable cheatsheet = [6, 7, 8, 9, 10];

    foreach (R; AllDummyRanges)
    {
        static if (isInputRange!R && !isInfinite!R &&
                   (hasLength!R || isForwardRange!R))
        {
            assert(R.init.tail(5).equal(cheatsheet));
            static assert(R.init.tail(5).equal(cheatsheet));

            assert(R.init.tail(0).length == 0);
            assert(R.init.tail(10).equal(R.init));
            assert(R.init.tail(11).equal(R.init));
        }
    }

    // Infinite ranges are not supported
    static assert(!__traits(compiles, repeat(0).tail(0)));

    // Neither are non-forward ranges without length
    static assert(!__traits(compiles, DummyRange!(ReturnBy.Value, Length.No,
        RangeType.Input).init.tail(5)));
}

pure @safe nothrow @nogc unittest
{
    static immutable input = [1, 2, 3];
    static immutable expectedOutput = [2, 3];
    assert(input.tail(2) == expectedOutput);
}

/++
    Convenience function which calls
    $(REF popFrontN, std, range, primitives)`(range, n)` and returns `range`.
    `drop` makes it easier to pop elements from a range
    and then pass it to another function within a single expression,
    whereas `popFrontN` would require multiple statements.

    `dropBack` provides the same functionality but instead calls
    $(REF popBackN, std, range, primitives)`(range, n)`

    Note: `drop` and `dropBack` will only pop $(I up to)
    `n` elements but will stop if the range is empty first.
    In other languages this is sometimes called `skip`.

    Params:
        range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to drop from
        n = the number of elements to drop

    Returns:
        `range` with up to `n` elements dropped

    See_Also:
        $(REF popFront, std, range, primitives), $(REF popBackN, std, range, primitives)
  +/
R drop(R)(R range, size_t n)
if (isInputRange!R)
{
    range.popFrontN(n);
    return range;
}

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

    assert([0, 2, 1, 5, 0, 3].drop(3) == [5, 0, 3]);
    assert("hello world".drop(6) == "world");
    assert("hello world".drop(50).empty);
    assert("hello world".take(6).drop(3).equal("lo "));
}

/// ditto
R dropBack(R)(R range, size_t n)
if (isBidirectionalRange!R)
{
    range.popBackN(n);
    return range;
}

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

    assert([0, 2, 1, 5, 0, 3].dropBack(3) == [0, 2, 1]);
    assert("hello world".dropBack(6) == "hello");
    assert("hello world".dropBack(50).empty);
    assert("hello world".drop(4).dropBack(4).equal("o w"));
}

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

    //Remove all but the first two elements
    auto a = DList!int(0, 1, 9, 9, 9, 9);
    a.remove(a[].drop(2));
    assert(a[].equal(a[].take(2)));
}

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

    assert(drop("", 5).empty);
    assert(equal(drop(filter!"true"([0, 2, 1, 5, 0, 3]), 3), [5, 0, 3]));
}

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

    //insert before the last two elements
    auto a = DList!int(0, 1, 2, 5, 6);
    a.insertAfter(a[].dropBack(2), [3, 4]);
    assert(a[].equal(iota(0, 7)));
}

/++
    Similar to $(LREF drop) and `dropBack` but they call
    $(D range.$(LREF popFrontExactly)(n)) and `range.popBackExactly(n)`
    instead.

    Note: Unlike `drop`, `dropExactly` will assume that the
    range holds at least `n` elements. This makes `dropExactly`
    faster than `drop`, 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.

    Params:
        range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to drop from
        n = the number of elements to drop

    Returns:
        `range` with `n` elements dropped

    See_Also:
        $(REF popFrontExcatly, std, range, primitives),
        $(REF popBackExcatly, std, range, primitives)
+/
R dropExactly(R)(R range, size_t n)
if (isInputRange!R)
{
    popFrontExactly(range, n);
    return range;
}
/// ditto
R dropBackExactly(R)(R range, size_t n)
if (isBidirectionalRange!R)
{
    popBackExactly(range, n);
    return range;
}

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

    auto a = [1, 2, 3];
    assert(a.dropExactly(2) == [3]);
    assert(a.dropBackExactly(2) == [1]);

    string s = "日本語";
    assert(s.dropExactly(2) == "語");
    assert(s.dropBackExactly(2) == "日");

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

/++
    Convenience function which calls
    `range.popFront()` and returns `range`. `dropOne`
    makes it easier to pop an element from a range
    and then pass it to another function within a single expression,
    whereas `popFront` would require multiple statements.

    `dropBackOne` provides the same functionality but instead calls
    `range.popBack()`.
+/
R dropOne(R)(R range)
if (isInputRange!R)
{
    range.popFront();
    return range;
}
/// ditto
R dropBackOne(R)(R range)
if (isBidirectionalRange!R)
{
    range.popBack();
    return range;
}

///
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filterBidirectional;
    import std.container.dlist : DList;

    auto dl = DList!int(9, 1, 2, 3, 9);
    assert(dl[].dropOne().dropBackOne().equal([1, 2, 3]));

    auto a = [1, 2, 3];
    assert(a.dropOne() == [2, 3]);
    assert(a.dropBackOne() == [1, 2]);

    string s = "日本語";
    import std.exception : assumeWontThrow;
    assert(assumeWontThrow(s.dropOne() == "本語"));
    assert(assumeWontThrow(s.dropBackOne() == "日本"));

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

/**
Create a range which repeats one value.

Params:
    value = the _value to repeat
    n = the number of times to repeat `value`

Returns:
    If `n` is not defined, an infinite random access range
    with slicing.

    If `n` is defined, a random access range with slicing.
*/
struct Repeat(T)
{
private:
    import std.typecons : Rebindable2;

    // Store a rebindable T to make Repeat assignable.
    Rebindable2!T _value;

public:
    /// Range primitives
    @property inout(T) front() inout { return _value.get; }

    /// ditto
    @property inout(T) back() inout { return _value.get; }

    /// ditto
    enum bool empty = false;

    /// ditto
    void popFront() {}

    /// ditto
    void popBack() {}

    /// ditto
    @property auto save() inout { return this; }

    /// ditto
    inout(T) opIndex(size_t) inout { return _value.get; }

    /// ditto
    auto opSlice(size_t i, size_t j)
    in
    {
        assert(
            i <= j,
            "Attempting to slice a Repeat with a larger first argument than the second."
        );
    }
    do
    {
        return this.takeExactly(j - i);
    }
    private static struct DollarToken {}

    /// ditto
    enum opDollar = DollarToken.init;

    /// ditto
    auto opSlice(size_t, DollarToken) inout { return this; }
}

/// Ditto
Repeat!T repeat(T)(T value)
{
    import std.typecons : Rebindable2;

    return Repeat!T(Rebindable2!T(value));
}

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

    assert(5.repeat().take(4).equal([5, 5, 5, 5]));
}

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

    auto  r = repeat(5);
    alias R = typeof(r);
    static assert(isBidirectionalRange!R);
    static assert(isForwardRange!R);
    static assert(isInfinite!R);
    static assert(hasSlicing!R);

    assert(r.back == 5);
    assert(r.front == 5);
    assert(r.take(4).equal([ 5, 5, 5, 5 ]));
    assert(r[0 .. 4].equal([ 5, 5, 5, 5 ]));

    R r2 = r[5 .. $];
    assert(r2.back == 5);
    assert(r2.front == 5);
}

/// ditto
Take!(Repeat!T) repeat(T)(T value, size_t n)
{
    return take(repeat(value), n);
}

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

    assert(5.repeat(4).equal([5, 5, 5, 5]));
}

// https://issues.dlang.org/show_bug.cgi?id=12007
pure @safe nothrow unittest
{
    static class C{}
    Repeat!(immutable int) ri;
    ri = ri.save;
    Repeat!(immutable C) rc;
    rc = rc.save;

    import std.algorithm.setops : cartesianProduct;
    import std.algorithm.comparison : equal;
    import std.typecons : tuple;
    immutable int[] A = [1,2,3];
    immutable int[] B = [4,5,6];

    assert(equal(cartesianProduct(A,B),
        [
            tuple(1, 4), tuple(1, 5), tuple(1, 6),
            tuple(2, 4), tuple(2, 5), tuple(2, 6),
            tuple(3, 4), tuple(3, 5), tuple(3, 6),
        ]));
}

/**
Given callable ($(REF isCallable, std,traits)) `fun`, create as a range
whose front is defined by successive calls to `fun()`.
This is especially useful to call function with global side effects (random
functions), or to create ranges expressed as a single delegate, rather than
an entire `front`/`popFront`/`empty` structure.
`fun` maybe be passed either a template alias parameter (existing
function, delegate, struct type defining `static opCall`) or
a run-time value argument (delegate, function object).
The result range models an InputRange
($(REF isInputRange, std,range,primitives)).
The resulting range will call `fun()` on construction, and every call to
`popFront`, and the cached value will be returned when `front` is called.

Returns: an `inputRange` where each element represents another call to fun.
*/
auto generate(Fun)(Fun fun)
if (isCallable!fun)
{
    auto gen = Generator!(Fun)(fun);
    gen.popFront(); // prime the first element
    return gen;
}

/// ditto
auto generate(alias fun)()
if (isCallable!fun)
{
    auto gen = Generator!(fun)();
    gen.popFront(); // prime the first element
    return gen;
}

///
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;

    int i = 1;
    auto powersOfTwo = generate!(() => i *= 2)().take(10);
    assert(equal(powersOfTwo, iota(1, 11).map!"2^^a"()));
}

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

    //Returns a run-time delegate
    auto infiniteIota(T)(T low, T high)
    {
        T i = high;
        return (){if (i == high) i = low; return i++;};
    }
    //adapted as a range.
    assert(equal(generate(infiniteIota(1, 4)).take(10), [1, 2, 3, 1, 2, 3, 1, 2, 3, 1]));
}

///
@safe unittest
{
    import std.format : format;
    import std.random : uniform;

    auto r = generate!(() => uniform(0, 6)).take(10);
    format("%(%s %)", r);
}

private struct Generator(Fun...)
{
    static assert(Fun.length == 1);
    static assert(isInputRange!Generator);
    import std.traits : FunctionAttribute, functionAttributes, ReturnType;

private:
    static if (is(Fun[0]))
        Fun[0] fun;
    else
        alias fun = Fun[0];

    enum returnByRef_ = (functionAttributes!fun & FunctionAttribute.ref_) ? true : false;

    import std.traits : hasIndirections;
    static if (!hasIndirections!(ReturnType!fun))
        alias RetType = Unqual!(ReturnType!fun);
    else
        alias RetType = ReturnType!fun;

    static if (returnByRef_)
        RetType *elem_;
    else
        RetType elem_;
public:
    /// Range primitives
    enum empty = false;

    static if (returnByRef_)
    {
        /// ditto
        ref front() @property
        {
            return *elem_;
        }
        /// ditto
        void popFront()
        {
            elem_ = &fun();
        }
    }
    else
    {
        /// ditto
        auto front() @property
        {
            return elem_;
        }
        /// ditto
        void popFront()
        {
            elem_ = fun();
        }
    }
}

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

    struct StaticOpCall
    {
        static ubyte opCall() { return 5 ; }
    }

    assert(equal(generate!StaticOpCall().take(10), repeat(5).take(10)));
}

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

    struct OpCall
    {
        ubyte opCall() @safe pure { return 5 ; }
    }

    OpCall op;
    assert(equal(generate(op).take(10), repeat(5).take(10)));
}

// verify ref mechanism works
@system nothrow unittest
{
    int[10] arr;
    int idx;

    ref int fun() {
        auto x = idx++;
        idx %= arr.length;
        return arr[x];
    }
    int y = 1;
    foreach (ref x; generate!(fun).take(20))
    {
        x += y++;
    }
    import std.algorithm.comparison : equal;
    assert(equal(arr[], iota(12, 32, 2)));
}

// assure front isn't the mechanism to make generate go to the next element.
@safe unittest
{
    int i;
    auto g = generate!(() => ++i);
    auto f = g.front;
    assert(f == g.front);
    g = g.drop(5); // reassign because generate caches
    assert(g.front == f + 5);
}

// https://issues.dlang.org/show_bug.cgi?id=23319
@safe pure nothrow unittest
{
    auto b = generate!(() => const(int)(42));
    assert(b.front == 42);
}

/**
Repeats the given forward range ad infinitum. If the original range is
infinite (fact that would make `Cycle` the identity application),
`Cycle` detects that and aliases itself to the range type
itself. That works for non-forward ranges too.
If the original range has random access, `Cycle` offers
random access and also offers a constructor taking an initial position
`index`. `Cycle` works with static arrays in addition to ranges,
mostly for performance reasons.

Note: The input range must not be empty.

Tip: This is a great way to implement simple circular buffers.
*/
struct Cycle(R)
if (isForwardRange!R && !isInfinite!R)
{
    static if (isRandomAccessRange!R && hasLength!R)
    {
        private R _original;
        private size_t _index;

        /// Range primitives
        this(R input, size_t index = 0)
        {
            _original = input;
            _index = index % _original.length;
        }

        /// ditto
        @property auto ref front()
        {
            return _original[_index];
        }

        static if (is(typeof((cast(const R)_original)[_index])))
        {
            /// ditto
            @property auto ref front() const
            {
                return _original[_index];
            }
        }

        static if (hasAssignableElements!R)
        {
            /// ditto
            @property void front(ElementType!R val)
            {
                import core.lifetime : forward;

                // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                _original[_index] = __ctfe ? val : forward!val;
            }
        }

        /// ditto
        enum bool empty = false;

        /// ditto
        void popFront()
        {
            ++_index;
            if (_index >= _original.length)
                _index = 0;
        }

        /// ditto
        auto ref opIndex(size_t n)
        {
            return _original[(n + _index) % _original.length];
        }

        static if (is(typeof((cast(const R)_original)[_index])) &&
                   is(typeof((cast(const R)_original).length)))
        {
            /// ditto
            auto ref opIndex(size_t n) const
            {
                return _original[(n + _index) % _original.length];
            }
        }

        static if (hasAssignableElements!R)
        {
            /// ditto
            void opIndexAssign(ElementType!R val, size_t n)
            {
                _original[(n + _index) % _original.length] = val;
            }
        }

        /// ditto
        @property Cycle save()
        {
            //No need to call _original.save, because Cycle never actually modifies _original
            return Cycle(_original, _index);
        }

        private static struct DollarToken {}

        /// ditto
        enum opDollar = DollarToken.init;

        static if (hasSlicing!R)
        {
            /// ditto
            auto opSlice(size_t i, size_t j)
            in
            {
                assert(i <= j);
            }
            do
            {
                return this[i .. $].takeExactly(j - i);
            }

            /// ditto
            auto opSlice(size_t i, DollarToken)
            {
                return typeof(this)(_original, _index + i);
            }
        }
    }
    else
    {
        private R _original;
        private R _current;

        /// ditto
        this(R input)
        {
            _original = input;
            _current = input.save;
        }

        private this(R original, R current)
        {
            _original = original;
            _current = current;
        }

        /// ditto
        @property auto ref front()
        {
            return _current.front;
        }

        static if (is(typeof((cast(const R)_current).front)))
        {
            /// ditto
            @property auto ref front() const
            {
                return _current.front;
            }
        }

        static if (hasAssignableElements!R)
        {
            /// ditto
            @property auto front(ElementType!R val)
            {
                import core.lifetime : forward;

                // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                return _current.front = __ctfe ? val : forward!val;
            }
        }

        /// ditto
        enum bool empty = false;

        /// ditto
        void popFront()
        {
            _current.popFront();
            if (_current.empty)
                _current = _original.save;
        }

        /// ditto
        @property Cycle save()
        {
            //No need to call _original.save, because Cycle never actually modifies _original
            return Cycle(_original, _current.save);
        }
    }
}

/// ditto
template Cycle(R)
if (isInfinite!R)
{
    alias Cycle = R;
}

/// ditto
struct Cycle(R)
if (isStaticArray!R)
{
    private alias ElementType = typeof(R.init[0]);
    private ElementType* _ptr;
    private size_t _index;

nothrow:

    /// Range primitives
    this(ref R input, size_t index = 0) @system
    {
        _ptr = input.ptr;
        _index = index % R.length;
    }

    /// ditto
    @property ref inout(ElementType) front() inout @safe
    {
        static ref auto trustedPtrIdx(typeof(_ptr) p, size_t idx) @trusted
        {
            return p[idx];
        }
        return trustedPtrIdx(_ptr, _index);
    }

    /// ditto
    enum bool empty = false;

    /// ditto
    void popFront() @safe
    {
        ++_index;
        if (_index >= R.length)
            _index = 0;
    }

    /// ditto
    ref inout(ElementType) opIndex(size_t n) inout @safe
    {
        static ref auto trustedPtrIdx(typeof(_ptr) p, size_t idx) @trusted
        {
            return p[idx % R.length];
        }
        return trustedPtrIdx(_ptr, n + _index);
    }

    /// ditto
    @property inout(Cycle) save() inout @safe
    {
        return this;
    }

    private static struct DollarToken {}
    /// ditto
    enum opDollar = DollarToken.init;

    /// ditto
    auto opSlice(size_t i, size_t j) @safe
    in
    {
        assert(
            i <= j,
            "Attempting to slice a Repeat with a larger first argument than the second."
        );
    }
    do
    {
        return this[i .. $].takeExactly(j - i);
    }

    /// ditto
    inout(typeof(this)) opSlice(size_t i, DollarToken) inout @safe
    {
        static auto trustedCtor(typeof(_ptr) p, size_t idx) @trusted
        {
            return cast(inout) Cycle(*cast(R*)(p), idx);
        }
        return trustedCtor(_ptr, _index + i);
    }
}

/// Ditto
auto cycle(R)(R input)
if (isInputRange!R)
{
    static assert(isForwardRange!R || isInfinite!R,
        "Cycle requires a forward range argument unless it's statically known"
         ~ " to be infinite");
    assert(!input.empty, "Attempting to pass an empty input to cycle");
    static if (isInfinite!R) return input;
    else return Cycle!R(input);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : cycle, take;

    // Here we create an infinitive cyclic sequence from [1, 2]
    // (i.e. get here [1, 2, 1, 2, 1, 2 and so on]) then
    // take 5 elements of this sequence (so we have [1, 2, 1, 2, 1])
    // and compare them with the expected values for equality.
    assert(cycle([1, 2]).take(5).equal([ 1, 2, 1, 2, 1 ]));
}

/// Ditto
Cycle!R cycle(R)(R input, size_t index = 0)
if (isRandomAccessRange!R && !isInfinite!R)
{
    assert(!input.empty, "Attempting to pass an empty input to cycle");
    return Cycle!R(input, index);
}

/// Ditto
Cycle!R cycle(R)(ref R input, size_t index = 0) @system
if (isStaticArray!R)
{
    return Cycle!R(input, index);
}

@safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;

    static assert(isForwardRange!(Cycle!(uint[])));

    // Make sure ref is getting propagated properly.
    int[] nums = [1,2,3];
    auto c2 = cycle(nums);
    c2[3]++;
    assert(nums[0] == 2);

    immutable int[] immarr = [1, 2, 3];

    foreach (DummyType; AllDummyRanges)
    {
        static if (isForwardRange!DummyType)
        {
            DummyType dummy;
            auto cy = cycle(dummy);
            static assert(isForwardRange!(typeof(cy)));
            auto t = take(cy, 20);
            assert(equal(t, [1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10]));

            const cRange = cy;
            assert(cRange.front == 1);

            static if (hasAssignableElements!DummyType)
            {
                {
                    cy.front = 66;
                    scope(exit) cy.front = 1;
                    assert(dummy.front == 66);
                }

                static if (isRandomAccessRange!DummyType)
                {
                    {
                        cy[10] = 66;
                        scope(exit) cy[10] = 1;
                        assert(dummy.front == 66);
                    }

                    assert(cRange[10] == 1);
                }
            }

            static if (hasSlicing!DummyType)
            {
                auto slice = cy[5 .. 15];
                assert(equal(slice, [6, 7, 8, 9, 10, 1, 2, 3, 4, 5]));
                static assert(is(typeof(slice) == typeof(takeExactly(cy, 5))));

                auto infSlice = cy[7 .. $];
                assert(equal(take(infSlice, 5), [8, 9, 10, 1, 2]));
                static assert(isInfinite!(typeof(infSlice)));
            }
        }
    }
}

@system nothrow unittest // For static arrays.
{
    import std.algorithm.comparison : equal;

    int[3] a = [ 1, 2, 3 ];
    static assert(isStaticArray!(typeof(a)));
    auto c = cycle(a);
    assert(a.ptr == c._ptr);
    assert(equal(take(cycle(a), 5), [ 1, 2, 3, 1, 2 ][]));
    static assert(isForwardRange!(typeof(c)));

    // Test qualifiers on slicing.
    alias C = typeof(c);
    static assert(is(typeof(c[1 .. $]) == C));
    const cConst = c;
    static assert(is(typeof(cConst[1 .. $]) == const(C)));
}

@safe nothrow unittest // For infinite ranges
{
    struct InfRange
    {
        void popFront() { }
        @property int front() { return 0; }
        enum empty = false;
        auto save() { return this; }
    }
    struct NonForwardInfRange
    {
        void popFront() { }
        @property int front() { return 0; }
        enum empty = false;
    }

    InfRange i;
    NonForwardInfRange j;
    auto c = cycle(i);
    assert(c == i);
    //make sure it can alias out even non-forward infinite ranges
    static assert(is(typeof(j.cycle) == typeof(j)));
}

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

    int[5] arr = [0, 1, 2, 3, 4];
    auto cleD = cycle(arr[]); //Dynamic
    assert(equal(cleD[5 .. 10], arr[]));

    //n is a multiple of 5 worth about 3/4 of size_t.max
    auto n = size_t.max/4 + size_t.max/2;
    n -= n % 5;

    //Test index overflow
    foreach (_ ; 0 .. 10)
    {
        cleD = cleD[n .. $];
        assert(equal(cleD[5 .. 10], arr[]));
    }
}

@system @nogc nothrow unittest
{
    import std.algorithm.comparison : equal;

    int[5] arr = [0, 1, 2, 3, 4];
    auto cleS = cycle(arr);   //Static
    assert(equal(cleS[5 .. 10], arr[]));

    //n is a multiple of 5 worth about 3/4 of size_t.max
    auto n = size_t.max/4 + size_t.max/2;
    n -= n % 5;

    //Test index overflow
    foreach (_ ; 0 .. 10)
    {
        cleS = cleS[n .. $];
        assert(equal(cleS[5 .. 10], arr[]));
    }
}

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

    int[1] arr = [0];
    auto cleS = cycle(arr);
    cleS = cleS[10 .. $];
    assert(equal(cleS[5 .. 10], 0.repeat(5)));
    assert(cleS.front == 0);
}

// https://issues.dlang.org/show_bug.cgi?id=10845
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter;

    auto a = inputRangeObject(iota(3).filter!"true");
    assert(equal(cycle(a).take(10), [0, 1, 2, 0, 1, 2, 0, 1, 2, 0]));
}

// https://issues.dlang.org/show_bug.cgi?id=12177
@safe unittest
{
    static assert(__traits(compiles, recurrence!q{a[n - 1] ~ a[n - 2]}("1", "0")));
}

// https://issues.dlang.org/show_bug.cgi?id=13390
@system unittest
{
    import core.exception : AssertError;
    import std.exception : assertThrown;
    assertThrown!AssertError(cycle([0, 1, 2][0 .. 0]));
}

// https://issues.dlang.org/show_bug.cgi?id=18657
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    string s = "foo";
    auto r = refRange(&s).cycle.take(4);
    assert(equal(r.save, "foof"));
    assert(equal(r.save, "foof"));
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    import std.algorithm.iteration : filter;

    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[3] arr = [Handle(0), Handle(1), Handle(2)];
    {
        auto range = arr[].cycle().take(5);

        called = false;
        range.front = Handle(42);
        assert(called);
    }
    {
        auto range = arr[].filter!(a => true)().cycle().take(5);

        called = false;
        range.front = Handle(42);
        assert(called);
    }
}

private alias lengthType(R) = typeof(R.init.length.init);

/**
   Iterate several ranges in lockstep. The element type is a proxy tuple
   that allows accessing the current element in the `n`th range by
   using `e[n]`.

   `zip` is similar to $(LREF lockstep), but `lockstep` doesn't
   bundle its elements and uses the `opApply` protocol.
   `lockstep` allows reference access to the elements in
   `foreach` iterations.

    Params:
        sp = controls what `zip` will do if the ranges are different lengths
        ranges = the ranges to zip together
    Returns:
        At minimum, an input range. `Zip` offers the lowest range facilities
        of all components, e.g. it offers random access iff all ranges offer
        random access, and also offers mutation and swapping if all ranges offer
        it. Due to this, `Zip` is extremely powerful because it allows manipulating
        several ranges in lockstep.
    Throws:
        An `Exception` if all of the ranges are not the same length and
        `sp` is set to `StoppingPolicy.requireSameLength`.

    Limitations: The `@nogc` and `nothrow` attributes cannot be inferred for
    the `Zip` struct because $(LREF StoppingPolicy) can vary at runtime. This
    limitation is not shared by the anonymous range returned by the `zip`
    function when not given an explicit `StoppingPolicy` as an argument.
*/
struct Zip(Ranges...)
if (Ranges.length && allSatisfy!(isInputRange, Ranges))
{
    import std.format : format; //for generic mixins
    import std.typecons : Tuple;

    alias R = Ranges;
    private R ranges;
    alias ElementType = Tuple!(staticMap!(.ElementType, R));
    private StoppingPolicy stoppingPolicy = StoppingPolicy.shortest;

/**
   Builds an object. Usually this is invoked indirectly by using the
   $(LREF zip) function.
 */
    this(R rs, StoppingPolicy s = StoppingPolicy.shortest)
    {
        ranges[] = rs[];
        stoppingPolicy = s;
    }

/**
   Returns `true` if the range is at end. The test depends on the
   stopping policy.
*/
    static if (allSatisfy!(isInfinite, R))
    {
        // BUG:  Doesn't propagate infiniteness if only some ranges are infinite
        //       and s == StoppingPolicy.longest.  This isn't fixable in the
        //       current design since StoppingPolicy is known only at runtime.
        enum bool empty = false;
    }
    else
    {
        ///
        @property bool empty()
        {
            import std.exception : enforce;
            import std.meta : anySatisfy;

            final switch (stoppingPolicy)
            {
            case StoppingPolicy.shortest:
                foreach (i, Unused; R)
                {
                    if (ranges[i].empty) return true;
                }
                return false;
            case StoppingPolicy.longest:
                static if (anySatisfy!(isInfinite, R))
                {
                    return false;
                }
                else
                {
                    foreach (i, Unused; R)
                    {
                        if (!ranges[i].empty) return false;
                    }
                    return true;
                }
            case StoppingPolicy.requireSameLength:
                foreach (i, Unused; R[1 .. $])
                {
                    enforce(ranges[0].empty ==
                            ranges[i + 1].empty,
                            "Inequal-length ranges passed to Zip");
                }
                return ranges[0].empty;
            }
            assert(false);
        }
    }

    static if (allSatisfy!(isForwardRange, R))
    {
        ///
        @property Zip save()
        {
            //Zip(ranges[0].save, ranges[1].save, ..., stoppingPolicy)
            return mixin (q{Zip(%(ranges[%s].save%|, %), stoppingPolicy)}.format(iota(0, R.length)));
        }
    }

    private .ElementType!(R[i]) tryGetInit(size_t i)()
    {
        alias E = .ElementType!(R[i]);
        static if (!is(typeof({static E i;})))
            throw new Exception("Range with non-default constructable elements exhausted.");
        else
            return E.init;
    }

/**
   Returns the current iterated element.
*/
    @property ElementType front()
    {
        @property tryGetFront(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].front;}
        //ElementType(tryGetFront!0, tryGetFront!1, ...)
        return mixin(q{ElementType(%(tryGetFront!%s, %))}.format(iota(0, R.length)));
    }

/**
   Sets the front of all iterated ranges.
*/
    static if (allSatisfy!(hasAssignableElements, R))
    {
        @property void front(ElementType v)
        {
            foreach (i, Unused; R)
            {
                if (!ranges[i].empty)
                {
                    ranges[i].front = v[i];
                }
            }
        }
    }

/**
   Moves out the front.
*/
    static if (allSatisfy!(hasMobileElements, R))
    {
        ElementType moveFront()
        {
            @property tryMoveFront(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].moveFront();}
            //ElementType(tryMoveFront!0, tryMoveFront!1, ...)
            return mixin(q{ElementType(%(tryMoveFront!%s, %))}.format(iota(0, R.length)));
        }
    }

/**
   Returns the rightmost element.
*/
    static if (allSatisfy!(isBidirectionalRange, R))
    {
        @property ElementType back()
        {
            //TODO: Fixme! BackElement != back of all ranges in case of jagged-ness

            @property tryGetBack(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].back;}
            //ElementType(tryGetBack!0, tryGetBack!1, ...)
            return mixin(q{ElementType(%(tryGetBack!%s, %))}.format(iota(0, R.length)));
        }

/**
   Moves out the back.
*/
        static if (allSatisfy!(hasMobileElements, R))
        {
            ElementType moveBack()
            {
                //TODO: Fixme! BackElement != back of all ranges in case of jagged-ness

                @property tryMoveBack(size_t i)(){return ranges[i].empty ? tryGetInit!i() : ranges[i].moveBack();}
                //ElementType(tryMoveBack!0, tryMoveBack!1, ...)
                return mixin(q{ElementType(%(tryMoveBack!%s, %))}.format(iota(0, R.length)));
            }
        }

/**
   Returns the current iterated element.
*/
        static if (allSatisfy!(hasAssignableElements, R))
        {
            @property void back(ElementType v)
            {
                //TODO: Fixme! BackElement != back of all ranges in case of jagged-ness.
                //Not sure the call is even legal for StoppingPolicy.longest

                foreach (i, Unused; R)
                {
                    if (!ranges[i].empty)
                    {
                        ranges[i].back = v[i];
                    }
                }
            }
        }
    }

/**
   Advances to the next element in all controlled ranges.
*/
    void popFront()
    {
        import std.exception : enforce;

        final switch (stoppingPolicy)
        {
        case StoppingPolicy.shortest:
            foreach (i, Unused; R)
            {
                assert(!ranges[i].empty);
                ranges[i].popFront();
            }
            break;
        case StoppingPolicy.longest:
            foreach (i, Unused; R)
            {
                if (!ranges[i].empty) ranges[i].popFront();
            }
            break;
        case StoppingPolicy.requireSameLength:
            foreach (i, Unused; R)
            {
                enforce(!ranges[i].empty, "Invalid Zip object");
                ranges[i].popFront();
            }
            break;
        }
    }

/**
   Calls `popBack` for all controlled ranges.
*/
    static if (allSatisfy!(isBidirectionalRange, R))
    {
        void popBack()
        {
            //TODO: Fixme! In case of jaggedness, this is wrong.
            import std.exception : enforce;

            final switch (stoppingPolicy)
            {
            case StoppingPolicy.shortest:
                foreach (i, Unused; R)
                {
                    assert(!ranges[i].empty);
                    ranges[i].popBack();
                }
                break;
            case StoppingPolicy.longest:
                foreach (i, Unused; R)
                {
                    if (!ranges[i].empty) ranges[i].popBack();
                }
                break;
            case StoppingPolicy.requireSameLength:
                foreach (i, Unused; R)
                {
                    enforce(!ranges[i].empty, "Invalid Zip object");
                    ranges[i].popBack();
                }
                break;
            }
        }
    }

/**
   Returns the length of this range. Defined only if all ranges define
   `length`.
*/
    static if (allSatisfy!(hasLength, R))
    {
        @property auto length()
        {
            static if (Ranges.length == 1)
                return ranges[0].length;
            else
            {
                if (stoppingPolicy == StoppingPolicy.requireSameLength)
                    return ranges[0].length;

                //[min|max](ranges[0].length, ranges[1].length, ...)
                import std.algorithm.comparison : min, max;
                if (stoppingPolicy == StoppingPolicy.shortest)
                    return mixin(q{min(%(ranges[%s].length%|, %))}.format(iota(0, R.length)));
                else
                    return mixin(q{max(%(ranges[%s].length%|, %))}.format(iota(0, R.length)));
            }
        }

        alias opDollar = length;
    }

/**
   Returns a slice of the range. Defined only if all range define
   slicing.
*/
    static if (allSatisfy!(hasSlicing, R))
    {
        auto opSlice(size_t from, size_t to)
        {
            //Slicing an infinite range yields the type Take!R
            //For finite ranges, the type Take!R aliases to R
            alias ZipResult = Zip!(staticMap!(Take, R));

            //ZipResult(ranges[0][from .. to], ranges[1][from .. to], ..., stoppingPolicy)
            return mixin (q{ZipResult(%(ranges[%s][from .. to]%|, %), stoppingPolicy)}.format(iota(0, R.length)));
        }
    }

/**
   Returns the `n`th element in the composite range. Defined if all
   ranges offer random access.
*/
    static if (allSatisfy!(isRandomAccessRange, R))
    {
        ElementType opIndex(size_t n)
        {
            //TODO: Fixme! This may create an out of bounds access
            //for StoppingPolicy.longest

            //ElementType(ranges[0][n], ranges[1][n], ...)
            return mixin (q{ElementType(%(ranges[%s][n]%|, %))}.format(iota(0, R.length)));
        }

/**
   Assigns to the `n`th element in the composite range. Defined if
   all ranges offer random access.
*/
        static if (allSatisfy!(hasAssignableElements, R))
        {
            void opIndexAssign(ElementType v, size_t n)
            {
                //TODO: Fixme! Not sure the call is even legal for StoppingPolicy.longest
                foreach (i, Range; R)
                {
                    ranges[i][n] = v[i];
                }
            }
        }

/**
   Destructively reads the `n`th element in the composite
   range. Defined if all ranges offer random access.
*/
        static if (allSatisfy!(hasMobileElements, R))
        {
            ElementType moveAt(size_t n)
            {
                //TODO: Fixme! This may create an out of bounds access
                //for StoppingPolicy.longest

                //ElementType(ranges[0].moveAt(n), ranges[1].moveAt(n), ..., )
                return mixin (q{ElementType(%(ranges[%s].moveAt(n)%|, %))}.format(iota(0, R.length)));
            }
        }
    }
}

/// Ditto
auto zip(Ranges...)(Ranges ranges)
if (Ranges.length && allSatisfy!(isInputRange, Ranges))
{
    import std.meta : anySatisfy, templateOr;
    static if (allSatisfy!(isInfinite, Ranges) || Ranges.length == 1)
    {
        return ZipShortest!(Ranges)(ranges);
    }
    else static if (allSatisfy!(isBidirectionalRange, Ranges))
    {
        static if (allSatisfy!(templateOr!(isInfinite, hasLength), Ranges)
            && allSatisfy!(templateOr!(isInfinite, hasSlicing), Ranges)
            && allSatisfy!(isBidirectionalRange, staticMap!(Take, Ranges)))
        {
            // If all the ranges are bidirectional, if possible slice them to
            // the same length to simplify the implementation.
            static assert(anySatisfy!(hasLength, Ranges));
            static foreach (i, Range; Ranges)
                static if (hasLength!Range)
                {
                    static if (!is(typeof(minLen) == size_t))
                        size_t minLen = ranges[i].length;
                    else
                    {{
                        const x = ranges[i].length;
                        if (x < minLen) minLen = x;
                    }}
                }
            import std.format : format;
            static if (!anySatisfy!(isInfinite, Ranges))
                return mixin(`ZipShortest!(Yes.allKnownSameLength, staticMap!(Take, Ranges))`~
                    `(%(ranges[%s][0 .. minLen]%|, %))`.format(iota(0, Ranges.length)));
            else
                return mixin(`ZipShortest!(Yes.allKnownSameLength, staticMap!(Take, Ranges))`~
                    `(%(take(ranges[%s], minLen)%|, %))`.format(iota(0, Ranges.length)));
        }
        else static if (allSatisfy!(isRandomAccessRange, Ranges))
        {
            // We can't slice but we can still use random access to ensure
            // "back" is retrieving the same index for each range.
            return ZipShortest!(Ranges)(ranges);
        }
        else
        {
            // If bidirectional range operations would not be supported by
            // ZipShortest that might have actually been a bug since Zip
            // supported `back` without verifying that each range had the
            // same length, but for the sake of backwards compatibility
            // use the old Zip to continue supporting them.
            return Zip!Ranges(ranges);
        }
    }
    else
    {
        return ZipShortest!(Ranges)(ranges);
    }
}

///
@nogc nothrow pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;

    // pairwise sum
    auto arr = only(0, 1, 2);
    auto part1 = zip(arr, arr.dropOne).map!"a[0] + a[1]";
    assert(part1.equal(only(1, 3)));
}

///
nothrow pure @safe unittest
{
    import std.conv : to;

    int[] a = [ 1, 2, 3 ];
    string[] b = [ "a", "b", "c" ];
    string[] result;

    foreach (tup; zip(a, b))
    {
        result ~= tup[0].to!string ~ tup[1];
    }

    assert(result == [ "1a", "2b", "3c" ]);

    size_t idx = 0;
    // unpacking tuple elements with foreach
    foreach (e1, e2; zip(a, b))
    {
        assert(e1 == a[idx]);
        assert(e2 == b[idx]);
        ++idx;
    }
}

/// `zip` is powerful - the following code sorts two arrays in parallel:
nothrow pure @safe unittest
{
    import std.algorithm.sorting : sort;

    int[] a = [ 1, 2, 3 ];
    string[] b = [ "a", "c", "b" ];
    zip(a, b).sort!((t1, t2) => t1[0] > t2[0]);

    assert(a == [ 3, 2, 1 ]);
    // b is sorted according to a's sorting
    assert(b == [ "b", "c", "a" ]);
}

/// Ditto
auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges)
if (Ranges.length && allSatisfy!(isInputRange, Ranges))
{
    return Zip!Ranges(ranges, sp);
}

/**
   Dictates how iteration in a $(LREF zip) and $(LREF lockstep) should stop.
   By default stop at the end of the shortest of all ranges.
*/
enum StoppingPolicy
{
    /// Stop when the shortest range is exhausted
    shortest,
    /// Stop when the longest range is exhausted
    longest,
    /// Require that all ranges are equal
    requireSameLength,
}

///
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.exception : assertThrown;
    import std.range.primitives;
    import std.typecons : tuple;

    auto a = [1, 2, 3];
    auto b = [4, 5, 6, 7];

    auto shortest = zip(StoppingPolicy.shortest, a, b);
    assert(shortest.equal([
        tuple(1, 4),
        tuple(2, 5),
        tuple(3, 6)
    ]));

    auto longest = zip(StoppingPolicy.longest, a, b);
    assert(longest.equal([
        tuple(1, 4),
        tuple(2, 5),
        tuple(3, 6),
        tuple(0, 7)
    ]));

    auto same = zip(StoppingPolicy.requireSameLength, a, b);
    same.popFrontN(3);
    assertThrown!Exception(same.popFront);
}

/+
Non-public. Like $(LREF Zip) with `StoppingPolicy.shortest`
except it properly implements `back` and `popBack` in the
case of uneven ranges or disables those operations when
it is not possible to guarantee they are correct.
+/
package template ZipShortest(Ranges...)
if (Ranges.length && __traits(compiles,
    {
        static assert(allSatisfy!(isInputRange, Ranges));
    }))
{
    alias ZipShortest = .ZipShortest!(
        Ranges.length == 1 || allSatisfy!(isInfinite, Ranges)
            ? Yes.allKnownSameLength
            : No.allKnownSameLength,
        Ranges);
}
/+ non-public, ditto +/
package struct ZipShortest(Flag!"allKnownSameLength" allKnownSameLength, Ranges...)
if (Ranges.length && allSatisfy!(isInputRange, Ranges))
{
    import std.format : format; //for generic mixins
    import std.meta : anySatisfy, templateOr;
    import std.typecons : Tuple;

    deprecated("Use of an undocumented alias R.")
    alias R = Ranges; // Unused here but defined in case library users rely on it.
    private Ranges ranges;
    alias ElementType = Tuple!(staticMap!(.ElementType, Ranges));

    /+
       Builds an object. Usually this is invoked indirectly by using the
       $(LREF zip) function.
    +/
    this(Ranges rs)
    {
        ranges[] = rs[];
    }

    /+
       Returns `true` if the range is at end.
    +/
    static if (allKnownSameLength ? anySatisfy!(isInfinite, Ranges)
        : allSatisfy!(isInfinite, Ranges))
    {
        enum bool empty = false;
    }
    else
    {
        @property bool empty()
        {
            static if (allKnownSameLength)
            {
                return ranges[0].empty;
            }
            else
            {
                static foreach (i; 0 .. Ranges.length)
                {
                    if (ranges[i].empty)
                        return true;
                }
                return false;
            }
        }
    }

    /+
       Forward range primitive. Only present if each constituent range is a
       forward range.
    +/
    static if (allSatisfy!(isForwardRange, Ranges))
    @property typeof(this) save()
    {
        return mixin(`typeof(return)(%(ranges[%s].save%|, %))`.format(iota(0, Ranges.length)));
    }

    /+
       Returns the current iterated element.
    +/
    @property ElementType front()
    {
        return mixin(`typeof(return)(%(ranges[%s].front%|, %))`.format(iota(0, Ranges.length)));
    }

    /+
       Sets the front of all iterated ranges. Only present if each constituent
       range has assignable elements.
    +/
    static if (allSatisfy!(hasAssignableElements, Ranges))
    @property void front()(ElementType v)
    {
        static foreach (i; 0 .. Ranges.length)
            ranges[i].front = v[i];
    }

    /+
       Moves out the front. Present if each constituent range has mobile elements.
    +/
    static if (allSatisfy!(hasMobileElements, Ranges))
    ElementType moveFront()()
    {
        return mixin(`typeof(return)(%(ranges[%s].moveFront()%|, %))`.format(iota(0, Ranges.length)));
    }

    private enum bool isBackWellDefined = allSatisfy!(isBidirectionalRange, Ranges)
        && (allKnownSameLength
            || allSatisfy!(isRandomAccessRange, Ranges)
            // Could also add the case where there is one non-infinite bidirectional
            // range that defines `length` and all others are infinite random access
            // ranges. Adding this would require appropriate branches in
            // back/moveBack/popBack.
            );

    /+
       Returns the rightmost element. Present if all constituent ranges are
       bidirectional and either there is a compile-time guarantee that all
       ranges have the same length (in `allKnownSameLength`) or all ranges
       provide random access to elements.
    +/
    static if (isBackWellDefined)
    @property ElementType back()
    {
        static if (allKnownSameLength)
        {
            return mixin(`typeof(return)(%(ranges[%s].back()%|, %))`.format(iota(0, Ranges.length)));
        }
        else
        {
            const backIndex = length - 1;
            return mixin(`typeof(return)(%(ranges[%s][backIndex]%|, %))`.format(iota(0, Ranges.length)));
        }
    }

    /+
       Moves out the back. Present if `back` is defined and
       each constituent range has mobile elements.
    +/
    static if (isBackWellDefined && allSatisfy!(hasMobileElements, Ranges))
    ElementType moveBack()()
    {
        static if (allKnownSameLength)
        {
            return mixin(`typeof(return)(%(ranges[%s].moveBack()%|, %))`.format(iota(0, Ranges.length)));
        }
        else
        {
            const backIndex = length - 1;
            return mixin(`typeof(return)(%(ranges[%s].moveAt(backIndex)%|, %))`.format(iota(0, Ranges.length)));
        }
    }

    /+
       Sets the rightmost element. Only present if `back` is defined and
       each constituent range has assignable elements.
    +/
    static if (isBackWellDefined && allSatisfy!(hasAssignableElements, Ranges))
    @property void back()(ElementType v)
    {
        static if (allKnownSameLength)
        {
            static foreach (i; 0 .. Ranges.length)
                ranges[i].back = v[i];
        }
        else
        {
            const backIndex = length - 1;
            static foreach (i; 0 .. Ranges.length)
                ranges[i][backIndex] = v[i];
        }
    }

    /+
       Calls `popFront` on each constituent range.
    +/
    void popFront()
    {
        static foreach (i; 0 .. Ranges.length)
            ranges[i].popFront();
    }

    /+
       Pops the rightmost element. Present if `back` is defined.
    +/
    static if (isBackWellDefined)
    void popBack()
    {
        static if (allKnownSameLength)
        {
            static foreach (i; 0 .. Ranges.length)
                ranges[i].popBack;
        }
        else
        {
            const len = length;
            static foreach (i; 0 .. Ranges.length)
                static if (!isInfinite!(Ranges[i]))
                    if (ranges[i].length == len)
                        ranges[i].popBack();
        }
    }

    /+
       Returns the length of this range. Defined if at least one
       constituent range defines `length` and the other ranges all also
       define `length` or are infinite, or if at least one constituent
       range defines `length` and there is a compile-time guarantee that
       all ranges have the same length (in `allKnownSameLength`).
    +/
    static if (allKnownSameLength
        ? anySatisfy!(hasLength, Ranges)
        : (anySatisfy!(hasLength, Ranges)
            && allSatisfy!(templateOr!(isInfinite, hasLength), Ranges)))
    {
        @property size_t length()
        {
           static foreach (i, Range; Ranges)
           {
                static if (hasLength!Range)
                {
                    static if (!is(typeof(minLen) == size_t))
                        size_t minLen = ranges[i].length;
                    else static if (!allKnownSameLength)
                    {{
                        const x = ranges[i].length;
                        if (x < minLen) minLen = x;
                    }}
                }
            }
            return minLen;
        }

        alias opDollar = length;
    }

    /+
       Returns a slice of the range. Defined if all constituent ranges
       support slicing.
    +/
    static if (allSatisfy!(hasSlicing, Ranges))
    {
        // Note: we will know that all elements of the resultant range
        // will have the same length but we cannot change `allKnownSameLength`
        // because the `hasSlicing` predicate tests that the result returned
        // by `opSlice` has the same type as the receiver.
        auto opSlice()(size_t from, size_t to)
        {
            //(ranges[0][from .. to], ranges[1][from .. to], ...)
            enum sliceArgs = `(%(ranges[%s][from .. to]%|, %))`.format(iota(0, Ranges.length));
            static if (__traits(compiles, mixin(`typeof(this)`~sliceArgs)))
                return mixin(`typeof(this)`~sliceArgs);
            else
                // The type is different anyway so we might as well
                // explicitly set allKnownSameLength.
                return mixin(`ZipShortest!(Yes.allKnownSameLength, staticMap!(Take, Ranges))`
                    ~sliceArgs);
        }
    }

    /+
       Returns the `n`th element in the composite range. Defined if all
       constituent ranges offer random access.
    +/
    static if (allSatisfy!(isRandomAccessRange, Ranges))
    ElementType opIndex()(size_t n)
    {
        return mixin(`typeof(return)(%(ranges[%s][n]%|, %))`.format(iota(0, Ranges.length)));
    }

    /+
       Sets the `n`th element in the composite range. Defined if all
       constituent ranges offer random access and have assignable elements.
    +/
    static if (allSatisfy!(isRandomAccessRange, Ranges)
        && allSatisfy!(hasAssignableElements, Ranges))
    void opIndexAssign()(ElementType v, size_t n)
    {
        static foreach (i; 0 .. Ranges.length)
            ranges[i][n] = v[i];
    }

    /+
       Destructively reads the `n`th element in the composite
       range. Defined if all constituent ranges offer random
       access and have mobile elements.
    +/
    static if (allSatisfy!(isRandomAccessRange, Ranges)
        && allSatisfy!(hasMobileElements, Ranges))
    ElementType moveAt()(size_t n)
    {
        return mixin(`typeof(return)(%(ranges[%s].moveAt(n)%|, %))`.format(iota(0, Ranges.length)));
    }
}

pure @system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter, map;
    import std.algorithm.mutation : swap;
    import std.algorithm.sorting : sort;

    import std.exception : assertThrown, assertNotThrown;
    import std.typecons : tuple;

    int[] a = [ 1, 2, 3 ];
    float[] b = [ 1.0, 2.0, 3.0 ];
    foreach (e; zip(a, b))
    {
        assert(e[0] == e[1]);
    }

    swap(a[0], a[1]);
    {
        auto z = zip(a, b);
    }
    //swap(z.front(), z.back());
    sort!("a[0] < b[0]")(zip(a, b));
    assert(a == [1, 2, 3]);
    assert(b == [2.0, 1.0, 3.0]);

    auto z = zip(StoppingPolicy.requireSameLength, a, b);
    assertNotThrown(z.popBack());
    assertNotThrown(z.popBack());
    assertNotThrown(z.popBack());
    assert(z.empty);
    assertThrown(z.popBack());

    a = [ 1, 2, 3 ];
    b = [ 1.0, 2.0, 3.0 ];
    sort!("a[0] > b[0]")(zip(StoppingPolicy.requireSameLength, a, b));
    assert(a == [3, 2, 1]);
    assert(b == [3.0, 2.0, 1.0]);

    a = [];
    b = [];
    assert(zip(StoppingPolicy.requireSameLength, a, b).empty);

    // Test infiniteness propagation.
    static assert(isInfinite!(typeof(zip(repeat(1), repeat(1)))));

    // Test stopping policies with both value and reference.
    auto a1 = [1, 2];
    auto a2 = [1, 2, 3];
    auto stuff = tuple(tuple(a1, a2),
            tuple(filter!"a"(a1), filter!"a"(a2)));

    alias FOO = Zip!(immutable(int)[], immutable(float)[]);

    foreach (t; stuff.expand)
    {
        auto arr1 = t[0];
        auto arr2 = t[1];
        auto zShortest = zip(arr1, arr2);
        assert(equal(map!"a[0]"(zShortest), [1, 2]));
        assert(equal(map!"a[1]"(zShortest), [1, 2]));

        try {
            auto zSame = zip(StoppingPolicy.requireSameLength, arr1, arr2);
            foreach (elem; zSame) {}
            assert(0);
        } catch (Throwable) { /* It's supposed to throw.*/ }

        auto zLongest = zip(StoppingPolicy.longest, arr1, arr2);
        assert(!zLongest.ranges[0].empty);
        assert(!zLongest.ranges[1].empty);

        zLongest.popFront();
        zLongest.popFront();
        assert(!zLongest.empty);
        assert(zLongest.ranges[0].empty);
        assert(!zLongest.ranges[1].empty);

        zLongest.popFront();
        assert(zLongest.empty);
    }

    // https://issues.dlang.org/show_bug.cgi?id=8900
    assert(zip([1, 2], repeat('a')).array == [tuple(1, 'a'), tuple(2, 'a')]);
    assert(zip(repeat('a'), [1, 2]).array == [tuple('a', 1), tuple('a', 2)]);

    // https://issues.dlang.org/show_bug.cgi?id=18524
    // moveBack instead performs moveFront
    {
        auto r = zip([1,2,3]);
        assert(r.moveBack()[0] == 3);
        assert(r.moveFront()[0] == 1);
    }

    // Doesn't work yet.  Issues w/ emplace.
    // static assert(is(Zip!(immutable int[], immutable float[])));


    // These unittests pass, but make the compiler consume an absurd amount
    // of RAM and time.  Therefore, they should only be run if explicitly
    // uncommented when making changes to Zip.  Also, running them using
    // make -fwin32.mak unittest makes the compiler completely run out of RAM.
    // You need to test just this module.
    /+
     foreach (DummyType1; AllDummyRanges)
     {
         DummyType1 d1;
         foreach (DummyType2; AllDummyRanges)
         {
             DummyType2 d2;
             auto r = zip(d1, d2);
             assert(equal(map!"a[0]"(r), [1,2,3,4,5,6,7,8,9,10]));
             assert(equal(map!"a[1]"(r), [1,2,3,4,5,6,7,8,9,10]));

             static if (isForwardRange!DummyType1 && isForwardRange!DummyType2)
             {
                 static assert(isForwardRange!(typeof(r)));
             }

             static if (isBidirectionalRange!DummyType1 &&
                     isBidirectionalRange!DummyType2) {
                 static assert(isBidirectionalRange!(typeof(r)));
             }
             static if (isRandomAccessRange!DummyType1 &&
                     isRandomAccessRange!DummyType2) {
                 static assert(isRandomAccessRange!(typeof(r)));
             }
         }
     }
    +/
}

nothrow pure @safe unittest
{
    import std.algorithm.sorting : sort;

    auto a = [5,4,3,2,1];
    auto b = [3,1,2,5,6];
    auto z = zip(a, b);

    sort!"a[0] < b[0]"(z);

    assert(a == [1, 2, 3, 4, 5]);
    assert(b == [6, 5, 2, 1, 3]);
}

nothrow pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : tuple;

    auto LL = iota(1L, 1000L);
    auto z = zip(LL, [4]);

    assert(equal(z, [tuple(1L,4)]));

    auto LL2 = iota(0L, 500L);
    auto z2 = zip([7], LL2);
    assert(equal(z2, [tuple(7, 0L)]));
}

// Test for https://issues.dlang.org/show_bug.cgi?id=11196
@safe pure unittest
{
    import std.exception : assertThrown;

    static struct S { @disable this(); }
    assert(zip((S[5]).init[]).length == 5);
    assert(zip(StoppingPolicy.longest, cast(S[]) null, new int[1]).length == 1);
    assertThrown(zip(StoppingPolicy.longest, cast(S[]) null, new int[1]).front);
}

// https://issues.dlang.org/show_bug.cgi?id=12007
@nogc nothrow @safe pure unittest
{
    static struct R
    {
        enum empty = false;
        void popFront(){}
        int front(){return 1;} @property
        R save(){return this;} @property
        void opAssign(R) @disable;
    }
    R r;
    auto z = zip(r, r);
    assert(z.save == z);
}

nothrow pure @system unittest
{
    import std.typecons : tuple;

    auto r1 = [0,1,2];
    auto r2 = [1,2,3];
    auto z1 = zip(refRange(&r1), refRange(&r2));
    auto z2 = z1.save;
    z1.popFront();
    assert(z1.front == tuple(1,2));
    assert(z2.front == tuple(0,1));
}

@nogc nothrow pure @safe unittest
{
    // Test zip's `back` and `length` with non-equal ranges.
    static struct NonSliceableRandomAccess
    {
        private int[] a;
        @property ref front()
        {
            return a.front;
        }
        @property ref back()
        {
            return a.back;
        }
        ref opIndex(size_t i)
        {
            return a[i];
        }
        void popFront()
        {
            a.popFront();
        }
        void popBack()
        {
            a.popBack();
        }
        auto moveFront()
        {
            return a.moveFront();
        }
        auto moveBack()
        {
            return a.moveBack();
        }
        auto moveAt(size_t i)
        {
            return a.moveAt(i);
        }
        bool empty() const
        {
            return a.empty;
        }
        size_t length() const
        {
            return a.length;
        }
        typeof(this) save()
        {
            return this;
        }
    }
    static assert(isRandomAccessRange!NonSliceableRandomAccess);
    static assert(!hasSlicing!NonSliceableRandomAccess);
    static foreach (iteration; 0 .. 2)
    {{
        int[5] data = [101, 102, 103, 201, 202];
        static if (iteration == 0)
        {
            auto r1 = NonSliceableRandomAccess(data[0 .. 3]);
            auto r2 = NonSliceableRandomAccess(data[3 .. 5]);
        }
        else
        {
            auto r1 = data[0 .. 3];
            auto r2 = data[3 .. 5];
        }
        auto z = zip(r1, r2);
        static assert(isRandomAccessRange!(typeof(z)));
        assert(z.length == 2);
        assert(z.back[0] == 102 && z.back[1] == 202);
        z.back = typeof(z.back)(-102, -202);// Assign to back.
        assert(z.back[0] == -102 && z.back[1] == -202);
        z.popBack();
        assert(z.length == 1);
        assert(z.back[0] == 101 && z.back[1] == 201);
        z.front = typeof(z.front)(-101, -201);
        assert(z.moveBack() == typeof(z.back)(-101, -201));
        z.popBack();
        assert(z.empty);
    }}
}

@nogc nothrow pure @safe unittest
{
    // Test opSlice on infinite `zip`.
    auto z = zip(repeat(1), repeat(2));
    assert(hasSlicing!(typeof(z)));
    auto slice = z[10 .. 20];
    assert(slice.length == 10);
    static assert(!is(typeof(z) == typeof(slice)));
}

/*
    Generate lockstep's opApply function as a mixin string.
    If withIndex is true prepend a size_t index to the delegate.
*/
private struct LockstepMixin(Ranges...)
{
    import std.conv : text;
    import std.format : format;

    string name;
    string implName;
    string[] params;
    string[] emptyChecks;
    string[] dgArgs;
    string[] popFronts;
    string indexDef;
    string indexInc;

@safe pure:
    this(bool withIndex, bool reverse)
    {
        if (withIndex)
        {
            params ~= "size_t";
            dgArgs ~= "index";
            if (reverse)
            {
                indexDef = q{
                    size_t index = ranges[0].length - 1;
                    enforce(
                        this.stoppingPolicy == StoppingPolicy.requireSameLength,
                        "Indexed lockstep can only be used with foreach_reverse when " ~
                        "stoppingPolicy == requireSameLength");

                    foreach (range; ranges[1 .. $])
                        enforce(range.length == ranges[0].length);
                    };
                indexInc = "--index;";
            }
            else
            {
                indexDef = "size_t index = 0;";
                indexInc = "++index;";
            }
        }

        foreach (idx, Range; Ranges)
        {
            params ~= format("%sElementType!(Ranges[%s])", hasLvalueElements!Range ? "ref " : "", idx);
            emptyChecks ~= format("!ranges[%s].empty", idx);
            if (reverse)
            {
                dgArgs ~= format("ranges[%s].back", idx);
                popFronts ~= format("ranges[%s].popBack();", idx);
            }
            else
            {
                dgArgs ~= format("ranges[%s].front", idx);
                popFronts ~= format("ranges[%s].popFront();", idx);
            }
        }

        if (reverse)
        {
            name = "opApplyReverse";
            if (withIndex) implName = "opApplyReverseIdxImpl";
            else           implName = "opApplyReverseImpl";
        }
        else
        {
            name = "opApply";
            if (withIndex) implName = "opApplyIdxImpl";
            else           implName = "opApplyImpl";
        }
    }

const:
    string getAlias()
    {
        return format(q{
            alias %s = %s!(int delegate(%-(%s%|, %)));
        },
            name, implName, params
        );
    }

    string getImpl()
    {
        return format(q{
            int %s(DG)(scope DG dg) scope
            {
                import std.exception : enforce;

                auto ranges = this.ranges;
                %s

                while (%-(%s%| && %))
                {
                    if (int result = dg(%-(%s%|, %))) return result;
                    %-(%s%|
                    %)
                    %s
                }

                if (this.stoppingPolicy == StoppingPolicy.requireSameLength)
                {
                    foreach (range; ranges)
                        enforce(range.empty);
                }
                return 0;
            }
        },
            implName, indexDef, emptyChecks, dgArgs, popFronts, indexInc
        );
    }
}

/**
   Iterate multiple ranges in lockstep using a `foreach` loop. In contrast to
   $(LREF zip) it allows reference access to its elements. If only a single
   range is passed in, the `Lockstep` aliases itself away.  If the
   ranges are of different lengths and `s` == `StoppingPolicy.shortest`
   stop after the shortest range is empty.  If the ranges are of different
   lengths and `s` == `StoppingPolicy.requireSameLength`, throw an
   exception.  `s` may not be `StoppingPolicy.longest`, and passing this
   will throw an exception.

   Iterating over `Lockstep` in reverse and with an index is only possible
   when `s` == `StoppingPolicy.requireSameLength`, in order to preserve
   indexes. If an attempt is made at iterating in reverse when `s` ==
   `StoppingPolicy.shortest`, an exception will be thrown.

   By default `StoppingPolicy` is set to `StoppingPolicy.shortest`.

   See_Also: $(LREF zip)

       `lockstep` is similar to $(LREF zip), but `zip` bundles its
       elements and returns a range.
       `lockstep` also supports reference access.
       Use `zip` if you want to pass the result to a range function.
*/
struct Lockstep(Ranges...)
if (Ranges.length > 1 && allSatisfy!(isInputRange, Ranges))
{
    private Ranges ranges;
    private StoppingPolicy stoppingPolicy;

    ///
    this(Ranges ranges, StoppingPolicy sp = StoppingPolicy.shortest)
    {
        import std.exception : enforce;

        this.ranges = ranges;
        enforce(sp != StoppingPolicy.longest,
            "Can't use StoppingPolicy.Longest on Lockstep.");
        this.stoppingPolicy = sp;
    }

    private enum lockstepMixinFF = LockstepMixin!Ranges(withIndex: false, reverse: false);
    mixin(lockstepMixinFF.getImpl);

    private enum lockstepMixinTF = LockstepMixin!Ranges(withIndex: true, reverse: false);
    mixin(lockstepMixinTF.getImpl);

    mixin(lockstepMixinFF.getAlias);
    mixin(lockstepMixinTF.getAlias);

    static if (allSatisfy!(isBidirectionalRange, Ranges))
    {
        private enum lockstepMixinFT = LockstepMixin!Ranges(withIndex: false, reverse: true);
        mixin(lockstepMixinFT.getImpl);
        static if (allSatisfy!(hasLength, Ranges))
        {
            private enum lockstepMixinTT = LockstepMixin!Ranges(withIndex: true, reverse: true);
            mixin(lockstepMixinTT.getImpl);
            mixin(lockstepMixinTT.getAlias);
        }
        else
        {
            mixin(lockstepReverseFailMixin!Ranges(withIndex: true));
            alias opApplyReverse = opApplyReverseIdxFail;
        }
        mixin(lockstepMixinFT.getAlias);
    }
    else
    {
        mixin(lockstepReverseFailMixin!Ranges(withIndex: false));
        mixin(lockstepReverseFailMixin!Ranges(withIndex: true));
        alias opApplyReverse = opApplyReverseFail;
        alias opApplyReverse = opApplyReverseIdxFail;
    }
}

/// Ditto
Lockstep!(Ranges) lockstep(Ranges...)(Ranges ranges)
if (allSatisfy!(isInputRange, Ranges))
{
    return Lockstep!(Ranges)(ranges);
}
/// Ditto
Lockstep!(Ranges) lockstep(Ranges...)(Ranges ranges, StoppingPolicy s)
if (allSatisfy!(isInputRange, Ranges))
{
    static if (Ranges.length > 1)
        return Lockstep!Ranges(ranges, s);
    else
        return ranges[0];
}

///
pure @safe unittest
{
    int[6] arr1 = [1,2,3,4,5,100];
    int[5] arr2 = [6,7,8,9,10];

    foreach (ref a, b; lockstep(arr1[], arr2[]))
    {
        a += b;
    }

    assert(arr1 == [7,9,11,13,15,100]);
}

/// Lockstep also supports iterating with an index variable:
pure @safe unittest
{
    int[3] arr1 = [1,2,3];
    int[3] arr2 = [4,5,6];

    foreach (index, a, b; lockstep(arr1[], arr2[]))
    {
        assert(arr1[index] == a);
        assert(arr2[index] == b);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=15860: foreach_reverse on lockstep
pure @safe unittest
{
    auto arr1 = [0, 1, 2, 3];
    auto arr2 = [4, 5, 6, 7];

    size_t n = arr1.length - 1;
    foreach_reverse (index, a, b; lockstep(arr1, arr2, StoppingPolicy.requireSameLength))
    {
        assert(n == index);
        assert(index == a);
        assert(arr1[index] == a);
        assert(arr2[index] == b);
        n--;
    }

    auto arr3 = [4, 5];
    n = 1;
    foreach_reverse (a, b; lockstep(arr1, arr3))
    {
        assert(a == arr1[$-n] && b == arr3[$-n]);
        n++;
    }
}

pure @safe unittest
{
    import std.algorithm.iteration : filter;
    import std.conv : to;

    // The filters are to make these the lowest common forward denominator ranges,
    // i.e. w/o ref return, random access, length, etc.
    auto foo = filter!"a"([1,2,3,4,5]);
    immutable bar = [6f,7f,8f,9f,10f].idup;
    auto l = lockstep(foo, bar);

    // Should work twice.  These are forward ranges with implicit save.
    foreach (i; 0 .. 2)
    {
        uint[] res1;
        float[] res2;

        foreach (a, ref b; l)
        {
            res1 ~= a;
            res2 ~= b;
        }

        assert(res1 == [1,2,3,4,5]);
        assert(res2 == [6,7,8,9,10]);
        assert(bar == [6f,7f,8f,9f,10f]);
    }

    // Doc example.
    auto arr1 = [1,2,3,4,5];
    auto arr2 = [6,7,8,9,10];

    foreach (ref a, ref b; lockstep(arr1, arr2))
    {
        a += b;
    }

    assert(arr1 == [7,9,11,13,15]);

    // Make sure StoppingPolicy.requireSameLength doesn't throw.
    auto ls = lockstep(arr1, arr2, StoppingPolicy.requireSameLength);

    int k = 1;
    foreach (a, b; ls)
    {
        assert(a - b == k);
        ++k;
    }

    // Make sure StoppingPolicy.requireSameLength throws.
    arr2.popBack();
    ls = lockstep(arr1, arr2, StoppingPolicy.requireSameLength);

    try {
        foreach (a, b; ls) {}
        assert(0);
    } catch (Exception) {}

    // Just make sure 1-range case instantiates. This hangs the compiler
    // when no explicit stopping policy is specified due to
    // https://issues.dlang.org/show_bug.cgi?id=4652
    auto stuff = lockstep([1,2,3,4,5], StoppingPolicy.shortest);
    foreach (i, a; stuff)
    {
        assert(stuff[i] == a);
    }

    // Test with indexing.
    uint[] res1;
    float[] res2;
    size_t[] indices;
    foreach (i, a, b; lockstep(foo, bar))
    {
        indices ~= i;
        res1 ~= a;
        res2 ~= b;
    }

    assert(indices == to!(size_t[])([0, 1, 2, 3, 4]));
    assert(res1 == [1,2,3,4,5]);
    assert(res2 == [6f,7f,8f,9f,10f]);

    // Make sure we've worked around the relevant compiler bugs and this at least
    // compiles w/ >2 ranges.
    lockstep(foo, foo, foo);

    // Make sure it works with const.
    const(int[])[] foo2 = [[1, 2, 3]];
    const(int[])[] bar2 = [[4, 5, 6]];
    auto c = chain(foo2, bar2);

    foreach (f, b; lockstep(c, c)) {}

    // Regression 10468
    foreach (x, y; lockstep(iota(0, 10), iota(0, 10))) { }
}

pure @safe unittest
{
    struct RvalueRange
    {
        int[] impl;
        @property bool empty() { return impl.empty; }
        @property int front() { return impl[0]; } // N.B. non-ref
        void popFront() { impl.popFront(); }
    }
    auto data1 = [ 1, 2, 3, 4 ];
    auto data2 = [ 5, 6, 7, 8 ];
    auto r1 = RvalueRange(data1);
    auto r2 = data2;
    foreach (a, ref b; lockstep(r1, r2))
    {
        a++;
        b++;
    }
    assert(data1 == [ 1, 2, 3, 4 ]); // changes to a do not propagate to data
    assert(data2 == [ 6, 7, 8, 9 ]); // but changes to b do.

    // Since r1 is by-value only, the compiler should reject attempts to
    // foreach over it with ref.
    static assert(!__traits(compiles, {
        foreach (ref a, ref b; lockstep(r1, r2)) { a++; }
    }));
}

private string lockstepReverseFailMixin(Ranges...)(bool withIndex)
{
    import std.format : format;
    string[] params;
    string message;

    if (withIndex)
    {
        message = "Indexed reverse iteration with lockstep is only supported"
        ~"if all ranges are bidirectional and have a length.\n";
    }
    else
    {
        message = "Reverse iteration with lockstep is only supported if all ranges are bidirectional.\n";
    }

    if (withIndex)
    {
        params ~= "size_t";
    }

    foreach (idx, Range; Ranges)
    {
        params ~= format("%sElementType!(Ranges[%s])", hasLvalueElements!Range ? "ref " : "", idx);
    }

    return format(
    q{
        int opApplyReverse%sFail()(scope int delegate(%s) dg)
        {
            static assert(false, "%s");
        }
    }, withIndex ? "Idx" : "" , params.join(", "), message);
}

// For generic programming, make sure Lockstep!(Range) is well defined for a
// single range.
template Lockstep(Range)
{
    alias Lockstep = Range;
}

/**
Creates a mathematical sequence given the initial values and a
recurrence function that computes the next value from the existing
values. The sequence comes in the form of an infinite forward
range. The type `Recurrence` itself is seldom used directly; most
often, recurrences are obtained by calling the function $(D
recurrence).

When calling `recurrence`, the function that computes the next
value is specified as a template argument, and the initial values in
the recurrence are passed as regular arguments. For example, in a
Fibonacci sequence, there are two initial values (and therefore a
state size of 2) because computing the next Fibonacci value needs the
past two values.

The signature of this function should be:
----
auto fun(R)(R state, size_t n)
----
where `n` will be the index of the current value, and `state` will be an
opaque state vector that can be indexed with array-indexing notation
`state[i]`, where valid values of `i` range from $(D (n - 1)) to
$(D (n - State.length)).

If the function is passed in string form, the state has name `"a"`
and the zero-based index in the recurrence has name `"n"`. The
given string must return the desired value for `a[n]` given
`a[n - 1]`, `a[n - 2]`, `a[n - 3]`,..., `a[n - stateSize]`. The
state size is dictated by the number of arguments passed to the call
to `recurrence`. The `Recurrence` struct itself takes care of
managing the recurrence's state and shifting it appropriately.
 */
struct Recurrence(alias fun, StateType, size_t stateSize)
{
    import std.functional : binaryFun;

    StateType[stateSize] _state;
    size_t _n;

    this(StateType[stateSize] initial) { _state = initial; }

    void popFront()
    {
        static auto trustedCycle(ref typeof(_state) s) @trusted
        {
            return cycle(s);
        }
        // The cast here is reasonable because fun may cause integer
        // promotion, but needs to return a StateType to make its operation
        // closed.  Therefore, we have no other choice.
        _state[_n % stateSize] = cast(StateType) binaryFun!(fun, "a", "n")(
            trustedCycle(_state), _n + stateSize);
        ++_n;
    }

    @property StateType front()
    {
        return _state[_n % stateSize];
    }

    @property typeof(this) save()
    {
        return this;
    }

    enum bool empty = false;
}

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

    // The Fibonacci numbers, using function in string form:
    // a[0] = 1, a[1] = 1, and compute a[n+1] = a[n-1] + a[n]
    auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
    assert(fib.take(10).equal([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]));

    // The factorials, using function in lambda form:
    auto fac = recurrence!((a,n) => a[n-1] * n)(1);
    assert(take(fac, 10).equal([
        1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880
    ]));

    // The triangular numbers, using function in explicit form:
    static size_t genTriangular(R)(R state, size_t n)
    {
        return state[n-1] + n;
    }
    auto tri = recurrence!genTriangular(0);
    assert(take(tri, 10).equal([0, 1, 3, 6, 10, 15, 21, 28, 36, 45]));
}

/// Ditto
Recurrence!(fun, CommonType!(State), State.length)
recurrence(alias fun, State...)(State initial)
{
    CommonType!(State)[State.length] state;
    foreach (i, Unused; State)
    {
        state[i] = initial[i];
    }
    return typeof(return)(state);
}

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

    auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
    static assert(isForwardRange!(typeof(fib)));

    int[] witness = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ];
    assert(equal(take(fib, 10), witness));
    foreach (e; take(fib, 10)) {}
    auto fact = recurrence!("n * a[n-1]")(1);
    assert( equal(take(fact, 10), [1, 1, 2, 2*3, 2*3*4, 2*3*4*5, 2*3*4*5*6,
                            2*3*4*5*6*7, 2*3*4*5*6*7*8, 2*3*4*5*6*7*8*9][]) );
    auto piapprox = recurrence!("a[n] + (n & 1 ? 4.0 : -4.0) / (2 * n + 3)")(4.0);
    foreach (e; take(piapprox, 20)) {}
    // Thanks to yebblies for this test and the associated fix
    auto r = recurrence!"a[n-2]"(1, 2);
    witness = [1, 2, 1, 2, 1];
    assert(equal(take(r, 5), witness));
}

/**
   `Sequence` is similar to `Recurrence` except that iteration is
   presented in the so-called $(HTTP en.wikipedia.org/wiki/Closed_form,
   closed form). This means that the `n`th element in the series is
   computable directly from the initial values and `n` itself. This
   implies that the interface offered by `Sequence` is a random-access
   range, as opposed to the regular `Recurrence`, which only offers
   forward iteration.

   The state of the sequence is stored as a `Tuple` so it can be
   heterogeneous.
*/
struct Sequence(alias fun, State)
{
private:
    import std.functional : binaryFun;

    alias compute = binaryFun!(fun, "a", "n");
    alias ElementType = typeof(compute(State.init, cast(size_t) 1));
    State _state;
    size_t _n;

    static struct DollarToken{}

public:
    this(State initial, size_t n = 0)
    {
        _state = initial;
        _n = n;
    }

    @property ElementType front()
    {
        return compute(_state, _n);
    }

    void popFront()
    {
        ++_n;
    }

    enum opDollar = DollarToken();

    auto opSlice(size_t lower, size_t upper)
    in
    {
        assert(
            upper >= lower,
            "Attempting to slice a Sequence with a larger first argument than the second."
        );
    }
    do
    {
        return typeof(this)(_state, _n + lower).take(upper - lower);
    }

    auto opSlice(size_t lower, DollarToken)
    {
        return typeof(this)(_state, _n + lower);
    }

    ElementType opIndex(size_t n)
    {
        return compute(_state, n + _n);
    }

    enum bool empty = false;

    @property Sequence save() { return this; }
}

/// Ditto
auto sequence(alias fun, State...)(State args)
{
    import std.typecons : Tuple, tuple;
    alias Return = Sequence!(fun, Tuple!State);
    return Return(tuple(args));
}

/// Odd numbers, using function in string form:
pure @safe nothrow @nogc unittest
{
    auto odds = sequence!("a[0] + n * a[1]")(1, 2);
    assert(odds.front == 1);
    odds.popFront();
    assert(odds.front == 3);
    odds.popFront();
    assert(odds.front == 5);
}

/// Triangular numbers, using function in lambda form:
pure @safe nothrow @nogc unittest
{
    auto tri = sequence!((a,n) => n*(n+1)/2)();

    // Note random access
    assert(tri[0] == 0);
    assert(tri[3] == 6);
    assert(tri[1] == 1);
    assert(tri[4] == 10);
    assert(tri[2] == 3);
}

/// Fibonacci numbers, using function in explicit form:
@safe nothrow @nogc unittest
{
    import std.math.exponential : pow;
    import std.math.rounding : round;
    import std.math.algebraic : sqrt;
    static ulong computeFib(S)(S state, size_t n)
    {
        // Binet's formula
        return cast(ulong)(round((pow(state[0], n+1) - pow(state[1], n+1)) /
                                 state[2]));
    }
    auto fib = sequence!computeFib(
        (1.0 + sqrt(5.0)) / 2.0,    // Golden Ratio
        (1.0 - sqrt(5.0)) / 2.0,    // Conjugate of Golden Ratio
        sqrt(5.0));

    // Note random access with [] operator
    assert(fib[1] == 1);
    assert(fib[4] == 5);
    assert(fib[3] == 3);
    assert(fib[2] == 2);
    assert(fib[9] == 55);
}

pure @safe nothrow @nogc unittest
{
    import std.typecons : Tuple, tuple;
    auto y = Sequence!("a[0] + n * a[1]", Tuple!(int, int))(tuple(0, 4));
    static assert(isForwardRange!(typeof(y)));

    //@@BUG
    //auto y = sequence!("a[0] + n * a[1]")(0, 4);
    //foreach (e; take(y, 15))
    {}                                 //writeln(e);

    auto odds = Sequence!("a[0] + n * a[1]", Tuple!(int, int))(
        tuple(1, 2));
    for (int currentOdd = 1; currentOdd <= 21; currentOdd += 2)
    {
        assert(odds.front == odds[0]);
        assert(odds[0] == currentOdd);
        odds.popFront();
    }
}

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

    auto odds = sequence!("a[0] + n * a[1]")(1, 2);
    static assert(hasSlicing!(typeof(odds)));

    //Note: don't use drop or take as the target of an equal,
    //since they'll both just forward to opSlice, making the tests irrelevant

    // static slicing tests
    assert(equal(odds[0 .. 5], only(1,  3,  5,  7,  9)));
    assert(equal(odds[3 .. 7], only(7,  9, 11, 13)));

    // relative slicing test, testing slicing is NOT agnostic of state
    auto odds_less5 = odds.drop(5); //this should actually call odds[5 .. $]
    assert(equal(odds_less5[0 ..  3], only(11, 13, 15)));
    assert(equal(odds_less5[0 .. 10], odds[5 .. 15]));

    //Infinite slicing tests
    odds = odds[10 .. $];
    assert(equal(odds.take(3), only(21, 23, 25)));
}

// https://issues.dlang.org/show_bug.cgi?id=5036
pure @safe nothrow unittest
{
    auto s = sequence!((a, n) => new int)(0);
    assert(s.front != s.front);  // no caching
}

// iota
/**
   Creates a range of values that span the given starting and stopping
   values.

   Params:
   begin = The starting value.
   end = The value that serves as the stopping criterion. This value is not
        included in the range.
   step = The value to add to the current value at each iteration.

   Returns:
   A range that goes through the numbers `begin`, $(D begin + step),
   $(D begin + 2 * step), `...`, up to and excluding `end`.

   The two-argument overloads have $(D step = 1). If $(D begin < end && step <
   0) or $(D begin > end && step > 0) or $(D begin == end), then an empty range
   is returned. If $(D step == 0) then $(D begin == end) is an error.

   For built-in types, the range returned is a random access range. For
   user-defined types that support `++`, the range is an input
   range.

   An integral iota also supports `in` operator from the right. It takes
   the stepping into account, the integral won't be considered
   contained if it falls between two consecutive values of the range.
   `contains` does the same as in, but from lefthand side.

    Example:
    ---
    void main()
    {
        import std.stdio;

        // The following groups all produce the same output of:
        // 0 1 2 3 4

        foreach (i; 0 .. 5)
            writef("%s ", i);
        writeln();

        import std.range : iota;
        foreach (i; iota(0, 5))
            writef("%s ", i);
        writeln();

        writefln("%(%s %|%)", iota(0, 5));

        import std.algorithm.iteration : map;
        import std.algorithm.mutation : copy;
        import std.format;
        iota(0, 5).map!(i => format("%s ", i)).copy(stdout.lockingTextWriter());
        writeln();
    }
    ---
*/
auto iota(B, E, S)(B begin, E end, S step)
if ((isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)))
        && isIntegral!S)
{
    import std.conv : unsigned;

    alias Value = CommonType!(Unqual!B, Unqual!E);
    alias StepType = Unqual!S;

    assert(step != 0 || begin == end);

    static struct Result
    {
        private Value current, last;
        private StepType step; // by convention, 0 if range is empty

        this(Value current, Value pastLast, StepType step)
        {
            if (current < pastLast && step > 0)
            {
                // Iterating upward
                assert(unsigned((pastLast - current) / step) <= size_t.max);
                // Cast below can't fail because current < pastLast
                this.last = cast(Value) (pastLast - 1);
                this.last -= unsigned(this.last - current) % step;
            }
            else if (current > pastLast && step < 0)
            {
                // Iterating downward
                assert(unsigned((current - pastLast) / (0 - step)) <= size_t.max);
                // Cast below can't fail because current > pastLast
                this.last = cast(Value) (pastLast + 1);
                this.last += unsigned(current - this.last) % (0 - step);
            }
            else
            {
                // Initialize an empty range
                this.step = 0;
                return;
            }
            this.step = step;
            this.current = current;
        }

        @property bool empty() const { return step == 0; }
        @property inout(Value) front() inout { assert(!empty); return current; }
        void popFront()
        {
            assert(!empty);
            if (current == last) step = 0;
            else current += step;
        }

        @property inout(Value) back() inout
        {
            assert(!empty);
            return last;
        }
        void popBack()
        {
            assert(!empty);
            if (current == last) step = 0;
            else last -= step;
        }

        @property auto save() { return this; }

        inout(Value) opIndex(ulong n) inout
        {
            assert(n < this.length);

            // Just cast to Value here because doing so gives overflow behavior
            // consistent with calling popFront() n times.
            return cast(inout Value) (current + step * n);
        }
        auto opBinaryRight(string op)(Value val) const
        if (op == "in")
        {
            if (empty) return false;
            //cast to avoid becoming unsigned
            auto supposedIndex = cast(StepType)(val - current) / step;
            return supposedIndex < length && supposedIndex * step + current == val;
        }
        auto contains(Value x){return x in this;}
        inout(Result) opSlice() inout { return this; }
        inout(Result) opSlice(ulong lower, ulong upper) inout
        {
            assert(upper >= lower && upper <= this.length);

            return cast(inout Result) Result(
                cast(Value)(current + lower * step),
                cast(Value)(current + upper * step),
                step);
        }
        @property size_t length() const
        {
            if (step > 0)
                return 1 + cast(size_t) (unsigned(last - current) / step);
            if (step < 0)
                return 1 + cast(size_t) (unsigned(current - last) / (0 - step));
            return 0;
        }

        alias opDollar = length;
    }

    return Result(begin, end, step);
}

/// Ditto
auto iota(B, E)(B begin, E end)
if (isFloatingPoint!(CommonType!(B, E)))
{
    return iota(begin, end, CommonType!(B, E)(1));
}

/// Ditto
auto iota(B, E)(B begin, E end)
if (isIntegral!(CommonType!(B, E)) || isPointer!(CommonType!(B, E)))
{
    import std.conv : unsigned;

    alias Value = CommonType!(Unqual!B, Unqual!E);

    static struct Result
    {
        private Value current, pastLast;

        this(Value current, Value pastLast)
        {
            if (current < pastLast)
            {
                assert(unsigned(pastLast - current) <= size_t.max,
                    "`iota` range is too long");

                this.current = current;
                this.pastLast = pastLast;
            }
            else
            {
                // Initialize an empty range
                this.current = this.pastLast = current;
            }
        }

        @property bool empty() const { return current == pastLast; }
        @property inout(Value) front() inout
        {
            assert(!empty, "Attempt to access `front` of empty `iota` range");
            return current;
        }
        void popFront()
        {
            assert(!empty, "Attempt to `popFront` of empty `iota` range");
            ++current;
        }

        @property inout(Value) back() inout
        {
            assert(!empty, "Attempt to access `back` of empty `iota` range");
            return cast(inout(Value))(pastLast - 1);
        }
        void popBack()
        {
            assert(!empty, "Attempt to `popBack` of empty `iota` range");
            --pastLast;
        }

        @property auto save() { return this; }

        inout(Value) opIndex(size_t n) inout
        {
            assert(n < this.length,
                "Attempt to read out-of-bounds index of `iota` range");

            // Just cast to Value here because doing so gives overflow behavior
            // consistent with calling popFront() n times.
            return cast(inout Value) (current + n);
        }
        auto opBinaryRight(string op)(Value val) const
        if (op == "in")
        {
            return current <= val && val < pastLast;
        }
        auto contains(Value x){return x in this;}
        inout(Result) opSlice() inout { return this; }
        inout(Result) opSlice(ulong lower, ulong upper) inout
        {
            assert(upper >= lower && upper <= this.length,
                "Attempt to get out-of-bounds slice of `iota` range");

            return cast(inout Result) Result(cast(Value)(current + lower),
                                            cast(Value)(pastLast - (length - upper)));
        }
        @property size_t length() const
        {
            return cast(size_t)(pastLast - current);
        }

        alias opDollar = length;
    }

    return Result(begin, end);
}

/// Ditto
auto iota(E)(E end)
if (is(typeof(iota(E(0), end))))
{
    E begin = E(0);
    return iota(begin, end);
}

/// Ditto
// Specialization for floating-point types
auto iota(B, E, S)(B begin, E end, S step)
if (isFloatingPoint!(CommonType!(B, E, S)))
in
{
    assert(step != 0, "iota: step must not be 0");
    assert((end - begin) / step >= 0, "iota: incorrect startup parameters");
}
do
{
    alias Value = Unqual!(CommonType!(B, E, S));
    static struct Result
    {
        private Value start, step;
        private size_t index, count;

        this(Value start, Value end, Value step)
        {
            import std.conv : to;

            this.start = start;
            this.step = step;
            immutable fcount = (end - start) / step;
            count = to!size_t(fcount);
            auto pastEnd = start + count * step;
            if (step > 0)
            {
                if (pastEnd < end) ++count;
                assert(start + count * step >= end);
            }
            else
            {
                if (pastEnd > end) ++count;
                assert(start + count * step <= end);
            }
        }

        @property bool empty() const { return index == count; }
        @property Value front() const { assert(!empty); return start + step * index; }
        void popFront()
        {
            assert(!empty);
            ++index;
        }
        @property Value back() const
        {
            assert(!empty);
            return start + step * (count - 1);
        }
        void popBack()
        {
            assert(!empty);
            --count;
        }

        @property auto save() { return this; }

        Value opIndex(size_t n) const
        {
            assert(n < count);
            return start + step * (n + index);
        }
        inout(Result) opSlice() inout
        {
            return this;
        }
        inout(Result) opSlice(size_t lower, size_t upper) inout
        {
            assert(upper >= lower && upper <= count);

            Result ret = this;
            ret.index += lower;
            ret.count = upper - lower + ret.index;
            return cast(inout Result) ret;
        }
        @property size_t length() const
        {
            return count - index;
        }

        alias opDollar = length;
    }

    return Result(begin, end, step);
}

///
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.math.operations : isClose;

    auto r = iota(0, 10, 1);
    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));
    assert(3 in r);
    assert(r.contains(3)); //Same as above
    assert(!(10 in r));
    assert(!(-8 in r));
    r = iota(0, 11, 3);
    assert(equal(r, [0, 3, 6, 9]));
    assert(r[2] == 6);
    assert(!(2 in r));
    auto rf = iota(0.0, 0.5, 0.1);
    assert(isClose(rf, [0.0, 0.1, 0.2, 0.3, 0.4]));
}

pure nothrow @nogc @safe unittest
{
    import std.traits : Signed;
   //float overloads use std.conv.to so can't be @nogc or nothrow
    alias ssize_t = Signed!size_t;
    assert(iota(ssize_t.max, 0, -1).length == ssize_t.max);
    assert(iota(ssize_t.max, ssize_t.min, -1).length == size_t.max);
    assert(iota(ssize_t.max, ssize_t.min, -2).length == 1 + size_t.max / 2);
    assert(iota(ssize_t.min, ssize_t.max, 2).length == 1 + size_t.max / 2);
    assert(iota(ssize_t.max, ssize_t.min, -3).length == size_t.max / 3);
}

debug @system unittest
{//check the contracts
    import core.exception : AssertError;
    import std.exception : assertThrown;
    assertThrown!AssertError(iota(1,2,0));
    assertThrown!AssertError(iota(0f,1f,0f));
    assertThrown!AssertError(iota(1f,0f,0.1f));
    assertThrown!AssertError(iota(0f,1f,-0.1f));
}

pure @system nothrow unittest
{
    int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    auto r1 = iota(a.ptr, a.ptr + a.length, 1);
    assert(r1.front == a.ptr);
    assert(r1.back == a.ptr + a.length - 1);
    assert(&a[4] in r1);
}

pure @safe nothrow @nogc unittest
{
    assert(iota(1UL, 0UL).length == 0);
    assert(iota(1UL, 0UL, 1).length == 0);
    assert(iota(0, 1, 1).length == 1);
    assert(iota(1, 0, -1).length == 1);
    assert(iota(0, 1, -1).length == 0);
    assert(iota(ulong.max, 0).length == 0);
}

pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.searching : count;
    import std.math.operations : isClose, nextUp, nextDown;
    import std.meta : AliasSeq;

    static assert(is(ElementType!(typeof(iota(0f))) == float));

    static assert(hasLength!(typeof(iota(0, 2))));
    auto r = iota(0, 10, 1);
    assert(r[$ - 1] == 9);
    assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][]));

    auto rSlice = r[2 .. 8];
    assert(equal(rSlice, [2, 3, 4, 5, 6, 7]));

    rSlice.popFront();
    assert(rSlice[0] == rSlice.front);
    assert(rSlice.front == 3);

    rSlice.popBack();
    assert(rSlice[rSlice.length - 1] == rSlice.back);
    assert(rSlice.back == 6);

    rSlice = r[0 .. 4];
    assert(equal(rSlice, [0, 1, 2, 3]));
    assert(3 in rSlice);
    assert(!(4 in rSlice));

    auto rr = iota(10);
    assert(equal(rr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][]));

    r = iota(0, -10, -1);
    assert(equal(r, [0, -1, -2, -3, -4, -5, -6, -7, -8, -9][]));
    rSlice = r[3 .. 9];
    assert(equal(rSlice, [-3, -4, -5, -6, -7, -8]));

    r = iota(0, -6, -3);
    assert(equal(r, [0, -3][]));
    rSlice = r[1 .. 2];
    assert(equal(rSlice, [-3]));

    r = iota(0, -7, -3);
    assert(equal(r, [0, -3, -6][]));
    assert(0 in r);
    assert(-6 in r);
    rSlice = r[1 .. 3];
    assert(equal(rSlice, [-3, -6]));
    assert(!(0 in rSlice));
    assert(!(-2 in rSlice));
    assert(!(-5 in rSlice));
    assert(!(3 in rSlice));
    assert(!(-9 in rSlice));

    r = iota(0, 11, 3);
    assert(equal(r, [0, 3, 6, 9][]));
    assert(r[2] == 6);
    rSlice = r[1 .. 3];
    assert(equal(rSlice, [3, 6]));

    auto rf = iota(0.0, 0.5, 0.1);
    assert(isClose(rf, [0.0, 0.1, 0.2, 0.3, 0.4][]));
    assert(rf.length == 5);

    rf.popFront();
    assert(rf.length == 4);

    auto rfSlice = rf[1 .. 4];
    assert(rfSlice.length == 3);
    assert(isClose(rfSlice, [0.2, 0.3, 0.4]));

    rfSlice.popFront();
    assert(isClose(rfSlice[0], 0.3));

    rf.popFront();
    assert(rf.length == 3);

    rfSlice = rf[1 .. 3];
    assert(rfSlice.length == 2);
    assert(isClose(rfSlice, [0.3, 0.4]));
    assert(isClose(rfSlice[0], 0.3));

    // With something just above 0.5
    rf = iota(0.0, nextUp(0.5), 0.1);
    assert(isClose(rf, [0.0, 0.1, 0.2, 0.3, 0.4, 0.5][]));
    rf.popBack();
    assert(rf[rf.length - 1] == rf.back);
    assert(isClose(rf.back, 0.4));
    assert(rf.length == 5);

    // going down
    rf = iota(0.0, -0.5, -0.1);
    assert(isClose(rf, [0.0, -0.1, -0.2, -0.3, -0.4][]));
    rfSlice = rf[2 .. 5];
    assert(isClose(rfSlice, [-0.2, -0.3, -0.4]));

    rf = iota(0.0, nextDown(-0.5), -0.1);
    assert(isClose(rf, [0.0, -0.1, -0.2, -0.3, -0.4, -0.5][]));

    // iota of longs
    auto rl = iota(5_000_000L);
    assert(rl.length == 5_000_000L);
    assert(0 in rl);
    assert(4_000_000L in rl);
    assert(!(-4_000_000L in rl));
    assert(!(5_000_000L in rl));

    // iota of longs with steps
    auto iota_of_longs_with_steps = iota(50L, 101L, 10);
    assert(iota_of_longs_with_steps.length == 6);
    assert(equal(iota_of_longs_with_steps, [50L, 60L, 70L, 80L, 90L, 100L]));

    // iota of unsigned zero length (https://issues.dlang.org/show_bug.cgi?id=6222)
    // Actually trying to consume it is the only way to find something is wrong
    // because the public properties are all correct.
    auto iota_zero_unsigned = iota(0, 0u, 3);
    assert(count(iota_zero_unsigned) == 0);

    // https://issues.dlang.org/show_bug.cgi?id=7982
    // unsigned reverse iota can be buggy if `.length` doesn't
    // take them into account
    assert(iota(10u, 0u, -1).length == 10);
    assert(iota(10u, 0u, -2).length == 5);
    assert(iota(uint.max, uint.max-10, -1).length == 10);
    assert(iota(uint.max, uint.max-10, -2).length == 5);
    assert(iota(uint.max, 0u, -1).length == uint.max);

    assert(20 in iota(20u, 10u, -2));
    assert(16 in iota(20u, 10u, -2));
    assert(!(15 in iota(20u, 10u, -2)));
    assert(!(10 in iota(20u, 10u, -2)));
    assert(!(uint.max in iota(20u, 10u, -1)));
    assert(!(int.min in iota(20u, 10u, -1)));
    assert(!(int.max in iota(20u, 10u, -1)));


    // https://issues.dlang.org/show_bug.cgi?id=8920
    static foreach (Type; AliasSeq!(byte, ubyte, short, ushort,
        int, uint, long, ulong))
    {{
        Type val;
        foreach (i; iota(cast(Type) 0, cast(Type) 10)) { val++; }
        assert(val == 10);
    }}
}

pure @safe nothrow unittest
{
    import std.algorithm.mutation : copy;
    auto idx = new size_t[100];
    copy(iota(0, idx.length), idx);
}

@safe unittest
{
    import std.meta : AliasSeq;
    static foreach (range; AliasSeq!(iota(2, 27, 4),
                             iota(3, 9),
                             iota(2.7, 12.3, .1),
                             iota(3.2, 9.7)))
    {{
        const cRange = range;
        const e = cRange.empty;
        const f = cRange.front;
        const b = cRange.back;
        const i = cRange[2];
        const s1 = cRange[];
        const s2 = cRange[0 .. 3];
        const l = cRange.length;
    }}
}

@system unittest
{
    //The ptr stuff can't be done at compile time, so we unfortunately end
    //up with some code duplication here.
    auto arr = [0, 5, 3, 5, 5, 7, 9, 2, 0, 42, 7, 6];

    {
        const cRange = iota(arr.ptr, arr.ptr + arr.length, 3);
        const e = cRange.empty;
        const f = cRange.front;
        const b = cRange.back;
        const i = cRange[2];
        const s1 = cRange[];
        const s2 = cRange[0 .. 3];
        const l = cRange.length;
    }

    {
        const cRange = iota(arr.ptr, arr.ptr + arr.length);
        const e = cRange.empty;
        const f = cRange.front;
        const b = cRange.back;
        const i = cRange[2];
        const s1 = cRange[];
        const s2 = cRange[0 .. 3];
        const l = cRange.length;
    }
}

@nogc nothrow pure @safe unittest
{
    {
        ushort start = 0, end = 10, step = 2;
        foreach (i; iota(start, end, step))
            static assert(is(typeof(i) == ushort));
    }
    {
        ubyte start = 0, end = 255, step = 128;
        uint x;
        foreach (i; iota(start, end, step))
        {
            static assert(is(typeof(i) == ubyte));
            ++x;
        }
        assert(x == 2);
    }
}

/* Generic overload that handles arbitrary types that support arithmetic
 * operations.
 *
 * User-defined types such as $(REF BigInt, std,bigint) are also supported, as long
 * as they can be incremented with `++` and compared with `<` or `==`.
 */
/// ditto
auto iota(B, E)(B begin, E end)
if (!isIntegral!(CommonType!(B, E)) &&
    !isFloatingPoint!(CommonType!(B, E)) &&
    !isPointer!(CommonType!(B, E)) &&
    is(typeof((ref B b) { ++b; })) &&
    (is(typeof(B.init < E.init)) || is(typeof(B.init == E.init))) )
{
    static struct Result
    {
        B current;
        E end;

        @property bool empty()
        {
            static if (is(typeof(B.init < E.init)))
                return !(current < end);
            else static if (is(typeof(B.init != E.init)))
                return current == end;
            else
                static assert(0);
        }
        @property auto front() { return current; }
        void popFront()
        {
            assert(!empty);
            ++current;
        }
        @property auto save() { return this; }
    }
    return Result(begin, end);
}

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

    // Test iota() for a type that only supports ++ and != but does not have
    // '<'-ordering.
    struct Cyclic(int wrapAround)
    {
        int current;

        this(int start) { current = start % wrapAround; }

        bool opEquals(Cyclic c) const { return current == c.current; }
        bool opEquals(int i) const { return current == i; }
        void opUnary(string op)()
        if (op == "++")
        {
            current = (current + 1) % wrapAround;
        }
    }
    alias Cycle5 = Cyclic!5;

    // Easy case
    auto i1 = iota(Cycle5(1), Cycle5(4));
    assert(i1.equal([1, 2, 3]));

    // Wraparound case
    auto i2 = iota(Cycle5(3), Cycle5(2));
    assert(i2.equal([3, 4, 0, 1 ]));
}

// https://issues.dlang.org/show_bug.cgi?id=23453
@safe unittest
{
    auto r = iota('a', 'z');
    static assert(isForwardRange!(typeof(r)));
}

/**
   Options for the $(LREF FrontTransversal) and $(LREF Transversal) ranges
   (below).
*/
enum TransverseOptions
{
/**
   When transversed, the elements of a range of ranges are assumed to
   have different lengths (e.g. a jagged array).
*/
    assumeJagged,                      //default
    /**
       The transversal enforces that the elements of a range of ranges have
       all the same length (e.g. an array of arrays, all having the same
       length). Checking is done once upon construction of the transversal
       range.
    */
        enforceNotJagged,
    /**
       The transversal assumes, without verifying, that the elements of a
       range of ranges have all the same length. This option is useful if
       checking was already done from the outside of the range.
    */
        assumeNotJagged,
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;
    import std.exception : assertThrown;

    auto arr = [[1, 2], [3, 4, 5]];

    auto r1 = arr.frontTransversal!(TransverseOptions.assumeJagged);
    assert(r1.equal([1, 3]));

    // throws on construction
    assertThrown!Exception(arr.frontTransversal!(TransverseOptions.enforceNotJagged));

    auto r2 = arr.frontTransversal!(TransverseOptions.assumeNotJagged);
    assert(r2.equal([1, 3]));

    // either assuming or checking for equal lengths makes
    // the result a random access range
    assert(r2[0] == 1);
    static assert(!__traits(compiles, r1[0]));
}

/**
   Given a range of ranges, iterate transversally through the first
   elements of each of the enclosed ranges.
*/
struct FrontTransversal(Ror,
        TransverseOptions opt = TransverseOptions.assumeJagged)
{
    alias RangeOfRanges = Unqual!(Ror);
    alias RangeType     = .ElementType!RangeOfRanges;
    alias ElementType   = .ElementType!RangeType;

    private void prime()
    {
        static if (opt == TransverseOptions.assumeJagged)
        {
            while (!_input.empty && _input.front.empty)
            {
                _input.popFront();
            }
            static if (isBidirectionalRange!RangeOfRanges)
            {
                while (!_input.empty && _input.back.empty)
                {
                    _input.popBack();
                }
            }
        }
    }

/**
   Construction from an input.
*/
    this(RangeOfRanges input)
    {
        _input = input;
        prime();
        static if (opt == TransverseOptions.enforceNotJagged)
            // (isRandomAccessRange!RangeOfRanges
            //     && hasLength!RangeType)
        {
            import std.exception : enforce;

            if (empty) return;
            immutable commonLength = _input.front.length;
            foreach (e; _input)
            {
                enforce(e.length == commonLength);
            }
        }
    }

/**
   Forward range primitives.
*/
    static if (isInfinite!RangeOfRanges)
    {
        enum bool empty = false;
    }
    else
    {
        @property bool empty()
        {
            static if (opt != TransverseOptions.assumeJagged)
            {
                if (!_input.empty)
                    return _input.front.empty;
            }

            return _input.empty;
        }
    }

    /// Ditto
    @property auto ref front()
    {
        assert(!empty, "Attempting to fetch the front of an empty FrontTransversal");
        return _input.front.front;
    }

    /// Ditto
    static if (hasMobileElements!RangeType)
    {
        ElementType moveFront()
        {
            return _input.front.moveFront();
        }
    }

    static if (hasAssignableElements!RangeType)
    {
        @property void front(ElementType val)
        {
            import core.lifetime : forward;

            // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
            _input.front.front = __ctfe ? val : forward!val;
        }
    }

    /// Ditto
    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty FrontTransversal");
        _input.popFront();
        prime();
    }

/**
   Duplicates this `frontTransversal`. Note that only the encapsulating
   range of range will be duplicated. Underlying ranges will not be
   duplicated.
*/
    static if (isForwardRange!RangeOfRanges)
    {
        @property FrontTransversal save()
        {
            return FrontTransversal(_input.save);
        }
    }

    static if (isBidirectionalRange!RangeOfRanges)
    {
/**
   Bidirectional primitives. They are offered if $(D
   isBidirectionalRange!RangeOfRanges).
*/
        @property auto ref back()
        {
            assert(!empty, "Attempting to fetch the back of an empty FrontTransversal");
            return _input.back.front;
        }
        /// Ditto
        void popBack()
        {
            assert(!empty, "Attempting to popBack an empty FrontTransversal");
            _input.popBack();
            prime();
        }

        /// Ditto
        static if (hasMobileElements!RangeType)
        {
            ElementType moveBack()
            {
                return _input.back.moveFront();
            }
        }

        static if (hasAssignableElements!RangeType)
        {
            @property void back(ElementType val)
            {
                import core.lifetime : forward;

                // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                _input.back.front = __ctfe ? val : forward!val;
            }
        }
    }

    static if (isRandomAccessRange!RangeOfRanges &&
            (opt == TransverseOptions.assumeNotJagged ||
                    opt == TransverseOptions.enforceNotJagged))
    {
/**
   Random-access primitive. It is offered if $(D
   isRandomAccessRange!RangeOfRanges && (opt ==
   TransverseOptions.assumeNotJagged || opt ==
   TransverseOptions.enforceNotJagged)).
*/
        auto ref opIndex(size_t n)
        {
            return _input[n].front;
        }

        /// Ditto
        static if (hasMobileElements!RangeType)
        {
            ElementType moveAt(size_t n)
            {
                return _input[n].moveFront();
            }
        }
        /// Ditto
        static if (hasAssignableElements!RangeType)
        {
            void opIndexAssign(ElementType val, size_t n)
            {
                import core.lifetime : forward;

                // __ctfe check is workaround for https://issues.dlang.org/show_bug.cgi?id=21542
                _input[n].front = __ctfe ? val : forward!val;
            }
        }
        mixin ImplementLength!_input;

/**
   Slicing if offered if `RangeOfRanges` supports slicing and all the
   conditions for supporting indexing are met.
*/
        static if (hasSlicing!RangeOfRanges)
        {
            typeof(this) opSlice(size_t lower, size_t upper)
            {
                return typeof(this)(_input[lower .. upper]);
            }
        }
    }

    auto opSlice() { return this; }

private:
    RangeOfRanges _input;
}

/// Ditto
FrontTransversal!(RangeOfRanges, opt) frontTransversal(
    TransverseOptions opt = TransverseOptions.assumeJagged,
    RangeOfRanges)
(RangeOfRanges rr)
{
    return typeof(return)(rr);
}

///
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;
    int[][] x = new int[][2];
    x[0] = [1, 2];
    x[1] = [3, 4];
    auto ror = frontTransversal(x);
    assert(equal(ror, [ 1, 3 ][]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges, DummyRange, ReturnBy;

    static assert(is(FrontTransversal!(immutable int[][])));

    foreach (DummyType; AllDummyRanges)
    {
        auto dummies =
            [DummyType.init, DummyType.init, DummyType.init, DummyType.init];

        foreach (i, ref elem; dummies)
        {
            // Just violate the DummyRange abstraction to get what I want.
            elem.arr = elem.arr[i..$ - (3 - i)];
        }

        auto ft = frontTransversal!(TransverseOptions.assumeNotJagged)(dummies);
        static if (isForwardRange!DummyType)
        {
            static assert(isForwardRange!(typeof(ft)));
        }

        assert(equal(ft, [1, 2, 3, 4]));

        // Test slicing.
        assert(equal(ft[0 .. 2], [1, 2]));
        assert(equal(ft[1 .. 3], [2, 3]));

        assert(ft.front == ft.moveFront());
        assert(ft.back == ft.moveBack());
        assert(ft.moveAt(1) == ft[1]);


        // Test infiniteness propagation.
        static assert(isInfinite!(typeof(frontTransversal(repeat("foo")))));

        static if (DummyType.r == ReturnBy.Reference)
        {
            {
                ft.front++;
                scope(exit) ft.front--;
                assert(dummies.front.front == 2);
            }

            {
                ft.front = 5;
                scope(exit) ft.front = 1;
                assert(dummies[0].front == 5);
            }

            {
                ft.back = 88;
                scope(exit) ft.back = 4;
                assert(dummies.back.front == 88);
            }

            {
                ft[1] = 99;
                scope(exit) ft[1] = 2;
                assert(dummies[1].front == 99);
            }
        }
    }
}

// https://issues.dlang.org/show_bug.cgi?id=16363
pure @safe nothrow unittest
{
    import std.algorithm.comparison : equal;

    int[][] darr = [[0, 1], [4, 5]];
    auto ft = frontTransversal!(TransverseOptions.assumeNotJagged)(darr);

    assert(equal(ft, [0, 4]));
    static assert(isRandomAccessRange!(typeof(ft)));
}

// https://issues.dlang.org/show_bug.cgi?id=16442
pure @safe nothrow unittest
{
    int[][] arr = [[], []];

    auto ft = frontTransversal!(TransverseOptions.assumeNotJagged)(arr);
    assert(ft.empty);
}

// ditto
pure @safe unittest
{
    int[][] arr = [[], []];

    auto ft = frontTransversal!(TransverseOptions.enforceNotJagged)(arr);
    assert(ft.empty);
}

// https://issues.dlang.org/show_bug.cgi?id=24481
@safe unittest
{
    bool called;
    struct Handle
    {
        int entry;
        void opAssign()(auto ref const(typeof(this)) that) const { called = true; }
    }

    const(Handle)[][] arr = [[Handle(0), Handle(10)],
                             [Handle(1), Handle(11)],
                             [Handle(2), Handle(12)],
                             [Handle(3), Handle(13)],
                             [Handle(4), Handle(14)]];

    {
        auto range = arr.frontTransversal();

        called = false;
        range.front = Handle(42);
        assert(called == true);

        called = false;
        range.back = Handle(42);
        assert(called == true);
    }
    {
        auto range = arr.frontTransversal!(TransverseOptions.assumeNotJagged)();

        called = false;
        range.front = Handle(42);
        assert(called == true);

        called = false;
        range.back = Handle(42);
        assert(called == true);

        called = false;
        range[0] = Handle(42);
        assert(called == true);
    }
}

/**
    Given a range of ranges, iterate transversally through the
    `n`th element of each of the enclosed ranges. This function
    is similar to `unzip` in other languages.

    Params:
        opt = Controls the assumptions the function makes about the lengths
        of the ranges
        rr = An input range of random access ranges
    Returns:
        At minimum, an input range. Range primitives such as bidirectionality
        and random access are given if the element type of `rr` provides them.
*/
struct Transversal(Ror,
        TransverseOptions opt = TransverseOptions.assumeJagged)
{
    private alias RangeOfRanges = Unqual!Ror;
    private alias InnerRange = ElementType!RangeOfRanges;
    private alias E = ElementType!InnerRange;

    private void prime()
    {
        static if (opt == TransverseOptions.assumeJagged)
        {
            while (!_input.empty && _input.front.length <= _n)
            {
                _input.popFront();
            }
            static if (isBidirectionalRange!RangeOfRanges)
            {
                while (!_input.empty && _input.back.length <= _n)
                {
                    _input.popBack();
                }
            }
        }
    }

/**
   Construction from an input and an index.
*/
    this(RangeOfRanges input, size_t n)
    {
        _input = input;
        _n = n;
        prime();
        static if (opt == TransverseOptions.enforceNotJagged)
        {
            import std.exception : enforce;

            if (empty) return;
            immutable commonLength = _input.front.length;
            foreach (e; _input)
            {
                enforce(e.length == commonLength);
            }
        }
    }

/**
   Forward range primitives.
*/
    static if (isInfinite!(RangeOfRanges))
    {
        enum bool empty = false;
    }
    else
    {
        @property bool empty()
        {
            return _input.empty;
        }
    }

    /// Ditto
    @property auto ref front()
    {
        assert(!empty, "Attempting to fetch the front of an empty Transversal");
        return _input.front[_n];
    }

    /// Ditto
    static if (hasMobileElements!InnerRange)
    {
        E moveFront()
        {
            return _input.front.moveAt(_n);
        }
    }

    /// Ditto
    static if (hasAssignableElements!InnerRange)
    {
        @property void front(E val)
        {
            _input.front[_n] = val;
        }
    }


    /// Ditto
    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty Transversal");
        _input.popFront();
        prime();
    }

    /// Ditto
    static if (isForwardRange!RangeOfRanges)
    {
        @property typeof(this) save()
        {
            auto ret = this;
            ret._input = _input.save;
            return ret;
        }
    }

    static if (isBidirectionalRange!RangeOfRanges)
    {
/**
   Bidirectional primitives. They are offered if $(D
   isBidirectionalRange!RangeOfRanges).
*/
        @property auto ref back()
        {
            assert(!empty, "Attempting to fetch the back of an empty Transversal");
            return _input.back[_n];
        }

        /// Ditto
        void popBack()
        {
            assert(!empty, "Attempting to popBack an empty Transversal");
            _input.popBack();
            prime();
        }

        /// Ditto
        static if (hasMobileElements!InnerRange)
        {
            E moveBack()
            {
                return _input.back.moveAt(_n);
            }
        }

        /// Ditto
        static if (hasAssignableElements!InnerRange)
        {
            @property void back(E val)
            {
                _input.back[_n] = val;
            }
        }

    }

    static if (isRandomAccessRange!RangeOfRanges &&
            (opt == TransverseOptions.assumeNotJagged ||
                    opt == TransverseOptions.enforceNotJagged))
    {
/**
   Random-access primitive. It is offered if $(D
   isRandomAccessRange!RangeOfRanges && (opt ==
   TransverseOptions.assumeNotJagged || opt ==
   TransverseOptions.enforceNotJagged)).
*/
        auto ref opIndex(size_t n)
        {
            return _input[n][_n];
        }

        /// Ditto
        static if (hasMobileElements!InnerRange)
        {
            E moveAt(size_t n)
            {
                return _input[n].moveAt(_n);
            }
        }

        /// Ditto
        static if (hasAssignableElements!InnerRange)
        {
            void opIndexAssign(E val, size_t n)
            {
                _input[n][_n] = val;
            }
        }

        mixin ImplementLength!_input;

/**
   Slicing if offered if `RangeOfRanges` supports slicing and all the
   conditions for supporting indexing are met.
*/
        static if (hasSlicing!RangeOfRanges)
        {
            typeof(this) opSlice(size_t lower, size_t upper)
            {
                return typeof(this)(_input[lower .. upper], _n);
            }
        }
    }

    auto opSlice() { return this; }

private:
    RangeOfRanges _input;
    size_t _n;
}

/// Ditto
Transversal!(RangeOfRanges, opt) transversal
(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)
(RangeOfRanges rr, size_t n)
{
    return typeof(return)(rr, n);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    int[][] x = new int[][2];
    x[0] = [1, 2];
    x[1] = [3, 4];
    auto ror = transversal(x, 1);
    assert(equal(ror, [ 2, 4 ]));
}

/// The following code does a full unzip
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    int[][] y = [[1, 2, 3], [4, 5, 6]];
    auto z = y.front.walkLength.iota.map!(i => transversal(y, i));
    assert(equal!equal(z, [[1, 4], [2, 5], [3, 6]]));
}

@safe unittest
{
    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;

    int[][] x = new int[][2];
    x[0] = [ 1, 2 ];
    x[1] = [3, 4];
    auto ror = transversal!(TransverseOptions.assumeNotJagged)(x, 1);
    auto witness = [ 2, 4 ];
    uint i;
    foreach (e; ror) assert(e == witness[i++]);
    assert(i == 2);
    assert(ror.length == 2);

    static assert(is(Transversal!(immutable int[][])));

    // Make sure ref, assign is being propagated.
    {
        ror.front++;
        scope(exit) ror.front--;
        assert(x[0][1] == 3);
    }
    {
        ror.front = 5;
        scope(exit) ror.front = 2;
        assert(x[0][1] == 5);
        assert(ror.moveFront() == 5);
    }
    {
        ror.back = 999;
        scope(exit) ror.back = 4;
        assert(x[1][1] == 999);
        assert(ror.moveBack() == 999);
    }
    {
        ror[0] = 999;
        scope(exit) ror[0] = 2;
        assert(x[0][1] == 999);
        assert(ror.moveAt(0) == 999);
    }

    // Test w/o ref return.
    alias D = DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random);
    auto drs = [D.init, D.init];
    foreach (num; 0 .. 10)
    {
        auto t = transversal!(TransverseOptions.enforceNotJagged)(drs, num);
        assert(t[0] == t[1]);
        assert(t[1] == num + 1);
    }

    static assert(isInfinite!(typeof(transversal(repeat([1,2,3]), 1))));

    // Test slicing.
    auto mat = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]];
    auto mat1 = transversal!(TransverseOptions.assumeNotJagged)(mat, 1)[1 .. 3];
    assert(mat1[0] == 6);
    assert(mat1[1] == 10);
}

struct Transposed(RangeOfRanges,
    TransverseOptions opt = TransverseOptions.assumeJagged)
if (isForwardRange!RangeOfRanges &&
    isInputRange!(ElementType!RangeOfRanges) &&
    hasAssignableElements!RangeOfRanges)
{
    this(RangeOfRanges input)
    {
        this._input = input;
        static if (opt == TransverseOptions.enforceNotJagged)
        {
            import std.exception : enforce;

            if (empty) return;
            immutable commonLength = _input.front.length;
            foreach (e; _input)
            {
                enforce(e.length == commonLength);
            }
        }
    }

    @property auto front()
    {
        import std.algorithm.iteration : filter, map;
        return _input.save
                     .filter!(a => !a.empty)
                     .map!(a => a.front);
    }

    void popFront()
    {
        // Advance the position of each subrange.
        auto r = _input.save;
        while (!r.empty)
        {
            auto e = r.front;
            if (!e.empty)
            {
                e.popFront();
                r.front = e;
            }

            r.popFront();
        }
    }

    static if (isRandomAccessRange!(ElementType!RangeOfRanges))
    {
        auto ref opIndex(size_t n)
        {
            return transversal!opt(_input, n);
        }
    }

    @property bool empty()
    {
        if (_input.empty) return true;
        foreach (e; _input.save)
        {
            if (!e.empty) return false;
        }
        return true;
    }

    auto opSlice() { return this; }

private:
    RangeOfRanges _input;
}

@safe unittest
{
    // Boundary case: transpose of empty range should be empty
    int[][] ror = [];
    assert(transposed(ror).empty);
}

// https://issues.dlang.org/show_bug.cgi?id=9507
@safe unittest
{
    import std.algorithm.comparison : equal;

    auto r = [[1,2], [3], [4,5], [], [6]];
    assert(r.transposed.equal!equal([
        [1, 3, 4, 6],
        [2, 5]
    ]));
}

// https://issues.dlang.org/show_bug.cgi?id=17742
@safe unittest
{
    import std.algorithm.iteration : map;
    import std.algorithm.comparison : equal;
    auto ror = 5.iota.map!(y => 5.iota.map!(x => x * y).array).array;
    assert(ror[3][2] == 6);
    auto result = transposed!(TransverseOptions.assumeNotJagged)(ror);
    assert(result[2][3] == 6);

    auto x = [[1,2,3],[4,5,6]];
    auto y = transposed!(TransverseOptions.assumeNotJagged)(x);
    assert(y.front.equal([1,4]));
    assert(y[0].equal([1,4]));
    assert(y[0][0] == 1);
    assert(y[1].equal([2,5]));
    assert(y[1][1] == 5);

    auto yy = transposed!(TransverseOptions.enforceNotJagged)(x);
    assert(yy.front.equal([1,4]));
    assert(yy[0].equal([1,4]));
    assert(yy[0][0] == 1);
    assert(yy[1].equal([2,5]));
    assert(yy[1][1] == 5);

    auto z = x.transposed; // assumeJagged
    assert(z.front.equal([1,4]));
    assert(z[0].equal([1,4]));
    assert(!is(typeof(z[0][0])));
}

@safe unittest
{
    import std.exception : assertThrown;

    auto r = [[1,2], [3], [4,5], [], [6]];
    assertThrown(r.transposed!(TransverseOptions.enforceNotJagged));
}

/**
Given a range of ranges, returns a range of ranges where the $(I i)'th subrange
contains the $(I i)'th elements of the original subranges.

Params:
    opt = Controls the assumptions the function makes about the lengths of the ranges (i.e. jagged or not)
    rr = Range of ranges
 */
Transposed!(RangeOfRanges, opt) transposed
(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)
(RangeOfRanges rr)
if (isForwardRange!RangeOfRanges &&
    isInputRange!(ElementType!RangeOfRanges) &&
    hasAssignableElements!RangeOfRanges)
{
    return Transposed!(RangeOfRanges, opt)(rr);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    int[][] ror = [
        [1, 2, 3],
        [4, 5, 6]
    ];
    auto xp = transposed(ror);
    assert(equal!"a.equal(b)"(xp, [
        [1, 4],
        [2, 5],
        [3, 6]
    ]));
}

///
@safe unittest
{
    int[][] x = new int[][2];
    x[0] = [1, 2];
    x[1] = [3, 4];
    auto tr = transposed(x);
    int[][] witness = [ [ 1, 3 ], [ 2, 4 ] ];
    uint i;

    foreach (e; tr)
    {
        assert(array(e) == witness[i++]);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=8764
@safe unittest
{
    import std.algorithm.comparison : equal;
    ulong[] t0 = [ 123 ];

    assert(!hasAssignableElements!(typeof(t0[].chunks(1))));
    assert(!is(typeof(transposed(t0[].chunks(1)))));
    assert(is(typeof(transposed(t0[].chunks(1).array()))));

    auto t1 = transposed(t0[].chunks(1).array());
    assert(equal!"a.equal(b)"(t1, [[123]]));
}

/**
This struct takes two ranges, `source` and `indices`, and creates a view
of `source` as if its elements were reordered according to `indices`.
`indices` may include only a subset of the elements of `source` and
may also repeat elements.

`Source` must be a random access range.  The returned range will be
bidirectional or random-access if `Indices` is bidirectional or
random-access, respectively.
*/
struct Indexed(Source, Indices)
if (isRandomAccessRange!Source && isInputRange!Indices &&
    is(typeof(Source.init[ElementType!(Indices).init])))
{
    this(Source source, Indices indices)
    {
        this._source = source;
        this._indices = indices;
    }

    /// Range primitives
    @property auto ref front()
    {
        assert(!empty, "Attempting to fetch the front of an empty Indexed");
        return _source[_indices.front];
    }

    /// Ditto
    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty Indexed");
        _indices.popFront();
    }

    static if (isInfinite!Indices)
    {
        enum bool empty = false;
    }
    else
    {
        /// Ditto
        @property bool empty()
        {
            return _indices.empty;
        }
    }

    static if (isForwardRange!Indices)
    {
        /// Ditto
        @property typeof(this) save()
        {
            // Don't need to save _source because it's never consumed.
            return typeof(this)(_source, _indices.save);
        }
    }

    /// Ditto
    static if (hasAssignableElements!Source)
    {
        @property auto ref front(ElementType!Source newVal)
        {
            assert(!empty);
            return _source[_indices.front] = newVal;
        }
    }


    static if (hasMobileElements!Source)
    {
        /// Ditto
        auto moveFront()
        {
            assert(!empty);
            return _source.moveAt(_indices.front);
        }
    }

    static if (isBidirectionalRange!Indices)
    {
        /// Ditto
        @property auto ref back()
        {
            assert(!empty, "Attempting to fetch the back of an empty Indexed");
            return _source[_indices.back];
        }

        /// Ditto
        void popBack()
        {
           assert(!empty, "Attempting to popBack an empty Indexed");
           _indices.popBack();
        }

        /// Ditto
        static if (hasAssignableElements!Source)
        {
            @property auto ref back(ElementType!Source newVal)
            {
                assert(!empty);
                return _source[_indices.back] = newVal;
            }
        }


        static if (hasMobileElements!Source)
        {
            /// Ditto
            auto moveBack()
            {
                assert(!empty);
                return _source.moveAt(_indices.back);
            }
        }
    }

    mixin ImplementLength!_indices;

    static if (isRandomAccessRange!Indices)
    {
        /// Ditto
        auto ref opIndex(size_t index)
        {
            return _source[_indices[index]];
        }

        static if (hasSlicing!Indices)
        {
            /// Ditto
            typeof(this) opSlice(size_t a, size_t b)
            {
                return typeof(this)(_source, _indices[a .. b]);
            }
        }


        static if (hasAssignableElements!Source)
        {
            /// Ditto
            auto opIndexAssign(ElementType!Source newVal, size_t index)
            {
                return _source[_indices[index]] = newVal;
            }
        }


        static if (hasMobileElements!Source)
        {
            /// Ditto
            auto moveAt(size_t index)
            {
                return _source.moveAt(_indices[index]);
            }
        }
    }

    // All this stuff is useful if someone wants to index an Indexed
    // without adding a layer of indirection.

    /**
    Returns the source range.
    */
    @property Source source()
    {
        return _source;
    }

    /**
    Returns the indices range.
    */
     @property Indices indices()
    {
        return _indices;
    }

    static if (isRandomAccessRange!Indices)
    {
        /**
        Returns the physical index into the source range corresponding to a
        given logical index.  This is useful, for example, when indexing
        an `Indexed` without adding another layer of indirection.
        */
        size_t physicalIndex(size_t logicalIndex)
        {
            return _indices[logicalIndex];
        }

        ///
        @safe unittest
        {
            auto ind = indexed([1, 2, 3, 4, 5], [1, 3, 4]);
            assert(ind.physicalIndex(0) == 1);
        }
    }

private:
    Source _source;
    Indices _indices;

}

/// Ditto
Indexed!(Source, Indices) indexed(Source, Indices)(Source source, Indices indices)
{
    return typeof(return)(source, indices);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto source = [1, 2, 3, 4, 5];
    auto indices = [4, 3, 1, 2, 0, 4];
    auto ind = indexed(source, indices);
    assert(equal(ind, [5, 4, 2, 3, 1, 5]));
    assert(equal(retro(ind), [5, 1, 3, 2, 4, 5]));
}

@safe unittest
{
    {
        auto ind = indexed([1, 2, 3, 4, 5], [1, 3, 4]);
        assert(ind.physicalIndex(0) == 1);
    }

    auto source = [1, 2, 3, 4, 5];
    auto indices = [4, 3, 1, 2, 0, 4];
    auto ind = indexed(source, indices);

    // When elements of indices are duplicated and Source has lvalue elements,
    // these are aliased in ind.
    ind[0]++;
    assert(ind[0] == 6);
    assert(ind[5] == 6);
}

@safe unittest
{
    import std.internal.test.dummyrange : AllDummyRanges, propagatesLength,
        propagatesRangeType, RangeType;

    foreach (DummyType; AllDummyRanges)
    {
        auto d = DummyType.init;
        auto r = indexed([1, 2, 3, 4, 5], d);
        static assert(propagatesRangeType!(DummyType, typeof(r)));
        static assert(propagatesLength!(DummyType, typeof(r)));
    }
}

/**
This range iterates over fixed-sized chunks of size `chunkSize` of a
`source` range. `Source` must be an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
`chunkSize` must be greater than zero.

If `!isInfinite!Source` and `source.walkLength` is not evenly
divisible by `chunkSize`, the back element of this range will contain
fewer than `chunkSize` elements.

If `Source` is a forward range, the resulting range will be forward ranges as
well. Otherwise, the resulting chunks will be input ranges consuming the same
input: iterating over `front` will shrink the chunk such that subsequent
invocations of `front` will no longer return the full chunk, and calling
`popFront` on the outer range will invalidate any lingering references to
previous values of `front`.

Params:
    source = Range from which the chunks will be selected
    chunkSize = Chunk size

See_Also: $(LREF slide)

Returns: Range of chunks.
*/
struct Chunks(Source)
if (isInputRange!Source)
{
    static if (isForwardRange!Source)
    {
        /// Standard constructor
        this(Source source, size_t chunkSize)
        {
            assert(chunkSize != 0, "Cannot create a Chunk with an empty chunkSize");
            _source = source;
            _chunkSize = chunkSize;
        }

        /// Input range primitives. Always present.
        @property auto front()
        {
            assert(!empty, "Attempting to fetch the front of an empty Chunks");
            return _source.save.take(_chunkSize);
        }

        /// Ditto
        void popFront()
        {
            assert(!empty, "Attempting to popFront and empty Chunks");
            _source.popFrontN(_chunkSize);
        }

        static if (!isInfinite!Source)
            /// Ditto
            @property bool empty()
            {
                return _source.empty;
            }
        else
            // undocumented
            enum empty = false;

        /// Forward range primitives. Only present if `Source` is a forward range.
        @property typeof(this) save()
        {
            return typeof(this)(_source.save, _chunkSize);
        }

        static if (hasLength!Source)
        {
            /// Length. Only if `hasLength!Source` is `true`
            @property size_t length()
            {
                // Note: _source.length + _chunkSize may actually overflow.
                // We cast to ulong to mitigate the problem on x86 machines.
                // For x64 machines, we just suppose we'll never overflow.
                // The "safe" code would require either an extra branch, or a
                //   modulo operation, which is too expensive for such a rare case
                return cast(size_t)((cast(ulong)(_source.length) + _chunkSize - 1) / _chunkSize);
            }
            //Note: No point in defining opDollar here without slicing.
            //opDollar is defined below in the hasSlicing!Source section
        }

        static if (hasSlicing!Source)
        {
            //Used for various purposes
            private enum hasSliceToEnd = is(typeof(Source.init[_chunkSize .. $]) == Source);

            /**
            Indexing and slicing operations. Provided only if
            `hasSlicing!Source` is `true`.
             */
            auto opIndex(size_t index)
            {
                immutable start = index * _chunkSize;
                immutable end   = start + _chunkSize;

                static if (isInfinite!Source)
                    return _source[start .. end];
                else
                {
                    import std.algorithm.comparison : min;
                    immutable len = _source.length;
                    assert(start < len, "chunks index out of bounds");
                    return _source[start .. min(end, len)];
                }
            }

            /// Ditto
            static if (hasLength!Source)
                typeof(this) opSlice(size_t lower, size_t upper)
                {
                    import std.algorithm.comparison : min;
                    assert(lower <= upper && upper <= length, "chunks slicing index out of bounds");
                    immutable len = _source.length;
                    return chunks(_source[min(lower * _chunkSize, len) .. min(upper * _chunkSize, len)], _chunkSize);
                }
            else static if (hasSliceToEnd)
                //For slicing an infinite chunk, we need to slice the source to the end.
                typeof(takeExactly(this, 0)) opSlice(size_t lower, size_t upper)
                {
                    assert(lower <= upper, "chunks slicing index out of bounds");
                    return chunks(_source[lower * _chunkSize .. $], _chunkSize).takeExactly(upper - lower);
                }

            static if (isInfinite!Source)
            {
                static if (hasSliceToEnd)
                {
                    private static struct DollarToken{}
                    DollarToken opDollar()
                    {
                        return DollarToken();
                    }
                    //Slice to dollar
                    typeof(this) opSlice(size_t lower, DollarToken)
                    {
                        return typeof(this)(_source[lower * _chunkSize .. $], _chunkSize);
                    }
                }
            }
            else
            {
                //Dollar token carries a static type, with no extra information.
                //It can lazily transform into _source.length on algorithmic
                //operations such as : chunks[$/2, $-1];
                private static struct DollarToken
                {
                    Chunks!Source* mom;
                    @property size_t momLength()
                    {
                        return mom.length;
                    }
                    alias momLength this;
                }
                DollarToken opDollar()
                {
                    return DollarToken(&this);
                }

                //Slice overloads optimized for using dollar. Without this, to slice to end, we would...
                //1. Evaluate chunks.length
                //2. Multiply by _chunksSize
                //3. To finally just compare it (with min) to the original length of source (!)
                //These overloads avoid that.
                typeof(this) opSlice(DollarToken, DollarToken)
                {
                    static if (hasSliceToEnd)
                        return chunks(_source[$ .. $], _chunkSize);
                    else
                    {
                        immutable len = _source.length;
                        return chunks(_source[len .. len], _chunkSize);
                    }
                }
                typeof(this) opSlice(size_t lower, DollarToken)
                {
                    import std.algorithm.comparison : min;
                    assert(lower <= length, "chunks slicing index out of bounds");
                    static if (hasSliceToEnd)
                        return chunks(_source[min(lower * _chunkSize, _source.length) .. $], _chunkSize);
                    else
                    {
                        immutable len = _source.length;
                        return chunks(_source[min(lower * _chunkSize, len) .. len], _chunkSize);
                    }
                }
                typeof(this) opSlice(DollarToken, size_t upper)
                {
                    assert(upper == length, "chunks slicing index out of bounds");
                    return this[$ .. $];
                }
            }
        }

        //Bidirectional range primitives
        static if (hasSlicing!Source && hasLength!Source)
        {
            /**
            Bidirectional range primitives. Provided only if both
            `hasSlicing!Source` and `hasLength!Source` are `true`.
             */
            @property auto back()
            {
                assert(!empty, "back called on empty chunks");
                immutable len = _source.length;
                immutable start = (len - 1) / _chunkSize * _chunkSize;
                return _source[start .. len];
            }

            /// Ditto
            void popBack()
            {
                assert(!empty, "popBack() called on empty chunks");
                immutable end = (_source.length - 1) / _chunkSize * _chunkSize;
                _source = _source[0 .. end];
            }
        }

    private:
        Source _source;
        size_t _chunkSize;
    }
    else // is input range only
    {
        import std.typecons : RefCounted;

        static struct Chunk
        {
            private RefCounted!Impl impl;

            @property bool empty() { return impl.curSizeLeft == 0 || impl.r.empty; }
            @property auto front() { return impl.r.front; }
            void popFront()
            {
                assert(impl.curSizeLeft > 0 && !impl.r.empty);
                impl.curSizeLeft--;
                impl.r.popFront();
            }
        }

        static struct Impl
        {
            private Source r;
            private size_t chunkSize;
            private size_t curSizeLeft;
        }

        private RefCounted!Impl impl;

        private this(Source r, size_t chunkSize)
        {
            impl = RefCounted!Impl(r, r.empty ? 0 : chunkSize, chunkSize);
        }

        @property bool empty() { return impl.chunkSize == 0; }
        @property Chunk front() return { return Chunk(impl); }

        void popFront()
        {
            impl.curSizeLeft -= impl.r.popFrontN(impl.curSizeLeft);
            if (!impl.r.empty)
                impl.curSizeLeft = impl.chunkSize;
            else
                impl.chunkSize = 0;
        }

        static assert(isInputRange!(typeof(this)));
    }
}

/// Ditto
Chunks!Source chunks(Source)(Source source, size_t chunkSize)
if (isInputRange!Source)
{
    return typeof(return)(source, chunkSize);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    auto chunks = chunks(source, 4);
    assert(chunks[0] == [1, 2, 3, 4]);
    assert(chunks[1] == [5, 6, 7, 8]);
    assert(chunks[2] == [9, 10]);
    assert(chunks.back == chunks[2]);
    assert(chunks.front == chunks[0]);
    assert(chunks.length == 3);
    assert(equal(retro(array(chunks)), array(retro(chunks))));
}

/// Non-forward input ranges are supported, but with limited semantics.
@system /*@safe*/ unittest // FIXME: can't be @safe because RefCounted isn't.
{
    import std.algorithm.comparison : equal;

    int i;

    // The generator doesn't save state, so it cannot be a forward range.
    auto inputRange = generate!(() => ++i).take(10);

    // We can still process it in chunks, but it will be single-pass only.
    auto chunked = inputRange.chunks(2);

    assert(chunked.front.equal([1, 2]));
    assert(chunked.front.empty); // Iterating the chunk has consumed it
    chunked.popFront;
    assert(chunked.front.equal([3, 4]));
}

@system /*@safe*/ unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : ReferenceInputRange;

    auto data = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
    auto r = new ReferenceInputRange!int(data).chunks(3);
    assert(r.equal!equal([
        [ 1, 2, 3 ],
        [ 4, 5, 6 ],
        [ 7, 8, 9 ],
        [ 10 ]
    ]));

    auto data2 = [ 1, 2, 3, 4, 5, 6 ];
    auto r2 = new ReferenceInputRange!int(data2).chunks(3);
    assert(r2.equal!equal([
        [ 1, 2, 3 ],
        [ 4, 5, 6 ]
    ]));

    auto data3 = [ 1, 2, 3, 4, 5 ];
    auto r3 = new ReferenceInputRange!int(data3).chunks(2);
    assert(r3.front.equal([1, 2]));
    r3.popFront();
    assert(!r3.empty);
    r3.popFront();
    assert(r3.front.equal([5]));
}

@safe unittest
{
    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    auto chunks = chunks(source, 4);
    auto chunks2 = chunks.save;
    chunks.popFront();
    assert(chunks[0] == [5, 6, 7, 8]);
    assert(chunks[1] == [9, 10]);
    chunks2.popBack();
    assert(chunks2[1] == [5, 6, 7, 8]);
    assert(chunks2.length == 2);

    static assert(isRandomAccessRange!(typeof(chunks)));
}

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

    //Extra toying with slicing and indexing.
    auto chunks1 = [0, 0, 1, 1, 2, 2, 3, 3, 4].chunks(2);
    auto chunks2 = [0, 0, 1, 1, 2, 2, 3, 3, 4, 4].chunks(2);

    assert(chunks1.length == 5);
    assert(chunks2.length == 5);
    assert(chunks1[4] == [4]);
    assert(chunks2[4] == [4, 4]);
    assert(chunks1.back == [4]);
    assert(chunks2.back == [4, 4]);

    assert(chunks1[0 .. 1].equal([[0, 0]]));
    assert(chunks1[0 .. 2].equal([[0, 0], [1, 1]]));
    assert(chunks1[4 .. 5].equal([[4]]));
    assert(chunks2[4 .. 5].equal([[4, 4]]));

    assert(chunks1[0 .. 0].equal((int[][]).init));
    assert(chunks1[5 .. 5].equal((int[][]).init));
    assert(chunks2[5 .. 5].equal((int[][]).init));

    //Fun with opDollar
    assert(chunks1[$ .. $].equal((int[][]).init)); //Quick
    assert(chunks2[$ .. $].equal((int[][]).init)); //Quick
    assert(chunks1[$ - 1 .. $].equal([[4]]));      //Semiquick
    assert(chunks2[$ - 1 .. $].equal([[4, 4]]));   //Semiquick
    assert(chunks1[$ .. 5].equal((int[][]).init)); //Semiquick
    assert(chunks2[$ .. 5].equal((int[][]).init)); //Semiquick

    assert(chunks1[$ / 2 .. $ - 1].equal([[2, 2], [3, 3]])); //Slow
}

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

    //ForwardRange
    auto r = filter!"true"([1, 2, 3, 4, 5]).chunks(2);
    assert(equal!"equal(a, b)"(r, [[1, 2], [3, 4], [5]]));

    //InfiniteRange w/o RA
    auto fibsByPairs = recurrence!"a[n-1] + a[n-2]"(1, 1).chunks(2);
    assert(equal!`equal(a, b)`(fibsByPairs.take(2),         [[ 1,  1], [ 2,  3]]));

    //InfiniteRange w/ RA and slicing
    auto odds = sequence!("a[0] + n * a[1]")(1, 2);
    auto oddsByPairs = odds.chunks(2);
    assert(equal!`equal(a, b)`(oddsByPairs.take(2),         [[ 1,  3], [ 5,  7]]));

    //Requires phobos#991 for Sequence to have slice to end
    static assert(hasSlicing!(typeof(odds)));
    assert(equal!`equal(a, b)`(oddsByPairs[3 .. 5],         [[13, 15], [17, 19]]));
    assert(equal!`equal(a, b)`(oddsByPairs[3 .. $].take(2), [[13, 15], [17, 19]]));
}



/**
This range splits a `source` range into `chunkCount` chunks of
approximately equal length. `Source` must be a forward range with
known length.

Unlike $(LREF chunks), `evenChunks` takes a chunk count (not size).
The returned range will contain zero or more $(D source.length /
chunkCount + 1) elements followed by $(D source.length / chunkCount)
elements. If $(D source.length < chunkCount), some chunks will be empty.

`chunkCount` must not be zero, unless `source` is also empty.
*/
struct EvenChunks(Source)
if (isForwardRange!Source && hasLength!Source)
{
    /// Standard constructor
    this(Source source, size_t chunkCount)
    {
        assert(chunkCount != 0 || source.empty, "Cannot create EvenChunks with a zero chunkCount");
        _source = source;
        _chunkCount = chunkCount;
    }

    /// Forward range primitives. Always present.
    @property auto front()
    {
        assert(!empty, "Attempting to fetch the front of an empty evenChunks");
        return _source.save.take(_chunkPos(1));
    }

    /// Ditto
    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty evenChunks");
        _source.popFrontN(_chunkPos(1));
        _chunkCount--;
    }

    /// Ditto
    @property bool empty()
    {
        return _chunkCount == 0;
    }

    /// Ditto
    @property typeof(this) save()
    {
        return typeof(this)(_source.save, _chunkCount);
    }

    /// Length
    @property size_t length() const
    {
        return _chunkCount;
    }
    //Note: No point in defining opDollar here without slicing.
    //opDollar is defined below in the hasSlicing!Source section

    static if (hasSlicing!Source)
    {
        /**
        Indexing, slicing and bidirectional operations and range primitives.
        Provided only if `hasSlicing!Source` is `true`.
         */
        auto opIndex(size_t index)
        {
            assert(index < _chunkCount, "evenChunks index out of bounds");
            return _source[_chunkPos(index) .. _chunkPos(index+1)];
        }

        /// Ditto
        typeof(this) opSlice(size_t lower, size_t upper)
        {
            assert(lower <= upper && upper <= length, "evenChunks slicing index out of bounds");
            return evenChunks(_source[_chunkPos(lower) .. _chunkPos(upper)], upper - lower);
        }

        /// Ditto
        @property auto back()
        {
            assert(!empty, "back called on empty evenChunks");
            return _source[_chunkPos(_chunkCount - 1) .. _source.length];
        }

        /// Ditto
        void popBack()
        {
            assert(!empty, "popBack() called on empty evenChunks");
            _source = _source[0 .. _chunkPos(_chunkCount - 1)];
            _chunkCount--;
        }
    }

private:
    Source _source;
    size_t _chunkCount;

    size_t _chunkPos(size_t i)
    {
        /*
            _chunkCount = 5, _source.length = 13:

               chunk0
                 |   chunk3
                 |     |
                 v     v
                +-+-+-+-+-+   ^
                |0|3|.| | |   |
                +-+-+-+-+-+   | div
                |1|4|.| | |   |
                +-+-+-+-+-+   v
                |2|5|.|
                +-+-+-+

                <----->
                  mod

                <--------->
                _chunkCount

            One column is one chunk.
            popFront and popBack pop the left-most
            and right-most column, respectively.
        */

        auto div = _source.length / _chunkCount;
        auto mod = _source.length % _chunkCount;
        auto pos = i <= mod
            ? i   * (div+1)
            : mod * (div+1) + (i-mod) * div
        ;
        //auto len = i < mod
        //    ? div+1
        //    : div
        //;
        return pos;
    }
}

/// Ditto
EvenChunks!Source evenChunks(Source)(Source source, size_t chunkCount)
if (isForwardRange!Source && hasLength!Source)
{
    return typeof(return)(source, chunkCount);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    auto chunks = evenChunks(source, 3);
    assert(chunks[0] == [1, 2, 3, 4]);
    assert(chunks[1] == [5, 6, 7]);
    assert(chunks[2] == [8, 9, 10]);
}

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

    auto source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    auto chunks = evenChunks(source, 3);
    assert(chunks.back == chunks[2]);
    assert(chunks.front == chunks[0]);
    assert(chunks.length == 3);
    assert(equal(retro(array(chunks)), array(retro(chunks))));

    auto chunks2 = chunks.save;
    chunks.popFront();
    assert(chunks[0] == [5, 6, 7]);
    assert(chunks[1] == [8, 9, 10]);
    chunks2.popBack();
    assert(chunks2[1] == [5, 6, 7]);
    assert(chunks2.length == 2);

    static assert(isRandomAccessRange!(typeof(chunks)));
}

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

    int[] source = [];
    auto chunks = source.evenChunks(0);
    assert(chunks.length == 0);
    chunks = source.evenChunks(3);
    assert(equal(chunks, [[], [], []]));
    chunks = [1, 2, 3].evenChunks(5);
    assert(equal(chunks, [[1], [2], [3], [], []]));
}

/**
A fixed-sized sliding window iteration
of size `windowSize` over a `source` range by a custom `stepSize`.

The `Source` range must be at least a $(REF_ALTTEXT ForwardRange, isForwardRange, std,range,primitives)
and the `windowSize` must be greater than zero.

For `windowSize = 1` it splits the range into single element groups (aka `unflatten`)
For `windowSize = 2` it is similar to `zip(source, source.save.dropOne)`.

Params:
    f = Whether the last element has fewer elements than `windowSize`
        it should be be ignored (`No.withPartial`) or added (`Yes.withPartial`)
    source = Range from which the slide will be selected
    windowSize = Sliding window size
    stepSize = Steps between the windows (by default 1)

Returns: Range of all sliding windows with propagated bi-directionality,
         forwarding, random access, and slicing.

Note: To avoid performance overhead, $(REF_ALTTEXT bi-directionality, isBidirectionalRange, std,range,primitives)
      is only available when $(REF hasSlicing, std,range,primitives)
      and $(REF hasLength, std,range,primitives) are true.

See_Also: $(LREF chunks)
*/
auto slide(Flag!"withPartial" f = Yes.withPartial,
            Source)(Source source, size_t windowSize, size_t stepSize = 1)
if (isForwardRange!Source)
{
    return Slides!(f, Source)(source, windowSize, stepSize);
}

/// Iterate over ranges with windows
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    assert([0, 1, 2, 3].slide(2).equal!equal(
        [[0, 1], [1, 2], [2, 3]]
    ));

    assert(5.iota.slide(3).equal!equal(
        [[0, 1, 2], [1, 2, 3], [2, 3, 4]]
    ));
}

/// set a custom stepsize (default 1)
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    assert(6.iota.slide(1, 2).equal!equal(
        [[0], [2], [4]]
    ));

    assert(6.iota.slide(2, 4).equal!equal(
        [[0, 1], [4, 5]]
    ));

    assert(iota(7).slide(2, 2).equal!equal(
        [[0, 1], [2, 3], [4, 5], [6]]
    ));

    assert(iota(12).slide(2, 4).equal!equal(
        [[0, 1], [4, 5], [8, 9]]
    ));
}

/// Allow the last slide to have fewer elements than windowSize
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    assert(3.iota.slide!(No.withPartial)(4).empty);
    assert(3.iota.slide!(Yes.withPartial)(4).equal!equal(
        [[0, 1, 2]]
    ));
}

/// Count all the possible substrings of length 2
@safe pure nothrow unittest
{
    import std.algorithm.iteration : each;

    int[dstring] d;
    "AGAGA"d.slide!(Yes.withPartial)(2).each!(a => d[a]++);
    assert(d == ["AG"d: 2, "GA"d: 2]);
}

/// withPartial only has an effect if last element in the range doesn't have the full size
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    assert(5.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4]]));
    assert(6.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5]]));
    assert(7.iota.slide!(Yes.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5, 6]]));

    assert(5.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2]]));
    assert(6.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2]]));
    assert(7.iota.slide!(No.withPartial)(3, 4).equal!equal([[0, 1, 2], [4, 5, 6]]));
}

private struct Slides(Flag!"withPartial" withPartial = Yes.withPartial, Source)
if (isForwardRange!Source)
{
private:
    Source source;
    size_t windowSize;
    size_t stepSize;

    static if (hasLength!Source)
    {
        enum needsEndTracker = false;
    }
    else
    {
        // If there's no information about the length, track needs to be kept manually
        Source nextSource;
        enum needsEndTracker = true;
    }

    bool _empty;

    static if (hasSlicing!Source)
        enum hasSliceToEnd = hasSlicing!Source && is(typeof(Source.init[0 .. $]) == Source);

    static if (withPartial)
        bool hasShownPartialBefore;

public:
    /// Standard constructor
    this(Source source, size_t windowSize, size_t stepSize)
    {
        assert(windowSize > 0, "windowSize must be greater than zero");
        assert(stepSize > 0, "stepSize must be greater than zero");
        this.source = source;
        this.windowSize = windowSize;
        this.stepSize = stepSize;

        static if (needsEndTracker)
        {
            // `nextSource` is used to "look one step into the future" and check for the end
            // this means `nextSource` is advanced by `stepSize` on every `popFront`
            nextSource = source.save;
            auto poppedElems = nextSource.popFrontN(windowSize);
        }

        if (source.empty)
        {
            _empty = true;
            return;
        }

        static if (withPartial)
        {
            static if (needsEndTracker)
            {
                if (nextSource.empty)
                    hasShownPartialBefore = true;
            }
            else
            {
                if (source.length <= windowSize)
                    hasShownPartialBefore = true;
            }
        }
        else
        {
            // empty source range is needed, s.t. length, slicing etc. works properly
            static if (needsEndTracker)
            {
                if (poppedElems < windowSize)
                     _empty = true;
            }
            else
            {
                if (source.length < windowSize)
                     _empty = true;
            }
        }
    }

    /// Forward range primitives. Always present.
    @property auto front()
    {
        assert(!empty, "Attempting to access front on an empty slide.");
        static if (hasSlicing!Source && hasLength!Source)
        {
            static if (withPartial)
            {
                import std.algorithm.comparison : min;
                return source[0 .. min(windowSize, source.length)];
            }
            else
            {
                assert(windowSize <= source.length, "The last element is smaller than the current windowSize.");
                return source[0 .. windowSize];
            }
        }
        else
        {
            static if (withPartial)
                return source.save.take(windowSize);
            else
                return source.save.takeExactly(windowSize);
        }
    }

    /// Ditto
    void popFront()
    {
        assert(!empty, "Attempting to call popFront() on an empty slide.");
        source.popFrontN(stepSize);

        if (source.empty)
        {
            _empty = true;
            return;
        }

        static if (withPartial)
        {
            if (hasShownPartialBefore)
                _empty = true;
        }

        static if (needsEndTracker)
        {
            // Check the upcoming slide
            auto poppedElements = nextSource.popFrontN(stepSize);
            static if (withPartial)
            {
                if (poppedElements < stepSize || nextSource.empty)
                    hasShownPartialBefore = true;
            }
            else
            {
                if (poppedElements < stepSize)
                    _empty = true;
            }
        }
        else
        {
            static if (withPartial)
            {
                if (source.length <= windowSize)
                    hasShownPartialBefore = true;
            }
            else
            {
                if (source.length < windowSize)
                    _empty = true;
            }
        }
    }

    static if (!isInfinite!Source)
    {
        /// Ditto
        @property bool empty() const
        {
            return _empty;
        }
    }
    else
    {
        // undocumented
        enum empty = false;
    }

    /// Ditto
    @property typeof(this) save()
    {
        return typeof(this)(source.save, windowSize, stepSize);
    }

    static if (hasLength!Source)
    {
        // gaps between the last element and the end of the range
        private size_t gap()
        {
            /*
            * Note:
            * - In the following `end` is the exclusive end as used in opSlice
            * - For the trivial case with `stepSize = 1`  `end` is at `len`:
            *
            *    iota(4).slide(2) = [[0, 1], [1, 2], [2, 3]]    (end = 4)
            *    iota(4).slide(3) = [[0, 1, 2], [1, 2, 3]]      (end = 4)
            *
            * - For the non-trivial cases, we need to calculate the gap
            *   between `len` and `end` - this is the number of missing elements
            *   from the input range:
            *
            *    iota(7).slide(2, 3) = [[0, 1], [3, 4]] || <gap: 2> 6
            *    iota(7).slide(2, 4) = [[0, 1], [4, 5]] || <gap: 1> 6
            *    iota(7).slide(1, 5) = [[0], [5]]       || <gap: 1> 6
            *
            *   As it can be seen `gap` can be at most `stepSize - 1`
            *   More generally the elements of the sliding window with
            *   `w = windowSize` and `s = stepSize` are:
            *
            *     [0, w], [s, s + w], [2 * s, 2 * s + w], ... [n * s, n * s + w]
            *
            *  We can thus calculate the gap between the `end` and `len` as:
            *
            *     gap = len - (n * s + w) = len - w - (n * s)
            *
            *  As we aren't interested in exact value of `n`, but the best
            *  minimal `gap` value, we can use modulo to "cut" `len - w` optimally:
            *
            *     gap = len - w - (s - s ... - s) = (len - w) % s
            *
            *  So for example:
            *
            *    iota(7).slide(2, 3) = [[0, 1], [3, 4]]
            *      gap: (7 - 2) % 3 = 5 % 3 = 2
            *      end: 7 - 2 = 5
            *
            *    iota(7).slide(4, 2) = [[0, 1, 2, 3], [2, 3, 4, 5]]
            *      gap: (7 - 4) % 2 = 3 % 2 = 1
            *      end: 7 - 1 = 6
            */
            return (source.length - windowSize)  % stepSize;
        }

        private size_t numberOfFullFrames()
        {
            /**
            5.iota.slides(2, 1) => [0, 1], [1, 2], [2, 3], [3, 4]       (4)
            7.iota.slides(2, 2) => [0, 1], [2, 3], [4, 5], [6]          (3)
            7.iota.slides(2, 3) => [0, 1], [3, 4], [6]                  (2)
            6.iota.slides(3, 2) => [0, 1, 2], [2, 3, 4], [4, 5]         (2)
            7.iota.slides(3, 3) => [0, 1, 2], [3, 4, 5], [6]            (2)

            As the last window is only added iff its complete,
            we don't count the last window except if it's full due to integer rounding.
            */
            return 1 + (source.length - windowSize) / stepSize;
        }

        // Whether the last slide frame size is less than windowSize
        private bool hasPartialElements()
        {
            static if (withPartial)
                return gap != 0 && source.length > numberOfFullFrames * stepSize;
            else
                return 0;
        }

        /// Length. Only if `hasLength!Source` is `true`
        @property size_t length()
        {
            if (source.length < windowSize)
            {
                static if (withPartial)
                    return source.length > 0;
                else
                    return 0;
            }
            else
            {
                /***
                  We bump the pointer by stepSize for every element.
                  If withPartial, we don't count the last element if its size
                  isn't windowSize

                  At most:
                      [p, p + stepSize, ..., p + stepSize * n]

                5.iota.slides(2, 1) => [0, 1], [1, 2], [2, 3], [3, 4]       (4)
                7.iota.slides(2, 2) => [0, 1], [2, 3], [4, 5], [6]          (4)
                7.iota.slides(2, 3) => [0, 1], [3, 4], [6]                  (3)
                7.iota.slides(3, 2) => [0, 1, 2], [2, 3, 4], [4, 5, 6]      (3)
                7.iota.slides(3, 3) => [0, 1, 2], [3, 4, 5], [6]            (3)
                */
                return numberOfFullFrames + hasPartialElements;
            }
        }
    }

    static if (hasSlicing!Source)
    {
        /**
        Indexing and slicing operations. Provided only if
        `hasSlicing!Source` is `true`.
         */
        auto opIndex(size_t index)
        {
            immutable start = index * stepSize;

            static if (isInfinite!Source)
            {
                immutable end = start + windowSize;
            }
            else
            {
                import std.algorithm.comparison : min;

                immutable len = source.length;
                assert(start < len, "slide index out of bounds");
                immutable end = min(start + windowSize, len);
            }

            return source[start .. end];
        }

        static if (!isInfinite!Source)
        {
            /// ditto
            typeof(this) opSlice(size_t lower, size_t upper)
            {
                import std.algorithm.comparison : min;

                assert(upper <= length, "slide slicing index out of bounds");
                assert(lower <= upper, "slide slicing index out of bounds");

                lower *= stepSize;
                upper *= stepSize;

                immutable len = source.length;

                static if (withPartial)
                {
                    import std.algorithm.comparison : max;

                    if (lower == upper)
                        return this[$ .. $];

                    /*
                    A) If `stepSize` >= `windowSize` => `rightPos = upper`

                       [0, 1, 2, 3, 4, 5, 6].slide(2, 3) -> s = [[0, 1], [3, 4], [6]]
                         rightPos for s[0 .. 2]: (upper=2) * (stepSize=3) = 6
                         6.iota.slide(2, 3) = [[0, 1], [3, 4]]

                    B) If `stepSize` < `windowSize` => add `windowSize - stepSize` to `upper`

                       [0, 1, 2, 3].slide(2) = [[0, 1], [1, 2], [2, 3]]
                         rightPos for s[0 .. 1]: = (upper=1) * (stepSize=1) = 1
                         1.iota.slide(2) = [[0]]

                         rightPos for s[0 .. 1]: = (upper=1) * (stepSize=1) + (windowSize-stepSize=1) = 2
                         1.iota.slide(2) = [[0, 1]]

                       More complex:

                       20.iota.slide(7, 6)[0 .. 2]
                         rightPos: (upper=2) * (stepSize=6) = 12.iota
                         12.iota.slide(7, 6) = [[0, 1, 2, 3, 4, 5, 6], [6, 7, 8, 9, 10, 11]]

                       Now we add up for the difference between `windowSize` and `stepSize`:

                         rightPos: (upper=2) * (stepSize=6) + (windowSize-stepSize=1) = 13.iota
                         13.iota.slide(7, 6) = [[0, 1, 2, 3, 4, 5, 6], [6, 7, 8, 9, 10, 11, 12]]
                    */
                    immutable rightPos = min(len, upper + max(0, windowSize - stepSize));
                }
                else
                {
                    /*
                    After we have normalized `lower` and `upper` by `stepSize`,
                    we only need to look at the case of `stepSize=1`.
                    As `leftPos`, is equal to `lower`, we will only look `rightPos`.
                    Notice that starting from `upper`,
                    we only need to move for `windowSize - 1` to the right:

                      - [0, 1, 2, 3].slide(2) -> s = [[0, 1], [1, 2], [2, 3]]
                        rightPos for s[0 .. 3]: (upper=3) + (windowSize=2) - 1 = 4

                      - [0, 1, 2, 3].slide(3) -> s = [[0, 1, 2], [1, 2, 3]]
                        rightPos for s[0 .. 2]: (upper=2) + (windowSize=3) - 1 = 4

                      - [0, 1, 2, 3, 4].slide(4) -> s = [[0, 1, 2, 3], [1, 2, 3, 4]]
                        rightPos for s[0 .. 2]: (upper=2) + (windowSize=4) - 1 = 5
                    */
                    immutable rightPos = min(upper + windowSize - 1, len);
                }

                return typeof(this)(source[min(lower, len) .. rightPos], windowSize, stepSize);
            }
        }
        else static if (hasSliceToEnd)
        {
            // For slicing an infinite chunk, we need to slice the source to the infinite end.
            auto opSlice(size_t lower, size_t upper)
            {
                assert(lower <= upper, "slide slicing index out of bounds");
                return typeof(this)(source[lower * stepSize .. $], windowSize, stepSize)
                                    .takeExactly(upper - lower);
            }
        }

        static if (isInfinite!Source)
        {
            static if (hasSliceToEnd)
            {
                private static struct DollarToken{}
                DollarToken opDollar()
                {
                    return DollarToken();
                }
                //Slice to dollar
                typeof(this) opSlice(size_t lower, DollarToken)
                {
                    return typeof(this)(source[lower * stepSize .. $], windowSize, stepSize);
                }
            }
        }
        else
        {
            // Dollar token carries a static type, with no extra information.
            // It can lazily transform into source.length on algorithmic
            // operations such as : slide[$/2, $-1];
            private static struct DollarToken
            {
                private size_t _length;
                alias _length this;
            }

            DollarToken opDollar()
            {
                return DollarToken(this.length);
            }

            // Optimized slice overloads optimized for using dollar.
            typeof(this) opSlice(DollarToken, DollarToken)
            {
                static if (hasSliceToEnd)
                {
                    return typeof(this)(source[$ .. $], windowSize, stepSize);
                }
                else
                {
                    immutable len = source.length;
                    return typeof(this)(source[len .. len], windowSize, stepSize);
                }
            }

            // Optimized slice overloads optimized for using dollar.
            typeof(this) opSlice(size_t lower, DollarToken)
            {
                import std.algorithm.comparison : min;
                assert(lower <= length, "slide slicing index out of bounds");
                lower *= stepSize;
                static if (hasSliceToEnd)
                {
                    return typeof(this)(source[min(lower, source.length) .. $], windowSize, stepSize);
                }
                else
                {
                    immutable len = source.length;
                    return typeof(this)(source[min(lower, len) .. len], windowSize, stepSize);
                }
            }

            // Optimized slice overloads optimized for using dollar.
            typeof(this) opSlice(DollarToken, size_t upper)
            {
                assert(upper == length, "slide slicing index out of bounds");
                return this[$ .. $];
            }
        }

        // Bidirectional range primitives
        static if (!isInfinite!Source)
        {
            /**
            Bidirectional range primitives. Provided only if both
            `hasSlicing!Source` and `!isInfinite!Source` are `true`.
             */
            @property auto back()
            {
                import std.algorithm.comparison : max;

                assert(!empty, "Attempting to access front on an empty slide");

                immutable len = source.length;

                static if (withPartial)
                {
                    if (source.length <= windowSize)
                        return source[0 .. source.length];

                    if (hasPartialElements)
                        return source[numberOfFullFrames * stepSize .. len];
                }

                // check for underflow
                immutable start = (len > windowSize + gap) ? len - windowSize - gap : 0;
                return source[start .. len - gap];
            }

            /// Ditto
            void popBack()
            {
                assert(!empty, "Attempting to call popBack() on an empty slide");

                // Move by stepSize
                immutable end = source.length > stepSize ? source.length - stepSize : 0;

                static if (withPartial)
                {
                    if (hasShownPartialBefore || source.empty)
                    {
                        _empty = true;
                        return;
                    }

                    // pop by stepSize, except for the partial frame at the end
                    if (hasPartialElements)
                        source = source[0 .. source.length - gap];
                    else
                        source = source[0 .. end];
                }
                else
                {
                    source = source[0 .. end];
                }

                if (source.length < windowSize)
                    _empty = true;
            }
        }
    }
}

// test @nogc
@safe pure nothrow @nogc unittest
{
    import std.algorithm.comparison : equal;

    static immutable res1 = [[0], [1], [2], [3]];
    assert(4.iota.slide!(Yes.withPartial)(1).equal!equal(res1));

    static immutable res2 = [[0, 1], [1, 2], [2, 3]];
    assert(4.iota.slide!(Yes.withPartial)(2).equal!equal(res2));
}

// test different window sizes
@safe pure nothrow unittest
{
    import std.array : array;
    import std.algorithm.comparison : equal;

    assert([0, 1, 2, 3].slide!(Yes.withPartial)(1).array == [[0], [1], [2], [3]]);
    assert([0, 1, 2, 3].slide!(Yes.withPartial)(2).array == [[0, 1], [1, 2], [2, 3]]);
    assert([0, 1, 2, 3].slide!(Yes.withPartial)(3).array == [[0, 1, 2], [1, 2, 3]]);
    assert([0, 1, 2, 3].slide!(Yes.withPartial)(4).array == [[0, 1, 2, 3]]);
    assert([0, 1, 2, 3].slide!(No.withPartial)(5).walkLength == 0);
    assert([0, 1, 2, 3].slide!(Yes.withPartial)(5).array == [[0, 1, 2, 3]]);

    assert(iota(2).slide!(Yes.withPartial)(2).front.equal([0, 1]));
    assert(iota(3).slide!(Yes.withPartial)(2).equal!equal([[0, 1],[1, 2]]));
    assert(iota(3).slide!(Yes.withPartial)(3).equal!equal([[0, 1, 2]]));
    assert(iota(3).slide!(No.withPartial)(4).walkLength == 0);
    assert(iota(3).slide!(Yes.withPartial)(4).equal!equal([[0, 1, 2]]));
    assert(iota(1, 4).slide!(Yes.withPartial)(1).equal!equal([[1], [2], [3]]));
    assert(iota(1, 4).slide!(Yes.withPartial)(3).equal!equal([[1, 2, 3]]));
}

// test combinations
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : tuple;

    alias t = tuple;
    auto list = [
        t(t(1, 1), [[0], [1], [2], [3], [4], [5]]),
        t(t(1, 2), [[0], [2], [4]]),
        t(t(1, 3), [[0], [3]]),
        t(t(1, 4), [[0], [4]]),
        t(t(1, 5), [[0], [5]]),
        t(t(2, 1), [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]),
        t(t(2, 2), [[0, 1], [2, 3], [4, 5]]),
        t(t(2, 3), [[0, 1], [3, 4]]),
        t(t(2, 4), [[0, 1], [4, 5]]),
        t(t(3, 1), [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5]]),
        t(t(3, 3), [[0, 1, 2], [3, 4, 5]]),
        t(t(4, 1), [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]),
        t(t(4, 2), [[0, 1, 2, 3], [2, 3, 4, 5]]),
        t(t(5, 1), [[0, 1, 2, 3, 4], [1, 2, 3, 4, 5]]),
    ];

    static foreach (Partial; [Yes.withPartial, No.withPartial])
        foreach (e; list)
            assert(6.iota.slide!Partial(e[0].expand).equal!equal(e[1]));

    auto listSpecial = [
        t(t(2, 5), [[0, 1], [5]]),
        t(t(3, 2), [[0, 1, 2], [2, 3, 4], [4, 5]]),
        t(t(3, 4), [[0, 1, 2], [4, 5]]),
        t(t(4, 3), [[0, 1, 2, 3], [3, 4, 5]]),
        t(t(5, 2), [[0, 1, 2, 3, 4], [2, 3, 4, 5]]),
        t(t(5, 3), [[0, 1, 2, 3, 4], [3, 4, 5]]),
    ];
    foreach (e; listSpecial)
    {
        assert(6.iota.slide!(Yes.withPartial)(e[0].expand).equal!equal(e[1]));
        assert(6.iota.slide!(No.withPartial)(e[0].expand).equal!equal(e[1].dropBackOne));
    }
}

// test emptiness and copyability
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;

    // check with empty input
    int[] d;
    assert(d.slide!(Yes.withPartial)(2).empty);
    assert(d.slide!(Yes.withPartial)(2, 2).empty);

    // is copyable?
    auto e = iota(5).slide!(Yes.withPartial)(2);
    e.popFront;
    assert(e.save.equal!equal([[1, 2], [2, 3], [3, 4]]));
    assert(e.save.equal!equal([[1, 2], [2, 3], [3, 4]]));
    assert(e.map!"a.array".array == [[1, 2], [2, 3], [3, 4]]);
}

// test with strings
@safe pure nothrow unittest
{
    import std.algorithm.iteration : each;

    int[dstring] f;
    "AGAGA"d.slide!(Yes.withPartial)(3).each!(a => f[a]++);
    assert(f == ["AGA"d: 2, "GAG"d: 1]);

    int[dstring] g;
    "ABCDEFG"d.slide!(Yes.withPartial)(3, 3).each!(a => g[a]++);
    assert(g == ["ABC"d:1, "DEF"d:1, "G": 1]);
    g = null;
    "ABCDEFG"d.slide!(No.withPartial)(3, 3).each!(a => g[a]++);
    assert(g == ["ABC"d:1, "DEF"d:1]);
}

// test with utf8 strings
@safe unittest
{
    import std.stdio;
    import std.algorithm.comparison : equal;

    assert("ä.ö.ü.".slide!(Yes.withPartial)(3, 2).equal!equal(["ä.ö", "ö.ü", "ü."]));
    assert("ä.ö.ü.".slide!(No.withPartial)(3, 2).equal!equal(["ä.ö", "ö.ü"]));

    "😄😅😆😇😈😄😅😆😇😈".slide!(Yes.withPartial)(2, 4).equal!equal(["😄😅", "😈😄", "😇😈"]);
    "😄😅😆😇😈😄😅😆😇😈".slide!(No.withPartial)(2, 4).equal!equal(["😄😅", "😈😄", "😇😈"]);
    "😄😅😆😇😈😄😅😆😇😈".slide!(Yes.withPartial)(3, 3).equal!equal(["😄😅😆", "😇😈😄", "😅😆😇", "😈"]);
    "😄😅😆😇😈😄😅😆😇😈".slide!(No.withPartial)(3, 3).equal!equal(["😄😅😆", "😇😈😄", "😅😆😇"]);
}

// test length
@safe pure nothrow unittest
{
    // Slides with fewer elements are empty or 1 for Yes.withPartial
    static foreach (expectedLength, Partial; [No.withPartial, Yes.withPartial])
    {{
        assert(3.iota.slide!(Partial)(4, 2).walkLength == expectedLength);
        assert(3.iota.slide!(Partial)(4).walkLength == expectedLength);
        assert(3.iota.slide!(Partial)(4, 3).walkLength == expectedLength);
    }}

    static immutable list = [
    //  iota   slide    expected
        [4,    2, 1,     3, 3],
        [5,    3, 1,     3, 3],
        [7,    2, 2,     4, 3],
        [12,   2, 4,     3, 3],
        [6,    1, 2,     3, 3],
        [6,    2, 4,     2, 2],
        [3,    2, 4,     1, 1],
        [5,    2, 1,     4, 4],
        [7,    2, 2,     4, 3],
        [7,    2, 3,     3, 2],
        [7,    3, 2,     3, 3],
        [7,    3, 3,     3, 2],
    ];
    foreach (e; list)
    {
        assert(e[0].iota.slide!(Yes.withPartial)(e[1], e[2]).length == e[3]);
        assert(e[0].iota.slide!(No.withPartial)(e[1], e[2]).length == e[4]);
    }
}

// test index and slicing
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.array : array;

    static foreach (Partial; [Yes.withPartial, No.withPartial])
    {
        foreach (s; [5, 7, 10, 15, 20])
        foreach (windowSize; 1 .. 10)
        foreach (stepSize; 1 .. 10)
        {
            auto r = s.iota.slide!Partial(windowSize, stepSize);
            auto arr = r.array;
            assert(r.length == arr.length);

            // test indexing
            foreach (i; 0 .. arr.length)
                assert(r[i] == arr[i]);

            // test slicing
            foreach (i; 0 .. arr.length)
            {
                foreach (j; i .. arr.length)
                    assert(r[i .. j].equal(arr[i .. j]));

                assert(r[i .. $].equal(arr[i .. $]));
            }

            // test opDollar slicing
            assert(r[$/2 .. $].equal(arr[$/2 .. $]));
            assert(r[$ .. $].empty);
            if (arr.empty)
            {
                assert(r[$ .. 0].empty);
                assert(r[$/2 .. $].empty);

            }
        }
    }
}

// test with infinite ranges
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    static foreach (Partial; [Yes.withPartial, No.withPartial])
    {{
        // InfiniteRange without RandomAccess
        auto fibs = recurrence!"a[n-1] + a[n-2]"(1, 1);
        assert(fibs.slide!Partial(2).take(2).equal!equal([[1,  1], [1,  2]]));
        assert(fibs.slide!Partial(2, 3).take(2).equal!equal([[1,  1], [3,  5]]));

        // InfiniteRange with RandomAccess and slicing
        auto odds = sequence!("a[0] + n * a[1]")(1, 2);
        auto oddsByPairs = odds.slide!Partial(2);
        assert(oddsByPairs.take(2).equal!equal([[ 1,  3], [ 3,  5]]));
        assert(oddsByPairs[1].equal([3, 5]));
        assert(oddsByPairs[4].equal([9, 11]));

        static assert(hasSlicing!(typeof(odds)));
        assert(oddsByPairs[3 .. 5].equal!equal([[7, 9], [9, 11]]));
        assert(oddsByPairs[3 .. $].take(2).equal!equal([[7, 9], [9, 11]]));

        auto oddsWithGaps = odds.slide!Partial(2, 4);
        assert(oddsWithGaps.take(3).equal!equal([[1, 3], [9, 11], [17, 19]]));
        assert(oddsWithGaps[2].equal([17, 19]));
        assert(oddsWithGaps[1 .. 3].equal!equal([[9, 11], [17, 19]]));
        assert(oddsWithGaps[1 .. $].take(2).equal!equal([[9, 11], [17, 19]]));
    }}
}

// test reverse
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;

    static foreach (Partial; [Yes.withPartial, No.withPartial])
    {{
        foreach (windowSize; 1 .. 15)
        foreach (stepSize; 1 .. 15)
        {
            auto r = 20.iota.slide!Partial(windowSize, stepSize);
            auto rArr = r.array.retro;
            auto rRetro = r.retro;

            assert(rRetro.length == rArr.length);
            assert(rRetro.equal(rArr));
            assert(rRetro.array.retro.equal(r));
        }
    }}
}

// test with dummy ranges
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;
    import std.meta : Filter;

    static foreach (Range; Filter!(isForwardRange, AllDummyRanges))
    {{
        Range r;

        static foreach (Partial; [Yes.withPartial, No.withPartial])
        {
            assert(r.slide!Partial(1).equal!equal(
                [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]
            ));
            assert(r.slide!Partial(2).equal!equal(
                [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10]]
            ));
            assert(r.slide!Partial(3).equal!equal(
                [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6],
                [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]
            ));
            assert(r.slide!Partial(6).equal!equal(
                [[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8],
                [4, 5, 6, 7, 8, 9], [5, 6, 7, 8, 9, 10]]
            ));
        }

        // special cases
        assert(r.slide!(Yes.withPartial)(15).equal!equal(iota(1, 11).only));
        assert(r.slide!(Yes.withPartial)(15).walkLength == 1);
        assert(r.slide!(No.withPartial)(15).empty);
        assert(r.slide!(No.withPartial)(15).walkLength == 0);
    }}
}

// test with dummy ranges
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;
    import std.meta : Filter;
    import std.typecons : tuple;

    alias t = tuple;
    static immutable list = [
    // iota   slide    expected
        t(6,  t(4, 2), [[1, 2, 3, 4], [3, 4, 5, 6]]),
        t(6,  t(4, 6), [[1, 2, 3, 4]]),
        t(6,  t(4, 1), [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]),
        t(7,  t(4, 1), [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]]),
        t(7,  t(4, 3), [[1, 2, 3, 4], [4, 5, 6, 7]]),
        t(8,  t(4, 2), [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8]]),
        t(8,  t(4, 1), [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]),
        t(8,  t(3, 4), [[1, 2, 3], [5, 6, 7]]),
        t(10, t(3, 7), [[1, 2, 3], [8, 9, 10]]),
    ];

    static foreach (Range; Filter!(isForwardRange, AllDummyRanges))
    static foreach (Partial; [Yes.withPartial, No.withPartial])
    foreach (e; list)
        assert(Range().take(e[0]).slide!Partial(e[1].expand).equal!equal(e[2]));

    static immutable listSpecial = [
    // iota   slide    expected
        t(6,  t(4, 3), [[1, 2, 3, 4], [4, 5, 6]]),
        t(7,  t(4, 5), [[1, 2, 3, 4], [6, 7]]),
        t(7,  t(4, 4), [[1, 2, 3, 4], [5, 6, 7]]),
        t(7,  t(4, 2), [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7]]),
        t(8,  t(4, 3), [[1, 2, 3, 4], [4, 5, 6, 7], [7, 8]]),
        t(8,  t(3, 3), [[1, 2, 3], [4, 5, 6], [7, 8]]),
        t(8,  t(3, 6), [[1, 2, 3], [7, 8]]),
        t(10, t(7, 6), [[1, 2, 3, 4, 5, 6, 7], [7, 8, 9, 10]]),
        t(10, t(3, 8), [[1, 2, 3], [9, 10]]),
    ];
    static foreach (Range; Filter!(isForwardRange, AllDummyRanges))
    static foreach (Partial; [Yes.withPartial, No.withPartial])
    foreach (e; listSpecial)
    {
        Range r;
        assert(r.take(e[0]).slide!(Yes.withPartial)(e[1].expand).equal!equal(e[2]));
        assert(r.take(e[0]).slide!(No.withPartial)(e[1].expand).equal!equal(e[2].dropBackOne));
    }
}

// test reverse with dummy ranges
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;
    import std.meta : Filter, templateAnd;
    import std.typecons : tuple;
    alias t = tuple;

    static immutable list = [
    //   slide   expected
        t(1, 1, [[10], [9], [8], [7], [6], [5], [4], [3], [2], [1]]),
        t(2, 1, [[9, 10], [8, 9], [7, 8], [6, 7], [5, 6], [4, 5], [3, 4], [2, 3], [1, 2]]),
        t(5, 1, [[6, 7, 8, 9, 10], [5, 6, 7, 8, 9], [4, 5, 6, 7, 8],
                 [3, 4, 5, 6, 7], [2, 3, 4, 5, 6], [1, 2, 3, 4, 5]]),
        t(2, 2, [[9, 10], [7, 8], [5, 6], [3, 4], [1, 2]]),
        t(2, 4, [[9, 10], [5, 6], [1, 2]]),
    ];

    static foreach (Range; Filter!(templateAnd!(hasSlicing, hasLength, isBidirectionalRange), AllDummyRanges))
    {{
        Range r;
        static foreach (Partial; [Yes.withPartial, No.withPartial])
        {
            foreach (e; list)
                assert(r.slide!Partial(e[0], e[1]).retro.equal!equal(e[2]));

            // front = back
            foreach (windowSize; 1 .. 10)
            foreach (stepSize; 1 .. 10)
            {
                auto slider = r.slide!Partial(windowSize, stepSize);
                auto sliderRetro = slider.retro.array;
                assert(slider.length == sliderRetro.length);
                assert(sliderRetro.retro.equal!equal(slider));
            }
        }

        // special cases
        assert(r.slide!(No.withPartial)(15).retro.walkLength == 0);
        assert(r.slide!(Yes.withPartial)(15).retro.equal!equal(iota(1, 11).only));
    }}
}

// test different sliceable ranges
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges;
    import std.meta : AliasSeq;

    struct SliceableRange(Range, Flag!"withOpDollar" withOpDollar = No.withOpDollar,
                                 Flag!"withInfiniteness" withInfiniteness = No.withInfiniteness)
    {
        Range arr = 10.iota.array; // similar to DummyRange
        @property auto save() { return typeof(this)(arr); }
        @property auto front() { return arr[0]; }
        void popFront() { arr.popFront(); }
        auto opSlice(size_t i, size_t j)
        {
            // subslices can't be infinite
            return SliceableRange!(Range, withOpDollar, No.withInfiniteness)(arr[i .. j]);
        }

        static if (withInfiniteness)
        {
            enum empty = false;
        }
        else
        {
            @property bool empty() { return arr.empty; }
            @property auto length() { return arr.length; }
        }

        static if (withOpDollar)
        {
            static if (withInfiniteness)
            {
                struct Dollar {}
                Dollar opDollar() const { return Dollar.init; }

                // Slice to dollar
                typeof(this) opSlice(size_t lower, Dollar)
                {
                    return typeof(this)(arr[lower .. $]);
                }

            }
            else
            {
                alias opDollar = length;
            }
        }
    }

    import std.meta : Filter,  templateNot;
    alias SliceableDummyRanges = Filter!(hasSlicing, AllDummyRanges);

    static foreach (Partial; [Yes.withPartial, No.withPartial])
    {{
        static foreach (Range; SliceableDummyRanges)
        {{
            Range r;
            r.reinit;
            r.arr[] -= 1; // use a 0-based array (for clarity)

            assert(r.slide!Partial(2)[0].equal([0, 1]));
            assert(r.slide!Partial(2)[1].equal([1, 2]));

            // saveable
            auto s = r.slide!Partial(2);
            assert(s[0 .. 2].equal!equal([[0, 1], [1, 2]]));
            s.save.popFront;
            assert(s[0 .. 2].equal!equal([[0, 1], [1, 2]]));

            assert(r.slide!Partial(3)[1 .. 3].equal!equal([[1, 2, 3], [2, 3, 4]]));
        }}

        static foreach (Range; Filter!(templateNot!isInfinite, SliceableDummyRanges))
        {{
            Range r;
            r.reinit;
            r.arr[] -= 1; // use a 0-based array (for clarity)

            assert(r.slide!(No.withPartial)(6).equal!equal(
                [[0, 1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7],
                [3, 4, 5, 6, 7, 8], [4, 5, 6, 7, 8, 9]]
            ));
            assert(r.slide!(No.withPartial)(16).empty);

            assert(r.slide!Partial(4)[0 .. $].equal(r.slide!Partial(4)));
            assert(r.slide!Partial(2)[$/2 .. $].equal!equal([[4, 5], [5, 6], [6, 7], [7, 8], [8, 9]]));
            assert(r.slide!Partial(2)[$ .. $].empty);

            assert(r.slide!Partial(3).retro.equal!equal(
                [[7, 8, 9], [6, 7, 8], [5, 6, 7], [4, 5, 6], [3, 4, 5], [2, 3, 4], [1, 2, 3], [0, 1, 2]]
            ));
        }}

        alias T = int[];

        // separate checks for infinity
        auto infIndex = SliceableRange!(T, No.withOpDollar, Yes.withInfiniteness)([0, 1, 2, 3]);
        assert(infIndex.slide!Partial(2)[0].equal([0, 1]));
        assert(infIndex.slide!Partial(2)[1].equal([1, 2]));

        auto infDollar = SliceableRange!(T, Yes.withOpDollar, Yes.withInfiniteness)();
        assert(infDollar.slide!Partial(2)[1 .. $].front.equal([1, 2]));
        assert(infDollar.slide!Partial(4)[0 .. $].front.equal([0, 1, 2, 3]));
        assert(infDollar.slide!Partial(4)[2 .. $].front.equal([2, 3, 4, 5]));
    }}
}

// https://issues.dlang.org/show_bug.cgi?id=19082
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    assert([1].map!(x => x).slide(2).equal!equal([[1]]));
}

// https://issues.dlang.org/show_bug.cgi?id=19642
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : splitter;

    assert("ab cd".splitter(' ').slide!(No.withPartial)(2).equal!equal([["ab", "cd"]]));
}

// https://issues.dlang.org/show_bug.cgi?id=23976
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : splitter;

    assert("1<2".splitter('<').slide(2).equal!equal([["1", "2"]]));
}

private struct OnlyResult(Values...)
if (Values.length > 1)
{
    import std.meta : ApplyRight;
    import std.traits : isAssignable;

    private enum arity = Values.length;

    private alias UnqualValues = staticMap!(Unqual, Values);

    private enum canAssignElements = allSatisfy!(
        ApplyRight!(isAssignable, CommonType!Values),
        Values
    );

    private this(return scope ref Values values)
    {
        ref @trusted unqual(T)(ref T x){return cast() x;}

        // TODO: this calls any possible copy constructors without qualifiers.
        // Find a way to initialize values using qualified copy constructors.
        static foreach (i; 0 .. Values.length)
        {
            this.values[i] = unqual(values[i]);
        }
        this.backIndex = arity;
    }

    bool empty() @property
    {
        return frontIndex >= backIndex;
    }

    CommonType!Values front() @property
    {
        assert(!empty, "Attempting to fetch the front of an empty Only range");
        return this[0];
    }

    static if (canAssignElements)
    {
        void front(CommonType!Values value) @property
        {
            assert(!empty, "Attempting to assign the front of an empty Only range");
            this[0] = value;
        }
    }

    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty Only range");
        ++frontIndex;
    }

    CommonType!Values back() @property
    {
        assert(!empty, "Attempting to fetch the back of an empty Only range");
        return this[$ - 1];
    }

    static if (canAssignElements)
    {
        void back(CommonType!Values value) @property
        {
            assert(!empty, "Attempting to assign the back of an empty Only range");
            this[$ - 1] = value;
        }
    }

    void popBack()
    {
        assert(!empty, "Attempting to popBack an empty Only range");
        --backIndex;
    }

    OnlyResult save() @property
    {
        return this;
    }

    size_t length() const @property
    {
        return backIndex - frontIndex;
    }

    alias opDollar = length;

    @trusted CommonType!Values opIndex(size_t idx)
    {
        // when i + idx points to elements popped
        // with popBack
        assert(idx < length, "Attempting to fetch an out of bounds index from an Only range");
        final switch (frontIndex + idx)
            static foreach (i, T; Values)
            case i:
                return cast(T) values[i];
    }

    static if (canAssignElements)
    {
        void opIndexAssign(CommonType!Values value, size_t idx)
        {
            assert(idx < length, "Attempting to assign to an out of bounds index of an Only range");
            final switch (frontIndex + idx)
                static foreach (i; 0 .. Values.length)
                case i:
                    values[i] = value;
        }
    }

    OnlyResult opSlice()
    {
        return this;
    }

    OnlyResult opSlice(size_t from, size_t to)
    {
        OnlyResult result = this;
        result.frontIndex += from;
        result.backIndex = this.frontIndex + to;
        assert(
            from <= to,
            "Attempting to slice an Only range with a larger first argument than the second."
        );
        assert(
            to <= length,
            "Attempting to slice using an out of bounds index on an Only range"
        );
        return result;
    }

    private size_t frontIndex = 0;
    private size_t backIndex = 0;

    // https://issues.dlang.org/show_bug.cgi?id=10643
    version (none)
    {
        import std.traits : hasElaborateAssign;
        static if (hasElaborateAssign!T)
            private UnqualValues values;
        else
            private UnqualValues values = void;
    }
    else
        // These may alias to shared or immutable data. Do not let the user
        // to access these directly, and do not allow mutation without checking
        // the qualifier.
        private UnqualValues values;
}

// Specialize for single-element results
private struct OnlyResult(T)
{
    import std.traits : isAssignable;

    @property T front()
    {
        assert(!empty, "Attempting to fetch the front of an empty Only range");
        return fetchFront();
    }
    static if (isAssignable!T)
    {
        @property void front(T value)
        {
            assert(!empty, "Attempting to assign the front of an empty Only range");
            assignFront(value);
        }
    }
    @property T back()
    {
        assert(!empty, "Attempting to fetch the back of an empty Only range");
        return fetchFront();
    }
    static if (isAssignable!T)
    {
        @property void back(T value)
        {
            assert(!empty, "Attempting to assign the front of an empty Only range");
            assignFront(value);
        }
    }
    @property bool empty() const { return _empty; }
    @property size_t length() const { return !_empty; }
    @property auto save() { return this; }
    void popFront()
    {
        assert(!_empty, "Attempting to popFront an empty Only range");
        _empty = true;
    }
    void popBack()
    {
        assert(!_empty, "Attempting to popBack an empty Only range");
        _empty = true;
    }
    alias opDollar = length;

    // FIXME Workaround for https://issues.dlang.org/show_bug.cgi?id=24415
    import std.traits : hasElaborateCopyConstructor;
    static if (hasElaborateCopyConstructor!T)
    {
        private static struct WorkaroundBugzilla24415 {}
        public this()(WorkaroundBugzilla24415) {}
    }

    private this()(return scope auto ref T value)
    {
        ref @trusted unqual(ref T x){return cast() x;}
        // TODO: this calls the possible copy constructor without qualifiers.
        // Find a way to initialize value using a qualified copy constructor.
        this._value = unqual(value);
        this._empty = false;
    }

    T opIndex(size_t i)
    {
        assert(!_empty && i == 0, "Attempting to fetch an out of bounds index from an Only range");
        return fetchFront();
    }

    static if (isAssignable!T)
    {
        void opIndexAssign(T value, size_t i)
        {
            assert(!_empty && i == 0, "Attempting to assign an out of bounds index of an Only range");
            assignFront(value);
        }
    }

    OnlyResult opSlice()
    {
        return this;
    }

    OnlyResult opSlice(size_t from, size_t to)
    {
        assert(
            from <= to,
            "Attempting to slice an Only range with a larger first argument than the second."
        );
        assert(
            to <= length,
            "Attempting to slice using an out of bounds index on an Only range"
        );
        OnlyResult copy = this;
        copy._empty = _empty || from == to;
        return copy;
    }

    // This may alias to shared or immutable data. Do not let the user
    // to access this directly, and do not allow mutation without checking
    // the qualifier.
    private Unqual!T _value;
    private bool _empty = true;
    private @trusted T fetchFront()
    {
        return *cast(T*)&_value;
    }
    static if (isAssignable!T)
    {
        private @trusted void assignFront(T newValue)
        {
            *cast(T*) &_value = newValue;
        }
    }
}

/**
Assemble `values` into a range that carries all its
elements in-situ.

Useful when a single value or multiple disconnected values
must be passed to an algorithm expecting a range, without
having to perform dynamic memory allocation.

As copying the range means copying all elements, it can be
safely returned from functions. For the same reason, copying
the returned range may be expensive for a large number of arguments.

Params:
    values = the values to assemble together

Returns:
    A `RandomAccessRange` of the assembled values.

    The returned range can be sliced. Its elements can be assigned to if every
    type in `Values` supports assignment from the range's element type.

See_Also: $(LREF chain) to chain ranges
 */
auto only(Values...)(return scope Values values)
if (!is(CommonType!Values == void))
{
    return OnlyResult!Values(values);
}

/// ditto
auto only()()
{
    // cannot use noreturn due to https://issues.dlang.org/show_bug.cgi?id=22383
    struct EmptyElementType {}
    EmptyElementType[] result;
    return result;
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter, joiner, map;
    import std.algorithm.searching : findSplitBefore;
    import std.uni : isUpper;

    assert(equal(only('♡'), "♡"));
    assert([1, 2, 3, 4].findSplitBefore(only(3))[0] == [1, 2]);

    assert(only("one", "two", "three").joiner(" ").equal("one two three"));

    string title = "The D Programming Language";
    assert(title
        .filter!isUpper // take the upper case letters
        .map!only       // make each letter its own range
        .joiner(".")    // join the ranges together lazily
        .equal("T.D.P.L"));
}

// https://issues.dlang.org/show_bug.cgi?id=20314
@safe unittest
{
    import std.algorithm.iteration : joiner;

    const string s = "foo", t = "bar";

    assert([only(s, t), only(t, s)].joiner(only(", ")).join == "foobar, barfoo");
}

// Tests the zero-element result
@safe unittest
{
    import std.algorithm.comparison : equal;

    auto emptyRange = only();

    alias EmptyRange = typeof(emptyRange);
    static assert(isInputRange!EmptyRange);
    static assert(isForwardRange!EmptyRange);
    static assert(isBidirectionalRange!EmptyRange);
    static assert(isRandomAccessRange!EmptyRange);
    static assert(hasLength!EmptyRange);
    static assert(hasSlicing!EmptyRange);

    assert(emptyRange.empty);
    assert(emptyRange.length == 0);
    assert(emptyRange.equal(emptyRange[]));
    assert(emptyRange.equal(emptyRange.save));
    assert(emptyRange[0 .. 0].equal(emptyRange));
}

// Tests the single-element result
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : tuple;
    foreach (x; tuple(1, '1', 1.0, "1", [1]))
    {
        auto a = only(x);
        typeof(x)[] e = [];
        assert(a.front == x);
        assert(a.back == x);
        assert(!a.empty);
        assert(a.length == 1);
        assert(equal(a, a[]));
        assert(equal(a, a[0 .. 1]));
        assert(equal(a[0 .. 0], e));
        assert(equal(a[1 .. 1], e));
        assert(a[0] == x);

        auto b = a.save;
        assert(equal(a, b));
        a.popFront();
        assert(a.empty && a.length == 0 && a[].empty);
        b.popBack();
        assert(b.empty && b.length == 0 && b[].empty);

        alias A = typeof(a);
        static assert(isInputRange!A);
        static assert(isForwardRange!A);
        static assert(isBidirectionalRange!A);
        static assert(isRandomAccessRange!A);
        static assert(hasLength!A);
        static assert(hasSlicing!A);
    }

    auto imm = only!(immutable int)(1);
    immutable int[] imme = [];
    assert(imm.front == 1);
    assert(imm.back == 1);
    assert(!imm.empty);
    assert(imm.init.empty); // https://issues.dlang.org/show_bug.cgi?id=13441
    assert(imm.length == 1);
    assert(equal(imm, imm[]));
    assert(equal(imm, imm[0 .. 1]));
    assert(equal(imm[0 .. 0], imme));
    assert(equal(imm[1 .. 1], imme));
    assert(imm[0] == 1);
}

// Tests multiple-element results
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : joiner;
    import std.meta : AliasSeq;
    static assert(!__traits(compiles, only(1, "1")));

    auto nums = only!(byte, uint, long)(1, 2, 3);
    static assert(is(ElementType!(typeof(nums)) == long));
    assert(nums.length == 3);

    foreach (i; 0 .. 3)
        assert(nums[i] == i + 1);

    auto saved = nums.save;

    foreach (i; 1 .. 4)
    {
        assert(nums.front == nums[0]);
        assert(nums.front == i);
        nums.popFront();
        assert(nums.length == 3 - i);
    }

    assert(nums.empty);

    assert(saved.equal(only(1, 2, 3)));
    assert(saved.equal(saved[]));
    assert(saved[0 .. 1].equal(only(1)));
    assert(saved[0 .. 2].equal(only(1, 2)));
    assert(saved[0 .. 3].equal(saved));
    assert(saved[1 .. 3].equal(only(2, 3)));
    assert(saved[2 .. 3].equal(only(3)));
    assert(saved[0 .. 0].empty);
    assert(saved[3 .. 3].empty);

    alias data = AliasSeq!("one", "two", "three", "four");
    static joined =
        ["one two", "one two three", "one two three four"];
    string[] joinedRange = joined;

    static foreach (argCount; 2 .. 5)
    {{
        auto values = only(data[0 .. argCount]);
        alias Values = typeof(values);
        static assert(is(ElementType!Values == string));
        static assert(isInputRange!Values);
        static assert(isForwardRange!Values);
        static assert(isBidirectionalRange!Values);
        static assert(isRandomAccessRange!Values);
        static assert(hasSlicing!Values);
        static assert(hasLength!Values);

        assert(values.length == argCount);
        assert(values[0 .. $].equal(values[0 .. values.length]));
        assert(values.joiner(" ").equal(joinedRange.front));
        joinedRange.popFront();
    }}

    assert(saved.retro.equal(only(3, 2, 1)));
    assert(saved.length == 3);

    assert(saved.back == 3);
    saved.popBack();
    assert(saved.length == 2);
    assert(saved.back == 2);

    assert(saved.front == 1);
    saved.popFront();
    assert(saved.length == 1);
    assert(saved.front == 2);

    saved.popBack();
    assert(saved.empty);

    auto imm = only!(immutable int, immutable int)(42, 24);
    alias Imm = typeof(imm);
    static assert(is(ElementType!Imm == immutable(int)));
    assert(!imm.empty);
    assert(imm.init.empty); // https://issues.dlang.org/show_bug.cgi?id=13441
    assert(imm.front == 42);
    imm.popFront();
    assert(imm.front == 24);
    imm.popFront();
    assert(imm.empty);

    static struct Test { int* a; }
    immutable(Test) test;
    cast(void) only(test, test); // Works with mutable indirection
}

// https://issues.dlang.org/show_bug.cgi?id=21129
@safe unittest
{
    auto range = () @safe {
        const(char)[5] staticStr = "Hello";

        // `only` must store a char[5] - not a char[]!
        return only(staticStr, " World");
    } ();

    assert(range.join == "Hello World");
}

// https://issues.dlang.org/show_bug.cgi?id=21129
@safe unittest
{
    struct AliasedString
    {
        const(char)[5] staticStr = "Hello";

        @property const(char)[] slice() const
        {
            return staticStr[];
        }
        alias slice this;
    }

    auto range = () @safe {
        auto hello = AliasedString();

        // a copy of AliasedString is stored in the range.
        return only(hello, " World");
    } ();

    assert(range.join == "Hello World");
}

// https://issues.dlang.org/show_bug.cgi?id=21022
@safe pure nothrow unittest
{
    struct S
    {
        int* mem;
    }

    immutable S x;
    immutable(S)[] arr;
    auto r1 = arr.chain(x.only, only(x, x));
}

// https://issues.dlang.org/show_bug.cgi?id=24382
@safe unittest
{
    auto r1 = only(123);
    r1.front = 456;
    r1.back = 456;
    r1[0] = 456;

    auto r2 = only(123, 456);
    r2.front = 789;
    r2.back = 789;
    r2[0] = 789;

    auto r3 = only(1.23, 456);
    // Can't assign double to int
    static assert(!__traits(compiles, r3.front = 7.89));
    static assert(!__traits(compiles, r3.back = 7.89));
    // Workaround https://issues.dlang.org/show_bug.cgi?id=24383
    static assert(!__traits(compiles, () { r3[0] = 7.89; }));
    // Can't assign type other than element type (even if compatible)
    static assert(!__traits(compiles, r3.front = 789));
    static assert(!__traits(compiles, r3.back = 789));
    // Workaround https://issues.dlang.org/show_bug.cgi?id=24383
    static assert(!__traits(compiles, () { r3[0] = 789; }));
}

// https://github.com/dlang/phobos/issues/10561
@safe unittest
{
    static struct Range
    {
        private int i;

        enum bool empty = false;
        int front() => i;
        void popFront() { ++i; }
    }
    import std.algorithm;

    assert(Range().take(10).filter!"a>8".chain(only(100)).equal([9,100]));
    assert((new Range()).take(10).filter!"a>8".chain(only(100)).equal([9,100]));
}

/**
Iterate over `range` with an attached index variable.

Each element is a $(REF Tuple, std,typecons) containing the index
and the element, in that order, where the index member is named `index`
and the element member is named `value`.

The index starts at `start` and is incremented by one on every iteration.

Overflow:
    If `range` has length, then it is an error to pass a value for `start`
    so that `start + range.length` is bigger than `Enumerator.max`, thus
    it is ensured that overflow cannot happen.

    If `range` does not have length, and `popFront` is called when
    `front.index == Enumerator.max`, the index will overflow and
    continue from `Enumerator.min`.

Params:
    range = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to attach indexes to
    start = the number to start the index counter from

Returns:
    At minimum, an input range. All other range primitives are given in the
    resulting range if `range` has them. The exceptions are the bidirectional
    primitives, which are propagated only if `range` has length.

Example:
Useful for using `foreach` with an index loop variable:
----
    import std.stdio : stdin, stdout;
    import std.range : enumerate;

    foreach (lineNum, line; stdin.byLine().enumerate(1))
        stdout.writefln("line #%s: %s", lineNum, line);
----
*/
auto enumerate(Enumerator = size_t, Range)(Range range, Enumerator start = 0)
if (isIntegral!Enumerator && isInputRange!Range)
in
{
    static if (hasLength!Range)
    {
        // TODO: core.checkedint supports mixed signedness yet?
        import core.checkedint : adds, addu;
        import std.conv : ConvException, to;
        import std.traits : isSigned, Largest, Signed;

        alias LengthType = typeof(range.length);
        bool overflow;
        static if (isSigned!Enumerator && isSigned!LengthType)
            auto result = adds(start, range.length, overflow);
        else static if (isSigned!Enumerator)
        {
            alias signed_t = Largest!(Enumerator, Signed!LengthType);
            signed_t signedLength;
            //This is to trick the compiler because if length is enum
            //the compiler complains about unreachable code.
            auto getLength()
            {
                return range.length;
            }
            //Can length fit in the signed type
            assert(getLength() < signed_t.max,
                "a signed length type is required but the range's length() is too great");
            signedLength = range.length;
            auto result = adds(start, signedLength, overflow);
        }
        else
        {
            static if (isSigned!LengthType)
                assert(range.length >= 0);
            auto result = addu(start, range.length, overflow);
        }

        assert(!overflow && result <= Enumerator.max);
    }
}
do
{
    // TODO: Relax isIntegral!Enumerator to allow user-defined integral types
    static struct Result
    {
        import std.typecons : Tuple;

        private:
        alias ElemType = Tuple!(Enumerator, "index", ElementType!Range, "value");
        Range range;
        Unqual!Enumerator index;

        public:
        ElemType front() @property
        {
            assert(!range.empty, "Attempting to fetch the front of an empty enumerate");
            return typeof(return)(index, range.front);
        }

        static if (isInfinite!Range)
            enum bool empty = false;
        else
        {
            bool empty() @property
            {
                return range.empty;
            }
        }

        void popFront()
        {
            assert(!range.empty, "Attempting to popFront an empty enumerate");
            range.popFront();
            ++index; // When !hasLength!Range, overflow is expected
        }

        static if (isForwardRange!Range)
        {
            Result save() @property
            {
                return typeof(return)(range.save, index);
            }
        }

        static if (hasLength!Range)
        {
            mixin ImplementLength!range;

            static if (isBidirectionalRange!Range)
            {
                ElemType back() @property
                {
                    assert(!range.empty, "Attempting to fetch the back of an empty enumerate");
                    return typeof(return)(cast(Enumerator)(index + range.length - 1), range.back);
                }

                void popBack()
                {
                    assert(!range.empty, "Attempting to popBack an empty enumerate");
                    range.popBack();
                }
            }
        }

        static if (isRandomAccessRange!Range)
        {
             ElemType opIndex(size_t i)
             {
                return typeof(return)(cast(Enumerator)(index + i), range[i]);
             }
        }

        static if (hasSlicing!Range)
        {
            static if (hasLength!Range)
            {
                Result opSlice(size_t i, size_t j)
                {
                    return typeof(return)(range[i .. j], cast(Enumerator)(index + i));
                }
            }
            else
            {
                static struct DollarToken {}
                enum opDollar = DollarToken.init;

                Result opSlice(size_t i, DollarToken)
                {
                    return typeof(return)(range[i .. $], cast(Enumerator)(index + i));
                }

                auto opSlice(size_t i, size_t j)
                {
                    return this[i .. $].takeExactly(j - 1);
                }
            }
        }
    }

    return Result(range, start);
}

/// Can start enumeration from a negative position:
pure @safe nothrow unittest
{
    import std.array : assocArray;
    import std.range : enumerate;

    bool[int] aa = true.repeat(3).enumerate(-1).assocArray();
    assert(aa[-1]);
    assert(aa[0]);
    assert(aa[1]);
}

// Make sure passing qualified types works
pure @safe nothrow unittest
{
    char[4] v;
    immutable start = 2;
    v[2 .. $].enumerate(start);
}

pure @safe nothrow unittest
{
    import std.internal.test.dummyrange : AllDummyRanges;
    import std.meta : AliasSeq;
    import std.typecons : tuple;

    static struct HasSlicing
    {
        typeof(this) front() @property { return typeof(this).init; }
        bool empty() @property { return true; }
        void popFront() {}

        typeof(this) opSlice(size_t, size_t)
        {
            return typeof(this)();
        }
    }

    static foreach (DummyType; AliasSeq!(AllDummyRanges, HasSlicing))
    {{
        alias R = typeof(enumerate(DummyType.init));
        static assert(isInputRange!R);
        static assert(isForwardRange!R == isForwardRange!DummyType);
        static assert(isRandomAccessRange!R == isRandomAccessRange!DummyType);
        static assert(!hasAssignableElements!R);

        static if (hasLength!DummyType)
        {
            static assert(hasLength!R);
            static assert(isBidirectionalRange!R ==
                isBidirectionalRange!DummyType);
        }

        static assert(hasSlicing!R == hasSlicing!DummyType);
    }}

    static immutable values = ["zero", "one", "two", "three"];
    auto enumerated = values[].enumerate();
    assert(!enumerated.empty);
    assert(enumerated.front == tuple(0, "zero"));
    assert(enumerated.back == tuple(3, "three"));

    typeof(enumerated) saved = enumerated.save;
    saved.popFront();
    assert(enumerated.front == tuple(0, "zero"));
    assert(saved.front == tuple(1, "one"));
    assert(saved.length == enumerated.length - 1);
    saved.popBack();
    assert(enumerated.back == tuple(3, "three"));
    assert(saved.back == tuple(2, "two"));
    saved.popFront();
    assert(saved.front == tuple(2, "two"));
    assert(saved.back == tuple(2, "two"));
    saved.popFront();
    assert(saved.empty);

    size_t control = 0;
    foreach (i, v; enumerated)
    {
        static assert(is(typeof(i) == size_t));
        static assert(is(typeof(v) == typeof(values[0])));
        assert(i == control);
        assert(v == values[i]);
        assert(tuple(i, v) == enumerated[i]);
        ++control;
    }

    assert(enumerated[0 .. $].front == tuple(0, "zero"));
    assert(enumerated[$ - 1 .. $].front == tuple(3, "three"));

    foreach (i; 0 .. 10)
    {
        auto shifted = values[0 .. 2].enumerate(i);
        assert(shifted.front == tuple(i, "zero"));
        assert(shifted[0] == shifted.front);

        auto next = tuple(i + 1, "one");
        assert(shifted[1] == next);
        shifted.popFront();
        assert(shifted.front == next);
        shifted.popFront();
        assert(shifted.empty);
    }

    static foreach (T; AliasSeq!(ubyte, byte, uint, int))
    {{
        auto inf = 42.repeat().enumerate(T.max);
        alias Inf = typeof(inf);
        static assert(isInfinite!Inf);
        static assert(hasSlicing!Inf);

        // test overflow
        assert(inf.front == tuple(T.max, 42));
        inf.popFront();
        assert(inf.front == tuple(T.min, 42));

        // test slicing
        inf = inf[42 .. $];
        assert(inf.front == tuple(T.min + 42, 42));
        auto window = inf[0 .. 2];
        assert(window.length == 1);
        assert(window.front == inf.front);
        window.popFront();
        assert(window.empty);
    }}
}

pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.meta : AliasSeq;
    static immutable int[] values = [0, 1, 2, 3, 4];
    static foreach (T; AliasSeq!(ubyte, ushort, uint, ulong))
    {{
        auto enumerated = values.enumerate!T();
        static assert(is(typeof(enumerated.front.index) == T));
        assert(enumerated.equal(values[].zip(values)));

        foreach (T i; 0 .. 5)
        {
            auto subset = values[cast(size_t) i .. $];
            auto offsetEnumerated = subset.enumerate(i);
            static assert(is(typeof(enumerated.front.index) == T));
            assert(offsetEnumerated.equal(subset.zip(subset)));
        }
    }}
}
@nogc @safe unittest
{
   const val = iota(1, 100).enumerate(1);
}
@nogc @safe unittest
{
    import core.exception : AssertError;
    import std.exception : assertThrown;
    struct RangePayload {
        enum length = size_t.max;
        void popFront() {}
        int front() { return 0; }
        bool empty() { return true; }
    }
    RangePayload thePayload;
    //Assertion won't happen when contracts are disabled for -release.
    debug assertThrown!AssertError(enumerate(thePayload, -10));
}
// https://issues.dlang.org/show_bug.cgi?id=10939
version (none)
{
    // Re-enable (or remove) if 10939 is resolved.
    /+pure+/ @safe unittest // Impure because of std.conv.to
    {
        import core.exception : RangeError;
        import std.exception : assertNotThrown, assertThrown;
        import std.meta : AliasSeq;

        static immutable values = [42];

        static struct SignedLengthRange
        {
            immutable(int)[] _values = values;

            int front() @property { assert(false); }
            bool empty() @property { assert(false); }
            void popFront() { assert(false); }

            int length() @property
            {
                return cast(int)_values.length;
            }
        }

        SignedLengthRange svalues;
        static foreach (Enumerator; AliasSeq!(ubyte, byte, ushort, short, uint, int, ulong, long))
        {
            assertThrown!RangeError(values[].enumerate!Enumerator(Enumerator.max));
            assertNotThrown!RangeError(values[].enumerate!Enumerator(Enumerator.max - values.length));
            assertThrown!RangeError(values[].enumerate!Enumerator(Enumerator.max - values.length + 1));

            assertThrown!RangeError(svalues.enumerate!Enumerator(Enumerator.max));
            assertNotThrown!RangeError(svalues.enumerate!Enumerator(Enumerator.max - values.length));
            assertThrown!RangeError(svalues.enumerate!Enumerator(Enumerator.max - values.length + 1));
        }

        static foreach (Enumerator; AliasSeq!(byte, short, int))
        {
            assertThrown!RangeError(repeat(0, uint.max).enumerate!Enumerator());
        }

        assertNotThrown!RangeError(repeat(0, uint.max).enumerate!long());
    }
}

/**
  Returns true if `fn` accepts variables of type T1 and T2 in any order.
  The following code should compile:
  ---
  (ref T1 a, ref T2 b)
  {
    fn(a, b);
    fn(b, a);
  }
  ---
*/
template isTwoWayCompatible(alias fn, T1, T2)
{
    enum isTwoWayCompatible = is(typeof((ref T1 a, ref T2 b)
        {
            cast(void) fn(a, b);
            cast(void) fn(b, a);
        }
    ));
}

///
@safe unittest
{
    void func1(int a, int b);
    void func2(int a, float b);

    static assert(isTwoWayCompatible!(func1, int, int));
    static assert(isTwoWayCompatible!(func1, short, int));
    static assert(!isTwoWayCompatible!(func2, int, float));

    void func3(ref int a, ref int b);
    static assert( isTwoWayCompatible!(func3, int, int));
    static assert(!isTwoWayCompatible!(func3, short, int));
}


/**
   Policy used with the searching primitives `lowerBound`, $(D
   upperBound), and `equalRange` of $(LREF SortedRange) below.
 */
enum SearchPolicy
{
    /**
       Searches in a linear fashion.
    */
    linear,

    /**
       Searches with a step that is grows linearly (1, 2, 3,...)
       leading to a quadratic search schedule (indexes tried are 0, 1,
       3, 6, 10, 15, 21, 28,...) Once the search overshoots its target,
       the remaining interval is searched using binary search. The
       search is completed in $(BIGOH sqrt(n)) time. Use it when you
       are reasonably confident that the value is around the beginning
       of the range.
    */
    trot,

    /**
       Performs a $(LINK2 https://en.wikipedia.org/wiki/Exponential_search,
       galloping search algorithm), i.e. searches
       with a step that doubles every time, (1, 2, 4, 8, ...)  leading
       to an exponential search schedule (indexes tried are 0, 1, 3,
       7, 15, 31, 63,...) Once the search overshoots its target, the
       remaining interval is searched using binary search. A value is
       found in $(BIGOH log(n)) time.
    */
    gallop,

    /**
       Searches using a classic interval halving policy. The search
       starts in the middle of the range, and each search step cuts
       the range in half. This policy finds a value in $(BIGOH log(n))
       time but is less cache friendly than `gallop` for large
       ranges. The `binarySearch` policy is used as the last step
       of `trot`, `gallop`, `trotBackwards`, and $(D
       gallopBackwards) strategies.
    */
    binarySearch,

    /**
       Similar to `trot` but starts backwards. Use it when
       confident that the value is around the end of the range.
    */
    trotBackwards,

    /**
       Similar to `gallop` but starts backwards. Use it when
       confident that the value is around the end of the range.
    */
    gallopBackwards
}

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

    auto a = assumeSorted([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
    auto p1 = a.upperBound!(SearchPolicy.binarySearch)(3);
    assert(p1.equal([4, 5, 6, 7, 8, 9]));

    auto p2 = a.lowerBound!(SearchPolicy.gallop)(4);
    assert(p2.equal([0, 1, 2, 3]));
}

/**
   Options for $(LREF SortedRange) ranges (below).
*/
enum SortedRangeOptions
{
   /**
      Assume, that the range is sorted without checking.
   */
   assumeSorted,

   /**
      All elements of the range are checked to be sorted.
      The check is performed in O(n) time.
   */
   checkStrictly,

   /**
      Some elements of the range are checked to be sorted.
      For ranges with random order, this will almost surely
      detect, that it is not sorted. For almost sorted ranges
      it's more likely to fail. The checked elements are choosen
      in a deterministic manner, which makes this check reproducable.
      The check is performed in O(log(n)) time.
   */
   checkRoughly,
}

///
@safe pure unittest
{
    // create a SortedRange, that's checked strictly
    SortedRange!(int[],"a < b", SortedRangeOptions.checkStrictly)([ 1, 3, 5, 7, 9 ]);
}

/**
   Represents a sorted range. In addition to the regular range
   primitives, supports additional operations that take advantage of the
   ordering, such as merge and binary search. To obtain a $(D
   SortedRange) from an unsorted range `r`, use
   $(REF sort, std,algorithm,sorting) which sorts `r` in place and returns the
   corresponding `SortedRange`. To construct a `SortedRange` from a range
   `r` that is known to be already sorted, use $(LREF assumeSorted).

   Params:
       pred: The predicate used to define the sortedness
       opt: Controls how strongly the range is checked for sortedness.
            Will only be used for `RandomAccessRanges`.
            Will not be used in CTFE.
*/
struct SortedRange(Range, alias pred = "a < b",
    SortedRangeOptions opt = SortedRangeOptions.assumeSorted)
if (isInputRange!Range && !isInstanceOf!(SortedRange, Range))
{
    import std.functional : binaryFun;

    private alias predFun = binaryFun!pred;
    private bool geq(L, R)(L lhs, R rhs)
    {
        return !predFun(lhs, rhs);
    }
    private bool gt(L, R)(L lhs, R rhs)
    {
        return predFun(rhs, lhs);
    }
    private Range _input;

    // Undocummented because a clearer way to invoke is by calling
    // assumeSorted.
    this(Range input)
    {
        static if (opt == SortedRangeOptions.checkRoughly)
        {
            roughlyVerifySorted(input);
        }
        static if (opt == SortedRangeOptions.checkStrictly)
        {
            strictlyVerifySorted(input);
        }
        this._input = input;
    }

    // Assertion only.
    static if (opt == SortedRangeOptions.checkRoughly)
    private void roughlyVerifySorted(Range r)
    {
        if (!__ctfe)
        {
            static if (isRandomAccessRange!Range && hasLength!Range)
            {
                import core.bitop : bsr;
                import std.algorithm.sorting : isSorted;
                import std.exception : enforce;

                // Check the sortedness of the input
                if (r.length < 2) return;

                immutable size_t msb = bsr(r.length) + 1;
                assert(msb > 0 && msb <= r.length);
                immutable step = r.length / msb;
                auto st = stride(r, step);

                enforce(isSorted!pred(st), "Range is not sorted");
            }
        }
    }

    // Assertion only.
    static if (opt == SortedRangeOptions.checkStrictly)
    private void strictlyVerifySorted(Range r)
    {
        if (!__ctfe)
        {
            static if (isRandomAccessRange!Range && hasLength!Range)
            {
                import std.algorithm.sorting : isSorted;
                import std.exception : enforce;

                enforce(isSorted!pred(r), "Range is not sorted");
            }
        }
    }

    /// Range primitives.
    @property bool empty()             //const
    {
        return this._input.empty;
    }

    /// Ditto
    static if (isForwardRange!Range)
    @property auto save()
    {
        // Avoid the constructor
        typeof(this) result = this;
        result._input = _input.save;
        return result;
    }

    /// Ditto
    @property auto ref front()
    {
        return _input.front;
    }

    /// Ditto
    void popFront()
    {
        _input.popFront();
    }

    /// Ditto
    static if (isBidirectionalRange!Range)
    {
        @property auto ref back()
        {
            return _input.back;
        }

        /// Ditto
        void popBack()
        {
            _input.popBack();
        }
    }

    /// Ditto
    static if (isRandomAccessRange!Range)
        auto ref opIndex(size_t i)
        {
            return _input[i];
        }

    /// Ditto
    static if (hasSlicing!Range)
        auto opSlice(size_t a, size_t b) return scope
        {
            assert(
                a <= b,
                "Attempting to slice a SortedRange with a larger first argument than the second."
            );
            typeof(this) result = this;
            result._input = _input[a .. b];// skip checking
            return result;
        }

    mixin ImplementLength!_input;

/**
    Releases the controlled range and returns it.

    This does the opposite of $(LREF assumeSorted): instead of turning a range
    into a `SortedRange`, it extracts the original range back out of the `SortedRange`
    using $(REF, move, std,algorithm,mutation).
*/
    auto release() return scope
    {
        import std.algorithm.mutation : move;
        return move(_input);
    }

    ///
    static if (is(Range : int[]))
    @safe unittest
    {
        import std.algorithm.sorting : sort;
        int[3] data = [ 1, 2, 3 ];
        auto a = assumeSorted(data[]);
        assert(a == sort!"a < b"(data[]));
        int[] p = a.release();
        assert(p == [ 1, 2, 3 ]);
    }

    // Assuming a predicate "test" that returns 0 for a left portion
    // of the range and then 1 for the rest, returns the index at
    // which the first 1 appears. Used internally by the search routines.
    private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v)
    if (sp == SearchPolicy.binarySearch && isRandomAccessRange!Range && hasLength!Range)
    {
        size_t first = 0, count = _input.length;
        while (count > 0)
        {
            immutable step = count / 2, it = first + step;
            if (!test(_input[it], v))
            {
                first = it + 1;
                count -= step + 1;
            }
            else
            {
                count = step;
            }
        }
        return first;
    }

    // Specialization for trot and gallop
    private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v)
    if ((sp == SearchPolicy.trot || sp == SearchPolicy.gallop)
        && isRandomAccessRange!Range)
    {
        if (empty || test(front, v)) return 0;
        immutable count = length;
        if (count == 1) return 1;
        size_t below = 0, above = 1, step = 2;
        while (!test(_input[above], v))
        {
            // Still too small, update below and increase gait
            below = above;
            immutable next = above + step;
            if (next >= count)
            {
                // Overshot - the next step took us beyond the end. So
                // now adjust next and simply exit the loop to do the
                // binary search thingie.
                above = count;
                break;
            }
            // Still in business, increase step and continue
            above = next;
            static if (sp == SearchPolicy.trot)
                ++step;
            else
                step <<= 1;
        }
        return below + this[below .. above].getTransitionIndex!(
            SearchPolicy.binarySearch, test, V)(v);
    }

    // Specialization for trotBackwards and gallopBackwards
    private size_t getTransitionIndex(SearchPolicy sp, alias test, V)(V v)
    if ((sp == SearchPolicy.trotBackwards || sp == SearchPolicy.gallopBackwards)
        && isRandomAccessRange!Range)
    {
        immutable count = length;
        if (empty || !test(back, v)) return count;
        if (count == 1) return 0;
        size_t below = count - 2, above = count - 1, step = 2;
        while (test(_input[below], v))
        {
            // Still too large, update above and increase gait
            above = below;
            if (below < step)
            {
                // Overshot - the next step took us beyond the end. So
                // now adjust next and simply fall through to do the
                // binary search thingie.
                below = 0;
                break;
            }
            // Still in business, increase step and continue
            below -= step;
            static if (sp == SearchPolicy.trot)
                ++step;
            else
                step <<= 1;
        }
        return below + this[below .. above].getTransitionIndex!(
            SearchPolicy.binarySearch, test, V)(v);
    }

// lowerBound
/**
   This function uses a search with policy `sp` to find the
   largest left subrange on which $(D pred(x, value)) is `true` for
   all `x` (e.g., if `pred` is "less than", returns the portion of
   the range with elements strictly smaller than `value`). The search
   schedule and its complexity are documented in
   $(LREF SearchPolicy).
*/
    auto lowerBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)
    if (isTwoWayCompatible!(predFun, ElementType!Range, V)
         && hasSlicing!Range)
    {
        return this[0 .. getTransitionIndex!(sp, geq)(value)];
    }

    ///
    static if (is(Range : int[]))
    @safe unittest
    {
        import std.algorithm.comparison : equal;
        auto a = assumeSorted([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]);
        auto p = a.lowerBound(4);
        assert(equal(p, [ 0, 1, 2, 3 ]));
    }

// upperBound
/**
This function searches with policy `sp` to find the largest right
subrange on which $(D pred(value, x)) is `true` for all `x`
(e.g., if `pred` is "less than", returns the portion of the range
with elements strictly greater than `value`). The search schedule
and its complexity are documented in $(LREF SearchPolicy).

For ranges that do not offer random access, `SearchPolicy.linear`
is the only policy allowed (and it must be specified explicitly lest it exposes
user code to unexpected inefficiencies). For random-access searches, all
policies are allowed, and `SearchPolicy.binarySearch` is the default.
*/
    auto upperBound(SearchPolicy sp = SearchPolicy.binarySearch, V)(V value)
    if (isTwoWayCompatible!(predFun, ElementType!Range, V))
    {
        static assert(hasSlicing!Range || sp == SearchPolicy.linear,
            "Specify SearchPolicy.linear explicitly for "
            ~ typeof(this).stringof);
        static if (sp == SearchPolicy.linear)
        {
            for (; !_input.empty && !predFun(value, _input.front);
                 _input.popFront())
            {
            }
            return this;
        }
        else
        {
            return this[getTransitionIndex!(sp, gt)(value) .. length];
        }
    }

    ///
    static if (is(Range : int[]))
    @safe unittest
    {
        import std.algorithm.comparison : equal;
        auto a = assumeSorted([ 1, 2, 3, 3, 3, 4, 4, 5, 6 ]);
        auto p = a.upperBound(3);
        assert(equal(p, [4, 4, 5, 6]));
    }


// equalRange
/**
   Returns the subrange containing all elements `e` for which both $(D
   pred(e, value)) and $(D pred(value, e)) evaluate to `false` (e.g.,
   if `pred` is "less than", returns the portion of the range with
   elements equal to `value`). Uses a classic binary search with
   interval halving until it finds a value that satisfies the condition,
   then uses `SearchPolicy.gallopBackwards` to find the left boundary
   and `SearchPolicy.gallop` to find the right boundary. These
   policies are justified by the fact that the two boundaries are likely
   to be near the first found value (i.e., equal ranges are relatively
   small). Completes the entire search in $(BIGOH log(n)) time.
*/
    auto equalRange(V)(V value)
    if (isTwoWayCompatible!(predFun, ElementType!Range, V)
        && isRandomAccessRange!Range)
    {
        size_t first = 0, count = _input.length;
        while (count > 0)
        {
            immutable step = count / 2;
            auto it = first + step;
            if (predFun(_input[it], value))
            {
                // Less than value, bump left bound up
                first = it + 1;
                count -= step + 1;
            }
            else if (predFun(value, _input[it]))
            {
                // Greater than value, chop count
                count = step;
            }
            else
            {
                // Equal to value, do binary searches in the
                // leftover portions
                // Gallop towards the left end as it's likely nearby
                immutable left = first
                    + this[first .. it]
                    .lowerBound!(SearchPolicy.gallopBackwards)(value).length;
                first += count;
                // Gallop towards the right end as it's likely nearby
                immutable right = first
                    - this[it + 1 .. first]
                    .upperBound!(SearchPolicy.gallop)(value).length;
                return this[left .. right];
            }
        }
        return this.init;
    }

    ///
    static if (is(Range : int[]))
    @safe unittest
    {
        import std.algorithm.comparison : equal;
        auto a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
        auto r = a.assumeSorted.equalRange(3);
        assert(equal(r, [ 3, 3, 3 ]));
    }

// trisect
/**
Returns a tuple `r` such that `r[0]` is the same as the result
of `lowerBound(value)`, `r[1]` is the same as the result of $(D
equalRange(value)), and `r[2]` is the same as the result of $(D
upperBound(value)). The call is faster than computing all three
separately. Uses a search schedule similar to $(D
equalRange). Completes the entire search in $(BIGOH log(n)) time.
*/
    auto trisect(V)(V value)
    if (isTwoWayCompatible!(predFun, ElementType!Range, V)
        && isRandomAccessRange!Range && hasLength!Range)
    {
        import std.typecons : tuple;
        size_t first = 0, count = _input.length;
        while (count > 0)
        {
            immutable step = count / 2;
            auto it = first + step;
            if (predFun(_input[it], value))
            {
                // Less than value, bump left bound up
                first = it + 1;
                count -= step + 1;
            }
            else if (predFun(value, _input[it]))
            {
                // Greater than value, chop count
                count = step;
            }
            else
            {
                // Equal to value, do binary searches in the
                // leftover portions
                // Gallop towards the left end as it's likely nearby
                immutable left = first
                    + this[first .. it]
                    .lowerBound!(SearchPolicy.gallopBackwards)(value).length;
                first += count;
                // Gallop towards the right end as it's likely nearby
                immutable right = first
                    - this[it + 1 .. first]
                    .upperBound!(SearchPolicy.gallop)(value).length;
                return tuple(this[0 .. left], this[left .. right],
                        this[right .. length]);
            }
        }
        // No equal element was found
        return tuple(this[0 .. first], this.init, this[first .. length]);
    }

    ///
    static if (is(Range : int[]))
    @safe unittest
    {
        import std.algorithm.comparison : equal;
        auto a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
        auto r = assumeSorted(a).trisect(3);
        assert(equal(r[0], [ 1, 2 ]));
        assert(equal(r[1], [ 3, 3, 3 ]));
        assert(equal(r[2], [ 4, 4, 5, 6 ]));
    }

// contains
/**
Returns `true` if and only if `value` can be found in $(D
range), which is assumed to be sorted. Performs $(BIGOH log(r.length))
evaluations of `pred`.
 */

    bool contains(V)(V value)
    if (isRandomAccessRange!Range)
    {
        if (empty) return false;
        immutable i = getTransitionIndex!(SearchPolicy.binarySearch, geq)(value);
        if (i >= length) return false;
        return !predFun(value, _input[i]);
    }

/**
Like `contains`, but the value is specified before the range.
*/
    bool opBinaryRight(string op, V)(V value)
    if (op == "in" && isRandomAccessRange!Range)
    {
        return contains(value);
    }

// groupBy
/**
Returns a range of subranges of elements that are equivalent according to the
sorting relation.
 */
    auto groupBy()()
    {
        import std.algorithm.iteration : chunkBy;
        return _input.chunkBy!((a, b) => !predFun(a, b) && !predFun(b, a));
    }
}

/// ditto
template SortedRange(Range, alias pred = "a < b",
                     SortedRangeOptions opt = SortedRangeOptions.assumeSorted)
if (isInstanceOf!(SortedRange, Range))
{
    // Avoid nesting SortedRange types (see https://issues.dlang.org/show_bug.cgi?id=18933);
    alias SortedRange = SortedRange!(Unqual!(typeof(Range._input)), pred, opt);
}

///
@safe unittest
{
    import std.algorithm.sorting : sort;
    auto a = [ 1, 2, 3, 42, 52, 64 ];
    auto r = assumeSorted(a);
    assert(r.contains(3));
    assert(!(32 in r));
    auto r1 = sort!"a > b"(a);
    assert(3 in r1);
    assert(!r1.contains(32));
    assert(r1.release() == [ 64, 52, 42, 3, 2, 1 ]);
}

/**
`SortedRange` could accept ranges weaker than random-access, but it
is unable to provide interesting functionality for them. Therefore,
`SortedRange` is currently restricted to random-access ranges.

No copy of the original range is ever made. If the underlying range is
changed concurrently with its corresponding `SortedRange` in ways
that break its sorted-ness, `SortedRange` will work erratically.
*/
@safe unittest
{
    import std.algorithm.mutation : swap;
    auto a = [ 1, 2, 3, 42, 52, 64 ];
    auto r = assumeSorted(a);
    assert(r.contains(42));
    swap(a[3], a[5]);         // illegal to break sortedness of original range
    assert(!r.contains(42));  // passes although it shouldn't
}

/**
`SortedRange` can be searched with predicates that do not take
two elements of the underlying range as arguments.

This is useful, if a range of structs is sorted by a member and you
want to search in that range by only providing a value for that member.

*/
@safe unittest
{
    import std.algorithm.comparison : equal;
    static struct S { int i; }
    static bool byI(A, B)(A a, B b)
    {
        static if (is(A == S))
            return a.i < b;
        else
            return a < b.i;
    }
    auto r = assumeSorted!byI([S(1), S(2), S(3)]);
    auto lessThanTwo = r.lowerBound(2);
    assert(equal(lessThanTwo, [S(1)]));
}

@safe unittest
{
    import std.exception : assertThrown, assertNotThrown;

    assertNotThrown(SortedRange!(int[])([ 1, 3, 10, 5, 7 ]));
    assertThrown(SortedRange!(int[],"a < b", SortedRangeOptions.checkStrictly)([ 1, 3, 10, 5, 7 ]));

    // these two checks are implementation depended
    assertNotThrown(SortedRange!(int[],"a < b", SortedRangeOptions.checkRoughly)([ 1, 3, 10, 5, 12, 2 ]));
    assertThrown(SortedRange!(int[],"a < b", SortedRangeOptions.checkRoughly)([ 1, 3, 10, 5, 2, 12 ]));
}

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

    auto a = [ 10, 20, 30, 30, 30, 40, 40, 50, 60 ];
    auto r = assumeSorted(a).trisect(30);
    assert(equal(r[0], [ 10, 20 ]));
    assert(equal(r[1], [ 30, 30, 30 ]));
    assert(equal(r[2], [ 40, 40, 50, 60 ]));

    r = assumeSorted(a).trisect(35);
    assert(equal(r[0], [ 10, 20, 30, 30, 30 ]));
    assert(r[1].empty);
    assert(equal(r[2], [ 40, 40, 50, 60 ]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    auto a = [ "A", "AG", "B", "E", "F" ];
    auto r = assumeSorted!"cmp(a,b) < 0"(a).trisect("B"w);
    assert(equal(r[0], [ "A", "AG" ]));
    assert(equal(r[1], [ "B" ]));
    assert(equal(r[2], [ "E", "F" ]));
    r = assumeSorted!"cmp(a,b) < 0"(a).trisect("A"d);
    assert(r[0].empty);
    assert(equal(r[1], [ "A" ]));
    assert(equal(r[2], [ "AG", "B", "E", "F" ]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    static void test(SearchPolicy pol)()
    {
        auto a = [ 1, 2, 3, 42, 52, 64 ];
        auto r = assumeSorted(a);
        assert(equal(r.lowerBound(42), [1, 2, 3]));

        assert(equal(r.lowerBound!(pol)(42), [1, 2, 3]));
        assert(equal(r.lowerBound!(pol)(41), [1, 2, 3]));
        assert(equal(r.lowerBound!(pol)(43), [1, 2, 3, 42]));
        assert(equal(r.lowerBound!(pol)(51), [1, 2, 3, 42]));
        assert(equal(r.lowerBound!(pol)(3), [1, 2]));
        assert(equal(r.lowerBound!(pol)(55), [1, 2, 3, 42, 52]));
        assert(equal(r.lowerBound!(pol)(420), a));
        assert(equal(r.lowerBound!(pol)(0), a[0 .. 0]));

        assert(equal(r.upperBound!(pol)(42), [52, 64]));
        assert(equal(r.upperBound!(pol)(41), [42, 52, 64]));
        assert(equal(r.upperBound!(pol)(43), [52, 64]));
        assert(equal(r.upperBound!(pol)(51), [52, 64]));
        assert(equal(r.upperBound!(pol)(53), [64]));
        assert(equal(r.upperBound!(pol)(55), [64]));
        assert(equal(r.upperBound!(pol)(420), a[0 .. 0]));
        assert(equal(r.upperBound!(pol)(0), a));
    }

    test!(SearchPolicy.trot)();
    test!(SearchPolicy.gallop)();
    test!(SearchPolicy.trotBackwards)();
    test!(SearchPolicy.gallopBackwards)();
    test!(SearchPolicy.binarySearch)();
}

@safe unittest
{
    // Check for small arrays
    int[] a;
    auto r = assumeSorted(a);
    a = [ 1 ];
    r = assumeSorted(a);
    a = [ 1, 2 ];
    r = assumeSorted(a);
    a = [ 1, 2, 3 ];
    r = assumeSorted(a);
}

@safe unittest
{
    import std.algorithm.mutation : swap;
    auto a = [ 1, 2, 3, 42, 52, 64 ];
    auto r = assumeSorted(a);
    assert(r.contains(42));
    swap(a[3], a[5]);                  // illegal to break sortedness of original range
    assert(!r.contains(42));            // passes although it shouldn't
}

@betterC @nogc nothrow @safe unittest
{
    static immutable(int)[] arr = [ 1, 2, 3 ];
    auto s = assumeSorted(arr);
}

@system unittest
{
    import std.algorithm.comparison : equal;
    int[] arr = [100, 101, 102, 200, 201, 300];
    auto s = assumeSorted!((a, b) => a / 100 < b / 100)(arr);
    assert(s.groupBy.equal!equal([[100, 101, 102], [200, 201], [300]]));
}

// Test on an input range
@system unittest
{
    import std.conv : text;
    import std.file : exists, remove, tempDir;
    import std.path : buildPath;
    import std.stdio : File;
    import std.uuid : randomUUID;
    auto name = buildPath(tempDir(), "test.std.range.line-" ~ text(__LINE__) ~
                          "." ~ randomUUID().toString());
    auto f = File(name, "w");
    scope(exit) if (exists(name)) remove(name);
    // write a sorted range of lines to the file
    f.write("abc\ndef\nghi\njkl");
    f.close();
    f.open(name, "r");
    auto r = assumeSorted(f.byLine());
    auto r1 = r.upperBound!(SearchPolicy.linear)("def");
    assert(r1.front == "ghi", r1.front);
    f.close();
}

// https://issues.dlang.org/show_bug.cgi?id=19337
@safe unittest
{
    import std.algorithm.sorting : sort;
    auto a = [ 1, 2, 3, 42, 52, 64 ];
    a.sort.sort!"a > b";
}

/**
Assumes `r` is sorted by predicate `pred` and returns the
corresponding $(D SortedRange!(pred, R)) having `r` as support.
To check for sorted-ness at
cost $(BIGOH n), use $(REF isSorted, std,algorithm,sorting).
 */
auto assumeSorted(alias pred = "a < b", R)(R r)
if (isInputRange!(Unqual!R))
{
    // Avoid senseless `SortedRange!(SortedRange!(...), pred)` nesting.
    static if (is(R == SortedRange!(RRange, RPred), RRange, alias RPred))
    {
        static if (isInputRange!R && __traits(isSame, pred, RPred))
            // If the predicate is the same and we don't need to cast away
            // constness for the result to be an input range.
            return r;
        else
            return SortedRange!(Unqual!(typeof(r._input)), pred)(r._input);
    }
    else
    {
        return SortedRange!(Unqual!R, pred)(r);
    }
}

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

    int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    auto p = assumeSorted(a);

    assert(equal(p.lowerBound(4), [0, 1, 2, 3]));
    assert(equal(p.lowerBound(5), [0, 1, 2, 3, 4]));
    assert(equal(p.lowerBound(6), [0, 1, 2, 3, 4, 5]));
    assert(equal(p.lowerBound(6.9), [0, 1, 2, 3, 4, 5, 6]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    static assert(isRandomAccessRange!(SortedRange!(int[])));
    int[] a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
    auto p = assumeSorted(a).upperBound(3);
    assert(equal(p, [4, 4, 5, 6 ]));
    p = assumeSorted(a).upperBound(4.2);
    assert(equal(p, [ 5, 6 ]));

    // https://issues.dlang.org/show_bug.cgi?id=18933
    // don't create senselessly nested SortedRange types.
    assert(is(typeof(assumeSorted(a)) == typeof(assumeSorted(assumeSorted(a)))));
    assert(is(typeof(assumeSorted(a)) == typeof(assumeSorted(assumeSorted!"a > b"(a)))));
}

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

    int[] a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
    auto p = assumeSorted(a).equalRange(3);
    assert(equal(p, [ 3, 3, 3 ]), text(p));
    p = assumeSorted(a).equalRange(4);
    assert(equal(p, [ 4, 4 ]), text(p));
    p = assumeSorted(a).equalRange(2);
    assert(equal(p, [ 2 ]));
    p = assumeSorted(a).equalRange(0);
    assert(p.empty);
    p = assumeSorted(a).equalRange(7);
    assert(p.empty);
    p = assumeSorted(a).equalRange(3.0);
    assert(equal(p, [ 3, 3, 3]));
}

@safe unittest
{
    int[] a = [ 1, 2, 3, 3, 3, 4, 4, 5, 6 ];
    if (a.length)
    {
        auto b = a[a.length / 2];
        //auto r = sort(a);
        //assert(r.contains(b));
    }
}

@safe unittest
{
    auto a = [ 5, 7, 34, 345, 677 ];
    auto r = assumeSorted(a);
    a = null;
    r = assumeSorted(a);
    a = [ 1 ];
    r = assumeSorted(a);
}

// https://issues.dlang.org/show_bug.cgi?id=15003
@nogc @safe unittest
{
    static immutable a = [1, 2, 3, 4];
    auto r = a.assumeSorted;
}

/++
    Wrapper which effectively makes it possible to pass a range by reference.
    Both the original range and the RefRange will always have the exact same
    elements. Any operation done on one will affect the other. So, for instance,
    if it's passed to a function which would implicitly copy the original range
    if it were passed to it, the original range is $(I not) copied but is
    consumed as if it were a reference type.

    Note:
        `save` works as normal and operates on a new range, so if
        `save` is ever called on the `RefRange`, then no operations on the
        saved range will affect the original.

    Params:
        range = the range to construct the `RefRange` from

    Returns:
        A `RefRange`. If the given range is a class type
        (and thus is already a reference type), then the original
        range is returned rather than a `RefRange`.
  +/
struct RefRange(R)
if (isInputRange!R)
{
public:

    /++ +/
    this(R* range) @safe pure nothrow
    {
        _range = range;
    }


    /++
        This does not assign the pointer of `rhs` to this `RefRange`.
        Rather it assigns the range pointed to by `rhs` to the range pointed
        to by this `RefRange`. This is because $(I any) operation on a
        `RefRange` is the same is if it occurred to the original range. The
        one exception is when a `RefRange` is assigned `null` either
        directly or because `rhs` is `null`. In that case, `RefRange`
        no longer refers to the original range but is `null`.
      +/
    auto opAssign(RefRange rhs)
    {
        if (_range && rhs._range)
            *_range = *rhs._range;
        else
            _range = rhs._range;

        return this;
    }

    /++ +/
    void opAssign(typeof(null) rhs)
    {
        _range = null;
    }


    /++
        A pointer to the wrapped range.
      +/
    @property inout(R*) ptr() @safe inout pure nothrow
    {
        return _range;
    }


    version (StdDdoc)
    {
        /++ +/
        @property auto front() {assert(0);}
        /++ Ditto +/
        @property auto front() const {assert(0);}
        /++ Ditto +/
        @property auto front(ElementType!R value) {assert(0);}
    }
    else
    {
        @property auto front()
        {
            return (*_range).front;
        }

        static if (is(typeof(((const R* r) => (*r).front)(null)))) @property auto front() const
        {
            return (*_range).front;
        }

        static if (is(typeof((*_range).front = (*_range).front))) @property auto front(ElementType!R value)
        {
            return (*_range).front = value;
        }
    }


    version (StdDdoc)
    {
        @property bool empty(); ///
        @property bool empty() const; ///Ditto
    }
    else static if (isInfinite!R)
        enum empty = false;
    else
    {
        @property bool empty()
        {
            return (*_range).empty;
        }

        static if (is(typeof(((const R* r) => (*r).empty)(null)))) @property bool empty() const
        {
            return (*_range).empty;
        }
    }


    /++ +/
    void popFront()
    {
        return (*_range).popFront();
    }


    version (StdDdoc)
    {
        /++
            Only defined if `isForwardRange!R` is `true`.
          +/
        @property auto save() {assert(0);}
        /++ Ditto +/
        @property auto save() const {assert(0);}
        /++ Ditto +/
        auto opSlice() {assert(0);}
        /++ Ditto +/
        auto opSlice() const {assert(0);}
    }
    else static if (isForwardRange!R)
    {
        import std.traits : isSafe;
        private alias S = typeof((() => (*_range).save)());

        static if (is(typeof(((const R* r) => (*r).save)(null))))
            private alias CS = typeof(((const R* r) => (*r).save)(null));


        static if (isSafe!((R* r) => (*r).save))
        {
            @property RefRange!S save() @trusted
            {
                mixin(_genSave());
            }

            static if (is(typeof(((const R* r) => (*r).save)(null)))) @property RefRange!CS save() @trusted const
            {
                mixin(_genSave());
            }
        }
        else
        {
            @property RefRange!S save()
            {
                mixin(_genSave());
            }

            static if (is(typeof(((const R* r) => (*r).save)(null)))) @property RefRange!CS save() const
            {
                mixin(_genSave());
            }
        }

        auto opSlice()()
        {
            return save;
        }

        auto opSlice()() const
        {
            return save;
        }

        private static string _genSave() @safe pure nothrow
        {
            return `import core.lifetime : emplace;` ~
                   `alias S = typeof((() => (*_range).save)());` ~
                   `static assert(isForwardRange!S, S.stringof ~ " is not a forward range.");` ~
                   `auto mem = new void[S.sizeof];` ~
                   `emplace!S(mem, cast(S)(*_range).save);` ~
                   `return RefRange!S(cast(S*) mem.ptr);`;
        }

        static assert(isForwardRange!RefRange);
    }


    version (StdDdoc)
    {
        /++
            Only defined if `isBidirectionalRange!R` is `true`.
          +/
        @property auto back() {assert(0);}
        /++ Ditto +/
        @property auto back() const {assert(0);}
        /++ Ditto +/
        @property auto back(ElementType!R value) {assert(0);}
    }
    else static if (isBidirectionalRange!R)
    {
        @property auto back()
        {
            return (*_range).back;
        }

        static if (is(typeof(((const R* r) => (*r).back)(null)))) @property auto back() const
        {
            return (*_range).back;
        }

        static if (is(typeof((*_range).back = (*_range).back))) @property auto back(ElementType!R value)
        {
            return (*_range).back = value;
        }
    }


    /++ Ditto +/
    static if (isBidirectionalRange!R) void popBack()
    {
        return (*_range).popBack();
    }


    version (StdDdoc)
    {
        /++
            Only defined if `isRandomAccessRange!R` is `true`.
          +/
        auto ref opIndex(IndexType)(IndexType index) {assert(0);}

        /++ Ditto +/
        auto ref opIndex(IndexType)(IndexType index) const {assert(0);}
    }
    else static if (isRandomAccessRange!R)
    {
        auto ref opIndex(IndexType)(IndexType index)
        if (is(typeof((*_range)[index])))
        {
            return (*_range)[index];
        }

        auto ref opIndex(IndexType)(IndexType index) const
        if (is(typeof((*cast(const R*)_range)[index])))
        {
            return (*_range)[index];
        }
    }


    /++
        Only defined if `hasMobileElements!R` and `isForwardRange!R` are
        `true`.
      +/
    static if (hasMobileElements!R && isForwardRange!R) auto moveFront()
    {
        return (*_range).moveFront();
    }


    /++
        Only defined if `hasMobileElements!R` and `isBidirectionalRange!R`
        are `true`.
      +/
    static if (hasMobileElements!R && isBidirectionalRange!R) auto moveBack()
    {
        return (*_range).moveBack();
    }


    /++
        Only defined if `hasMobileElements!R` and `isRandomAccessRange!R`
        are `true`.
      +/
    static if (hasMobileElements!R && isRandomAccessRange!R) auto moveAt(size_t index)
    {
        return (*_range).moveAt(index);
    }


    version (StdDdoc)
    {
        /// Only defined if `hasLength!R` is `true`.
        @property size_t length();
        /// ditto
        @property size_t length() const;
        /// Ditto
        alias opDollar = length;
    }
    else static if (hasLength!R)
    {
        @property auto length()
        {
            return (*_range).length;
        }
        static if (is(typeof(((const R* r) => (*r).length)(null)))) @property auto length() const
        {
            return (*_range).length;
        }
        alias opDollar = length;
    }


    version (StdDdoc)
    {
        /++
            Only defined if `hasSlicing!R` is `true`.
          +/
        auto opSlice(IndexType1, IndexType2)
                    (IndexType1 begin, IndexType2 end) {assert(0);}

        /++ Ditto +/
        auto opSlice(IndexType1, IndexType2)
                    (IndexType1 begin, IndexType2 end) const {assert(0);}
    }
    else static if (hasSlicing!R)
    {
        private alias T = typeof((*_range)[1 .. 2]);
        static if (is(typeof((*cast(const R*)_range)[1 .. 2])))
        {
            private alias CT = typeof((*cast(const R*)_range)[1 .. 2]);
        }

        RefRange!T opSlice(IndexType1, IndexType2)
                    (IndexType1 begin, IndexType2 end)
        if (is(typeof((*_range)[begin .. end])))
        {
            mixin(_genOpSlice());
        }

        RefRange!CT opSlice(IndexType1, IndexType2)
                    (IndexType1 begin, IndexType2 end) const
        if (is(typeof((*cast(const R*)_range)[begin .. end])))
        {
            mixin(_genOpSlice());
        }

        private static string _genOpSlice() @safe pure nothrow
        {
            return `import core.lifetime : emplace;` ~
                   `alias S = typeof((*_range)[begin .. end]);` ~
                   `static assert(hasSlicing!S, S.stringof ~ " is not sliceable.");` ~
                   `auto mem = new void[S.sizeof];` ~
                   `emplace!S(mem, cast(S)(*_range)[begin .. end]);` ~
                   `return RefRange!S(cast(S*) mem.ptr);`;
        }
    }


private:

    R* _range;
}

/// Basic Example
@system unittest
{
    import std.algorithm.searching : find;
    ubyte[] buffer = [1, 9, 45, 12, 22];
    auto found1 = find(buffer, 45);
    assert(found1 == [45, 12, 22]);
    assert(buffer == [1, 9, 45, 12, 22]);

    auto wrapped1 = refRange(&buffer);
    auto found2 = find(wrapped1, 45);
    assert(*found2.ptr == [45, 12, 22]);
    assert(buffer == [45, 12, 22]);

    auto found3 = find(wrapped1.save, 22);
    assert(*found3.ptr == [22]);
    assert(buffer == [45, 12, 22]);

    string str = "hello world";
    auto wrappedStr = refRange(&str);
    assert(str.front == 'h');
    str.popFrontN(5);
    assert(str == " world");
    assert(wrappedStr.front == ' ');
    assert(*wrappedStr.ptr == " world");
}

/// opAssign Example.
@system unittest
{
    ubyte[] buffer1 = [1, 2, 3, 4, 5];
    ubyte[] buffer2 = [6, 7, 8, 9, 10];
    auto wrapped1 = refRange(&buffer1);
    auto wrapped2 = refRange(&buffer2);
    assert(wrapped1.ptr is &buffer1);
    assert(wrapped2.ptr is &buffer2);
    assert(wrapped1.ptr !is wrapped2.ptr);
    assert(buffer1 != buffer2);

    wrapped1 = wrapped2;

    //Everything points to the same stuff as before.
    assert(wrapped1.ptr is &buffer1);
    assert(wrapped2.ptr is &buffer2);
    assert(wrapped1.ptr !is wrapped2.ptr);

    //But buffer1 has changed due to the assignment.
    assert(buffer1 == [6, 7, 8, 9, 10]);
    assert(buffer2 == [6, 7, 8, 9, 10]);

    buffer2 = [11, 12, 13, 14, 15];

    //Everything points to the same stuff as before.
    assert(wrapped1.ptr is &buffer1);
    assert(wrapped2.ptr is &buffer2);
    assert(wrapped1.ptr !is wrapped2.ptr);

    //But buffer2 has changed due to the assignment.
    assert(buffer1 == [6, 7, 8, 9, 10]);
    assert(buffer2 == [11, 12, 13, 14, 15]);

    wrapped2 = null;

    //The pointer changed for wrapped2 but not wrapped1.
    assert(wrapped1.ptr is &buffer1);
    assert(wrapped2.ptr is null);
    assert(wrapped1.ptr !is wrapped2.ptr);

    //buffer2 is not affected by the assignment.
    assert(buffer1 == [6, 7, 8, 9, 10]);
    assert(buffer2 == [11, 12, 13, 14, 15]);
}

@system unittest
{
    import std.algorithm.iteration : filter;
    {
        ubyte[] buffer = [1, 2, 3, 4, 5];
        auto wrapper = refRange(&buffer);
        auto p = wrapper.ptr;
        auto f = wrapper.front;
        wrapper.front = f;
        auto e = wrapper.empty;
        wrapper.popFront();
        auto s = wrapper.save;
        auto b = wrapper.back;
        wrapper.back = b;
        wrapper.popBack();
        auto i = wrapper[0];
        wrapper.moveFront();
        wrapper.moveBack();
        wrapper.moveAt(0);
        auto l = wrapper.length;
        auto sl = wrapper[0 .. 1];
        assert(wrapper[0 .. $].length == buffer[0 .. $].length);
    }

    {
        ubyte[] buffer = [1, 2, 3, 4, 5];
        const wrapper = refRange(&buffer);
        const p = wrapper.ptr;
        const f = wrapper.front;
        const e = wrapper.empty;
        const s = wrapper.save;
        const b = wrapper.back;
        const i = wrapper[0];
        const l = wrapper.length;
        const sl = wrapper[0 .. 1];
    }

    {
        ubyte[] buffer = [1, 2, 3, 4, 5];
        auto filtered = filter!"true"(buffer);
        auto wrapper = refRange(&filtered);
        auto p = wrapper.ptr;
        auto f = wrapper.front;
        wrapper.front = f;
        auto e = wrapper.empty;
        wrapper.popFront();
        auto s = wrapper.save;
        wrapper.moveFront();
    }

    {
        ubyte[] buffer = [1, 2, 3, 4, 5];
        auto filtered = filter!"true"(buffer);
        const wrapper = refRange(&filtered);
        const p = wrapper.ptr;

        //Cannot currently be const. filter needs to be updated to handle const.
        /+
        const f = wrapper.front;
        const e = wrapper.empty;
        const s = wrapper.save;
        +/
    }

    {
        string str = "hello world";
        auto wrapper = refRange(&str);
        auto p = wrapper.ptr;
        auto f = wrapper.front;
        auto e = wrapper.empty;
        wrapper.popFront();
        auto s = wrapper.save;
        auto b = wrapper.back;
        wrapper.popBack();
    }

    {
        // https://issues.dlang.org/show_bug.cgi?id=16534
        // opDollar should be defined if the wrapped range defines length.
        auto range = 10.iota.takeExactly(5);
        auto wrapper = refRange(&range);
        assert(wrapper.length == 5);
        assert(wrapper[0 .. $ - 1].length == 4);
    }
}

//Test assignment.
@system unittest
{
    ubyte[] buffer1 = [1, 2, 3, 4, 5];
    ubyte[] buffer2 = [6, 7, 8, 9, 10];
    RefRange!(ubyte[]) wrapper1;
    RefRange!(ubyte[]) wrapper2 = refRange(&buffer2);
    assert(wrapper1.ptr is null);
    assert(wrapper2.ptr is &buffer2);

    wrapper1 = refRange(&buffer1);
    assert(wrapper1.ptr is &buffer1);

    wrapper1 = wrapper2;
    assert(wrapper1.ptr is &buffer1);
    assert(buffer1 == buffer2);

    wrapper1 = RefRange!(ubyte[]).init;
    assert(wrapper1.ptr is null);
    assert(wrapper2.ptr is &buffer2);
    assert(buffer1 == buffer2);
    assert(buffer1 == [6, 7, 8, 9, 10]);

    wrapper2 = null;
    assert(wrapper2.ptr is null);
    assert(buffer2 == [6, 7, 8, 9, 10]);
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.mutation : bringToFront;
    import std.algorithm.searching : commonPrefix, find, until;
    import std.algorithm.sorting : sort;

    //Test that ranges are properly consumed.
    {
        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];
        auto wrapper = refRange(&arr);

        assert(*find(wrapper, 41).ptr == [41, 3, 40, 4, 42, 9]);
        assert(arr == [41, 3, 40, 4, 42, 9]);

        assert(*drop(wrapper, 2).ptr == [40, 4, 42, 9]);
        assert(arr == [40, 4, 42, 9]);

        assert(equal(until(wrapper, 42), [40, 4]));
        assert(arr == [42, 9]);

        assert(find(wrapper, 12).empty);
        assert(arr.empty);
    }

    {
        string str = "Hello, world-like object.";
        auto wrapper = refRange(&str);

        assert(*find(wrapper, "l").ptr == "llo, world-like object.");
        assert(str == "llo, world-like object.");

        assert(equal(take(wrapper, 5), "llo, "));
        assert(str == "world-like object.");
    }

    //Test that operating on saved ranges does not consume the original.
    {
        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];
        auto wrapper = refRange(&arr);
        auto saved = wrapper.save;
        saved.popFrontN(3);
        assert(*saved.ptr == [41, 3, 40, 4, 42, 9]);
        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);
    }

    {
        string str = "Hello, world-like object.";
        auto wrapper = refRange(&str);
        auto saved = wrapper.save;
        saved.popFrontN(13);
        assert(*saved.ptr == "like object.");
        assert(str == "Hello, world-like object.");
    }

    //Test that functions which use save work properly.
    {
        int[] arr = [1, 42];
        auto wrapper = refRange(&arr);
        assert(equal(commonPrefix(wrapper, [1, 27]), [1]));
    }

    {
        int[] arr = [4, 5, 6, 7, 1, 2, 3];
        auto wrapper = refRange(&arr);
        assert(bringToFront(wrapper[0 .. 4], wrapper[4 .. arr.length]) == 3);
        assert(arr == [1, 2, 3, 4, 5, 6, 7]);
    }

    //Test bidirectional functions.
    {
        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];
        auto wrapper = refRange(&arr);

        assert(wrapper.back == 9);
        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);

        wrapper.popBack();
        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42]);
    }

    {
        string str = "Hello, world-like object.";
        auto wrapper = refRange(&str);

        assert(wrapper.back == '.');
        assert(str == "Hello, world-like object.");

        wrapper.popBack();
        assert(str == "Hello, world-like object");
    }

    //Test random access functions.
    {
        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];
        auto wrapper = refRange(&arr);

        assert(wrapper[2] == 2);
        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);

        assert(*wrapper[3 .. 6].ptr != null, [41, 3, 40]);
        assert(arr == [1, 42, 2, 41, 3, 40, 4, 42, 9]);
    }

    //Test move functions.
    {
        int[] arr = [1, 42, 2, 41, 3, 40, 4, 42, 9];
        auto wrapper = refRange(&arr);

        auto t1 = wrapper.moveFront();
        auto t2 = wrapper.moveBack();
        wrapper.front = t2;
        wrapper.back = t1;
        assert(arr == [9, 42, 2, 41, 3, 40, 4, 42, 1]);

        sort(wrapper.save);
        assert(arr == [1, 2, 3, 4, 9, 40, 41, 42, 42]);
    }
}

@system unittest
{
    struct S
    {
        @property int front() @safe const pure nothrow { return 0; }
        enum bool empty = false;
        void popFront() @safe pure nothrow { }
        @property auto save() @safe pure nothrow return scope { return this; }
    }

    S s;
    auto wrapper = refRange(&s);
    static assert(isInfinite!(typeof(wrapper)));
}

@system unittest
{
    class C
    {
        @property int front() @safe const pure nothrow { return 0; }
        @property bool empty() @safe const pure nothrow { return false; }
        void popFront() @safe pure nothrow { }
        @property auto save() @safe pure nothrow return scope { return this; }
    }
    static assert(isForwardRange!C);

    auto c = new C;
    auto cWrapper = refRange(&c);
    static assert(is(typeof(cWrapper) == C));
    assert(cWrapper is c);
}

// https://issues.dlang.org/show_bug.cgi?id=14373
@system unittest
{
    static struct R
    {
        @property int front() {return 0;}
        void popFront() {empty = true;}
        bool empty = false;
    }
    R r;
    refRange(&r).popFront();
    assert(r.empty);
}

// https://issues.dlang.org/show_bug.cgi?id=14575
@system unittest
{
    struct R
    {
        Object front;
        alias back = front;
        bool empty = false;
        void popFront() {empty = true;}
        alias popBack = popFront;
        @property R save() {return this;}
    }
    static assert(isBidirectionalRange!R);
    R r;
    auto rr = refRange(&r);

    struct R2
    {
        @property Object front() {return null;}
        @property const(Object) front() const {return null;}
        alias back = front;
        bool empty = false;
        void popFront() {empty = true;}
        alias popBack = popFront;
        @property R2 save() {return this;}
    }
    static assert(isBidirectionalRange!R2);
    R2 r2;
    auto rr2 = refRange(&r2);
}

// https://issues.dlang.org/show_bug.cgi?id=24801
@safe unittest
{

    {
        static struct R
        {
            int front() => 0;
            void popFront() {}
            bool empty() => false;
        }
        R range;
        auto r = RefRange!R(&range);
    }

    {
        static struct R
        {
            size_t start, end;
            size_t length() => end - start;
            int opIndex(size_t i) => 0;


            int front() => this[0];
            int back() => this[length-1];
            void popFront() { start++; }
            void popBack() { end--; }
            bool empty() => length == 0;
            R save() const => R();
        }

        R range;
        auto r = RefRange!R(&range);
    }


}

/// ditto
auto refRange(R)(R* range)
if (isInputRange!R)
{
    static if (!is(R == class))
        return RefRange!R(range);
    else
        return *range;
}

// https://issues.dlang.org/show_bug.cgi?id=9060
@safe unittest
{
    import std.algorithm.iteration : map, joiner, group;
    import std.algorithm.searching : until;
    // fix for std.algorithm
    auto r = map!(x => 0)([1]);
    chain(r, r);
    zip(r, r);
    roundRobin(r, r);

    struct NRAR {
        typeof(r) input;
        @property empty() { return input.empty; }
        @property front() { return input.front; }
        void popFront()   { input.popFront(); }
        @property save()  { return NRAR(input.save); }
    }
    auto n1 = NRAR(r);
    cycle(n1);  // non random access range version

    assumeSorted(r);

    // fix for std.range
    joiner([r], [9]);

    struct NRAR2 {
        NRAR input;
        @property empty() { return true; }
        @property front() { return input; }
        void popFront() { }
        @property save()  { return NRAR2(input.save); }
    }
    auto n2 = NRAR2(n1);
    joiner(n2);

    group(r);

    until(r, 7);
    static void foo(R)(R r) { until!(x => x > 7)(r); }
    foo(r);
}

private struct Bitwise(R)
if (isInputRange!R && isIntegral!(ElementType!R))
{
    import std.traits : Unsigned;
private:
    alias ElemType = ElementType!R;
    alias UnsignedElemType = Unsigned!ElemType;

    R parent;
    enum bitsNum = ElemType.sizeof * 8;
    size_t maskPos = 1;

    static if (isBidirectionalRange!R)
    {
        size_t backMaskPos = bitsNum;
    }

public:
    this()(auto ref R range)
    {
        parent = range;
    }

    static if (isInfinite!R)
    {
        enum empty = false;
    }
    else
    {
        /**
         * Check if the range is empty
         *
         * Returns: a boolean true or false
         */
        bool empty()
        {
            static if (hasLength!R)
            {
                return length == 0;
            }
            else static if (isBidirectionalRange!R)
            {
                if (parent.empty)
                {
                    return true;
                }
                else
                {
                    /*
                       If we have consumed the last element of the range both from
                       the front and the back, then the masks positions will overlap
                     */
                    return parent.save.dropOne.empty && (maskPos > backMaskPos);
                }
            }
            else
            {
                /*
                   If we consumed the last element of the range, but not all the
                   bits in the last element
                 */
                return parent.empty;
            }
        }
    }

    bool front()
    {
        assert(!empty);
        return (parent.front & mask(maskPos)) != 0;
    }

    void popFront()
    {
        assert(!empty);
        ++maskPos;
        if (maskPos > bitsNum)
        {
            parent.popFront;
            maskPos = 1;
        }
    }

    static if (hasLength!R)
    {
        size_t length()
        {
            auto len = parent.length * bitsNum - (maskPos - 1);
            static if (isBidirectionalRange!R)
            {
                len -= bitsNum - backMaskPos;
            }
            return len;
        }

        alias opDollar = length;
    }

    static if (isForwardRange!R)
    {
        typeof(this) save()
        {
            auto result = this;
            result.parent = parent.save;
            return result;
        }
    }

    static if (isBidirectionalRange!R)
    {
        bool back()
        {
            assert(!empty);
            return (parent.back & mask(backMaskPos)) != 0;
        }

        void popBack()
        {
            assert(!empty);
            --backMaskPos;
            if (backMaskPos == 0)
            {
                parent.popBack;
                backMaskPos = bitsNum;
            }
        }
    }

    static if (isRandomAccessRange!R)
    {
        /**
          Return the `n`th bit within the range
         */
        bool opIndex(size_t n)
        in
        {
            /*
               If it does not have the length property, it means that R is
               an infinite range
             */
            static if (hasLength!R)
            {
                assert(n < length, "Index out of bounds");
            }
        }
        do
        {
            immutable size_t remainingBits = bitsNum - maskPos + 1;
            // If n >= maskPos, then the bit sign will be 1, otherwise 0
            immutable ptrdiff_t sign = (remainingBits - n - 1) >> (ptrdiff_t.sizeof * 8 - 1);
            /*
               By truncating n with remainingBits bits we have skipped the
               remaining bits in parent[0], so we need to add 1 to elemIndex.

               Because bitsNum is a power of 2, n / bitsNum == n >> bitsNum.bsf
             */
            import core.bitop : bsf;
            immutable size_t elemIndex = sign * (((n - remainingBits) >> bitsNum.bsf) + 1);

            /*
               Since the indexing is from LSB to MSB, we need to index at the
               remainder of (n - remainingBits).

               Because bitsNum is a power of 2, n % bitsNum == n & (bitsNum - 1)
             */
            immutable size_t elemMaskPos = (sign ^ 1) * (maskPos + n)
                             + sign * (1 + ((n - remainingBits) & (bitsNum - 1)));

            return (parent[elemIndex] & mask(elemMaskPos)) != 0;
        }

        static if (hasAssignableElements!R)
        {
            /**
              Assigns `flag` to the `n`th bit within the range
             */
            void opIndexAssign(bool flag, size_t n)
                in
                {
                    static if (hasLength!R)
                    {
                        assert(n < length, "Index out of bounds");
                    }
                }
            do
            {
                import core.bitop : bsf;

                immutable size_t remainingBits = bitsNum - maskPos + 1;
                immutable ptrdiff_t sign = (remainingBits - n - 1) >> (ptrdiff_t.sizeof * 8 - 1);
                immutable size_t elemIndex = sign * (((n - remainingBits) >> bitsNum.bsf) + 1);
                immutable size_t elemMaskPos = (sign ^ 1) * (maskPos + n)
                    + sign * (1 + ((n - remainingBits) & (bitsNum - 1)));

                auto elem = parent[elemIndex];
                auto elemMask = mask(elemMaskPos);
                parent[elemIndex] = cast(UnsignedElemType)(flag * (elem | elemMask)
                        + (flag ^ 1) * (elem & ~elemMask));
            }
        }

        Bitwise!R opSlice()
        {
            return this.save;
        }

        Bitwise!R opSlice(size_t start, size_t end)
        in
        {
            assert(start < end, "Invalid bounds: end <= start");
        }
        do
        {
            import core.bitop : bsf;

            size_t remainingBits = bitsNum - maskPos + 1;
            ptrdiff_t sign = (remainingBits - start - 1) >> (ptrdiff_t.sizeof * 8 - 1);
            immutable size_t startElemIndex = sign * (((start - remainingBits) >> bitsNum.bsf) + 1);
            immutable size_t startElemMaskPos = (sign ^ 1) * (maskPos + start)
                                              + sign * (1 + ((start - remainingBits) & (bitsNum - 1)));

            immutable size_t sliceLen = end - start - 1;
            remainingBits = bitsNum - startElemMaskPos + 1;
            sign = (remainingBits - sliceLen - 1) >> (ptrdiff_t.sizeof * 8 - 1);
            immutable size_t endElemIndex = startElemIndex
                                          + sign * (((sliceLen - remainingBits) >> bitsNum.bsf) + 1);
            immutable size_t endElemMaskPos = (sign ^ 1) * (startElemMaskPos + sliceLen)
                                            + sign * (1 + ((sliceLen - remainingBits) & (bitsNum - 1)));

            typeof(return) result;
            // Get the slice to be returned from the parent
            result.parent = (parent[startElemIndex .. endElemIndex + 1]).save;
            result.maskPos = startElemMaskPos;
            static if (isBidirectionalRange!R)
            {
                result.backMaskPos = endElemMaskPos;
            }
            return result;
        }
    }

private:
    auto mask(size_t maskPos)
    {
        return (1UL << (maskPos - 1UL));
    }
}

/**
Bitwise adapter over an integral type range. Consumes the range elements bit by
bit, from the least significant bit to the most significant bit.

Params:
    R = an integral $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to iterate over
    range = range to consume bit by by

Returns:
    A `Bitwise` input range with propagated forward, bidirectional
    and random access capabilities
*/
auto bitwise(R)(auto ref R range)
if (isInputRange!R && isIntegral!(ElementType!R))
{
    return Bitwise!R(range);
}

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

    // 00000011 00001001
    ubyte[] arr = [3, 9];
    auto r = arr.bitwise;

    // iterate through it as with any other range
    assert(format("%(%d%)", r) == "1100000010010000");
    assert(format("%(%d%)", r.retro).equal("1100000010010000".retro));

    auto r2 = r[5 .. $];
    // set a bit
    r[2] = 1;
    assert(arr[0] == 7);
    assert(r[5] == r2[0]);
}

/// You can use bitwise to implement an uniform bool generator
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.random : rndGen;

    auto rb = rndGen.bitwise;
    static assert(isInfinite!(typeof(rb)));

    auto rb2 = rndGen.bitwise;
    // Don't forget that structs are passed by value
    assert(rb.take(10).equal(rb2.take(10)));
}

// Test nogc inference
@safe @nogc unittest
{
    static ubyte[] arr = [3, 9];
    auto bw = arr.bitwise;
    auto bw2 = bw[];
    auto bw3 = bw[8 .. $];
    bw3[2] = true;

    assert(arr[1] == 13);
    assert(bw[$ - 6]);
    assert(bw[$ - 6] == bw2[$ - 6]);
    assert(bw[$ - 6] == bw3[$ - 6]);
}

// Test all range types over all integral types
@safe pure nothrow unittest
{
    import std.meta : AliasSeq;
    import std.internal.test.dummyrange;

    alias IntegralTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint,
            long, ulong);
    foreach (IntegralType; IntegralTypes)
    {
        foreach (T; AllDummyRangesType!(IntegralType[]))
        {
            T a;
            auto bw = Bitwise!T(a);

            static if (isForwardRange!T)
            {
                auto bwFwdSave = bw.save;
            }

            static if (isBidirectionalRange!T)
            {
                auto bwBack = bw.save;
                auto bwBackSave = bw.save;
            }

            static if (hasLength!T)
            {
                auto bwLength = bw.length;
                assert(bw.length == (IntegralType.sizeof * 8 * a.length));
                static if (isForwardRange!T)
                {
                    assert(bw.length == bwFwdSave.length);
                }
            }

            // Make sure front and back are not the mechanisms that modify the range
            long numCalls = 42;
            bool initialFrontValue;

            if (!bw.empty)
            {
                initialFrontValue = bw.front;
            }

            while (!bw.empty && (--numCalls))
            {
                bw.front;
                assert(bw.front == initialFrontValue);
            }

            /*
               Check that empty works properly and that popFront does not get called
               more times than it should
             */
            numCalls = 0;
            while (!bw.empty)
            {
                ++numCalls;

                static if (hasLength!T)
                {
                    assert(bw.length == bwLength);
                    --bwLength;
                }

                static if (isForwardRange!T)
                {
                    assert(bw.front == bwFwdSave.front);
                    bwFwdSave.popFront();
                }

                static if (isBidirectionalRange!T)
                {
                    assert(bwBack.front == bwBackSave.front);
                    bwBack.popBack();
                    bwBackSave.popBack();
                }
                bw.popFront();
            }

            auto rangeLen = numCalls / (IntegralType.sizeof * 8);
            assert(numCalls == (IntegralType.sizeof * 8 * rangeLen));
            assert(bw.empty);
            static if (isForwardRange!T)
            {
                assert(bwFwdSave.empty);
            }

            static if (isBidirectionalRange!T)
            {
                assert(bwBack.empty);
            }
        }
    }
}

// Test opIndex and opSlice
@system unittest
{
    import std.meta : AliasSeq;
    alias IntegralTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint,
            long, ulong);
    foreach (IntegralType; IntegralTypes)
    {
        size_t bitsNum = IntegralType.sizeof * 8;

        auto first = IntegralType(1);

        // 2 ^ (bitsNum - 1)
        auto second = cast(IntegralType)(IntegralType(1) << (bitsNum - 2));

        IntegralType[] a = [first, second];
        auto bw = Bitwise!(IntegralType[])(a);

        // Check against lsb of a[0]
        assert(bw[0] == true);
        // Check against msb - 1 of a[1]
        assert(bw[2 * bitsNum - 2] == true);

        bw.popFront();
        assert(bw[2 * bitsNum - 3] == true);

        import std.exception : assertThrown;

        version (D_NoBoundsChecks) {}
        else
        {
            // Check out of bounds error
            assertThrown!Error(bw[2 * bitsNum - 1]);
        }

        bw[2] = true;
        assert(bw[2] == true);
        bw.popFront();
        assert(bw[1] == true);

        auto bw2 = bw[0 .. $ - 5];
        auto bw3 = bw2[];
        assert(bw2.length == bw.length - 5);
        assert(bw2.length == bw3.length);
        bw2.popFront();
        assert(bw2.length != bw3.length);
    }
}

/*********************************
 * An OutputRange that discards the data it receives.
 */
struct NullSink
{
    void put(E)(scope const E) pure @safe @nogc nothrow {}
}

/// ditto
auto ref nullSink()
{
    static NullSink sink;
    return sink;
}

///
@safe nothrow unittest
{
    import std.algorithm.iteration : map;
    import std.algorithm.mutation : copy;
    [4, 5, 6].map!(x => x * 2).copy(nullSink); // data is discarded
}

///
@safe unittest
{
    import std.csv : csvNextToken;

    string line = "a,b,c";

    // ignore the first column
    line.csvNextToken(nullSink, ',', '"');
    line.popFront;

    // look at the second column
    Appender!string app;
    line.csvNextToken(app, ',', '"');
    assert(app.data == "b");
}

@safe unittest
{
    auto r = 10.iota
                .tee(nullSink)
                .dropOne;

    assert(r.front == 1);
}

/++

  Implements a "tee" style pipe, wrapping an input range so that elements of the
  range can be passed to a provided function or $(LREF OutputRange) as they are
  iterated over. This is useful for printing out intermediate values in a long
  chain of range code, performing some operation with side-effects on each call
  to `front` or `popFront`, or diverting the elements of a range into an
  auxiliary $(LREF OutputRange).

  It is important to note that as the resultant range is evaluated lazily,
  in the case of the version of `tee` that takes a function, the function
  will not actually be executed until the range is "walked" using functions
  that evaluate ranges, such as $(REF array, std,array) or
  $(REF fold, std,algorithm,iteration).

  Params:
  pipeOnPop = If `Yes.pipeOnPop`, simply iterating the range without ever
  calling `front` is enough to have `tee` mirror elements to `outputRange` (or,
  respectively, `fun`). Note that each `popFront()` call will mirror the
  old `front` value, not the new one. This means that the last value will
  not be forwarded if the range isn't iterated until empty. If
  `No.pipeOnPop`, only elements for which `front` does get called will be
  also sent to `outputRange`/`fun`. If `front` is called twice for the same
  element, it will still be sent only once. If this caching is undesired,
  consider using $(REF map, std,algorithm,iteration) instead.
  inputRange = The input range being passed through.
  outputRange = This range will receive elements of `inputRange` progressively
  as iteration proceeds.
  fun = This function will be called with elements of `inputRange`
  progressively as iteration proceeds.

  Returns:
  An input range that offers the elements of `inputRange`. Regardless of
  whether `inputRange` is a more powerful range (forward, bidirectional etc),
  the result is always an input range. Reading this causes `inputRange` to be
  iterated and returns its elements in turn. In addition, the same elements
  will be passed to `outputRange` or `fun` as well.

  See_Also: $(REF each, std,algorithm,iteration)
+/
auto tee(Flag!"pipeOnPop" pipeOnPop = Yes.pipeOnPop, R1, R2)(R1 inputRange, R2 outputRange)
if (isInputRange!R1 && isOutputRange!(R2, ElementType!R1))
{
    static struct Result
    {
        private R1 _input;
        private R2 _output;
        static if (!pipeOnPop)
        {
            private bool _frontAccessed;
        }

        mixin ImplementLength!_input;

        static if (isInfinite!R1)
        {
            enum bool empty = false;
        }
        else
        {
            @property bool empty() { return _input.empty; }
        }

        void popFront()
        {
            assert(!_input.empty, "Attempting to popFront an empty tee");
            static if (pipeOnPop)
            {
                put(_output, _input.front);
            }
            else
            {
                _frontAccessed = false;
            }
            _input.popFront();
        }

        @property auto ref front()
        {
            assert(!_input.empty, "Attempting to fetch the front of an empty tee");
            static if (!pipeOnPop)
            {
                if (!_frontAccessed)
                {
                    _frontAccessed = true;
                    put(_output, _input.front);
                }
            }
            return _input.front;
        }
    }

    return Result(inputRange, outputRange);
}

/// Ditto
auto tee(alias fun, Flag!"pipeOnPop" pipeOnPop = Yes.pipeOnPop, R1)(R1 inputRange)
if (is(typeof(fun) == void) || isSomeFunction!fun)
{
    import std.traits : isDelegate, isFunctionPointer;
    /*
        Distinguish between function literals and template lambdas
        when using either as an $(LREF OutputRange). Since a template
        has no type, typeof(template) will always return void.
        If it's a template lambda, it's first necessary to instantiate
        it with `ElementType!R1`.
    */
    static if (is(typeof(fun) == void))
        alias _fun = fun!(ElementType!R1);
    else
        alias _fun = fun;

    static if (isFunctionPointer!_fun || isDelegate!_fun)
    {
        return tee!pipeOnPop(inputRange, _fun);
    }
    else
    {
        return tee!pipeOnPop(inputRange, &_fun);
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter, map;

    // Sum values while copying
    int[] values = [1, 4, 9, 16, 25];
    int sum = 0;
    auto newValues = values.tee!(a => sum += a).array;
    assert(equal(newValues, values));
    assert(sum == 1 + 4 + 9 + 16 + 25);

    // Count values that pass the first filter
    int count = 0;
    auto newValues4 = values.filter!(a => a < 10)
                            .tee!(a => count++)
                            .map!(a => a + 1)
                            .filter!(a => a < 10);

    //Fine, equal also evaluates any lazy ranges passed to it.
    //count is not 3 until equal evaluates newValues4
    assert(equal(newValues4, [2, 5]));
    assert(count == 3);
}

//
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter, map;

    int[] values = [1, 4, 9, 16, 25];

    int count = 0;
    auto newValues = values.filter!(a => a < 10)
        .tee!(a => count++, No.pipeOnPop)
        .map!(a => a + 1)
        .filter!(a => a < 10);

    auto val = newValues.front;
    assert(count == 1);
    //front is only evaluated once per element
    val = newValues.front;
    assert(count == 1);

    //popFront() called, fun will be called
    //again on the next access to front
    newValues.popFront();
    newValues.front;
    assert(count == 2);

    int[] preMap = new int[](3), postMap = [];
    auto mappedValues = values.filter!(a => a < 10)
        //Note the two different ways of using tee
        .tee(preMap)
        .map!(a => a + 1)
        .tee!(a => postMap ~= a)
        .filter!(a => a < 10);
    assert(equal(mappedValues, [2, 5]));
    assert(equal(preMap, [1, 4, 9]));
    assert(equal(postMap, [2, 5, 10]));
}

//
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter, map;

    char[] txt = "Line one, Line 2".dup;

    bool isVowel(dchar c)
    {
        import std.string : indexOf;
        return "AaEeIiOoUu".indexOf(c) != -1;
    }

    int vowelCount = 0;
    int shiftedCount = 0;
    auto removeVowels = txt.tee!(c => isVowel(c) ? vowelCount++ : 0)
                                .filter!(c => !isVowel(c))
                                .map!(c => (c == ' ') ? c : c + 1)
                                .tee!(c => isVowel(c) ? shiftedCount++ : 0);
    assert(equal(removeVowels, "Mo o- Mo 3"));
    assert(vowelCount == 6);
    assert(shiftedCount == 3);
}

@safe unittest
{
    // Manually stride to test different pipe behavior.
    void testRange(Range)(Range r)
    {
        const int strideLen = 3;
        int i = 0;
        ElementType!Range elem1;
        ElementType!Range elem2;
        while (!r.empty)
        {
            if (i % strideLen == 0)
            {
                //Make sure front is only
                //evaluated once per item
                elem1 = r.front;
                elem2 = r.front;
                assert(elem1 == elem2);
            }
            r.popFront();
            i++;
        }
    }

    string txt = "abcdefghijklmnopqrstuvwxyz";

    int popCount = 0;
    auto pipeOnPop = txt.tee!(a => popCount++);
    testRange(pipeOnPop);
    assert(popCount == 26);

    int frontCount = 0;
    auto pipeOnFront = txt.tee!(a => frontCount++, No.pipeOnPop);
    testRange(pipeOnFront);
    assert(frontCount == 9);
}

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

    //Test diverting elements to an OutputRange
    string txt = "abcdefghijklmnopqrstuvwxyz";

    dchar[] asink1 = [];
    auto fsink = (dchar c) { asink1 ~= c; };
    auto result1 = txt.tee(fsink).array;
    assert(equal(txt, result1) && (equal(result1, asink1)));

    dchar[] _asink1 = [];
    auto _result1 = txt.tee!((dchar c) { _asink1 ~= c; })().array;
    assert(equal(txt, _result1) && (equal(_result1, _asink1)));

    dchar[] asink2 = new dchar[](txt.length);
    void fsink2(dchar c) { static int i = 0; asink2[i] = c; i++; }
    auto result2 = txt.tee(&fsink2).array;
    assert(equal(txt, result2) && equal(result2, asink2));

    dchar[] asink3 = new dchar[](txt.length);
    auto result3 = txt.tee(asink3).array;
    assert(equal(txt, result3) && equal(result3, asink3));

    static foreach (CharType; AliasSeq!(char, wchar, dchar))
    {{
        auto appSink = appender!(CharType[])();
        auto appResult = txt.tee(appSink).array;
        assert(equal(txt, appResult) && equal(appResult, appSink.data));
    }}

    static foreach (StringType; AliasSeq!(string, wstring, dstring))
    {{
        auto appSink = appender!StringType();
        auto appResult = txt.tee(appSink).array;
        assert(equal(txt, appResult) && equal(appResult, appSink.data));
    }}
}

// https://issues.dlang.org/show_bug.cgi?id=13483
@safe unittest
{
    static void func1(T)(T x) {}
    void func2(int x) {}

    auto r = [1, 2, 3, 4].tee!func1.tee!func2;
}

/**
Extends the length of the input range `r` by padding out the start of the
range with the element `e`. The element `e` must be of a common type with
the element type of the range `r` as defined by $(REF CommonType, std, traits).
If `n` is less than the length of of `r`, then `r` is returned unmodified.

If `r` is a string with Unicode characters in it, `padLeft` follows D's rules
about length for strings, which is not the number of characters, or
graphemes, but instead the number of encoding units. If you want to treat each
grapheme as only one encoding unit long, then call
$(REF byGrapheme, std, uni) before calling this function.

If `r` has a length, then this is $(BIGOH 1). Otherwise, it's $(BIGOH r.length).

Params:
    r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with a length, or a forward range
    e = element to pad the range with
    n = the length to pad to

Returns:
    A range containing the elements of the original range with the extra padding

See Also:
    $(REF leftJustifier, std, string)
*/
auto padLeft(R, E)(R r, E e, size_t n)
if (
    ((isInputRange!R && hasLength!R) || isForwardRange!R) &&
    !is(CommonType!(ElementType!R, E) == void)
)
{
    static if (hasLength!R)
        auto dataLength = r.length;
    else
        auto dataLength = r.save.walkLength(n);

    return e.repeat(n > dataLength ? n - dataLength : 0).chain(r);
}

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

    assert([1, 2, 3, 4].padLeft(0, 6).equal([0, 0, 1, 2, 3, 4]));
    assert([1, 2, 3, 4].padLeft(0, 3).equal([1, 2, 3, 4]));

    assert("abc".padLeft('_', 6).equal("___abc"));
}

@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : DummyRange, Length, RangeType, ReturnBy;
    import std.meta : AliasSeq;

    alias DummyRanges = AliasSeq!(
        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input),
        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Forward),
        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Bidirectional),
        DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random),
        DummyRange!(ReturnBy.Reference, Length.No, RangeType.Forward),
        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Input),
        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Forward),
        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Bidirectional),
        DummyRange!(ReturnBy.Value, Length.Yes, RangeType.Random),
        DummyRange!(ReturnBy.Value, Length.No, RangeType.Forward)
    );

    foreach (Range; DummyRanges)
    {
        Range r;
        assert(r
            .padLeft(0, 12)
            .equal([0, 0, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U])
        );
    }
}

// Test nogc inference
@safe @nogc pure unittest
{
    import std.algorithm.comparison : equal;

    static immutable r1 = [1, 2, 3, 4];
    static immutable r2 = [0, 0, 1, 2, 3, 4];
    assert(r1.padLeft(0, 6).equal(r2));
}

/**
Extend the length of the input range `r` by padding out the end of the range
with the element `e`. The element `e` must be of a common type with the
element type of the range `r` as defined by $(REF CommonType, std, traits).
If `n` is less than the length of of `r`, then the contents of `r` are
returned.

The range primitives that the resulting range provides depends whether or not `r`
provides them. Except the functions `back` and `popBack`, which also require
the range to have a length as well as `back` and `popBack`

Params:
    r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with a length
    e = element to pad the range with
    n = the length to pad to

Returns:
    A range containing the elements of the original range with the extra padding

See Also:
    $(REF rightJustifier, std, string)
*/
auto padRight(R, E)(R r, E e, size_t n)
if (
    isInputRange!R &&
    !isInfinite!R &&
    !is(CommonType!(ElementType!R, E) == void))
{
    static struct Result
    {
        private:
        R data;
        E element;
        static if (hasLength!R)
        {
            size_t padLength;
        }
        else
        {
            size_t minLength;
            size_t consumed;
        }

        public:
        bool empty() @property
        {
            static if (hasLength!R)
            {
                return data.empty && padLength == 0;
            }
            else
            {
                return data.empty && consumed >= minLength;
            }
        }

        auto front() @property
        {
            assert(!empty, "Attempting to fetch the front of an empty padRight");
            return data.empty ? element : data.front;
        }

        void popFront()
        {
            assert(!empty, "Attempting to popFront an empty padRight");

            static if (hasLength!R)
            {
                if (!data.empty)
                {
                    data.popFront;
                }
                else
                {
                    --padLength;
                }
            }
            else
            {
                ++consumed;
                if (!data.empty)
                {
                    data.popFront;
                }
            }
        }

        static if (hasLength!R)
        {
            size_t length() @property
            {
                return data.length + padLength;
            }
        }

        static if (isForwardRange!R)
        {
            auto save() @property
            {
                typeof(this) result = this;
                data = data.save;
                return result;
            }
        }

        static if (isBidirectionalRange!R && hasLength!R)
        {
            auto back() @property
            {
                assert(!empty, "Attempting to fetch the back of an empty padRight");
                return padLength > 0 ? element : data.back;
            }

            void popBack()
            {
                assert(!empty, "Attempting to popBack an empty padRight");
                if (padLength > 0)
                {
                    --padLength;
                }
                else
                {
                    data.popBack;
                }
            }
        }

        static if (isRandomAccessRange!R && hasLength!R)
        {
            E opIndex(size_t index)
            {
                assert(index <= this.length, "Index out of bounds");
                return index >= data.length ? element : data[index];
            }
        }

        static if (hasSlicing!R && hasLength!R)
        {
            auto opSlice(size_t a, size_t b)
            {
                assert(
                    a <= b,
                    "Attempting to slice a padRight with a larger first argument than the second."
                );
                assert(
                    b <= length,
                    "Attempting to slice using an out of bounds index on a padRight"
                );
                return Result(
                    a >= data.length ? data[0 .. 0] : b <= data.length ? data[a .. b] : data[a .. data.length],
                    element, b - a);
            }

            alias opDollar = length;
        }

        this(R r, E e, size_t n)
        {
            data = r;
            element = e;
            static if (hasLength!R)
            {
                padLength = n > data.length ? n - data.length : 0;
            }
            else
            {
                minLength = n;
            }
        }

        @disable this();
    }

    return Result(r, e, n);
}

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

    assert([1, 2, 3, 4].padRight(0, 6).equal([1, 2, 3, 4, 0, 0]));
    assert([1, 2, 3, 4].padRight(0, 4).equal([1, 2, 3, 4]));

    assert("abc".padRight('_', 6).equal("abc___"));
}

pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges, ReferenceInputRange;
    import std.meta : AliasSeq;

    auto string_input_range = new ReferenceInputRange!dchar(['a', 'b', 'c']);
    dchar padding = '_';
    assert(string_input_range.padRight(padding, 6).equal("abc___"));

    foreach (RangeType; AllDummyRanges)
    {
        RangeType r1;
        assert(r1
            .padRight(0, 12)
            .equal([1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0, 0])
        );

        // test if Result properly uses random access ranges
        static if (isRandomAccessRange!RangeType)
        {
            RangeType r3;
            assert(r3.padRight(0, 12)[0] == 1);
            assert(r3.padRight(0, 12)[2] == 3);
            assert(r3.padRight(0, 12)[9] == 10);
            assert(r3.padRight(0, 12)[10] == 0);
            assert(r3.padRight(0, 12)[11] == 0);
        }

        // test if Result properly uses slicing and opDollar
        static if (hasSlicing!RangeType)
        {
            RangeType r4;
            assert(r4
                .padRight(0, 12)[0 .. 3]
                .equal([1, 2, 3])
            );
            assert(r4
                .padRight(0, 12)[0 .. 10]
                .equal([1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U])
            );
            assert(r4
                .padRight(0, 12)[0 .. 11]
                .equal([1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0])
            );
            assert(r4
                .padRight(0, 12)[2 .. $]
                .equal([3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0, 0])
            );
            assert(r4
                .padRight(0, 12)[0 .. $]
                .equal([1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 0, 0])
            );
        }

        // drop & dropBack test opslice ranges when available, popFront/popBack otherwise
        RangeType r5;
        foreach (i; 1 .. 13) assert(r5.padRight(0, 12).drop(i).walkLength == 12 - i);
    }
}

// Test nogc inference
@safe @nogc pure unittest
{
    import std.algorithm.comparison : equal;

    static immutable r1 = [1, 2, 3, 4];
    static immutable r2 = [1, 2, 3, 4, 0, 0];
    assert(r1.padRight(0, 6).equal(r2));
}

// Test back, popBack, and save
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    auto r1 = [1, 2, 3, 4].padRight(0, 6);
    assert(r1.back == 0);

    r1.popBack;
    auto r2 = r1.save;
    assert(r1.equal([1, 2, 3, 4, 0]));
    assert(r2.equal([1, 2, 3, 4, 0]));

    r1.popBackN(2);
    assert(r1.back == 3);
    assert(r1.length == 3);
    assert(r2.length == 5);
    assert(r2.equal([1, 2, 3, 4, 0]));

    r2.popFront;
    assert(r2.length == 4);
    assert(r2[0] == 2);
    assert(r2[1] == 3);
    assert(r2[2] == 4);
    assert(r2[3] == 0);
    assert(r2.equal([2, 3, 4, 0]));

    r2.popBack;
    assert(r2.equal([2, 3, 4]));

    auto r3 = [1, 2, 3, 4].padRight(0, 6);
    size_t len = 0;
    while (!r3.empty)
    {
        ++len;
        r3.popBack;
    }
    assert(len == 6);
}

// https://issues.dlang.org/show_bug.cgi?id=19042
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert([2, 5, 13].padRight(42, 10).chunks(5)
           .equal!equal([[2, 5, 13, 42, 42], [42, 42, 42, 42, 42]]));

    assert([1, 2, 3, 4].padRight(0, 10)[7 .. 9].equal([0, 0]));
}

/**
This simplifies a commonly used idiom in phobos for accepting any kind of string
parameter. The type `R` can for example be a simple string, chained string using
$(REF chain, std,range), $(REF chainPath, std,path) or any other input range of
characters.

Only finite length character ranges are allowed with this constraint.

This template is equivalent to:
---
isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R)
---

See_Also:
$(REF isInputRange, std,range,primitives),
$(REF isInfinite, std,range,primitives),
$(LREF isSomeChar),
$(REF ElementEncodingType, std,range,primitives)
*/
template isSomeFiniteCharInputRange(R)
{
    import std.traits : isSomeChar;

    enum isSomeFiniteCharInputRange = isInputRange!R && !isInfinite!R
        && isSomeChar!(ElementEncodingType!R);
}

///
@safe unittest
{
    import std.path : chainPath;
    import std.range : chain;

    void someLibraryMethod(R)(R argument)
    if (isSomeFiniteCharInputRange!R)
    {
        // implementation detail, would iterate over each character of argument
    }

    someLibraryMethod("simple strings work");
    someLibraryMethod(chain("chained", " ", "strings", " ", "work"));
    someLibraryMethod(chainPath("chained", "paths", "work"));
    // you can also use custom structs implementing a char range
}

