// 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;

import std.internal.attributes : betterC;
import std.meta : 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)
                {
                    source.back = val;
                }

                @property void back(ElementType!R val)
                {
                    source.front = 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)
                    {
                        source[retroIndex(n)] = 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) {}
}


/**
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)
                {
                    source.front = 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]));
}

/**
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.

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);
            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;
                }
            }

            // This is the entire state
            R source;
            // TODO: use a vtable (or more) instead of linear iteration

        public:
            this(R input)
            {
                // Must be static foreach because of https://issues.dlang.org/show_bug.cgi?id=21209
                static foreach (i, v; input)
                {
                    source[i] = v;
                }
            }

            import std.meta : anySatisfy;

            static if (anySatisfy!(isInfinite, R))
            {
                // Propagate infiniteness.
                enum bool empty = false;
            }
            else
            {
                @property bool empty()
                {
                    foreach (i, Unused; R)
                    {
                        if (!source[i].empty) return false;
                    }
                    return true;
                }
            }

            static if (allSatisfy!(isForwardRange, R))
                @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!(R.length).expand);
                }

            void popFront()
            {
                foreach (i, Unused; R)
                {
                    if (source[i].empty) continue;
                    source[i].popFront();
                    return;
                }
                assert(false, "Attempt to `popFront` of empty `chain` range");
            }

            @property auto ref front()
            {
                foreach (i, Unused; R)
                {
                    if (source[i].empty) continue;
                    return fixRef(source[i].front);
                }
                assert(false, "Attempt to get `front` of empty `chain` range");
            }

            static if (allSameType && allSatisfy!(hasAssignableElements, R))
            {
                // @@@BUG@@@
                //@property void front(T)(T v) if (is(T : RvalueElementType))

                @property void front(RvalueElementType v)
                {
                    foreach (i, Unused; R)
                    {
                        if (source[i].empty) continue;
                        source[i].front = v;
                        return;
                    }
                    assert(false, "Attempt to set `front` of empty `chain` range");
                }
            }

            static if (allSatisfy!(hasMobileElements, R))
            {
                RvalueElementType moveFront()
                {
                    foreach (i, Unused; R)
                    {
                        if (source[i].empty) continue;
                        return source[i].moveFront();
                    }
                    assert(false, "Attempt to `moveFront` of empty `chain` range");
                }
            }

            static if (allSatisfy!(isBidirectionalRange, R))
            {
                @property auto ref back()
                {
                    foreach_reverse (i, Unused; R)
                    {
                        if (source[i].empty) continue;
                        return fixRef(source[i].back);
                    }
                    assert(false, "Attempt to get `back` of empty `chain` range");
                }

                void popBack()
                {
                    foreach_reverse (i, Unused; R)
                    {
                        if (source[i].empty) continue;
                        source[i].popBack();
                        return;
                    }
                    assert(false, "Attempt to `popBack` of empty `chain` range");
                }

                static if (allSatisfy!(hasMobileElements, R))
                {
                    RvalueElementType moveBack()
                    {
                        foreach_reverse (i, Unused; R)
                        {
                            if (source[i].empty) continue;
                            return source[i].moveBack();
                        }
                        assert(false, "Attempt to `moveBack` of empty `chain` range");
                    }
                }

                static if (allSameType && allSatisfy!(hasAssignableElements, R))
                {
                    @property void back(RvalueElementType v)
                    {
                        foreach_reverse (i, Unused; R)
                        {
                            if (source[i].empty) continue;
                            source[i].back = v;
                            return;
                        }
                        assert(false, "Attempt to set `back` of empty `chain` range");
                    }
                }
            }

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

                alias opDollar = length;
            }

            static if (allSatisfy!(isRandomAccessRange, R))
            {
                auto ref opIndex(size_t index)
                {
                    foreach (i, Range; R)
                    {
                        static if (isInfinite!(Range))
                        {
                            return source[i][index];
                        }
                        else
                        {
                            immutable length = source[i].length;
                            if (index < length) return fixRef(source[i][index]);
                            index -= length;
                        }
                    }
                    assert(false, "Attempt to access out-of-bounds index of `chain` range");
                }

                static if (allSatisfy!(hasMobileElements, R))
                {
                    RvalueElementType moveAt(size_t index)
                    {
                        foreach (i, Range; R)
                        {
                            static if (isInfinite!(Range))
                            {
                                return source[i].moveAt(index);
                            }
                            else
                            {
                                immutable length = source[i].length;
                                if (index < length) return source[i].moveAt(index);
                                index -= length;
                            }
                        }
                        assert(false, "Attempt to move out-of-bounds index of `chain` range");
                    }
                }

                static if (allSameType && allSatisfy!(hasAssignableElements, R))
                    void opIndexAssign(ElementType v, size_t index)
                    {
                        foreach (i, Range; R)
                        {
                            static if (isInfinite!(Range))
                            {
                                source[i][index] = v;
                            }
                            else
                            {
                                immutable length = source[i].length;
                                if (index < length)
                                {
                                    source[i][index] = v;
                                    return;
                                }
                                index -= length;
                            }
                        }
                        assert(false, "Attempt to write out-of-bounds index of `chain` range");
                    }
            }

            static if (allSatisfy!(hasLength, R) && allSatisfy!(hasSlicing, R))
                auto opSlice(size_t begin, size_t end) return scope
                {
                    auto result = this;
                    foreach (i, Unused; R)
                    {
                        immutable len = result.source[i].length;
                        if (len < begin)
                        {
                            result.source[i] = result.source[i]
                                [len .. len];
                            begin -= len;
                        }
                        else
                        {
                            result.source[i] = result.source[i]
                                [begin .. len];
                            break;
                        }
                    }
                    auto cut = length;
                    cut = cut <= end ? 0 : cut - end;
                    foreach_reverse (i, Unused; R)
                    {
                        immutable len = result.source[i].length;
                        if (cut > len)
                        {
                            result.source[i] = result.source[i]
                                [0 .. 0];
                            cut -= len;
                        }
                        else
                        {
                            result.source[i] = result.source[i]
                                [0 .. len - cut];
                            break;
                        }
                    }
                    return result;
                }
        }
        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[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"));
}

/**
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.__postblit();
            })(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;
}

/**
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;
        }
    }

    return Result(rs, 0);
}

///
@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"));
}

/**
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)
        {
            assert(!empty,
                "Attempting to assign to the front of an empty "
                ~ Take.stringof);
            // This has to return auto instead of void because of
            // https://issues.dlang.org/show_bug.cgi?id=4706
            source.front = 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)));
}


/**
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)
                {
                    assert(!empty,
                        "Attempting to assign to the front of an empty "
                        ~ typeof(this).stringof);
                    return _input.front = 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]));
    }}
}

/**
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:
    //Store a non-qualified T when possible: This is to make Repeat assignable
    static if ((is(T == class) || is(T == interface)) && (is(T == const) || is(T == immutable)))
    {
        import std.typecons : Rebindable;
        alias UT = Rebindable!T;
    }
    else static if (is(T : Unqual!T) && is(Unqual!T : T))
        alias UT = Unqual!T;
    else
        alias UT = T;
    UT _value;

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

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

    /// 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; }

    /// 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) { return Repeat!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)
            {
                _original[_index] = 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)
            {
                return _current.front = 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"));
}

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 string lockstepMixin(Ranges...)(bool withIndex, bool reverse)
{
    import std.format : format;

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

    if (withIndex)
    {
        params ~= "size_t";
        dgArgs ~= "index";
        if (reverse)
        {
            indexDef = q{
                size_t index = ranges[0].length-1;
                enforce(_stoppingPolicy == StoppingPolicy.requireSameLength,
                        "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);
        }
    }

    string name = reverse ? "opApplyReverse" : "opApply";

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

            auto ranges = _ranges;
            int res;
            %s

            while (%s)
            {
                res = dg(%s);
                if (res) break;
                %s
                %s
            }

            if (_stoppingPolicy == StoppingPolicy.requireSameLength)
            {
                foreach (range; ranges)
                    enforce(range.empty);
            }
            return res;
        }
    }, name, params.join(", "), indexDef,
       emptyChecks.join(" && "), dgArgs.join(", "),
       popFronts.join("\n                "),
       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`.

   Limitations: The `pure`, `@safe`, `@nogc`, or `nothrow` attributes cannot be
   inferred for `lockstep` iteration. $(LREF zip) can infer the first two due to
   a different implementation.

   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))
{
    ///
    this(R ranges, StoppingPolicy sp = StoppingPolicy.shortest)
    {
        import std.exception : enforce;

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

    mixin(lockstepMixin!Ranges(false, false));
    mixin(lockstepMixin!Ranges(true, false));
    static if (allSatisfy!(isBidirectionalRange, Ranges))
    {
        mixin(lockstepMixin!Ranges(false, true));
        static if (allSatisfy!(hasLength, Ranges))
        {
            mixin(lockstepMixin!Ranges(true, true));
        }
        else
        {
            mixin(lockstepReverseFailMixin!Ranges(true));
        }
    }
    else
    {
        mixin(lockstepReverseFailMixin!Ranges(false));
        mixin(lockstepReverseFailMixin!Ranges(true));
    }

private:
    alias R = Ranges;
    R _ranges;
    StoppingPolicy _stoppingPolicy;
}

/// 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];
}

///
@system unittest
{
   auto arr1 = [1,2,3,4,5,100];
   auto 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:
   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
@system 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++;
    }
}

@system 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))) { }
}

@system 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()(scope int delegate(%s) dg)
        {
            static assert(false, "%s");
        }
    }, 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)
        {
            _input.front.front = 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)
            {
                _input.back.front = 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)
            {
                _input[n].front = 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);
}

/**
    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.drop(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 (nextSource.empty)
                     _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]]));
}

private struct OnlyResult(Values...)
if (Values.length > 1)
{
    private enum arity = Values.length;

    private alias UnqualValues = staticMap!(Unqual, 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];
    }

    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];
    }

    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];
    }

    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)
{
    @property T front()
    {
        assert(!empty, "Attempting to fetch the front of an empty Only range");
        return fetchFront();
    }
    @property T back()
    {
        assert(!empty, "Attempting to fetch the back of an empty Only range");
        return fetchFront();
    }
    @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;

    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();
    }

    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;
    }
}

/**
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.

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 issue 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));
}

/**
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((*(cast(const R*)_range)).front))) @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((*cast(const R*)_range).empty))) @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((*cast(const R*)_range).save)))
            private alias CS = typeof((*cast(const R*)_range).save);

        static if (isSafe!((R* r) => (*r).save))
        {
            @property RefRange!S save() @trusted
            {
                mixin(_genSave());
            }

            static if (is(typeof((*cast(const R*)_range).save))) @property RefRange!CS save() @trusted const
            {
                mixin(_genSave());
            }
        }
        else
        {
            @property RefRange!S save()
            {
                mixin(_genSave());
            }

            static if (is(typeof((*cast(const R*)_range).save))) @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((*(cast(const R*)_range)).back))) @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((*cast(const R*)_range).length))) @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);
}

/// 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 = cast(IntegralType)(1);

        // 2 ^ (bitsNum - 1)
        auto second = cast(IntegralType)(cast(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
}

