// Written in the D programming language.
/**
This is a submodule of $(MREF std, algorithm).
It contains generic iteration algorithms.

$(SCRIPT inhibitQuickIndex = 1;)
$(BOOKTABLE Cheat Sheet,
$(TR $(TH Function Name) $(TH Description))
$(T2 cache,
        Eagerly evaluates and caches another range's `front`.)
$(T2 lazyCache,
        Lazily evaluates and caches another range's `front`, unlike `cache`.)
$(T2 cacheBidirectional,
        As above, but also provides `back` and `popBack`.)
$(T2 chunkBy,
        `chunkBy!((a,b) => a[1] == b[1])([[1, 1], [1, 2], [2, 2], [2, 1]])`
        returns a range containing 3 subranges: the first with just
        `[1, 1]`; the second with the elements `[1, 2]` and `[2, 2]`;
        and the third with just `[2, 1]`.)
$(T2 cumulativeFold,
        `cumulativeFold!((a, b) => a + b)([1, 2, 3, 4])` returns a
        lazily-evaluated range containing the successive reduced values `1`,
        `3`, `6`, `10`.)
$(T2 each,
        `each!writeln([1, 2, 3])` eagerly prints the numbers `1`, `2`
        and `3` on their own lines.)
$(T2 filter,
        `filter!(a => a > 0)([1, -1, 2, 0, -3])` iterates over elements `1`
        and `2`.)
$(T2 filterBidirectional,
        Similar to `filter`, but also provides `back` and `popBack` at
        a small increase in cost.)
$(T2 fold,
        `fold!((a, b) => a + b)([1, 2, 3, 4])` returns `10`.)
$(T2 group,
        `group([5, 2, 2, 3, 3])` returns a range containing the tuples
        `tuple(5, 1)`, `tuple(2, 2)`, and `tuple(3, 2)`.)
$(T2 joiner,
        `joiner(["hello", "world!"], "; ")` returns a range that iterates
        over the characters `"hello; world!"`. No new string is created -
        the existing inputs are iterated.)
$(T2 map,
        `map!(a => a * 2)([1, 2, 3])` lazily returns a range with the numbers
        `2`, `4`, `6`.)
$(T2 mean,
        Colloquially known as the average, `mean([1, 2, 3])` returns `2`.)
$(T2 permutations,
        Lazily computes all permutations using Heap's algorithm.)
$(T2 reduce,
        `reduce!((a, b) => a + b)([1, 2, 3, 4])` returns `10`.
        This is the old implementation of `fold`.)
$(T2 splitWhen,
        Lazily splits a range by comparing adjacent elements.)
$(T2 splitter,
        Lazily splits a range by a separator, element predicate or whitespace.)
$(T2 substitute,
        `[1, 2].substitute(1, 0.1)` returns `[0.1, 2]`.)
$(T2 sum,
        Same as `fold`, but specialized for accurate summation.)
$(T2 uniq,
        Iterates over the unique elements in a range, which is assumed sorted.)
)

Copyright: Andrei Alexandrescu 2008-.

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

Authors: $(HTTP erdani.com, Andrei Alexandrescu)

Source: $(PHOBOSSRC std/algorithm/iteration.d)

Macros:
T2=$(TR $(TDNW $(LREF $1)) $(TD $+))
 */
module std.algorithm.iteration;

import std.functional : unaryFun, binaryFun;
import std.range.primitives;
import std.traits;
import std.typecons : Flag, Yes, No;

/++
`cache` eagerly evaluates $(REF_ALTTEXT front, front, std,range,primitives) of `range`
on each construction or call to $(REF_ALTTEXT popFront, popFront, std,range,primitives),
to store the result in a _cache.
The result is then directly returned when $(REF_ALTTEXT front, front, std,range,primitives) is called,
rather than re-evaluated.

This can be a useful function to place in a chain, after functions
that have expensive evaluation, as a lazy alternative to $(REF array, std,array).
In particular, it can be placed after a call to $(LREF map), or before a call
$(REF filter, std,range) or $(REF tee, std,range)

`cache` may provide
$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)
iteration if needed, but since this comes at an increased cost, it must be explicitly requested via the
call to `cacheBidirectional`. Furthermore, a bidirectional _cache will
evaluate the "center" element twice, when there is only one element left in
the range.

`cache` does not provide random access primitives,
as `cache` would be unable to _cache the random accesses.
If `Range` provides slicing primitives,
then `cache` will provide the same slicing primitives,
but `hasSlicing!Cache` will not yield true (as the $(REF hasSlicing, std,range,primitives)
trait also checks for random access).

Params:
    range = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)

Returns:
    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with the cached values of range
+/
auto cache(Range)(Range range)
if (isInputRange!Range)
{
    return _Cache!(Range, false)(range);
}

/// ditto
auto cacheBidirectional(Range)(Range range)
if (isBidirectionalRange!Range)
{
    return _Cache!(Range, true)(range);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range, std.stdio;
    import std.typecons : tuple;

    ulong counter = 0;
    double fun(int x)
    {
        ++counter;
        // http://en.wikipedia.org/wiki/Quartic_function
        return ( (x + 4.0) * (x + 1.0) * (x - 1.0) * (x - 3.0) ) / 14.0 + 0.5;
    }
    // Without cache, with array (greedy)
    auto result1 = iota(-4, 5).map!(a =>tuple(a, fun(a)))()
                             .filter!(a => a[1] < 0)()
                             .map!(a => a[0])()
                             .array();

    // the values of x that have a negative y are:
    assert(equal(result1, [-3, -2, 2]));

    // Check how many times fun was evaluated.
    // As many times as the number of items in both source and result.
    assert(counter == iota(-4, 5).length + result1.length);

    counter = 0;
    // Without array, with cache (lazy)
    auto result2 = iota(-4, 5).map!(a =>tuple(a, fun(a)))()
                             .cache()
                             .filter!(a => a[1] < 0)()
                             .map!(a => a[0])();

    // the values of x that have a negative y are:
    assert(equal(result2, [-3, -2, 2]));

    // Check how many times fun was evaluated.
    // Only as many times as the number of items in source.
    assert(counter == iota(-4, 5).length);
}

// https://issues.dlang.org/show_bug.cgi?id=15891
@safe pure unittest
{
    assert([1].map!(x=>[x].map!(y=>y)).cache.front.front == 1);
}

/++
Tip: `cache` is eager when evaluating elements. If calling front on the
underlying range has a side effect, it will be observable before calling
front on the actual cached range.

Furthermore, care should be taken composing `cache` with $(REF take, std,range).
By placing `take` before `cache`, then `cache` will be "aware"
of when the range ends, and correctly stop caching elements when needed.
If calling front has no side effect though, placing `take` after `cache`
may yield a faster range.

Either way, the resulting ranges will be equivalent, but maybe not at the
same cost or side effects.
+/
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range;
    int i = 0;

    auto r = iota(0, 4).tee!((a){i = a;}, No.pipeOnPop);
    auto r1 = r.take(3).cache();
    auto r2 = r.cache().take(3);

    assert(equal(r1, [0, 1, 2]));
    assert(i == 2); //The last "seen" element was 2. The data in cache has been cleared.

    assert(equal(r2, [0, 1, 2]));
    assert(i == 3); //cache has accessed 3. It is still stored internally by cache.
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range;
    auto a = [1, 2, 3, 4];
    assert(equal(a.map!(a => (a - 1) * a)().cache(),                      [ 0, 2, 6, 12]));
    assert(equal(a.map!(a => (a - 1) * a)().cacheBidirectional().retro(), [12, 6, 2,  0]));
    auto r1 = [1, 2, 3, 4].cache()             [1 .. $];
    auto r2 = [1, 2, 3, 4].cacheBidirectional()[1 .. $];
    assert(equal(r1, [2, 3, 4]));
    assert(equal(r2, [2, 3, 4]));
}

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

    //immutable test
    static struct S
    {
        int i;
        this(int i)
        {
            //this.i = i;
        }
    }
    immutable(S)[] s = [S(1), S(2), S(3)];
    assert(equal(s.cache(),              s));
    assert(equal(s.cacheBidirectional(), s));
}

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

    //safety etc
    auto a = [1, 2, 3, 4];
    assert(equal(a.cache(),              a));
    assert(equal(a.cacheBidirectional(), a));
}

@safe unittest
{
    char[][] stringbufs = ["hello".dup, "world".dup];
    auto strings = stringbufs.map!((a)=>a.idup)().cache();
    assert(strings.front is strings.front);
}

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

    auto c = [1, 2, 3].cycle().cache();
    c = c[1 .. $];
    auto d = c[0 .. 1];
    assert(d.equal([2]));
}

@safe unittest
{
    static struct Range
    {
        bool initialized = false;
        bool front() @property {return initialized = true;}
        void popFront() {initialized = false;}
        enum empty = false;
    }
    auto r = Range().cache();
    assert(r.source.initialized == true);
}

private struct _Cache(R, bool bidir)
{
    import core.exception : RangeError;

    private
    {
        import std.algorithm.internal : algoFormat;
        import std.meta : AliasSeq;

        alias E  = ElementType!R;
        alias UE = Unqual!E;

        R source;

        static if (bidir) alias CacheTypes = AliasSeq!(UE, UE);
        else              alias CacheTypes = AliasSeq!UE;
        CacheTypes caches;

        static assert(isAssignable!(UE, E) && is(UE : E),
            algoFormat(
                "Cannot instantiate range with %s because %s elements are not assignable to %s.",
                R.stringof,
                E.stringof,
                UE.stringof
            )
        );
    }

    this(R range)
    {
        source = range;
        if (!range.empty)
        {
            caches[0] = source.front;
            static if (bidir)
                caches[1] = source.back;
        }
        else
        {
            // needed, because the compiler cannot deduce, that 'caches' is initialized
            // see https://issues.dlang.org/show_bug.cgi?id=15891
            caches[0] = UE.init;
            static if (bidir)
                caches[1] = UE.init;
        }
    }

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

    mixin ImplementLength!source;

    E front() @property
    {
        version (assert) if (empty) throw new RangeError();
        return caches[0];
    }
    static if (bidir) E back() @property
    {
        version (assert) if (empty) throw new RangeError();
        return caches[1];
    }

    void popFront()
    {
        version (assert) if (empty) throw new RangeError();
        source.popFront();
        if (!source.empty)
            caches[0] = source.front;
        else
        {
            // see https://issues.dlang.org/show_bug.cgi?id=15891
            caches[0] = UE.init;
            static if (bidir)
                caches[1] = UE.init;
        }
    }
    static if (bidir) void popBack()
    {
        version (assert) if (empty) throw new RangeError();
        source.popBack();
        if (!source.empty)
            caches[1] = source.back;
        else
        {
            // see https://issues.dlang.org/show_bug.cgi?id=15891
            caches[0] = UE.init;
            caches[1] = UE.init;
        }
    }

    static if (isForwardRange!R)
    {
        private this(R source, ref CacheTypes caches)
        {
            this.source = source;
            this.caches = caches;
        }
        typeof(this) save() @property
        {
            return typeof(this)(source.save, caches);
        }
    }

    static if (hasSlicing!R)
    {
        enum hasEndSlicing = is(typeof(source[size_t.max .. $]));

        static if (hasEndSlicing)
        {
            private static struct DollarToken{}
            enum opDollar = DollarToken.init;

            auto opSlice(size_t low, DollarToken)
            {
                return typeof(this)(source[low .. $]);
            }
        }

        static if (!isInfinite!R)
        {
            typeof(this) opSlice(size_t low, size_t high)
            {
                return typeof(this)(source[low .. high]);
            }
        }
        else static if (hasEndSlicing)
        {
            auto opSlice(size_t low, size_t high)
            in
            {
                assert(low <= high, "Bounds error when slicing cache.");
            }
            do
            {
                import std.range : takeExactly;
                return this[low .. $].takeExactly(high - low);
            }
        }
    }
}

/**
 * Similar to `cache`, but lazily evaluates the elements. Unlike `cache`,
 * this function does not eagerly evaluate the front of the range until
 * it's explicitly requested.
 *
 * This can be useful when evaluation of range elements has side effects that
 * should be delayed until actually needed.
 *
 * See_Also: cache
 *
 * Params:
 *    range = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
 *
 * Returns:
 *    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) with the lazily cached values of range
 */

auto lazyCache(Range)(Range range)
if (isInputRange!Range)
{
    return LazyCache!(Range, isBidirectionalRange!Range)(range);
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range, std.stdio;
    import std.typecons : tuple;

    ulong counter = 0;
    double fun(int x)
    {
        ++counter;
        // http://en.wikipedia.org/wiki/Quartic_function
        return ( (x + 4.0) * (x + 1.0) * (x - 1.0) * (x - 3.0) ) / 14.0 + 0.5;
    }
    // With lazyCache, front won't be evaluated until requested
    counter = 0;
    auto result = iota(-4, 5).map!(a => tuple(a, fun(a)))()
                            .lazyCache();
    // At this point, no elements have been evaluated yet
    assert(counter == 0);
    // Now access the first element
    auto firstElement = result.front;
    // Only now the first element is evaluated
    assert(counter == 1);
    // Process the result lazily
    auto filtered = result.filter!(a => a[1] < 0)()
                         .map!(a => a[0])();
    // Values are calculated as we iterate
    assert(equal(filtered, [-3, -2, 2]));
    // Only elements we actually accessed were evaluated
    assert(counter == iota(-4, 5).length);
}

private struct LazyCache(R, bool bidir)
{
    import core.exception : RangeError;

    private
    {
        import std.algorithm.internal : algoFormat;
        import std.meta : AliasSeq;

        alias E  = ElementType!R;
        alias UE = Unqual!E;

        R source;

        static if (bidir) alias CacheTypes = AliasSeq!(UE, UE);
        else              alias CacheTypes = AliasSeq!UE;
        CacheTypes caches;
        // Flags to track if front/back have been cached
        bool frontCached = false;
        static if (bidir) bool backCached = false;

        static assert(isAssignable!(UE, E) && is(UE : E),
            algoFormat(
                "Cannot instantiate range with %s because %s elements are not assignable to %s.",
                R.stringof,
                E.stringof,
                UE.stringof
            )
        );
    }

    this(R range)
    {
        source = range;
        // Don't eagerly evaluate anything in the constructor
    }

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

    mixin ImplementLength!source;

    E front() @property
    {
        version (assert) if (empty) throw new RangeError();
        // Only evaluate front if it hasn't been cached yet
        if (!frontCached && !source.empty)
        {
            caches[0] = source.front;
            frontCached = true;
        }
        return caches[0];
    }
    static if (bidir) E back() @property
    {
        version (assert) if (empty) throw new RangeError();
        // Only evaluate back if it hasn't been cached yet
        if (!backCached && !source.empty)
        {
            caches[1] = source.back;
            backCached = true;
        }
        return caches[1];
    }

    void popFront()
    {
        version (assert) if (empty) throw new RangeError();
        source.popFront();
        // Reset the cache state for front
        frontCached = false;
    }
    static if (bidir) void popBack()
    {
        version (assert) if (empty) throw new RangeError();
        source.popBack();
        // Reset the cache state for back
        backCached = false;
    }

    static if (isForwardRange!R)
    {
        private this(R source, ref CacheTypes caches, bool frontCached, bool backCached = false)
        {
            this.source = source;
            this.caches = caches;
            this.frontCached = frontCached;
            static if (bidir) this.backCached = backCached;
        }
        typeof(this) save() @property
        {
            static if (bidir)
                return typeof(this)(source.save, caches, frontCached, backCached);
            else
                return typeof(this)(source.save, caches, frontCached);
        }
    }

    static if (hasSlicing!R)
    {
        enum hasEndSlicing = is(typeof(source[size_t.max .. $]));

        static if (hasEndSlicing)
        {
            private static struct DollarToken{}
            enum opDollar = DollarToken.init;

            auto opSlice(size_t low, DollarToken)
            {
                return typeof(this)(source[low .. $]);
            }
        }

        static if (!isInfinite!R)
        {
            typeof(this) opSlice(size_t low, size_t high)
            {
                return typeof(this)(source[low .. high]);
            }
        }
        else static if (hasEndSlicing)
        {
            auto opSlice(size_t low, size_t high)
            in
            {
                assert(low <= high, "Bounds error when slicing lazyCache.");
            }
            do
            {
                import std.range : takeExactly;
                return this[low .. $].takeExactly(high - low);
            }
        }
    }
}

/**
Implements the homonym function (also known as `transform`) present
in many languages of functional flavor. The call `map!(fun)(range)`
returns a range of which elements are obtained by applying `fun(a)`
left to right for all elements `a` in `range`. The original ranges are
not changed. Evaluation is done lazily.

Params:
    fun = one or more transformation functions

See_Also:
    $(HTTP en.wikipedia.org/wiki/Map_(higher-order_function), Map (higher-order function))
*/
template map(fun...)
if (fun.length >= 1)
{
    /**
    Params:
        r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    Returns:
        A range with each fun applied to all the elements. If there is more than one
        fun, the element type will be `Tuple` containing one element for each fun.
     */
    auto map(Range)(Range r)
    if (isInputRange!(Unqual!Range))
    {
        import std.meta : staticMap;
        import std.functional : adjoin;

        alias RE = ElementType!(Range);

        alias _funs = staticMap!(unaryFun, fun);
        alias _fun = adjoin!_funs;

        // Once https://issues.dlang.org/show_bug.cgi?id=5710 is fixed
        // accross all compilers (as of 2020-04, it wasn't fixed in LDC and GDC),
        // this validation loop can be moved into a template.
        foreach (f; _funs)
        {
            static assert(!is(typeof(f(RE.init)) == void),
                    "Mapping function(s) must not return void. " ~
                    " Consider using `each` instead of `map!(" ~ _funs.stringof ~ ")`");
        }

        return MapResult!(_fun, Range)(r);
    }
}

///
@safe @nogc unittest
{
    import std.algorithm.comparison : equal;
    import std.range : chain, only;
    auto squares =
        chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
    assert(equal(squares, only(1, 4, 9, 16, 25, 36)));
}

/**
Multiple functions can be passed to `map`. In that case, the
element type of `map` is a tuple containing one element for each
function.
*/
@safe unittest
{
    auto sums = [2, 4, 6, 8];
    auto products = [1, 4, 9, 16];

    size_t i = 0;
    foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
    {
        assert(result[0] == sums[i]);
        assert(result[1] == products[i]);
        ++i;
    }
}

/**
You may alias `map` with some function(s) to a symbol and use
it separately:
*/
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.conv : to;

    alias stringize = map!(to!string);
    assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
}

// Verify workaround for https://issues.dlang.org/show_bug.cgi?id=15777
@safe unittest
{
    import std.algorithm.mutation, std.string;
    auto foo(string[] args)
    {
        return args.map!strip;
    }
}

private struct MapResult(alias fun, Range)
{
    alias R = Unqual!Range;
    R _input;

    static if (isBidirectionalRange!R)
    {
        @property auto ref back()()
        {
            assert(!empty, "Attempting to fetch the back of an empty map.");
            return fun(_input.back);
        }

        void popBack()()
        {
            assert(!empty, "Attempting to popBack an empty map.");
            _input.popBack();
        }
    }

    this(R input)
    {
        _input = input;
    }

    static if (isInfinite!R)
    {
        // Propagate infinite-ness.
        enum bool empty = false;
    }
    else
    {
        @property bool empty()
        {
            return _input.empty;
        }
    }

    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty map.");
        _input.popFront();
    }

    @property auto ref front()
    {
        assert(!empty, "Attempting to fetch the front of an empty map.");
        return fun(_input.front);
    }

    static if (isRandomAccessRange!R)
    {
        static if (is(typeof(Range.init[ulong.max])))
            private alias opIndex_t = ulong;
        else
            private alias opIndex_t = uint;

        auto ref opIndex(opIndex_t index)
        {
            return fun(_input[index]);
        }
    }

    mixin ImplementLength!_input;

    static if (hasSlicing!R)
    {
        static if (is(typeof(_input[ulong.max .. ulong.max])))
            private alias opSlice_t = ulong;
        else
            private alias opSlice_t = uint;

        static if (hasLength!R)
        {
            auto opSlice(opSlice_t low, opSlice_t high)
            {
                return typeof(this)(_input[low .. high]);
            }
        }
        else static if (is(typeof(_input[opSlice_t.max .. $])))
        {
            struct DollarToken{}
            enum opDollar = DollarToken.init;
            auto opSlice(opSlice_t low, DollarToken)
            {
                return typeof(this)(_input[low .. $]);
            }

            auto opSlice(opSlice_t low, opSlice_t high)
            {
                import std.range : takeExactly;
                return this[low .. $].takeExactly(high - low);
            }
        }
    }

    static if (isForwardRange!R)
    {
        @property auto save()
        {
            return typeof(this)(_input.save);
        }
    }
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.conv : to;
    import std.functional : adjoin;

    alias stringize = map!(to!string);
    assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));

    uint counter;
    alias count = map!((a) { return counter++; });
    assert(equal(count([ 10, 2, 30, 4 ]), [ 0, 1, 2, 3 ]));

    counter = 0;
    adjoin!((a) { return counter++; }, (a) { return counter++; })(1);
    alias countAndSquare = map!((a) { return counter++; }, (a) { return counter++; });
    //assert(equal(countAndSquare([ 10, 2 ]), [ tuple(0u, 100), tuple(1u, 4) ]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.ascii : toUpper;
    import std.internal.test.dummyrange;
    import std.range;
    import std.typecons : tuple;
    import std.random : uniform, Random = Xorshift;

    int[] arr1 = [ 1, 2, 3, 4 ];
    const int[] arr1Const = arr1;
    int[] arr2 = [ 5, 6 ];
    auto squares = map!("a * a")(arr1Const);
    assert(squares[$ - 1] == 16);
    assert(equal(squares, [ 1, 4, 9, 16 ][]));
    assert(equal(map!("a * a")(chain(arr1, arr2)), [ 1, 4, 9, 16, 25, 36 ][]));

    // Test the caching stuff.
    assert(squares.back == 16);
    auto squares2 = squares.save;
    assert(squares2.back == 16);

    assert(squares2.front == 1);
    squares2.popFront();
    assert(squares2.front == 4);
    squares2.popBack();
    assert(squares2.front == 4);
    assert(squares2.back == 9);

    assert(equal(map!("a * a")(chain(arr1, arr2)), [ 1, 4, 9, 16, 25, 36 ][]));

    uint i;
    foreach (e; map!("a", "a * a")(arr1))
    {
        assert(e[0] == ++i);
        assert(e[1] == i * i);
    }

    // Test length.
    assert(squares.length == 4);
    assert(map!"a * a"(chain(arr1, arr2)).length == 6);

    // Test indexing.
    assert(squares[0] == 1);
    assert(squares[1] == 4);
    assert(squares[2] == 9);
    assert(squares[3] == 16);

    // Test slicing.
    auto squareSlice = squares[1 .. squares.length - 1];
    assert(equal(squareSlice, [4, 9][]));
    assert(squareSlice.back == 9);
    assert(squareSlice[1] == 9);

    // Test on a forward range to make sure it compiles when all the fancy
    // stuff is disabled.
    auto fibsSquares = map!"a * a"(recurrence!("a[n-1] + a[n-2]")(1, 1));
    assert(fibsSquares.front == 1);
    fibsSquares.popFront();
    fibsSquares.popFront();
    assert(fibsSquares.front == 4);
    fibsSquares.popFront();
    assert(fibsSquares.front == 9);

    auto repeatMap = map!"a"(repeat(1));
    auto gen = Random(123_456_789);
    auto index = uniform(0, 1024, gen);
    static assert(isInfinite!(typeof(repeatMap)));
    assert(repeatMap[index] == 1);

    auto intRange = map!"a"([1,2,3]);
    static assert(isRandomAccessRange!(typeof(intRange)));
    assert(equal(intRange, [1, 2, 3]));

    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        auto m = map!"a * a"(d);

        static assert(propagatesRangeType!(typeof(m), DummyType));
        assert(equal(m, [1,4,9,16,25,36,49,64,81,100]));
    }

    //Test string access
    string  s1 = "hello world!";
    dstring s2 = "日本語";
    dstring s3 = "hello world!"d;
    auto ms1 = map!(toUpper)(s1);
    auto ms2 = map!(toUpper)(s2);
    auto ms3 = map!(toUpper)(s3);
    static assert(!is(ms1[0])); //narrow strings can't be indexed
    assert(ms2[0] == '日');
    assert(ms3[0] == 'H');
    static assert(!is(ms1[0 .. 1])); //narrow strings can't be sliced
    assert(equal(ms2[0 .. 2], "日本"w));
    assert(equal(ms3[0 .. 2], "HE"));

    // https://issues.dlang.org/show_bug.cgi?id=5753
    static void voidFun(int) {}
    static int nonvoidFun(int) { return 0; }
    static assert(!__traits(compiles, map!voidFun([1])));
    static assert(!__traits(compiles, map!(voidFun, voidFun)([1])));
    static assert(!__traits(compiles, map!(nonvoidFun, voidFun)([1])));
    static assert(!__traits(compiles, map!(voidFun, nonvoidFun)([1])));
    static assert(!__traits(compiles, map!(a => voidFun(a))([1])));

    // https://issues.dlang.org/show_bug.cgi?id=15480
    auto dd = map!(z => z * z, c => c * c * c)([ 1, 2, 3, 4 ]);
    assert(dd[0] == tuple(1, 1));
    assert(dd[1] == tuple(4, 8));
    assert(dd[2] == tuple(9, 27));
    assert(dd[3] == tuple(16, 64));
    assert(dd.length == 4);
}

// Verify fix for: https://issues.dlang.org/show_bug.cgi?id=16034
@safe unittest
{
    struct One
    {
        int entry = 1;
        @disable this(this);
    }

    One[] ones = [One(), One()];

    import std.algorithm.comparison : equal;

    assert(ones.map!`a.entry + 1`.equal([2, 2]));
}


@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range;
    auto LL = iota(1L, 4L);
    auto m = map!"a*a"(LL);
    assert(equal(m, [1L, 4L, 9L]));
}

@safe unittest
{
    import std.range : iota;

    // https://issues.dlang.org/show_bug.cgi?id=10130 - map of iota with const step.
    const step = 2;
    assert(map!(i => i)(iota(0, 10, step)).walkLength == 5);

    // Need these to all by const to repro the float case, due to the
    // CommonType template used in the float specialization of iota.
    const floatBegin = 0.0;
    const floatEnd = 1.0;
    const floatStep = 0.02;
    assert(map!(i => i)(iota(floatBegin, floatEnd, floatStep)).walkLength == 50);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range;
    //slicing infinites
    auto rr = iota(0, 5).cycle().map!"a * a"();
    alias RR = typeof(rr);
    static assert(hasSlicing!RR);
    rr = rr[6 .. $]; //Advances 1 cycle and 1 unit
    assert(equal(rr[0 .. 5], [1, 4, 9, 16, 0]));
}

@safe unittest
{
    import std.range;
    struct S {int* p;}
    auto m = immutable(S).init.repeat().map!"a".save;
    assert(m.front == immutable(S)(null));
}

// Issue 20928
@safe unittest
{
    struct Always3
    {
        enum empty = false;
        auto save() { return this; }
        long front() { return 3; }
        void popFront() {}
        long opIndex(ulong i) { return 3; }
        long opIndex(ulong i) immutable { return 3; }
    }

    import std.algorithm.iteration : map;
    Always3.init.map!(e => e)[ulong.max];
}

// each
/**
Eagerly iterates over `r` and calls `fun` with _each element.

If no function to call is specified, `each` defaults to doing nothing but
consuming the entire range. `r.front` will be evaluated, but that can be avoided
by specifying a lambda with a `lazy` parameter.

`each` also supports `opApply`-based types, so it works with e.g. $(REF
parallel, std,parallelism).

Normally the entire range is iterated. If partial iteration (early stopping) is
desired, `fun` needs to return a value of type $(REF Flag,
std,typecons)`!"each"` (`Yes.each` to continue iteration, or `No.each` to stop
iteration).

Params:
    fun = function to apply to _each element of the range
    r = range or iterable over which `each` iterates

Returns: `Yes.each` if the entire range was iterated, `No.each` in case of early
stopping.

See_Also: $(REF tee, std,range)
 */
template each(alias fun = "a")
{
    import std.meta : AliasSeq;
    import std.traits : Parameters, isInstanceOf;
    import std.typecons : Flag, Yes, No, Tuple;

private:
    alias BinaryArgs = AliasSeq!(fun, "i", "a");

    enum isRangeUnaryIterable(R) =
        is(typeof(unaryFun!fun(R.init.front)));

    enum isRangeBinaryIterable(R) =
        is(typeof(binaryFun!BinaryArgs(0, R.init.front)));

    enum isRangeIterable(R) =
        isInputRange!R &&
        (isRangeUnaryIterable!R || isRangeBinaryIterable!R);

    enum isForeachUnaryIterable(R) =
        is(typeof((R r) {
            foreach (ref a; r)
                cast(void) unaryFun!fun(a);
        }));

    enum isForeachUnaryWithIndexIterable(R) =
        is(typeof((R r) {
            foreach (i, ref a; r)
                cast(void) binaryFun!BinaryArgs(i, a);
        }));

    enum isForeachBinaryIterable(R) =
        is(typeof((R r) {
            foreach (ref a, ref b; r)
                cast(void) binaryFun!fun(a, b);
        }));

    enum isForeachIterable(R) =
        (!isForwardRange!R || isDynamicArray!R) &&
        (isForeachUnaryIterable!R || isForeachBinaryIterable!R ||
         isForeachUnaryWithIndexIterable!R);

public:
    /**
    Params:
        r = range or iterable over which each iterates
     */
    Flag!"each" each(Range)(Range r)
    if (!isForeachIterable!Range && (
        isRangeIterable!Range ||
        // Tuples get automatically expanded if function takes right number of args
        (isInputRange!Range && isInstanceOf!(Tuple, typeof(r.front)))))
    {
        static if (isRangeIterable!Range)
        {
            debug(each) pragma(msg, "Using while for ", Range.stringof);
            static if (isRangeUnaryIterable!Range)
            {
                while (!r.empty)
                {
                    static if (!is(typeof(unaryFun!fun(r.front)) == Flag!"each"))
                    {
                        cast(void) unaryFun!fun(r.front);
                    }
                    else
                    {
                        if (unaryFun!fun(r.front) == No.each) return No.each;
                    }

                    r.popFront();
                }
            }
            else // if (isRangeBinaryIterable!Range)
            {
                size_t i = 0;
                while (!r.empty)
                {
                    static if (!is(typeof(binaryFun!BinaryArgs(i, r.front)) == Flag!"each"))
                    {
                        cast(void) binaryFun!BinaryArgs(i, r.front);
                    }
                    else
                    {
                        if (binaryFun!BinaryArgs(i, r.front) == No.each) return No.each;
                    }
                    r.popFront();
                    i++;
                }
            }
        }
        else
        {
            /* Range over Tuples, fun must have correct number of args
            * If number of args of fun is <= 2, calling fun(tuple) or fun(idx, tuple)
            * will have precendence over fun(tuple.expand).
            * Provide types to delegate params to control this.
            */
            for (auto range = r; !range.empty; range.popFront())
            {
                static if (!is(typeof(fun(r.front.expand)) == Flag!"each"))
                {
                    cast(void) fun(range.front.expand);
                }
                else
                {
                    if (fun(range.front.expand)) return No.each;
                }
            }
        }
        return Yes.each;
    }

    /// ditto
    Flag!"each" each(Iterable)(auto ref Iterable r)
    if (isForeachIterable!Iterable ||
        __traits(compiles, Parameters!(Parameters!(r.opApply))))
    {
        static if (isForeachIterable!Iterable)
        {
            static if (isForeachUnaryIterable!Iterable)
            {
                debug(each) pragma(msg, "Using foreach UNARY for ", Iterable.stringof);
                {
                    foreach (ref e; r)
                    {
                        static if (!is(typeof(unaryFun!fun(e)) == Flag!"each"))
                        {
                            cast(void) unaryFun!fun(e);
                        }
                        else
                        {
                            if (unaryFun!fun(e) == No.each) return No.each;
                        }
                    }
                }
            }
            else static if (isForeachBinaryIterable!Iterable)
            {
                debug(each) pragma(msg, "Using foreach BINARY for ", Iterable.stringof);
                foreach (ref a, ref b; r)
                {
                    static if (!is(typeof(binaryFun!fun(a, b)) == Flag!"each"))
                    {
                        cast(void) binaryFun!fun(a, b);
                    }
                    else
                    {
                        if (binaryFun!fun(a, b) == No.each) return No.each;
                    }
                }
            }
            else static if (isForeachUnaryWithIndexIterable!Iterable)
            {
                debug(each) pragma(msg, "Using foreach INDEX for ", Iterable.stringof);
                foreach (i, ref e; r)
                {
                    static if (!is(typeof(binaryFun!BinaryArgs(i, e)) == Flag!"each"))
                    {
                        cast(void) binaryFun!BinaryArgs(i, e);
                    }
                    else
                    {
                        if (binaryFun!BinaryArgs(i, e) == No.each) return No.each;
                    }
                }
            }
            else
            {
                static assert(0, "Invalid foreach iteratable type " ~ Iterable.stringof ~ " met.");
            }
            return Yes.each;
        }
        else
        {
            // opApply with >2 parameters. count the delegate args.
            // only works if it is not templated (otherwise we cannot count the args)
            auto result = Yes.each;
            auto dg(Parameters!(Parameters!(r.opApply)) params)
            {
                static if (!is(typeof(binaryFun!BinaryArgs(i, e)) == Flag!"each"))
                {
                    fun(params);
                    return 0; // tells opApply to continue iteration
                }
                else
                {
                    result = fun(params);
                    return result == Yes.each ? 0 : -1;
                }
            }
            r.opApply(&dg);
            return result;
        }
    }
}

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

    int[] arr;
    iota(5).each!(n => arr ~= n);
    assert(arr == [0, 1, 2, 3, 4]);

    // stop iterating early
    iota(5).each!((n) { arr ~= n; return No.each; });
    assert(arr == [0, 1, 2, 3, 4, 0]);

    // If the range supports it, the value can be mutated in place
    arr.each!((ref n) => n++);
    assert(arr == [1, 2, 3, 4, 5, 1]);

    arr.each!"a++";
    assert(arr == [2, 3, 4, 5, 6, 2]);

    auto m = arr.map!(n => n);
    // by-ref lambdas are not allowed for non-ref ranges
    static assert(!__traits(compiles, m.each!((ref n) => n++)));

    // The default predicate consumes the range
    (&m).each();
    assert(m.empty);
}

/// `each` can pass an index variable for iterable objects which support this
@safe unittest
{
    auto arr = new size_t[4];

    arr.each!"a=i"();
    assert(arr == [0, 1, 2, 3]);

    arr.each!((i, ref e) => e = i * 2);
    assert(arr == [0, 2, 4, 6]);
}

/// opApply iterators work as well
@system unittest
{
    static class S
    {
        int x;
        int opApply(scope int delegate(ref int _x) dg) { return dg(x); }
    }

    auto s = new S;
    s.each!"a++";
    assert(s.x == 1);
}

// binary foreach with two ref args
@system unittest
{
    import std.range : lockstep;

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

    a.lockstep(b).each!((ref x, ref y) { ++x; ++y; });

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

// https://issues.dlang.org/show_bug.cgi?id=15358
// application of `each` with >2 args (opApply)
@system unittest
{
    import std.range : lockstep;
    auto a = [0,1,2];
    auto b = [3,4,5];
    auto c = [6,7,8];

    lockstep(a, b, c).each!((ref x, ref y, ref z) { ++x; ++y; ++z; });

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

// https://issues.dlang.org/show_bug.cgi?id=15358
// application of `each` with >2 args (range interface)
@safe unittest
{
    import std.range : zip;
    auto a = [0,1,2];
    auto b = [3,4,5];
    auto c = [6,7,8];

    int[] res;

    zip(a, b, c).each!((x, y, z) { res ~= x + y + z; });

    assert(res == [9, 12, 15]);
}

// https://issues.dlang.org/show_bug.cgi?id=16255
// `each` on opApply doesn't support ref
@safe unittest
{
    int[] dynamicArray = [1, 2, 3, 4, 5];
    int[5] staticArray = [1, 2, 3, 4, 5];

    dynamicArray.each!((ref x) => x++);
    assert(dynamicArray == [2, 3, 4, 5, 6]);

    staticArray.each!((ref x) => x++);
    assert(staticArray == [2, 3, 4, 5, 6]);

    staticArray[].each!((ref x) => x++);
    assert(staticArray == [3, 4, 5, 6, 7]);
}

// https://issues.dlang.org/show_bug.cgi?id=16255
// `each` on opApply doesn't support ref
@system unittest
{
    struct S
    {
       int x;
       int opApply(int delegate(ref int _x) dg) { return dg(x); }
    }

    S s;
    foreach (ref a; s) ++a;
    assert(s.x == 1);
    s.each!"++a";
    assert(s.x == 2);
}

// https://issues.dlang.org/show_bug.cgi?id=15357
// `each` should behave similar to foreach
@safe unittest
{
    import std.range : iota;

    auto arr = [1, 2, 3, 4];

    // 1 ref parameter
    arr.each!((ref e) => e = 0);
    assert(arr.sum == 0);

    // 1 ref parameter and index
    arr.each!((i, ref e) => e = cast(int) i);
    assert(arr.sum == 4.iota.sum);
}

// https://issues.dlang.org/show_bug.cgi?id=15357
// `each` should behave similar to foreach
@system unittest
{
    import std.range : iota, lockstep;

    // 2 ref parameters and index
    auto arrA = [1, 2, 3, 4];
    auto arrB = [5, 6, 7, 8];
    lockstep(arrA, arrB).each!((ref a, ref b) {
        a = 0;
        b = 1;
    });
    assert(arrA.sum == 0);
    assert(arrB.sum == 4);

    // 3 ref parameters
    auto arrC = [3, 3, 3, 3];
    lockstep(arrA, arrB, arrC).each!((ref a, ref b, ref c) {
        a = 1;
        b = 2;
        c = 3;
    });
    assert(arrA.sum == 4);
    assert(arrB.sum == 8);
    assert(arrC.sum == 12);
}

// https://issues.dlang.org/show_bug.cgi?id=15357
// `each` should behave similar to foreach
@system unittest
{
    import std.range : lockstep;
    import std.typecons : Tuple;

    auto a = "abc";
    auto b = "def";

    // print each character with an index
    {
        alias Element = Tuple!(size_t, "index", dchar, "value");
        Element[] rForeach, rEach;
        foreach (i, c ; a) rForeach ~= Element(i, c);
        a.each!((i, c) => rEach ~= Element(i, c));
        assert(rForeach == rEach);
        assert(rForeach == [Element(0, 'a'), Element(1, 'b'), Element(2, 'c')]);
    }

    // print pairs of characters
    {
        alias Element = Tuple!(dchar, "a", dchar, "b");
        Element[] rForeach, rEach;
        foreach (c1, c2 ; a.lockstep(b)) rForeach ~= Element(c1, c2);
        a.lockstep(b).each!((c1, c2) => rEach ~= Element(c1, c2));
        assert(rForeach == rEach);
        assert(rForeach == [Element('a', 'd'), Element('b', 'e'), Element('c', 'f')]);
    }
}

// filter
/**
`filter!(predicate)(range)` returns a new range containing only elements `x` in `range` for
which `predicate(x)` returns `true`.

The predicate is passed to $(REF unaryFun, std,functional), and can be either a string, or
any callable that can be executed via `pred(element)`.

Params:
    predicate = Function to apply to each element of range

Returns:
    An input range that contains the filtered elements. If `range` is at least a forward range, the return value of `filter`
    will also be a forward range.

See_Also:
    $(HTTP en.wikipedia.org/wiki/Filter_(higher-order_function), Filter (higher-order function)),
    $(REF filterBidirectional, std,algorithm,iteration)
 */
template filter(alias predicate)
if (is(typeof(unaryFun!predicate)))
{
    /**
    Params:
        range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        of elements
    Returns:
        A range containing only elements `x` in `range` for
        which `predicate(x)` returns `true`.
     */
    auto filter(Range)(Range range)
    if (isInputRange!(Unqual!Range))
    {
        return FilterResult!(unaryFun!predicate, Range)(range);
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.math.operations : isClose;
    import std.range;

    int[] arr = [ 1, 2, 3, 4, 5 ];

    // Filter below 3
    auto small = filter!(a => a < 3)(arr);
    assert(equal(small, [ 1, 2 ]));

    // Filter again, but with Uniform Function Call Syntax (UFCS)
    auto sum = arr.filter!(a => a < 3);
    assert(equal(sum, [ 1, 2 ]));

    // In combination with chain() to span multiple ranges
    int[] a = [ 3, -2, 400 ];
    int[] b = [ 100, -101, 102 ];
    auto r = chain(a, b).filter!(a => a > 0);
    assert(equal(r, [ 3, 400, 100, 102 ]));

    // Mixing convertible types is fair game, too
    double[] c = [ 2.5, 3.0 ];
    auto r1 = chain(c, a, b).filter!(a => cast(int) a != a);
    assert(isClose(r1, [ 2.5 ]));
}

private struct FilterResult(alias pred, Range)
{
    alias R = Unqual!Range;
    R _input;
    private bool _primed;

    private void prime()
    {
        if (_primed) return;
        while (!_input.empty && !pred(_input.front))
        {
            _input.popFront();
        }
        _primed = true;
    }

    this(R r)
    {
        _input = r;
    }

    private this(R r, bool primed)
    {
        _input = r;
        _primed = primed;
    }

    auto opSlice() { return this; }

    static if (isInfinite!Range)
    {
        enum bool empty = false;
    }
    else
    {
        @property bool empty() { prime; return _input.empty; }
    }

    void popFront()
    {
        prime;
        do
        {
            _input.popFront();
        } while (!_input.empty && !pred(_input.front));
    }

    @property auto ref front()
    {
        prime;
        assert(!empty, "Attempting to fetch the front of an empty filter.");
        return _input.front;
    }

    static if (isForwardRange!R)
    {
        @property auto save()
        {
            return typeof(this)(_input.save, _primed);
        }
    }
}

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

    auto shouldNotLoop4ever = repeat(1).filter!(x => x % 2 == 0);
    static assert(isInfinite!(typeof(shouldNotLoop4ever)));
    assert(!shouldNotLoop4ever.empty);

    int[] a = [ 3, 4, 2 ];
    auto r = filter!("a > 3")(a);
    static assert(isForwardRange!(typeof(r)));
    assert(equal(r, [ 4 ][]));

    a = [ 1, 22, 3, 42, 5 ];
    auto under10 = filter!("a < 10")(a);
    assert(equal(under10, [1, 3, 5][]));
    static assert(isForwardRange!(typeof(under10)));
    under10.front = 4;
    assert(equal(under10, [4, 3, 5][]));
    under10.front = 40;
    assert(equal(under10, [40, 3, 5][]));
    under10.front = 1;

    auto infinite = filter!"a > 2"(repeat(3));
    static assert(isInfinite!(typeof(infinite)));
    static assert(isForwardRange!(typeof(infinite)));
    assert(infinite.front == 3);

    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        auto f = filter!"a & 1"(d);
        assert(equal(f, [1,3,5,7,9]));

        static if (isForwardRange!DummyType)
        {
            static assert(isForwardRange!(typeof(f)));
        }
    }

    // With delegates
    int x = 10;
    int overX(int a) { return a > x; }
    typeof(filter!overX(a)) getFilter()
    {
        return filter!overX(a);
    }
    auto r1 = getFilter();
    assert(equal(r1, [22, 42]));

    // With chain
    auto nums = [0,1,2,3,4];
    assert(equal(filter!overX(chain(a, nums)), [22, 42]));

    // With copying of inner struct Filter to Map
    auto arr = [1,2,3,4,5];
    auto m = map!"a + 1"(filter!"a < 4"(arr));
    assert(equal(m, [2, 3, 4]));
}

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

    int[] a = [ 3, 4 ];
    const aConst = a;
    auto r = filter!("a > 3")(aConst);
    assert(equal(r, [ 4 ][]));

    a = [ 1, 22, 3, 42, 5 ];
    auto under10 = filter!("a < 10")(a);
    assert(equal(under10, [1, 3, 5][]));
    assert(equal(under10.save, [1, 3, 5][]));
    assert(equal(under10.save, under10));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.functional : compose, pipe;

    assert(equal(compose!(map!"2 * a", filter!"a & 1")([1,2,3,4,5]),
                    [2,6,10]));
    assert(equal(pipe!(filter!"a & 1", map!"2 * a")([1,2,3,4,5]),
            [2,6,10]));
}

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

    int x = 10;
    int underX(int a) { return a < x; }
    const(int)[] list = [ 1, 2, 10, 11, 3, 4 ];
    assert(equal(filter!underX(list), [ 1, 2, 3, 4 ]));
}

// https://issues.dlang.org/show_bug.cgi?id=19823
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : dropOne;

    auto a = [1, 2, 3, 4];
    assert(a.filter!(a => a != 1).dropOne.equal([3, 4]));
    assert(a.filter!(a => a != 2).dropOne.equal([3, 4]));
    assert(a.filter!(a => a != 3).dropOne.equal([2, 4]));
    assert(a.filter!(a => a != 4).dropOne.equal([2, 3]));
    assert(a.filter!(a => a == 1).dropOne.empty);
    assert(a.filter!(a => a == 2).dropOne.empty);
    assert(a.filter!(a => a == 3).dropOne.empty);
    assert(a.filter!(a => a == 4).dropOne.empty);
}

/**
 * Similar to `filter`, except it defines a
 * $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives).
 * There is a speed disadvantage - the constructor spends time
 * finding the last element in the range that satisfies the filtering
 * condition (in addition to finding the first one). The advantage is
 * that the filtered range can be spanned from both directions. Also,
 * $(REF retro, std,range) can be applied against the filtered range.
 *
 * The predicate is passed to $(REF unaryFun, std,functional), and can either
 * accept a string, or any callable that can be executed via `pred(element)`.
 *
 * Params:
 *     pred = Function to apply to each element of range
 */
template filterBidirectional(alias pred)
{
    /**
    Params:
        r = Bidirectional range of elements
    Returns:
        A range containing only the elements in `r` for which `pred` returns `true`.
     */
    auto filterBidirectional(Range)(Range r)
    if (isBidirectionalRange!(Unqual!Range))
    {
        return FilterBidiResult!(unaryFun!pred, Range)(r);
    }
}

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

    int[] arr = [ 1, 2, 3, 4, 5 ];
    auto small = filterBidirectional!("a < 3")(arr);
    static assert(isBidirectionalRange!(typeof(small)));
    assert(small.back == 2);
    assert(equal(small, [ 1, 2 ]));
    assert(equal(retro(small), [ 2, 1 ]));
    // In combination with chain() to span multiple ranges
    int[] a = [ 3, -2, 400 ];
    int[] b = [ 100, -101, 102 ];
    auto r = filterBidirectional!("a > 0")(chain(a, b));
    assert(r.back == 102);
}

private struct FilterBidiResult(alias pred, Range)
{
    alias R = Unqual!Range;
    R _input;

    this(R r)
    {
        _input = r;
        while (!_input.empty && !pred(_input.front)) _input.popFront();
        while (!_input.empty && !pred(_input.back)) _input.popBack();
    }

    @property bool empty() { return _input.empty; }

    void popFront()
    {
        do
        {
            _input.popFront();
        } while (!_input.empty && !pred(_input.front));
    }

    @property auto ref front()
    {
        assert(!empty, "Attempting to fetch the front of an empty filterBidirectional.");
        return _input.front;
    }

    void popBack()
    {
        do
        {
            _input.popBack();
        } while (!_input.empty && !pred(_input.back));
    }

    @property auto ref back()
    {
        assert(!empty, "Attempting to fetch the back of an empty filterBidirectional.");
        return _input.back;
    }

    @property auto save()
    {
        return typeof(this)(_input.save);
    }
}

/**
Groups consecutively equivalent elements into a single tuple of the element and
the number of its repetitions.

Similarly to `uniq`, `group` produces a range that iterates over unique
consecutive elements of the given range. Each element of this range is a tuple
of the element and the number of times it is repeated in the original range.
Equivalence of elements is assessed by using the predicate `pred`, which
defaults to `"a == b"`.  The predicate is passed to $(REF binaryFun, std,functional),
and can either accept a string, or any callable that can be executed via
`pred(element, element)`.

Params:
    pred = Binary predicate for determining equivalence of two elements.
    R = The range type
    r = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to
        iterate over.

Returns: A range of elements of type `Tuple!(ElementType!R, uint)`,
representing each consecutively unique element and its respective number of
occurrences in that run.  This will be an input range if `R` is an input
range, and a forward range in all other cases.

See_Also: $(LREF chunkBy), which chunks an input range into subranges
    of equivalent adjacent elements.
*/
Group!(pred, Range) group(alias pred = "a == b", Range)(Range r)
{
    return typeof(return)(r);
}

/// ditto
struct Group(alias pred, R)
if (isInputRange!R)
{
    import std.typecons : Rebindable, tuple, Tuple;

    private alias comp = binaryFun!pred;

    private alias E = ElementType!R;
    static if ((is(E == class) || is(E == interface)) &&
               (is(E == const) || is(E == immutable)))
    {
        private alias MutableE = Rebindable!E;
    }
    else static if (is(E : Unqual!E))
    {
        private alias MutableE = Unqual!E;
    }
    else
    {
        private alias MutableE = E;
    }

    private R _input;
    private Tuple!(MutableE, uint) _current;

    ///
    this(R input)
    {
        _input = input;
        if (!_input.empty) popFront();
    }

    private this(R input, Tuple!(MutableE, uint) current)
    {
        _input = input;
        _current = current;
    }

    ///
    void popFront()
    {
        if (_input.empty)
        {
            _current[1] = 0;
        }
        else
        {
            _current = tuple(_input.front, 1u);
            _input.popFront();
            while (!_input.empty && comp(_current[0], _input.front))
            {
                ++_current[1];
                _input.popFront();
            }
        }
    }

    static if (isInfinite!R)
    {
        ///
        enum bool empty = false;  // Propagate infiniteness.
    }
    else
    {
        ///
        @property bool empty()
        {
            return _current[1] == 0;
        }
    }

    /// Returns: the front of the range
    @property auto ref front()
    {
        assert(!empty, "Attempting to fetch the front of an empty Group.");
        return _current;
    }

    static if (isForwardRange!R)
    {
        ///
        @property typeof(this) save()
        {
            return Group(_input.save, _current);
        }
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : tuple, Tuple;

    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
    assert(equal(group(arr), [ tuple(1, 1u), tuple(2, 4u), tuple(3, 1u),
        tuple(4, 3u), tuple(5, 1u) ][]));
}

/**
 * Using group, an associative array can be easily generated with the count of each
 * unique element in the range.
 */
@safe unittest
{
    import std.algorithm.sorting : sort;
    import std.array : assocArray;

    uint[string] result;
    auto range = ["a", "b", "a", "c", "b", "c", "c", "d", "e"];
    result = range.sort!((a, b) => a < b)
        .group
        .assocArray;

    assert(result == ["a": 2U, "b": 2U, "c": 3U, "d": 1U, "e": 1U]);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange;
    import std.typecons : tuple, Tuple;

    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
    assert(equal(group(arr), [ tuple(1, 1u), tuple(2, 4u), tuple(3, 1u),
                            tuple(4, 3u), tuple(5, 1u) ][]));
    static assert(isForwardRange!(typeof(group(arr))));

    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        auto g = group(d);

        static assert(d.rt == RangeType.Input || isForwardRange!(typeof(g)));

        assert(equal(g, [tuple(1, 1u), tuple(2, 1u), tuple(3, 1u), tuple(4, 1u),
            tuple(5, 1u), tuple(6, 1u), tuple(7, 1u), tuple(8, 1u),
            tuple(9, 1u), tuple(10, 1u)]));
    }
}

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

    // https://issues.dlang.org/show_bug.cgi?id=13857
    immutable(int)[] a1 = [1,1,2,2,2,3,4,4,5,6,6,7,8,9,9,9];
    auto g1 = group(a1);
    assert(equal(g1, [ tuple(1, 2u), tuple(2, 3u), tuple(3, 1u),
                       tuple(4, 2u), tuple(5, 1u), tuple(6, 2u),
                       tuple(7, 1u), tuple(8, 1u), tuple(9, 3u)
                     ]));

    // https://issues.dlang.org/show_bug.cgi?id=13162
    immutable(ubyte)[] a2 = [1, 1, 1, 0, 0, 0];
    auto g2 = a2.group;
    assert(equal(g2, [ tuple(1, 3u), tuple(0, 3u) ]));

    // https://issues.dlang.org/show_bug.cgi?id=10104
    const a3 = [1, 1, 2, 2];
    auto g3 = a3.group;
    assert(equal(g3, [ tuple(1, 2u), tuple(2, 2u) ]));

    interface I {}
    static class C : I { override size_t toHash() const nothrow @safe { return 0; } }
    const C[] a4 = [new const C()];
    auto g4 = a4.group!"a is b";
    assert(g4.front[1] == 1);

    immutable I[] a5 = [new immutable C()];
    auto g5 = a5.group!"a is b";
    assert(g5.front[1] == 1);

    const(int[][]) a6 = [[1], [1]];
    auto g6 = a6.group;
    assert(equal(g6.front[0], [1]));
}

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

    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
    auto r = arr.group;
    assert(r.equal([ tuple(1,1u), tuple(2, 4u), tuple(3, 1u), tuple(4, 3u), tuple(5, 1u) ]));
    r.popFront;
    assert(r.equal([ tuple(2, 4u), tuple(3, 1u), tuple(4, 3u), tuple(5, 1u) ]));
    auto s = r.save;
    r.popFrontN(2);
    assert(r.equal([ tuple(4, 3u), tuple(5, 1u) ]));
    assert(s.equal([ tuple(2, 4u), tuple(3, 1u), tuple(4, 3u), tuple(5, 1u) ]));
    s.popFront;
    auto t = s.save;
    r.popFront;
    s.popFront;
    assert(r.equal([ tuple(5, 1u) ]));
    assert(s.equal([ tuple(4, 3u), tuple(5, 1u) ]));
    assert(t.equal([ tuple(3, 1u), tuple(4, 3u), tuple(5, 1u) ]));
}

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

// Used by implementation of chunkBy for non-forward input ranges.
private struct ChunkByChunkImpl(alias pred, Range)
if (isInputRange!Range && !isForwardRange!Range)
{
    alias fun = binaryFun!pred;

    private Range *r;
    private ElementType!Range prev;

    this(ref Range range, ElementType!Range _prev)
    {
        r = &range;
        prev = _prev;
    }

    @property bool empty()
    {
        return r.empty || !fun(prev, r.front);
    }

    @property ElementType!Range front()
    {
        assert(!empty, "Attempting to fetch the front of an empty chunkBy chunk.");
        return r.front;
    }

    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty chunkBy chunk.");
        r.popFront();
    }
}

private template ChunkByImplIsUnary(alias pred, Range)
{
    alias e = lvalueOf!(ElementType!Range);

    static if (is(typeof(binaryFun!pred(e, e)) : bool))
        enum ChunkByImplIsUnary = false;
    else static if (is(typeof(unaryFun!pred(e) == unaryFun!pred(e)) : bool))
        enum ChunkByImplIsUnary = true;
    else
        static assert(0, "chunkBy expects either a binary predicate or "~
                         "a unary predicate on range elements of type: "~
                         ElementType!Range.stringof);
}

// Implementation of chunkBy for non-forward input ranges.
private struct ChunkByImpl(alias pred, Range)
if (isInputRange!Range && !isForwardRange!Range)
{
    enum bool isUnary = ChunkByImplIsUnary!(pred, Range);

    static if (isUnary)
        alias eq = binaryFun!((a, b) => unaryFun!pred(a) == unaryFun!pred(b));
    else
        alias eq = binaryFun!pred;

    private Range r;
    private ElementType!Range _prev;
    private bool openChunk = false;

    this(Range _r)
    {
        r = _r;
        if (!empty)
        {
            // Check reflexivity if predicate is claimed to be an equivalence
            // relation.
            assert(eq(r.front, r.front),
                   "predicate is not reflexive");

            // _prev's type may be a nested struct, so must be initialized
            // directly in the constructor (cannot call savePred()).
            _prev = r.front;
        }
        else
        {
            // We won't use _prev, but must be initialized.
            _prev = typeof(_prev).init;
        }
    }
    @property bool empty() { return r.empty && !openChunk; }

    @property auto front()
    {
        assert(!empty, "Attempting to fetch the front of an empty chunkBy.");
        openChunk = true;
        static if (isUnary)
        {
            import std.typecons : tuple;
            return tuple(unaryFun!pred(_prev),
                         ChunkByChunkImpl!(eq, Range)(r, _prev));
        }
        else
        {
            return ChunkByChunkImpl!(eq, Range)(r, _prev);
        }
    }

    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty chunkBy.");
        openChunk = false;
        while (!r.empty)
        {
            if (!eq(_prev, r.front))
            {
                _prev = r.front;
                break;
            }
            r.popFront();
        }
    }
}
// Outer range for forward range version of chunkBy
private struct ChunkByOuter(Range, bool eqEquivalenceAssured)
{
    size_t groupNum;
    Range  current;
    Range  next;
    static if (!eqEquivalenceAssured)
    {
        bool nextUpdated;
    }
}

// Inner range for forward range version of chunkBy
private struct ChunkByGroup(alias eq, Range, bool eqEquivalenceAssured)
{
    import std.typecons : RefCounted;

    alias OuterRange = ChunkByOuter!(Range, eqEquivalenceAssured);

    private size_t groupNum;
    static if (eqEquivalenceAssured)
    {
        private Range  start;
    }
    private Range  current;

    // using union prevents RefCounted destructor from propagating @system to
    // user code
    union { private RefCounted!(OuterRange) mothership; }
    private @trusted ref cargo() { return mothership.refCountedPayload; }

    private this(ref RefCounted!(OuterRange) origin)
    {
        () @trusted { mothership = origin; }();
        groupNum = cargo.groupNum;
        current = cargo.current.save;
        assert(!current.empty, "Passed range 'r' must not be empty");

        static if (eqEquivalenceAssured)
        {
            start = cargo.current.save;

            // Check for reflexivity.
            assert(eq(start.front, current.front),
                "predicate is not reflexive");
        }
    }

    // Cannot be a copy constructor due to https://issues.dlang.org/show_bug.cgi?id=22239
    this(this) scope @trusted
    {
        import core.lifetime : emplace;
        // since mothership has to be in a union, we have to manually trigger
        // an increment to the reference count.
        auto temp = mothership;
        mothership = temp;

        // prevents the reference count from falling back with brute force
        emplace(&temp);
    }

    @property bool empty() { return groupNum == size_t.max; }
    @property auto ref front() { return current.front; }

    void popFront()
    {
        static if (!eqEquivalenceAssured)
        {
            auto prevElement = current.front;
        }

        current.popFront();

        static if (eqEquivalenceAssured)
        {
            //this requires transitivity from the predicate.
            immutable nowEmpty = current.empty || !eq(start.front, current.front);
        }
        else
        {
            immutable nowEmpty = current.empty || !eq(prevElement, current.front);
        }


        if (nowEmpty)
        {
            if (groupNum == cargo.groupNum)
            {
                // If parent range hasn't moved on yet, help it along by
                // saving location of start of next Group.
                cargo.next = current.save;
                static if (!eqEquivalenceAssured)
                {
                    cargo.nextUpdated = true;
                }
            }

            groupNum = size_t.max;
        }
    }

    @property auto save()
    {
        auto copy = this;
        copy.current = current.save;
        return copy;
    }

    @trusted ~this()
    {
        mothership.destroy;
    }
}

private enum GroupingOpType{binaryEquivalent, binaryAny, unary}

// Single-pass implementation of chunkBy for forward ranges.
private struct ChunkByImpl(alias pred, alias eq, GroupingOpType opType, Range)
if (isForwardRange!Range)
{
    import std.typecons : RefCounted;

    enum bool eqEquivalenceAssured = opType != GroupingOpType.binaryAny;
    alias OuterRange = ChunkByOuter!(Range, eqEquivalenceAssured);
    alias InnerRange = ChunkByGroup!(eq, Range, eqEquivalenceAssured);

    static assert(isForwardRange!InnerRange);

    // using union prevents RefCounted destructor from propagating @system to
    // user code
    union { private RefCounted!OuterRange _impl; }
    private @trusted ref impl() { return _impl; }
    private @trusted ref implPL() { return _impl.refCountedPayload; }

    this(Range r)
    {
        import core.lifetime : move;

        auto savedR = r.save;

        static if (eqEquivalenceAssured) () @trusted
        {
            _impl = RefCounted!OuterRange(0, r, savedR.move);
        }();
        else () @trusted
        {
            _impl = RefCounted!OuterRange(0, r, savedR.move, false);
        }();
    }

    // Cannot be a copy constructor due to https://issues.dlang.org/show_bug.cgi?id=22239
    this(this) scope @trusted
    {
        import core.lifetime : emplace;
        // since _impl has to be in a union, we have to manually trigger
        // an increment to the reference count.
        auto temp = _impl;
        _impl = temp;

        // prevents the reference count from falling back with brute force
        emplace(&temp);
    }

    @property bool empty() { return implPL.current.empty; }

    static if (opType == GroupingOpType.unary) @property auto front()
    {
        import std.typecons : tuple;

        return tuple(unaryFun!pred(implPL.current.front), InnerRange(impl));
    }
    else @property auto front()
    {
        return InnerRange(impl);
    }

    static if (eqEquivalenceAssured) void popFront()
    {
        // Scan for next group. If we're lucky, one of our Groups would have
        // already set .next to the start of the next group, in which case the
        // loop is skipped.
        while (!implPL.next.empty && eq(implPL.current.front, implPL.next.front))
        {
            implPL.next.popFront();
        }

        implPL.current = implPL.next.save;

        // Indicate to any remaining Groups that we have moved on.
        implPL.groupNum++;
    }
    else void popFront()
    {
        if (implPL.nextUpdated)
        {
            implPL.current = implPL.next.save;
        }
        else while (true)
        {
            auto prevElement = implPL.current.front;
            implPL.current.popFront();
            if (implPL.current.empty) break;
            if (!eq(prevElement, implPL.current.front)) break;
        }

        implPL.nextUpdated = false;
        // Indicate to any remaining Groups that we have moved on.
        implPL.groupNum++;
    }

    @property auto save()
    {
        // Note: the new copy of the range will be detached from any existing
        // satellite Groups, and will not benefit from the .next acceleration.
        return typeof(this)(implPL.current.save);
    }

    static assert(isForwardRange!(typeof(this)), typeof(this).stringof
            ~ " must be a forward range");

    @trusted ~this()
    {
        _impl.destroy;
    }
}

//Test for https://issues.dlang.org/show_bug.cgi?id=14909
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : tuple;
    import std.stdio;
    auto n = 3;
    auto s = [1,2,3].chunkBy!(a => a+n);
    auto t = s.save.map!(x=>x[0]);
    auto u = s.map!(x=>x[1]);
    assert(t.equal([4,5,6]));
    assert(u.equal!equal([[1],[2],[3]]));
}

//Testing inferring @system correctly
@safe unittest
{
    struct DeadlySave
    {
        int front;
        @safe void popFront(){front++;}
        @safe bool empty(){return front >= 5;}
        @system auto save(){return this;}
    }

    auto test1()
    {
        DeadlySave src;
        return src.walkLength;

    }

    auto test2()
    {
        DeadlySave src;
        return src.chunkBy!((a,b) => a % 2 == b % 2).walkLength;
    }

    static assert(isSafe!test1);
    static assert(!isSafe!test2);
}

//Test for https://issues.dlang.org/show_bug.cgi?id=18751
@safe unittest
{
    import std.algorithm.comparison : equal;

    string[] data = [ "abc", "abc", "def" ];
    int[] indices = [ 0, 1, 2 ];

    auto chunks = indices.chunkBy!((i, j) => data[i] == data[j]);
    assert(chunks.equal!equal([ [ 0, 1 ], [ 2 ] ]));
}

//Additional test for fix for issues 14909 and 18751
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto v = [2,4,8,3,6,9,1,5,7];
    auto i = 2;
    assert(v.chunkBy!((a,b) => a % i == b % i).equal!equal([[2,4,8],[3],[6],[9,1,5,7]]));
}

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

    size_t popCount = 0;
    static class RefFwdRange
    {
        int[]  impl;
        size_t* pcount;

        @safe nothrow:

        this(int[] data, size_t* pcount) { impl = data; this.pcount = pcount; }
        @property bool empty() { return impl.empty; }
        @property auto ref front() { return impl.front; }
        void popFront()
        {
            impl.popFront();
            (*pcount)++;
        }
        @property auto save() { return new RefFwdRange(impl, pcount); }
    }
    static assert(isForwardRange!RefFwdRange);

    auto testdata = new RefFwdRange([1, 3, 5, 2, 4, 7, 6, 8, 9], &popCount);
    auto groups = testdata.chunkBy!((a,b) => (a % 2) == (b % 2));
    auto outerSave1 = groups.save;

    // Sanity test
    assert(groups.equal!equal([[1, 3, 5], [2, 4], [7], [6, 8], [9]]));
    assert(groups.empty);

    // Performance test for single-traversal use case: popFront should not have
    // been called more times than there are elements if we traversed the
    // segmented range exactly once.
    assert(popCount == 9);

    // Outer range .save test
    groups = outerSave1.save;
    assert(!groups.empty);

    // Inner range .save test
    auto grp1 = groups.front.save;
    auto grp1b = grp1.save;
    assert(grp1b.equal([1, 3, 5]));
    assert(grp1.save.equal([1, 3, 5]));

    // Inner range should remain consistent after outer range has moved on.
    groups.popFront();
    assert(grp1.save.equal([1, 3, 5]));

    // Inner range should not be affected by subsequent inner ranges.
    assert(groups.front.equal([2, 4]));
    assert(grp1.save.equal([1, 3, 5]));
}

/**
 * Chunks an input range into subranges of equivalent adjacent elements.
 * In other languages this is often called `partitionBy`, `groupBy`
 * or `sliceWhen`.
 *
 * Equivalence is defined by the predicate `pred`, which can be either
 * binary, which is passed to $(REF binaryFun, std,functional), or unary, which is
 * passed to $(REF unaryFun, std,functional). In the binary form, two range elements
 * `a` and `b` are considered equivalent if `pred(a,b)` is true. In
 * unary form, two elements are considered equivalent if `pred(a) == pred(b)`
 * is true.
 *
 * This predicate must be an equivalence relation, that is, it must be
 * reflexive (`pred(x,x)` is always true), symmetric
 * (`pred(x,y) == pred(y,x)`), and transitive (`pred(x,y) && pred(y,z)`
 * implies `pred(x,z)`). If this is not the case, the range returned by
 * chunkBy may assert at runtime or behave erratically. Use $(LREF splitWhen)
 * if you want to chunk by a predicate that is not an equivalence relation.
 *
 * Params:
 *  pred = Predicate for determining equivalence.
 *  r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to be chunked.
 *
 * Returns: With a binary predicate, a range of ranges is returned in which
 * all elements in a given subrange are equivalent under the given predicate.
 * With a unary predicate, a range of tuples is returned, with the tuple
 * consisting of the result of the unary predicate for each subrange, and the
 * subrange itself. Copying the range currently has reference semantics, but this may
 * change in the future.
 *
 * Notes:
 *
 * Equivalent elements separated by an intervening non-equivalent element will
 * appear in separate subranges; this function only considers adjacent
 * equivalence. Elements in the subranges will always appear in the same order
 * they appear in the original range.
 *
 * See_also:
 * $(LREF group), which collapses adjacent equivalent elements into a single
 * element.
 */
auto chunkBy(alias pred, Range)(Range r)
if (isInputRange!Range)
{
    static if (ChunkByImplIsUnary!(pred, Range))
    {
        enum opType = GroupingOpType.unary;
        alias eq = binaryFun!((a, b) => unaryFun!pred(a) == unaryFun!pred(b));
    }
    else
    {
        enum opType = GroupingOpType.binaryEquivalent;
        alias eq = binaryFun!pred;
    }
    static if (isForwardRange!Range)
        return ChunkByImpl!(pred, eq, opType, Range)(r);
    else
        return ChunkByImpl!(pred, Range)(r);
}

/// Showing usage with binary predicate:
@safe unittest
{
    import std.algorithm.comparison : equal;

    // Grouping by particular attribute of each element:
    auto data = [
        [1, 1],
        [1, 2],
        [2, 2],
        [2, 3]
    ];

    auto r1 = data.chunkBy!((a,b) => a[0] == b[0]);
    assert(r1.equal!equal([
        [[1, 1], [1, 2]],
        [[2, 2], [2, 3]]
    ]));

    auto r2 = data.chunkBy!((a,b) => a[1] == b[1]);
    assert(r2.equal!equal([
        [[1, 1]],
        [[1, 2], [2, 2]],
        [[2, 3]]
    ]));
}

/// Showing usage with unary predicate:
/* FIXME: pure nothrow*/ @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range.primitives;
    import std.typecons : tuple;

    // Grouping by particular attribute of each element:
    auto range =
    [
        [1, 1],
        [1, 1],
        [1, 2],
        [2, 2],
        [2, 3],
        [2, 3],
        [3, 3]
    ];

    auto byX = chunkBy!(a => a[0])(range);
    auto expected1 =
    [
        tuple(1, [[1, 1], [1, 1], [1, 2]]),
        tuple(2, [[2, 2], [2, 3], [2, 3]]),
        tuple(3, [[3, 3]])
    ];
    foreach (e; byX)
    {
        assert(!expected1.empty);
        assert(e[0] == expected1.front[0]);
        assert(e[1].equal(expected1.front[1]));
        expected1.popFront();
    }

    auto byY = chunkBy!(a => a[1])(range);
    auto expected2 =
    [
        tuple(1, [[1, 1], [1, 1]]),
        tuple(2, [[1, 2], [2, 2]]),
        tuple(3, [[2, 3], [2, 3], [3, 3]])
    ];
    foreach (e; byY)
    {
        assert(!expected2.empty);
        assert(e[0] == expected2.front[0]);
        assert(e[1].equal(expected2.front[1]));
        expected2.popFront();
    }
}

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

    struct Item { int x, y; }

    // Force R to have only an input range API with reference semantics, so
    // that we're not unknowingly making use of array semantics outside of the
    // range API.
    class RefInputRange(R)
    {
        R data;
        this(R _data) pure @safe nothrow { data = _data; }
        @property bool empty() pure @safe nothrow { return data.empty; }
        @property auto front() pure @safe nothrow { assert(!empty); return data.front; }
        void popFront() pure @safe nothrow { assert(!empty); data.popFront(); }
    }
    auto refInputRange(R)(R range) { return new RefInputRange!R(range); }

    // An input range API with value semantics.
    struct ValInputRange(R)
    {
        R data;
        this(R _data) pure @safe nothrow { data = _data; }
        @property bool empty() pure @safe nothrow { return data.empty; }
        @property auto front() pure @safe nothrow { assert(!empty); return data.front; }
        void popFront() pure @safe nothrow { assert(!empty); data.popFront(); }
    }
    auto valInputRange(R)(R range) { return ValInputRange!R(range); }

    {
        auto arr = [ Item(1,2), Item(1,3), Item(2,3) ];
        static assert(isForwardRange!(typeof(arr)));

        auto byX = chunkBy!(a => a.x)(arr);
        static assert(isForwardRange!(typeof(byX)));

        auto byX_subrange1 = byX.front[1].save;
        auto byX_subrange2 = byX.front[1].save;
        static assert(isForwardRange!(typeof(byX_subrange1)));
        static assert(isForwardRange!(typeof(byX_subrange2)));

        byX.popFront();
        assert(byX_subrange1.equal([ Item(1,2), Item(1,3) ]));
        byX_subrange1.popFront();
        assert(byX_subrange1.equal([ Item(1,3) ]));
        assert(byX_subrange2.equal([ Item(1,2), Item(1,3) ]));

        auto byY = chunkBy!(a => a.y)(arr);
        static assert(isForwardRange!(typeof(byY)));

        auto byY2 = byY.save;
        static assert(is(typeof(byY) == typeof(byY2)));
        byY.popFront();
        assert(byY.front[0] == 3);
        assert(byY.front[1].equal([ Item(1,3), Item(2,3) ]));
        assert(byY2.front[0] == 2);
        assert(byY2.front[1].equal([ Item(1,2) ]));
    }

    // Test non-forward input ranges with reference semantics.
    {
        auto range = refInputRange([ Item(1,1), Item(1,2), Item(2,2) ]);
        auto byX = chunkBy!(a => a.x)(range);
        assert(byX.front[0] == 1);
        assert(byX.front[1].equal([ Item(1,1), Item(1,2) ]));
        byX.popFront();
        assert(byX.front[0] == 2);
        assert(byX.front[1].equal([ Item(2,2) ]));
        byX.popFront();
        assert(byX.empty);
        assert(range.empty);

        range = refInputRange([ Item(1,1), Item(1,2), Item(2,2) ]);
        auto byY = chunkBy!(a => a.y)(range);
        assert(byY.front[0] == 1);
        assert(byY.front[1].equal([ Item(1,1) ]));
        byY.popFront();
        assert(byY.front[0] == 2);
        assert(byY.front[1].equal([ Item(1,2), Item(2,2) ]));
        byY.popFront();
        assert(byY.empty);
        assert(range.empty);
    }

    // Test non-forward input ranges with value semantics.
    {
        auto range = valInputRange([ Item(1,1), Item(1,2), Item(2,2) ]);
        auto byX = chunkBy!(a => a.x)(range);
        assert(byX.front[0] == 1);
        assert(byX.front[1].equal([ Item(1,1), Item(1,2) ]));
        byX.popFront();
        assert(byX.front[0] == 2);
        assert(byX.front[1].equal([ Item(2,2) ]));
        byX.popFront();
        assert(byX.empty);
        assert(!range.empty);    // Opposite of refInputRange test

        range = valInputRange([ Item(1,1), Item(1,2), Item(2,2) ]);
        auto byY = chunkBy!(a => a.y)(range);
        assert(byY.front[0] == 1);
        assert(byY.front[1].equal([ Item(1,1) ]));
        byY.popFront();
        assert(byY.front[0] == 2);
        assert(byY.front[1].equal([ Item(1,2), Item(2,2) ]));
        byY.popFront();
        assert(byY.empty);
        assert(!range.empty);    // Opposite of refInputRange test
    }

    /* https://issues.dlang.org/show_bug.cgi?id=19532
     * General behavior of non-forward input ranges.
     *
     * - If the same chunk is retrieved multiple times via front, the separate chunk
     *   instances refer to a shared range segment that advances as a single range.
     * - Emptying a chunk via popFront does not implicitly popFront the chunk off
     *   main range. The chunk is still available via front, it is just empty.
     */
    {
        import std.algorithm.comparison : equal;
        import core.exception : AssertError;
        import std.exception : assertThrown;

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

        // Value input range
        {
            auto r = valInputRange(a).chunkBy!((a, b) => a[0] == b[0]);

            size_t numChunks = 0;
            while (!r.empty)
            {
                ++numChunks;
                auto chunk = r.front;
                while (!chunk.empty)
                {
                    assert(r.front.front[1] == chunk.front[1]);
                    chunk.popFront;
                }
                assert(!r.empty);
                assert(r.front.empty);
                r.popFront;
            }

            assert(numChunks == 5);

            // Now front and popFront should assert.
            bool thrown = false;
            try r.front;
            catch (AssertError) thrown = true;
            assert(thrown);

            thrown = false;
            try r.popFront;
            catch (AssertError) thrown = true;
            assert(thrown);
        }

        // Reference input range
        {
            auto r = refInputRange(a).chunkBy!((a, b) => a[0] == b[0]);

            size_t numChunks = 0;
            while (!r.empty)
            {
                ++numChunks;
                auto chunk = r.front;
                while (!chunk.empty)
                {
                    assert(r.front.front[1] == chunk.front[1]);
                    chunk.popFront;
                }
                assert(!r.empty);
                assert(r.front.empty);
                r.popFront;
            }

            assert(numChunks == 5);

            // Now front and popFront should assert.
            bool thrown = false;
            try r.front;
            catch (AssertError) thrown = true;
            assert(thrown);

            thrown = false;
            try r.popFront;
            catch (AssertError) thrown = true;
            assert(thrown);
        }

        // Ensure that starting with an empty range doesn't create an empty chunk.
        {
            int[] emptyRange = [];

            auto r1 = valInputRange(emptyRange).chunkBy!((a, b) => a == b);
            auto r2 = refInputRange(emptyRange).chunkBy!((a, b) => a == b);

            assert(r1.empty);
            assert(r2.empty);

            bool thrown = false;
            try r1.front;
            catch (AssertError) thrown = true;
            assert(thrown);

            thrown = false;
            try r1.popFront;
            catch (AssertError) thrown = true;
            assert(thrown);

            thrown = false;
            try r2.front;
            catch (AssertError) thrown = true;
            assert(thrown);

            thrown = false;
            try r2.popFront;
            catch (AssertError) thrown = true;
            assert(thrown);
        }
    }

    // https://issues.dlang.org/show_bug.cgi?id=19532 - Using roundRobin/chunkBy
    {
        import std.algorithm.comparison : equal;
        import std.range : roundRobin;

        auto a0 = [0, 1, 3, 6];
        auto a1 = [0, 2, 4, 6, 7];
        auto a2 = [1, 2, 4, 6, 8, 8, 9];

        auto expected =
            [[0, 0], [1, 1], [2, 2], [3], [4, 4], [6, 6, 6], [7], [8, 8], [9]];

        auto r1 = roundRobin(valInputRange(a0), valInputRange(a1), valInputRange(a2))
            .chunkBy!((a, b) => a == b);
        assert(r1.equal!equal(expected));

        auto r2 = roundRobin(refInputRange(a0), refInputRange(a1), refInputRange(a2))
            .chunkBy!((a, b) => a == b);
        assert(r2.equal!equal(expected));

        auto r3 = roundRobin(a0, a1, a2).chunkBy!((a, b) => a == b);
        assert(r3.equal!equal(expected));
    }

    // https://issues.dlang.org/show_bug.cgi?id=19532 - Using merge/chunkBy
    {
        import std.algorithm.comparison : equal;
        import std.algorithm.sorting : merge;

        auto a0 = [2, 3, 5];
        auto a1 = [2, 4, 5];
        auto a2 = [1, 2, 4, 5];

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

        auto r1 = merge(valInputRange(a0), valInputRange(a1), valInputRange(a2))
            .chunkBy!((a, b) => a == b);
        assert(r1.equal!equal(expected));

        auto r2 = merge(refInputRange(a0), refInputRange(a1), refInputRange(a2))
            .chunkBy!((a, b) => a == b);
        assert(r2.equal!equal(expected));

        auto r3 = merge(a0, a1, a2).chunkBy!((a, b) => a == b);
        assert(r3.equal!equal(expected));
    }

    // https://issues.dlang.org/show_bug.cgi?id=19532 - Using chunkBy/map-fold
    {
        import std.algorithm.comparison : equal;
        import std.algorithm.iteration : fold, map;

        auto a = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8, 9];
        auto expected = [0, 3, 4, 6, 8, 5, 18, 7, 16, 9];

        auto r1 = a
            .chunkBy!((a, b) => a == b)
            .map!(c => c.fold!((a, b) => a + b));
        assert(r1.equal(expected));

        auto r2 = valInputRange(a)
            .chunkBy!((a, b) => a == b)
            .map!(c => c.fold!((a, b) => a + b));
        assert(r2.equal(expected));

        auto r3 = refInputRange(a)
            .chunkBy!((a, b) => a == b)
            .map!(c => c.fold!((a, b) => a + b));
        assert(r3.equal(expected));
    }

    // https://issues.dlang.org/show_bug.cgi?id=16169
    // https://issues.dlang.org/show_bug.cgi?id=17966
    // https://issues.dlang.org/show_bug.cgi?id=19532
    // Using multiwayMerge/chunkBy
    {
        import std.algorithm.comparison : equal;
        import std.algorithm.setops : multiwayMerge;

        {
            auto a0 = [2, 3, 5];
            auto a1 = [2, 4, 5];
            auto a2 = [1, 2, 4, 5];

            auto expected = [[1], [2, 2, 2], [3], [4, 4], [5, 5, 5]];
            auto r = multiwayMerge([a0, a1, a2]).chunkBy!((a, b) => a == b);
            assert(r.equal!equal(expected));
        }
        {
            auto a0 = [2, 3, 5];
            auto a1 = [2, 4, 5];
            auto a2 = [1, 2, 4, 5];

            auto expected = [[1], [2, 2, 2], [3], [4, 4], [5, 5, 5]];
            auto r =
                multiwayMerge([valInputRange(a0), valInputRange(a1), valInputRange(a2)])
                .chunkBy!((a, b) => a == b);
            assert(r.equal!equal(expected));
        }
        {
            auto a0 = [2, 3, 5];
            auto a1 = [2, 4, 5];
            auto a2 = [1, 2, 4, 5];

            auto expected = [[1], [2, 2, 2], [3], [4, 4], [5, 5, 5]];
            auto r =
                multiwayMerge([refInputRange(a0), refInputRange(a1), refInputRange(a2)])
                .chunkBy!((a, b) => a == b);
            assert(r.equal!equal(expected));
        }
    }

    // https://issues.dlang.org/show_bug.cgi?id=20496
    {
        auto r = [1,1,1,2,2,2,3,3,3];
        r.chunkBy!((ref e1, ref e2) => e1 == e2);
    }
}



// https://issues.dlang.org/show_bug.cgi?id=13805
@safe unittest
{
    [""].map!((s) => s).chunkBy!((x, y) => true);
}

/**
Splits a forward range into subranges in places determined by a binary
predicate called with adjacent elements.

When iterating, one element of `r` is compared with `pred` to the next
element. If `pred` returns true, a new subrange is started for the next element.
Otherwise, they are part of the same subrange.

If the elements are compared with an inequality (!=) operator, consider
$(LREF chunkBy) instead, as it's likely faster to execute.

Params:
pred = Predicate for determining where to split. The earlier element in the
source range is always given as the first argument.
r = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to be split.

Returns: A range of subranges of `r`, split such that within a given subrange,
calling `pred` with any pair of adjacent elements as arguments returns `false`.
Copying the range currently has reference semantics, but this may change in the future.

See_also:
$(LREF splitter), which uses elements as splitters instead of element-to-element
relations.
*/

auto splitWhen(alias pred, Range)(Range r)
if (is(typeof(binaryFun!pred(r.front, r.front)) : bool) && isForwardRange!Range)
{   import std.functional : not;
    return ChunkByImpl!(not!pred, not!pred, GroupingOpType.binaryAny, Range)(r);
}

///
nothrow pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : dropExactly;
    auto source = [4, 3, 2, 11, 0, -3, -3, 5, 3, 0];

    auto result1 = source.splitWhen!((a,b) => a <= b);
    assert(result1.save.equal!equal([
        [4, 3, 2],
        [11, 0, -3],
        [-3],
        [5, 3, 0]
    ]));

    //splitWhen, like chunkBy, is currently a reference range (this may change
    //in future). Remember to call `save` when appropriate.
    auto result2 = result1.dropExactly(2);
    assert(result1.save.equal!equal([
        [-3],
        [5, 3, 0]
    ]));
}

//ensure we don't iterate the underlying range twice
nothrow @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.math.algebraic : abs;

    struct SomeRange
    {
        int[] elements;
        static int popfrontsSoFar;

        auto front(){return elements[0];}
        nothrow @safe void popFront()
        {   popfrontsSoFar++;
            elements = elements[1 .. $];
        }
        auto empty(){return elements.length == 0;}
        auto save(){return this;}
    }

    auto result = SomeRange([10, 9, 8, 5, 0, 1, 0, 8, 11, 10, 8, 12])
        .splitWhen!((a, b) => abs(a - b) >= 3);

    assert(result.equal!equal([
        [10, 9, 8],
        [5],
        [0, 1, 0],
        [8],
        [11, 10, 8],
        [12]
    ]));

    assert(SomeRange.popfrontsSoFar == 12);
}

// Issue 13595
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto r = [1, 2, 3, 4, 5, 6, 7, 8, 9].splitWhen!((x, y) => ((x*y) % 3) > 0);
    assert(r.equal!equal([
        [1],
        [2, 3, 4],
        [5, 6, 7],
        [8, 9]
    ]));
}

nothrow pure @safe unittest
{
    // Grouping by maximum adjacent difference:
    import std.math.algebraic : abs;
    import std.algorithm.comparison : equal;
    auto r3 = [1, 3, 2, 5, 4, 9, 10].splitWhen!((a, b) => abs(a-b) >= 3);
    assert(r3.equal!equal([
        [1, 3, 2],
        [5, 4],
        [9, 10]
    ]));
}

// empty range splitWhen
@nogc nothrow pure @system unittest
{
    int[1] sliceable;
    auto result = sliceable[0 .. 0].splitWhen!((a,b) => a+b > 10);
    assert(result.empty);
}

// joiner
/**
Lazily joins a range of ranges with a separator. The separator itself
is a range. If a separator is not provided, then the ranges are
joined directly without anything in between them (often called `flatten`
in other languages).

Params:
    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of input
        ranges to be joined.
    sep = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) of
        element(s) to serve as separators in the joined range.

Returns:
A range of elements in the joined range. This will be a bidirectional range if
both outer and inner ranges of `RoR` are at least bidirectional ranges. Else if
both outer and inner ranges of `RoR` are forward ranges, the returned range will
be likewise. Otherwise it will be only an input range. The
$(REF_ALTTEXT range bidirectionality, isBidirectionalRange, std,range,primitives)
is propagated if no separator is specified.

See_also:
$(REF chain, std,range), which chains a sequence of ranges with compatible elements
into a single range.

Note:
When both outer and inner ranges of `RoR` are bidirectional and the joiner is
iterated from the back to the front, the separator will still be consumed from
front to back, even if it is a bidirectional range too.
 */
auto joiner(RoR, Separator)(RoR r, Separator sep)
{
    static assert(isInputRange!RoR, "The type of RoR '", RoR.stringof
            , " must be an InputRange (isInputRange!", RoR.stringof, ").");
    static assert(isInputRange!(ElementType!RoR), "The ElementyType of RoR '"
            , ElementType!(RoR).stringof, "' must be an InputRange "
            , "(isInputRange!(ElementType!(", RoR.stringof , "))).");
    static assert(isForwardRange!Separator, "The type of the Separator '"
            , Separator.stringof, "' must be a ForwardRange (isForwardRange!("
            , Separator.stringof, ")).");
    static assert(is(ElementType!Separator : ElementType!(ElementType!RoR))
            , "The type of the elements of the separator range does not match "
            , "the type of the elements that are joined. Separator type '"
            , ElementType!(Separator).stringof, "' is not implicitly"
            , "convertible to range element type '"
            , ElementType!(ElementType!RoR).stringof, "' (is(ElementType!"
            , Separator.stringof, " : ElementType!(ElementType!", RoR.stringof
            , "))).");

    static struct Result
    {
        private RoR _items;
        private ElementType!RoR _current;
        bool inputStartsWithEmpty = false;
        static if (isBidirectional)
        {
            private ElementType!RoR _currentBack;
            bool inputEndsWithEmpty = false;
        }
        enum isBidirectional = isBidirectionalRange!RoR &&
                               isBidirectionalRange!(ElementType!RoR);
        static if (isRandomAccessRange!Separator)
        {
            static struct CurrentSep
            {
                private Separator _sep;
                private size_t sepIndex;
                private size_t sepLength; // cache the length for performance
                auto front() { return _sep[sepIndex]; }
                void popFront() { sepIndex++; }
                auto empty() { return sepIndex >= sepLength; }
                auto save()
                {
                    auto copy = this;
                    copy._sep = _sep;
                    return copy;
                }
                void reset()
                {
                    sepIndex = 0;
                }

                void initialize(Separator sep)
                {
                    _sep = sep;
                    sepIndex = sepLength = _sep.length;
                }
            }
        }
        else
        {
            static struct CurrentSep
            {
                private Separator _sep;
                Separator payload;

                alias payload this;

                auto save()
                {
                    auto copy = this;
                    copy._sep = _sep;
                    return copy;
                }

                void reset()
                {
                    payload = _sep.save;
                }

                void initialize(Separator sep)
                {
                    _sep = sep;
                }
            }
        }

        private CurrentSep _currentSep;
        static if (isBidirectional)
        {
            private CurrentSep _currentBackSep;
        }

        private void setItem()
        {
            if (!_items.empty)
            {
                // If we're exporting .save, we must not consume any of the
                // subranges, since RoR.save does not guarantee that the states
                // of the subranges are also saved.
                static if (isForwardRange!RoR &&
                           isForwardRange!(ElementType!RoR))
                    _current = _items.front.save;
                else
                    _current = _items.front;
            }
        }

        private void useSeparator()
        {
            // Separator must always come after an item.
            assert(_currentSep.empty,
                    "Attempting to reset a non-empty separator");
            assert(!_items.empty,
                    "Attempting to use a separator in an empty joiner");
            _items.popFront();

            // If there are no more items, we're done, since separators are not
            // terminators.
            if (_items.empty) return;

            if (_currentSep._sep.empty)
            {
                // Advance to the next range in the
                // input
                while (_items.front.empty)
                {
                    _items.popFront();
                    if (_items.empty) return;
                }
                setItem;
            }
            else
            {
                _currentSep.reset;
                assert(!_currentSep.empty, "separator must not be empty");
            }
        }

        this(RoR items, Separator sep)
        {
            _items = items;
            _currentSep.initialize(sep);
            static if (isBidirectional)
                _currentBackSep.initialize(sep);

            //mixin(useItem); // _current should be initialized in place
            if (_items.empty)
            {
                _current = _current.init;   // set invalid state
                static if (isBidirectional)
                    _currentBack = _currentBack.init;
            }
            else
            {
                // If we're exporting .save, we must not consume any of the
                // subranges, since RoR.save does not guarantee that the states
                // of the subranges are also saved.
                static if (isForwardRange!RoR &&
                           isForwardRange!(ElementType!RoR))
                    _current = _items.front.save;
                else
                    _current = _items.front;

                static if (isBidirectional)
                {
                    _currentBack = _items.back.save;

                    if (_currentBack.empty)
                    {
                        // No data in the currentBack item - toggle to use
                        // the separator
                        inputEndsWithEmpty = true;
                    }
                }

                if (_current.empty)
                {
                    // No data in the current item - toggle to use the separator
                    inputStartsWithEmpty = true;

                    // If RoR contains a single empty element,
                    // the returned Result will always be empty
                    import std.range : dropOne;
                    static if (hasLength!RoR)
                    {
                        if (_items.length == 1)
                            _items.popFront;
                    }
                    else static if (isForwardRange!RoR)
                    {
                        if (_items.save.dropOne.empty)
                            _items.popFront;
                    }
                    else
                    {
                        auto _itemsCopy = _items;
                        if (_itemsCopy.dropOne.empty)
                            _items.popFront;
                    }
                }
            }
        }

        @property auto empty()
        {
            return _items.empty;
        }

        //no data in the first item of the initial range - use the separator
        private enum useSepIfFrontIsEmpty = q{
            if (inputStartsWithEmpty)
            {
                useSeparator();
                inputStartsWithEmpty = false;
            }
        };

        @property ElementType!(ElementType!RoR) front()
        {
            mixin(useSepIfFrontIsEmpty);
            if (!_currentSep.empty) return _currentSep.front;
            assert(!_current.empty, "Attempting to fetch the front of an empty joiner.");
            return _current.front;
        }

        void popFront()
        {
            assert(!_items.empty, "Attempting to popFront an empty joiner.");
            // Using separator?
            mixin(useSepIfFrontIsEmpty);

            if (!_currentSep.empty)
            {
                _currentSep.popFront();
                if (_currentSep.empty && !_items.empty)
                {
                    setItem;
                    if (_current.empty)
                    {
                        // No data in the current item - toggle to use the separator
                        useSeparator();
                    }
                }
            }
            else
            {
                // we're using the range
                _current.popFront();
                if (_current.empty)
                    useSeparator();
            }
        }

        static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
        {
            @property auto save()
            {
                Result copy = this;
                copy._items = _items.save;
                copy._current = _current.save;
                copy._currentSep = _currentSep.save;
                static if (isBidirectional)
                {
                    copy._currentBack = _currentBack;
                    copy._currentBackSep = _currentBackSep;
                }
                return copy;
            }
        }

        static if (isBidirectional)
        {
            //no data in the last item of the initial range - use the separator
            private enum useSepIfBackIsEmpty = q{
                if (inputEndsWithEmpty)
                {
                    useBackSeparator;
                    inputEndsWithEmpty = false;
                }
            };

            private void setBackItem()
            {
                if (!_items.empty)
                {
                    _currentBack = _items.back.save;
                }
            }

            private void useBackSeparator()
            {
                // Separator must always come after an item.
                assert(_currentBackSep.empty,
                        "Attempting to reset a non-empty separator");
                assert(!_items.empty,
                        "Attempting to use a separator in an empty joiner");
                _items.popBack();

                // If there are no more items, we're done, since separators are not
                // terminators.
                if (_items.empty) return;

                if (_currentBackSep._sep.empty)
                {
                    // Advance to the next range in the
                    // input
                    while (_items.back.empty)
                    {
                        _items.popBack();
                        if (_items.empty) return;
                    }
                    setBackItem;
                }
                else
                {
                    _currentBackSep.reset;
                    assert(!_currentBackSep.empty, "separator must not be empty");
                }
            }

            @property ElementType!(ElementType!RoR) back()
            {
                mixin(useSepIfBackIsEmpty);

                if (!_currentBackSep.empty) return _currentBackSep.front;
                assert(!_currentBack.empty, "Attempting to fetch the back of an empty joiner.");
                return _currentBack.back;
            }

            void popBack()
            {
                assert(!_items.empty, "Attempting to popBack an empty joiner.");

                mixin(useSepIfBackIsEmpty);

                if (!_currentBackSep.empty)
                {
                    _currentBackSep.popFront();
                    if (_currentBackSep.empty && !_items.empty)
                    {
                        setBackItem;
                        if (_currentBack.empty)
                        {
                            // No data in the current item - toggle to use the separator
                            useBackSeparator();
                        }
                    }
                }
                else
                {
                    // we're using the range
                    _currentBack.popBack();
                    if (_currentBack.empty)
                        useBackSeparator();
                }
            }
        }
    }
    return Result(r, sep);
}

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

    assert(["abc", "def"].joiner.equal("abcdef"));
    assert(["Mary", "has", "a", "little", "lamb"]
        .joiner("...")
        .equal("Mary...has...a...little...lamb"));
    assert(["", "abc"].joiner("xyz").equal("xyzabc"));
    assert([""].joiner("xyz").equal(""));
    assert(["", ""].joiner("xyz").equal("xyz"));
}

@safe pure nothrow unittest
{
    //joiner with separator can return a bidirectional range
    assert(isBidirectionalRange!(typeof(["abc", "def"].joiner("..."))));
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.range.interfaces;
    import std.range.primitives;
    // joiner() should work for non-forward ranges too.
    auto r = inputRangeObject(["abc", "def"]);
    assert(equal(joiner(r, "xyz"), "abcxyzdef"));
}

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

    // Related to https://issues.dlang.org/show_bug.cgi?id=8061
    auto r = joiner([
        inputRangeObject("abc"),
        inputRangeObject("def"),
    ], "-*-");

    assert(equal(r, "abc-*-def"));

    // Test case where separator is specified but is empty.
    auto s = joiner([
        inputRangeObject("abc"),
        inputRangeObject("def"),
    ], "");

    assert(equal(s, "abcdef"));

    // Test empty separator with some empty elements
    auto t = joiner([
        inputRangeObject("abc"),
        inputRangeObject(""),
        inputRangeObject("def"),
        inputRangeObject(""),
    ], "");

    assert(equal(t, "abcdef"));

    // Test empty elements with non-empty separator
    auto u = joiner([
        inputRangeObject(""),
        inputRangeObject("abc"),
        inputRangeObject(""),
        inputRangeObject("def"),
        inputRangeObject(""),
    ], "+-");

    assert(equal(u, "+-abc+-+-def+-"));

    // https://issues.dlang.org/show_bug.cgi?id=13441: only(x) as separator
    string[][] lines = [null];
    lines
        .joiner(only("b"))
        .array();
}

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

    // Transience correctness test
    struct TransientRange
    {
    @safe:
        int[][] src;
        int[] buf;

        this(int[][] _src)
        {
            src = _src;
            buf.length = 100;
        }
        @property bool empty() { return src.empty; }
        @property int[] front()
        {
            assert(src.front.length <= buf.length);
            buf[0 .. src.front.length] = src.front[0..$];
            return buf[0 .. src.front.length];
        }
        void popFront() { src.popFront(); }
    }

    // Test embedded empty elements
    auto tr1 = TransientRange([[], [1,2,3], [], [4]]);
    assert(equal(joiner(tr1, [0]), [0,1,2,3,0,0,4]));

    // Test trailing empty elements
    auto tr2 = TransientRange([[], [1,2,3], []]);
    assert(equal(joiner(tr2, [0]), [0,1,2,3,0]));

    // Test no empty elements
    auto tr3 = TransientRange([[1,2], [3,4]]);
    assert(equal(joiner(tr3, [0,1]), [1,2,0,1,3,4]));

    // Test consecutive empty elements
    auto tr4 = TransientRange([[1,2], [], [], [], [3,4]]);
    assert(equal(joiner(tr4, [0,1]), [1,2,0,1,0,1,0,1,0,1,3,4]));

    // Test consecutive trailing empty elements
    auto tr5 = TransientRange([[1,2], [3,4], [], []]);
    assert(equal(joiner(tr5, [0,1]), [1,2,0,1,3,4,0,1,0,1]));
}

@safe unittest
{
    static assert(isInputRange!(typeof(joiner([""], ""))));
    static assert(isForwardRange!(typeof(joiner([""], ""))));
}

@safe pure unittest
{
    {
        import std.algorithm.comparison : equal;
        auto r = joiner(["abc", "def", "ghi"], "?!");
        char[] res;
        while (!r.empty)
        {
            res ~= r.back;
            r.popBack;
        }
        assert(res.equal("ihg?!fed?!cba"));
    }

    {
        wchar[] sep = ['Ș', 'Ț'];
        auto r = joiner(["","abc",""],sep);
        wchar[] resFront;
        wchar[] resBack;

        auto rCopy = r.save;
        while (!r.empty)
        {
            resFront ~= r.front;
            r.popFront;
        }

        while (!rCopy.empty)
        {
            resBack ~= rCopy.back;
            rCopy.popBack;
        }

        import std.algorithm.comparison : equal;

        assert(resFront.equal("ȘȚabcȘȚ"));
        assert(resBack.equal("ȘȚcbaȘȚ"));
    }

    {
        import std.algorithm.comparison : equal;
        auto r = [""];
        r.popBack;
        assert(r.joiner("AB").equal(""));
    }

    {
        auto r = ["", "", "", "abc", ""].joiner("../");
        auto rCopy = r.save;

        char[] resFront;
        char[] resBack;

        while (!r.empty)
        {
            resFront ~= r.front;
            r.popFront;
        }

        while (!rCopy.empty)
        {
            resBack ~= rCopy.back;
            rCopy.popBack;
        }

        import std.algorithm.comparison : equal;

        assert(resFront.equal("../../../abc../"));
        assert(resBack.equal("../cba../../../"));
    }

    {
        auto r = ["", "abc", ""].joiner("./");
        auto rCopy = r.save;
        r.popBack;
        rCopy.popFront;

        auto rRev = r.save;
        auto rCopyRev = rCopy.save;

        char[] r1, r2, r3, r4;

        while (!r.empty)
        {
            r1 ~= r.back;
            r.popBack;
        }

        while (!rCopy.empty)
        {
            r2 ~= rCopy.front;
            rCopy.popFront;
        }

        while (!rRev.empty)
        {
            r3 ~= rRev.front;
            rRev.popFront;
        }

        while (!rCopyRev.empty)
        {
            r4 ~= rCopyRev.back;
            rCopyRev.popBack;
        }

        import std.algorithm.comparison : equal;

        assert(r1.equal("/cba./"));
        assert(r2.equal("/abc./"));
        assert(r3.equal("./abc"));
        assert(r4.equal("./cba"));
    }
}

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

    assert(inputRangeObject([""]).joiner("lz").equal(""));
}

@safe pure unittest
{
    struct inputRangeStrings
    {
        private string[] strings;

        string front()
        {
            return strings[0];
        }

        void popFront()
        {
            strings = strings[1..$];
        }

        bool empty() const
        {
           return strings.length == 0;
        }
    }

    auto arr = inputRangeStrings([""]);

    import std.algorithm.comparison : equal;

    assert(arr.joiner("./").equal(""));
}

@safe pure unittest
{
    auto r = joiner(["", "", "abc", "", ""], "");
    char[] res;
    while (!r.empty)
    {
        res ~= r.back;
        r.popBack;
    }

    import std.algorithm.comparison : equal;

    assert(res.equal("cba"));
}

/// Ditto
auto joiner(RoR)(RoR r)
if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)))
{
    static struct Result
    {
    private:
        RoR _items;
        Unqual!(ElementType!RoR) _current;
        enum isBidirectional = isForwardRange!RoR && isForwardRange!(ElementType!RoR) &&
                               isBidirectionalRange!RoR && isBidirectionalRange!(ElementType!RoR);
        static if (isBidirectional)
        {
            Unqual!(ElementType!RoR) _currentBack;
            bool reachedFinalElement;
        }

        this(RoR items, ElementType!RoR current)
        {
            _items = items;
            _current = current;
            static if (isBidirectional && hasNested!Result)
                _currentBack = typeof(_currentBack).init;
        }

        void replaceCurrent(typeof(_current) current) @trusted
        {
            import core.lifetime : move;

            current.move(_current);
        }

        static if (isBidirectional)
        {
            void replaceCurrentBack(typeof(_currentBack) currentBack) @trusted
            {
                import core.lifetime : move;

                currentBack.move(_currentBack);
            }
        }

    public:
        this(RoR r)
        {
            _items = r;
            // field _current must be initialized in constructor, because it is nested struct
            _current = typeof(_current).init;

            static if (isBidirectional && hasNested!Result)
                _currentBack = typeof(_currentBack).init;
            mixin(popFrontEmptyElements);
            static if (isBidirectional)
                mixin(popBackEmptyElements);
        }
        static if (isInfinite!RoR)
        {
            enum bool empty = false;
        }
        else
        {
            @property auto empty()
            {
                return _items.empty;
            }
        }
        @property auto ref front()
        {
            assert(!empty, "Attempting to fetch the front of an empty joiner.");
            return _current.front;
        }
        void popFront()
        {
            assert(!_current.empty, "Attempting to popFront an empty joiner.");
            _current.popFront();
            if (_current.empty)
            {
                assert(!_items.empty, "Attempting to popFront an empty joiner.");
                _items.popFront();
                mixin(popFrontEmptyElements);
            }
        }

        private enum popFrontEmptyElements = q{
            // Skip over empty subranges.
            while (!_items.empty && _items.front.empty)
            {
                _items.popFront();
            }
            if (!_items.empty)
            {
                // We cannot export .save method unless we ensure subranges are not
                // consumed when a .save'd copy of ourselves is iterated over. So
                // we need to .save each subrange we traverse.
                static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
                    replaceCurrent(_items.front.save);
                else
                    replaceCurrent(_items.front);
            }
            else
            {
                replaceCurrent(typeof(_current).init);
            }
        };

        static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
        {
            @property auto save()
            {
                // the null check is important if it is a class range, since null.save will segfault; issue #22359
                // could not just compare x is y here without static if due to a compiler assertion failure
                static if (is(typeof(null) : typeof(_current)))
                    auto r = Result(_items.save, _current is null ? null : _current.save);
                else
                    auto r = Result(_items.save, _current.save);
                static if (isBidirectional)
                {
                    static if (is(typeof(null) : typeof(_currentBack)))
                        r.replaceCurrentBack(_currentBack is null ? null : _currentBack.save);
                    else
                        r.replaceCurrentBack(_currentBack.save);
                    r.reachedFinalElement = reachedFinalElement;
                }
                return r;
            }
        }

        static if (hasAssignableElements!(ElementType!RoR))
        {
            @property void front(ElementType!(ElementType!RoR) element)
            {
                assert(!empty, "Attempting to assign to front of an empty joiner.");
                _current.front = element;
            }

            @property void front(ref ElementType!(ElementType!RoR) element)
            {
                assert(!empty, "Attempting to assign to front of an empty joiner.");
                _current.front = element;
            }
        }

        static if (isBidirectional)
        {
            bool checkFinalElement()
            {
                import std.range : dropOne;

                if (reachedFinalElement)
                    return true;

                static if (hasLength!(typeof(_items)))
                {
                    if (_items.length == 1)
                        reachedFinalElement = true;
                }
                else
                {
                    if (_items.save.dropOne.empty)
                        reachedFinalElement = true;
                }

                return false;
            }

            @property auto ref back()
            {
                assert(!empty, "Attempting to fetch the back of an empty joiner.");
                if (reachedFinalElement)
                    return _current.back;
                else
                    return _currentBack.back;
            }

            void popBack()
            {
                assert(!_current.empty, "Attempting to popBack an empty joiner.");
                if (checkFinalElement)
                    _current.popBack();
                else
                    _currentBack.popBack();

                bool isEmpty = reachedFinalElement ? _current.empty : _currentBack.empty;
                if (isEmpty)
                {
                    assert(!_items.empty, "Attempting to popBack an empty joiner.");
                    _items.popBack();
                    mixin(popBackEmptyElements);
                }
            }

            private enum popBackEmptyElements = q{
                // Skip over empty subranges.
                while (!_items.empty && _items.back.empty)
                {
                    _items.popBack();
                }
                if (!_items.empty)
                {
                    checkFinalElement;
                    // We cannot export .save method unless we ensure subranges are not
                    // consumed when a .save'd copy of ourselves is iterated over. So
                    // we need to .save each subrange we traverse.
                    static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
                    {
                        if (reachedFinalElement)
                            replaceCurrent(_items.back.save);
                        else
                            replaceCurrentBack(_items.back.save);
                    }
                    else
                    {
                        if (reachedFinalElement)
                            replaceCurrent(_items.back);
                        else
                            replaceCurrentBack(_items.back);
                    }
                }
                else
                {
                    replaceCurrent(typeof(_current).init);
                    replaceCurrentBack(typeof(_currentBack).init);
                }
            };

            static if (hasAssignableElements!(ElementType!RoR))
            {
                @property void back(ElementType!(ElementType!RoR) element)
                {
                    assert(!empty, "Attempting to assign to back of an empty joiner.");
                    if (reachedFinalElement)
                        _current.back = element;
                    else
                        _currentBack.back = element;
                }

                @property void back(ref ElementType!(ElementType!RoR) element)
                {
                    assert(!empty, "Attempting to assign to back of an empty joiner.");
                    if (reachedFinalElement)
                        _current.back = element;
                    else
                        _currentBack.back = element;
                }
            }
        }
    }
    return Result(r);
}

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

    assert([""].joiner.equal(""));
    assert(["", ""].joiner.equal(""));
    assert(["", "abc"].joiner.equal("abc"));
    assert(["abc", ""].joiner.equal("abc"));
    assert(["abc", "def"].joiner.equal("abcdef"));
    assert(["Mary", "has", "a", "little", "lamb"].joiner.equal("Maryhasalittlelamb"));
    assert("abc".repeat(3).joiner.equal("abcabcabc"));
}

/// joiner allows in-place mutation!
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto a = [ [1, 2, 3], [42, 43] ];
    auto j = joiner(a);
    j.front = 44;
    assert(a == [ [44, 2, 3], [42, 43] ]);
    assert(equal(j, [44, 2, 3, 42, 43]));
}

/// insert characters fully lazily into a string
@safe pure unittest
{
    import std.algorithm.comparison : equal;
    import std.range : chain, cycle, iota, only, retro, take, zip;
    import std.format : format;

    static immutable number = "12345678";
    static immutable delimiter = ",";
    auto formatted = number.retro
        .zip(3.iota.cycle.take(number.length))
        .map!(z => chain(z[0].only, z[1] == 2 ? delimiter : null))
        .joiner
        .retro;
    static immutable expected = "12,345,678";
    assert(formatted.equal(expected));
}

@safe unittest
{
    import std.range.interfaces : inputRangeObject;
    static assert(isInputRange!(typeof(joiner([""]))));
    static assert(isForwardRange!(typeof(joiner([""]))));
}

@system unittest
{
    // this test is system because the virtual interface call to save
    // is flexible and thus cannot be inferred safe automatically

    // https://issues.dlang.org/show_bug.cgi?id=22359
    import std.range;
    ForwardRange!int bug(int[][] r)
    {
        import std.range : inputRangeObject;
        import std.algorithm.iteration : map, joiner;

        auto range = inputRangeObject(r);

        return range.map!(a =>inputRangeObject(a)).joiner.inputRangeObject;
    }
    auto f = bug([[]]);
    f.save(); // should not segfault
}

@safe unittest
{
    // Initial version of PR #6115 caused a compilation failure for
    // https://github.com/BlackEdder/ggplotd/blob/d4428c08db5ffdc05dfd29690bf7da9073ea1dc5/source/ggplotd/stat.d#L562-L583
    import std.range : zip;
    int[] xCoords = [1, 2, 3];
    int[] yCoords = [4, 5, 6];
    auto coords = zip(xCoords, xCoords[1..$]).map!( (xr) {
            return zip(yCoords, yCoords[1..$]).map!( (yr) {
                    return [
                    [[xr[0], xr[0], xr[1]],
                     [yr[0], yr[1], yr[1]]],
                    [[xr[0], xr[1], xr[1]],
                     [yr[0], yr[0], yr[1]]]
                     ];
            }).joiner;
    }).joiner;
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.range.interfaces : inputRangeObject;
    import std.range : retro;

    // https://issues.dlang.org/show_bug.cgi?id=8240
    assert(equal(joiner([inputRangeObject("")]), ""));
    assert(equal(joiner([inputRangeObject("")]).retro, ""));

    // https://issues.dlang.org/show_bug.cgi?id=8792
    auto b = [[1], [2], [3]];
    auto jb = joiner(b);
    auto js = jb.save;
    assert(equal(jb, js));

    auto js2 = jb.save;
    jb.popFront();
    assert(!equal(jb, js));
    assert(equal(js2, js));
    js.popFront();
    assert(equal(jb, js));
    assert(!equal(js2, js));
}

// https://issues.dlang.org/show_bug.cgi?id=19213
@system unittest
{
    auto results = [[1,2], [3,4]].map!(q => q.chunkBy!"a").joiner;
    int i = 1;
    foreach (ref e; results)
        assert(e[0] == i++);
}

/// joiner can be bidirectional
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : retro;

    auto a = [[1, 2, 3], [4, 5]];
    auto j = a.joiner;
    j.back = 44;
    assert(a == [[1, 2, 3], [4, 44]]);
    assert(equal(j.retro, [44, 4, 3, 2, 1]));
}

// bidirectional joiner: test for filtering empty elements
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : retro;

    alias El = (e) => new int(e);
    auto a = [null, [null, El(1), null, El(2), null, El(3), null], null, [null, El(4), null, El(5), null]];
    auto j = a.joiner;

    alias deref = a => a is null ? -1 : *a;
    auto expected = [-1, 5, -1, 4, -1, -1, 3, -1, 2, -1, 1, -1];
    // works with .save.
    assert(j.save.retro.map!deref.equal(expected));
    // and without .save
    assert(j.retro.map!deref.equal(expected));
    assert(j.retro.map!deref.equal(expected));
}

// bidirectional joiner is @nogc
@safe @nogc unittest
{
    import std.algorithm.comparison : equal;
    import std.range : iota, only, retro;

    auto a = only(iota(1, 4), iota(4, 6));
    auto j = a.joiner;
    static immutable expected = [5 , 4, 3, 2, 1];
    assert(equal(j.retro, expected));
}

// bidirectional joiner supports assignment to the back
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : popBackN;

    auto a = [[1, 2, 3], [4, 5]];
    auto j = a.joiner;
    j.back = 55;
    assert(a == [[1, 2, 3], [4, 55]]);
    j.popBackN(2);
    j.back = 33;
    assert(a == [[1, 2, 33], [4, 55]]);
}

// bidirectional joiner works with auto-decoding
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : retro;

    auto a = ["😀😐", "😠"];
    auto j = a.joiner;
    assert(j.retro.equal("😠😐😀"));
}

// test two-side iteration
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : popBackN;

    auto arrs = [
        [[1], [2], [3], [4], [5]],
        [[1], [2, 3, 4], [5]],
        [[1, 2, 3, 4, 5]],
    ];
    foreach (arr; arrs)
    {
        auto a = arr.joiner;
        assert(a.front == 1);
        assert(a.back == 5);
        a.popFront;
        assert(a.front == 2);
        assert(a.back == 5);
        a.popBack;
        assert(a.front == 2);
        assert(a.back == 4);
        a.popFront;
        assert(a.front == 3);
        assert(a.back == 4);
        a.popBack;
        assert(a.front == 3);
        assert(a.back == 3);
        a.popBack;
        assert(a.empty);
    }
}

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

    struct TransientRange
    {
    @safe:
        int[] _buf;
        int[][] _values;
        this(int[][] values)
        {
            _values = values;
            _buf = new int[128];
        }
        @property bool empty()
        {
            return _values.length == 0;
        }
        @property auto front()
        {
            foreach (i; 0 .. _values.front.length)
            {
                _buf[i] = _values[0][i];
            }
            return _buf[0 .. _values.front.length];
        }
        void popFront()
        {
            _values = _values[1 .. $];
        }
    }

    auto rr = TransientRange([[1,2], [3,4,5], [], [6,7]]);

    // Can't use array() or equal() directly because they fail with transient
    // .front.
    int[] result;
    foreach (c; rr.joiner())
    {
        result ~= c;
    }

    assert(equal(result, [1,2,3,4,5,6,7]));
}

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

    struct TransientRange
    {
    @safe:
        dchar[] _buf;
        dstring[] _values;
        this(dstring[] values)
        {
            _buf.length = 128;
            _values = values;
        }
        @property bool empty()
        {
            return _values.length == 0;
        }
        @property auto front()
        {
            foreach (i; 0 .. _values.front.length)
            {
                _buf[i] = _values[0][i];
            }
            return _buf[0 .. _values.front.length];
        }
        void popFront()
        {
            _values = _values[1 .. $];
        }
    }

    auto rr = TransientRange(["abc"d, "12"d, "def"d, "34"d]);

    // Can't use array() or equal() directly because they fail with transient
    // .front.
    dchar[] result;
    foreach (c; rr.joiner())
    {
        result ~= c;
    }

    import std.conv : to;
    assert(equal(result, "abc12def34"d),
        //Convert to string for assert's message
        to!string("Unexpected result: '%s'"d.algoFormat(result)));
}

// https://issues.dlang.org/show_bug.cgi?id=8061
@system unittest
{
    import std.conv : to;
    import std.range.interfaces;

    auto r = joiner([inputRangeObject("ab"), inputRangeObject("cd")]);
    assert(isForwardRange!(typeof(r)));

    auto str = to!string(r);
    assert(str == "abcd");
}

@safe unittest
{
    import std.range : repeat;

    class AssignableRange
    {
    @safe:
        int element;
        @property int front()
        {
            return element;
        }
        alias back = front;

        enum empty = false;

        auto save()
        {
            return this;
        }

        void popFront() {}
        alias popBack = popFront;

        @property void front(int newValue)
        {
            element = newValue;
        }
        alias back = front;
    }

    static assert(isInputRange!AssignableRange);
    static assert(is(ElementType!AssignableRange == int));
    static assert(hasAssignableElements!AssignableRange);
    static assert(!hasLvalueElements!AssignableRange);

    auto range = new AssignableRange();
    assert(range.element == 0);
    {
        auto joined = joiner(repeat(range));
        joined.front = 5;
        assert(range.element == 5);
        assert(joined.front == 5);

        joined.popFront;
        int byRef = 7;
        joined.front = byRef;
        assert(range.element == byRef);
        assert(joined.front == byRef);
    }
    {
        auto joined = joiner(repeat(range));
        joined.back = 5;
        assert(range.element == 5);
        assert(joined.back == 5);

        joined.popBack;
        int byRef = 7;
        joined.back = byRef;
        assert(range.element == byRef);
        assert(joined.back == byRef);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=19850
@safe pure unittest
{
    assert([[0]].joiner.save.back == 0);
}

// https://issues.dlang.org/show_bug.cgi?id=22561
@safe pure unittest
{
    import std.range : only;

    static immutable struct S { int[] array; }
    assert([only(S(null))].joiner.front == S(null));
}

// https://issues.dlang.org/show_bug.cgi?id=22785
@safe unittest
{

    import std.algorithm.iteration : joiner, map;
    import std.array : array;

    static immutable struct S
    {
        int value;
    }

    static immutable struct T
    {
        S[] arr;
    }

    auto range = [T([S(3)]), T([S(4), S(5)])];

    assert(range.map!"a.arr".joiner.array == [S(3), S(4), S(5)]);
}

/++
Implements the homonym function (also known as `accumulate`, $(D
compress), `inject`, or `foldl`) present in various programming
languages of functional flavor. There is also $(LREF fold) which does
the same thing but with the opposite parameter order.

* Use `seed` to initialize an internal `accumulator`.
* For each element `e` in $(D range), evaluate `accumulator = fun(result, e)`.
* Return $(D accumulator).

The one-argument version `reduce!(fun)(range)`
works similarly, but it uses the first element of the range as the
seed (the range must be non-empty, else this throws).

If range has only one element, the functions are never invoked and
`result` and the seed is returned unchanged.

Returns:
    the accumulated result

Params:
    fun = one or more functions of the form `Acc function(Acc, ElemT)`

See_Also:
    $(HTTP en.wikipedia.org/wiki/Fold_(higher-order_function), Fold (higher-order function))

    $(LREF fold) is functionally equivalent to $(LREF _reduce) with the argument
    order reversed, and without the need to use $(REF_ALTTEXT `tuple`,tuple,std,typecons)
    for multiple seeds. This makes it easier to use in UFCS chains.

    $(LREF sum) is similar to `reduce!((a, b) => a + b)` that offers
    pairwise summing of floating point numbers.
+/
template reduce(fun...)
if (fun.length >= 1)
{
    import std.meta : staticMap;

    alias binfuns = staticMap!(binaryFun, fun);
    static if (fun.length > 1)
        import std.typecons : tuple, isTuple;

    /++
    No-seed version. The first element of `r` is used as the seed's value.

    For each function `f` in `fun`, the corresponding
    seed type `S` is `Unqual!(typeof(f(e, e)))`, where `e` is an
    element of `r`: `ElementType!R` for ranges,
    and `ForeachType!R` otherwise.

    Once S has been determined, then `S s = e;` and `s = f(s, e);`
    must both be legal.

    Params:
        r = an iterable value as defined by `isIterable`

    Returns:
        the final result of the accumulator applied to the iterable

    Throws: `Exception` if `r` is empty
    +/
    auto reduce(R)(R r)
    if (isIterable!R)
    {
        import std.exception : enforce;
        alias E = Select!(isInputRange!R, ElementType!R, ForeachType!R);
        alias Args = staticMap!(ReduceSeedType!E, binfuns);

        static if (isInputRange!R)
        {
            // no need to throw if range is statically known to be non-empty
            static if (!__traits(compiles,
            {
                static assert(r.length > 0);
            }))
                enforce(!r.empty, "Cannot reduce an empty input range w/o an explicit seed value.");

            Args result = r.front;
            r.popFront();
            return reduceImpl!false(r, result);
        }
        else
        {
            auto result = Args.init;
            return reduceImpl!true(r, result);
        }
    }

    /++
    Seed version. The seed should be a single value if `fun` is a
    single function. If `fun` is multiple functions, then `seed`
    should be a $(REF Tuple, std,typecons), with one field per function in `f`.

    For convenience, if the seed is const, or has qualified fields, then
    `reduce` will operate on an unqualified copy. If this happens
    then the returned type will not perfectly match `S`.

    Use `fold` instead of `reduce` to use the seed version in a UFCS chain.

    Params:
        seed = the initial value of the accumulator
        r = an iterable value as defined by `isIterable`

    Returns:
        the final result of the accumulator applied to the iterable
    +/
    auto reduce(S, R)(S seed, R r)
    if (isIterable!R)
    {
        static if (fun.length == 1)
            return reducePreImpl(r, seed);
        else
        {
            import std.algorithm.internal : algoFormat;
            static assert(isTuple!S, algoFormat("Seed %s should be a Tuple", S.stringof));
            return reducePreImpl(r, seed.expand);
        }
    }

    private auto reducePreImpl(R, Args...)(R r, ref Args args)
    {
        alias Result = staticMap!(Unqual, Args);
        static if (is(Result == Args))
            alias result = args;
        else
            Result result = args;
        return reduceImpl!false(r, result);
    }

    private auto reduceImpl(bool mustInitialize, R, Args...)(R r, ref Args args)
    if (isIterable!R)
    {
        import std.algorithm.internal : algoFormat;
        static assert(Args.length == fun.length,
            algoFormat("Seed %s does not have the correct amount of fields (should be %s)", Args.stringof, fun.length));
        alias E = Select!(isInputRange!R, ElementType!R, ForeachType!R);

        static if (mustInitialize) bool initialized = false;
        foreach (/+auto ref+/ E e; r) // https://issues.dlang.org/show_bug.cgi?id=4707
        {
            foreach (i, f; binfuns)
            {
                static assert(!is(typeof(f(args[i], e))) || is(typeof(args[i] = f(args[i], e))),
                    algoFormat(
                        "Incompatible function/seed/element: %s/%s/%s",
                        fullyQualifiedName!f,
                        Args[i].stringof,
                        E.stringof
                    )
                );
            }

            static if (mustInitialize) if (initialized == false)
            {
                import core.internal.lifetime : emplaceRef;
                foreach (i, f; binfuns)
                    emplaceRef!(Args[i])(args[i], e);
                initialized = true;
                continue;
            }

            foreach (i, f; binfuns)
                args[i] = f(args[i], e);
        }
        static if (mustInitialize)
        // no need to throw if range is statically known to be non-empty
        static if (!__traits(compiles,
        {
            static assert(r.length > 0);
        }))
        {
            if (!initialized)
                throw new Exception("Cannot reduce an empty iterable w/o an explicit seed value.");
        }

        static if (Args.length == 1)
            return args[0];
        else
            return tuple(args);
    }
}

/**
Many aggregate range operations turn out to be solved with `reduce`
quickly and easily. The example below illustrates `reduce`'s
remarkable power and flexibility.
*/
@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.math.operations : isClose;
    import std.range;

    int[] arr = [ 1, 2, 3, 4, 5 ];
    // Sum all elements
    auto sum = reduce!((a,b) => a + b)(0, arr);
    assert(sum == 15);

    // Sum again, using a string predicate with "a" and "b"
    sum = reduce!"a + b"(0, arr);
    assert(sum == 15);

    // Compute the maximum of all elements
    auto largest = reduce!(max)(arr);
    assert(largest == 5);

    // Max again, but with Uniform Function Call Syntax (UFCS)
    largest = arr.reduce!(max);
    assert(largest == 5);

    // Compute the number of odd elements
    auto odds = reduce!((a,b) => a + (b & 1))(0, arr);
    assert(odds == 3);

    // Compute the sum of squares
    auto ssquares = reduce!((a,b) => a + b * b)(0, arr);
    assert(ssquares == 55);

    // Chain multiple ranges into seed
    int[] a = [ 3, 4 ];
    int[] b = [ 100 ];
    auto r = reduce!("a + b")(chain(a, b));
    assert(r == 107);

    // Mixing convertible types is fair game, too
    double[] c = [ 2.5, 3.0 ];
    auto r1 = reduce!("a + b")(chain(a, b, c));
    assert(isClose(r1, 112.5));

    // To minimize nesting of parentheses, Uniform Function Call Syntax can be used
    auto r2 = chain(a, b, c).reduce!("a + b");
    assert(isClose(r2, 112.5));
}

/**
Sometimes it is very useful to compute multiple aggregates in one pass.
One advantage is that the computation is faster because the looping overhead
is shared. That's why `reduce` accepts multiple functions.
If two or more functions are passed, `reduce` returns a
$(REF Tuple, std,typecons) object with one member per passed-in function.
The number of seeds must be correspondingly increased.
*/
@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.math.operations : isClose;
    import std.math.algebraic : sqrt;
    import std.typecons : tuple, Tuple;

    double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ];
    // Compute minimum and maximum in one pass
    auto r = reduce!(min, max)(a);
    // The type of r is Tuple!(int, int)
    assert(isClose(r[0], 2));  // minimum
    assert(isClose(r[1], 11)); // maximum

    // Compute sum and sum of squares in one pass
    r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a);
    assert(isClose(r[0], 35));  // sum
    assert(isClose(r[1], 233)); // sum of squares
    // Compute average and standard deviation from the above
    auto avg = r[0] / a.length;
    assert(avg == 5);
    auto stdev = sqrt(r[1] / a.length - avg * avg);
    assert(cast(int) stdev == 2);
}

@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.range : chain;
    import std.typecons : tuple, Tuple;

    double[] a = [ 3, 4 ];
    auto r = reduce!("a + b")(0.0, a);
    assert(r == 7);
    r = reduce!("a + b")(a);
    assert(r == 7);
    r = reduce!(min)(a);
    assert(r == 3);
    double[] b = [ 100 ];
    auto r1 = reduce!("a + b")(chain(a, b));
    assert(r1 == 107);

    // two funs
    auto r2 = reduce!("a + b", "a - b")(tuple(0.0, 0.0), a);
    assert(r2[0] == 7 && r2[1] == -7);
    auto r3 = reduce!("a + b", "a - b")(a);
    assert(r3[0] == 7 && r3[1] == -1);

    a = [ 1, 2, 3, 4, 5 ];
    // Stringize with commas
    string rep = reduce!("a ~ `, ` ~ to!(string)(b)")("", a);
    assert(rep[2 .. $] == "1, 2, 3, 4, 5", "["~rep[2 .. $]~"]");
}

@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.exception : assertThrown;
    import std.range : iota;
    import std.typecons : tuple, Tuple;

    // Test the opApply case.
    static struct OpApply
    {
        bool actEmpty;

        int opApply(scope int delegate(ref int) @safe dg)
        {
            int res;
            if (actEmpty) return res;

            foreach (i; 0 .. 100)
            {
                res = dg(i);
                if (res) break;
            }
            return res;
        }
    }

    OpApply oa;
    auto hundredSum = reduce!"a + b"(iota(100));
    assert(reduce!"a + b"(5, oa) == hundredSum + 5);
    assert(reduce!"a + b"(oa) == hundredSum);
    assert(reduce!("a + b", max)(oa) == tuple(hundredSum, 99));
    assert(reduce!("a + b", max)(tuple(5, 0), oa) == tuple(hundredSum + 5, 99));

    // Test for throwing on empty range plus no seed.
    assertThrown(reduce!"a + b"([1, 2][0 .. 0]));

    oa.actEmpty = true;
    assertThrown(reduce!"a + b"(oa));
}

@safe unittest
{
    const float a = 0.0;
    const float[] b = [ 1.2, 3, 3.3 ];
    float[] c = [ 1.2, 3, 3.3 ];
    auto r = reduce!"a + b"(a, b);
    r = reduce!"a + b"(a, c);
    assert(r == 7.5);
}

@safe unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=10408
    // Two-function reduce of a const array.
    import std.algorithm.comparison : max, min;
    import std.typecons : tuple, Tuple;

    const numbers = [10, 30, 20];
    immutable m = reduce!(min)(numbers);
    assert(m == 10);
    immutable minmax = reduce!(min, max)(numbers);
    assert(minmax == tuple(10, 30));
}

@safe unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=10709
    import std.typecons : tuple, Tuple;

    enum foo = "a + 0.5 * b";
    auto r = [0, 1, 2, 3];
    auto r1 = reduce!foo(r);
    auto r2 = reduce!(foo, foo)(r);
    assert(r1 == 3);
    assert(r2 == tuple(3, 3));
}

@safe unittest
{
    static struct OpApply
    {
        int opApply(int delegate(ref int) @safe dg)
        {
            int[] a = [1, 2, 3];

            int res = 0;
            foreach (ref e; a)
            {
                res = dg(e);
                if (res) break;
            }
            return res;
        }
    }
    //test CTFE and functions with context
    int fun(int a, int b) @safe {return a + b + 1;}
    auto foo()
    {
        import std.algorithm.comparison : max;
        import std.typecons : tuple, Tuple;

        auto a = reduce!(fun)([1, 2, 3]);
        auto b = reduce!(fun, fun)([1, 2, 3]);
        auto c = reduce!(fun)(0, [1, 2, 3]);
        auto d = reduce!(fun, fun)(tuple(0, 0), [1, 2, 3]);
        auto e = reduce!(fun)(0, OpApply());
        auto f = reduce!(fun, fun)(tuple(0, 0), OpApply());

        return max(a, b.expand, c, d.expand, e, f.expand);
    }
    auto a = foo();
    assert(a == 9);
    enum b = foo();
    assert(b == 9);
}

@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.typecons : tuple, Tuple;

    //http://forum.dlang.org/post/oghtttkopzjshsuflelk@forum.dlang.org
    //Seed is tuple of const.
    static auto minmaxElement(alias F = min, alias G = max, R)(in R range)
    @safe pure nothrow
    if (isInputRange!R)
    {
        return reduce!(F, G)(tuple(ElementType!R.max,
                                   ElementType!R.min), range);
    }
    assert(minmaxElement([1, 2, 3]) == tuple(1, 3));
}

// https://issues.dlang.org/show_bug.cgi?id=12569
@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.typecons : tuple;
    dchar c = 'a';
    reduce!(min, max)(tuple(c, c), "hello"); // OK
    static assert(!is(typeof(reduce!(min, max)(tuple(c), "hello"))));
    static assert(!is(typeof(reduce!(min, max)(tuple(c, c, c), "hello"))));


    //"Seed dchar should be a Tuple"
    static assert(!is(typeof(reduce!(min, max)(c, "hello"))));
    //"Seed (dchar) does not have the correct amount of fields (should be 2)"
    static assert(!is(typeof(reduce!(min, max)(tuple(c), "hello"))));
    //"Seed (dchar, dchar, dchar) does not have the correct amount of fields (should be 2)"
    static assert(!is(typeof(reduce!(min, max)(tuple(c, c, c), "hello"))));
    //"Incompatible function/seed/element: all(alias pred = "a")/int/dchar"
    static assert(!is(typeof(reduce!all(1, "hello"))));
    static assert(!is(typeof(reduce!(all, all)(tuple(1, 1), "hello"))));
}

// https://issues.dlang.org/show_bug.cgi?id=13304
@safe unittest
{
    int[] data;
    static assert(is(typeof(reduce!((a, b) => a + b)(data))));
    assert(data.length == 0);
}

// https://issues.dlang.org/show_bug.cgi?id=13880
// reduce shouldn't throw if the length is statically known
pure nothrow @safe @nogc unittest
{
    import std.algorithm.comparison : min;
    int[5] arr;
    arr[2] = -1;
    assert(arr.reduce!min == -1);

    int[0] arr0;
    assert(reduce!min(42, arr0) == 42);
}

//Helper for Reduce
private template ReduceSeedType(E)
{
    static template ReduceSeedType(alias fun)
    {
        import std.algorithm.internal : algoFormat;

        alias ReduceSeedType = Unqual!(typeof(fun(lvalueOf!E, lvalueOf!E)));

        //Check the Seed type is useable.
        ReduceSeedType s = ReduceSeedType.init;
        static assert(is(typeof({ReduceSeedType s = lvalueOf!E;})) &&
            is(typeof(lvalueOf!ReduceSeedType = fun(lvalueOf!ReduceSeedType, lvalueOf!E))),
            algoFormat(
                "Unable to deduce an acceptable seed type for %s with element type %s.",
                fullyQualifiedName!fun,
                E.stringof
            )
        );
    }
}


/++
Implements the homonym function (also known as `accumulate`, $(D
compress), `inject`, or `foldl`) present in various programming
languages of functional flavor, iteratively calling one or more predicates.

$(P Each predicate in `fun` must take two arguments:)
* An accumulator value
* An element of the range `r`
$(P Each function must return a value which implicitly converts to the
type of the accumulator.)

$(P For a single function,
the call `fold!(fun)(range, seed)` will:)

* Use `seed` to initialize an internal `accumulator`.
* For each element `e` in $(D range), evaluate `accumulator = fun(result, e)`.
* Return $(D accumulator).

$(P The one-argument version `fold!(fun)(range)`
works similarly, but it uses the first element of the range as the
seed (the range must be non-empty) and iterates over the remaining
elements.)

Multiple results are produced when using multiple functions.

If range has only one element, the functions are never invoked and
`result` and the seed is returned unchanged.

Params:
    fun = one or more functions of the form `Acc function(Acc, ElemT)`

See_Also:
    * $(HTTP en.wikipedia.org/wiki/Fold_(higher-order_function), Fold (higher-order function))

    * $(LREF sum) is similar to `fold!((a, b) => a + b)` that offers
      precise summing of floating point numbers.

    * `fold` is functionally equivalent to $(LREF reduce) with the argument order
      reversed, and without the need to use $(REF_ALTTEXT `tuple`,tuple,std,typecons)
      for multiple seeds.
+/
template fold(fun...)
if (fun.length >= 1)
{
    /**
    Params:
        r = the $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to fold
        seeds = the initial values of each accumulator (optional), one for each predicate
    Returns:
        Either the accumulated result for a single predicate, or a
        $(REF_ALTTEXT `Tuple`,Tuple,std,typecons) of results.
     */
    auto fold(R, S...)(R r, S seeds)
    {
        static if (S.length < 2)
        {
            return reduce!fun(seeds, r);
        }
        else
        {
            import std.typecons : tuple;
            return reduce!fun(tuple(seeds), r);
        }
    }
}

///
@safe pure unittest
{
    immutable arr = [1, 2, 3, 4, 5];

    // Sum all elements
    assert(arr.fold!((a, e) => a + e) == 15);

    // Sum all elements with explicit seed
    assert(arr.fold!((a, e) => a + e)(6) == 21);

    import std.algorithm.comparison : min, max;
    import std.typecons : tuple;

    // Compute minimum and maximum at the same time
    assert(arr.fold!(min, max) == tuple(1, 5));

    // Compute minimum and maximum at the same time with seeds
    assert(arr.fold!(min, max)(0, 7) == tuple(0, 7));

    // Can be used in a UFCS chain
    assert(arr.map!(a => a + 1).fold!((a, e) => a + e) == 20);

    // Return the last element of any range
    assert(arr.fold!((a, e) => e) == 5);
}

@safe @nogc pure nothrow unittest
{
    int[1] arr;
    static assert(!is(typeof(arr.fold!())));
    static assert(!is(typeof(arr.fold!(a => a))));
    static assert(is(typeof(arr.fold!((a, b) => a))));
    static assert(is(typeof(arr.fold!((a, b) => a)(1))));
    assert(arr.length == 1);
}

/++
Similar to `fold`, but returns a range containing the successive reduced values.
The call `cumulativeFold!(fun)(range, seed)` first assigns `seed` to an
internal variable `result`, also called the accumulator.
The returned range contains the values `result = fun(result, x)` lazily
evaluated for each element `x` in `range`. Finally, the last element has the
same value as `fold!(fun)(seed, range)`.
The one-argument version `cumulativeFold!(fun)(range)` works similarly, but
it returns the first element unchanged and uses it as seed for the next
elements.
This function is also known as
    $(HTTP en.cppreference.com/w/cpp/algorithm/partial_sum, partial_sum),
    $(HTTP docs.python.org/3/library/itertools.html#itertools.accumulate, accumulate),
    $(HTTP hackage.haskell.org/package/base-4.8.2.0/docs/Prelude.html#v:scanl, scan),
    $(HTTP mathworld.wolfram.com/CumulativeSum.html, Cumulative Sum).

Params:
    fun = one or more functions of the form `Acc function(Acc, ElemT)`

Returns:
    The function returns a range containing the consecutive reduced values. If
    there is more than one `fun`, the element type will be $(REF Tuple,
    std,typecons) containing one element for each `fun`.

See_Also:
    $(HTTP en.wikipedia.org/wiki/Prefix_sum, Prefix Sum)

Note:

    In functional programming languages this is typically called `scan`, `scanl`,
    `scanLeft` or `reductions`.
+/
template cumulativeFold(fun...)
if (fun.length >= 1)
{
    import std.meta : staticMap;
    private alias binfuns = staticMap!(binaryFun, fun);

    /++
    No-seed version. The first element of `r` is used as the seed's value.
    For each function `f` in `fun`, the corresponding seed type `S` is
    `Unqual!(typeof(f(e, e)))`, where `e` is an element of `r`:
    `ElementType!R`.
    Once `S` has been determined, then `S s = e;` and `s = f(s, e);` must
    both be legal.

    Params:
        range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    Returns:
        a range containing the consecutive reduced values.
    +/
    auto cumulativeFold(R)(R range)
    if (isInputRange!(Unqual!R))
    {
        return cumulativeFoldImpl(range);
    }

    /++
    Seed version. The seed should be a single value if `fun` is a single
    function. If `fun` is multiple functions, then `seed` should be a
    $(REF Tuple, std,typecons), with one field per function in `f`.
    For convenience, if the seed is `const`, or has qualified fields, then
    `cumulativeFold` will operate on an unqualified copy. If this happens
    then the returned type will not perfectly match `S`.

    Params:
        range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        seed = the initial value of the accumulator
    Returns:
        a range containing the consecutive reduced values.
    +/
    auto cumulativeFold(R, S)(R range, S seed)
    if (isInputRange!(Unqual!R))
    {
        static if (fun.length == 1)
            return cumulativeFoldImpl(range, seed);
        else
            return cumulativeFoldImpl(range, seed.expand);
    }

    private auto cumulativeFoldImpl(R, Args...)(R range, ref Args args)
    {
        import std.algorithm.internal : algoFormat;

        static assert(Args.length == 0 || Args.length == fun.length,
            algoFormat("Seed %s does not have the correct amount of fields (should be %s)",
                Args.stringof, fun.length));

        static if (args.length)
            alias State = staticMap!(Unqual, Args);
        else
            alias State = staticMap!(ReduceSeedType!(ElementType!R), binfuns);

        foreach (i, f; binfuns)
        {
            static assert(!__traits(compiles, f(args[i], e)) || __traits(compiles,
                    { args[i] = f(args[i], e); }()),
                algoFormat("Incompatible function/seed/element: %s/%s/%s",
                    fullyQualifiedName!f, Args[i].stringof, E.stringof));
        }

        static struct Result
        {
        private:
            R source;
            State state;

            this(R range, ref Args args)
            {
                source = range;
                if (source.empty)
                    return;

                foreach (i, f; binfuns)
                {
                    static if (args.length)
                        state[i] = f(args[i], source.front);
                    else
                        state[i] = source.front;
                }
            }

        public:
            @property bool empty()
            {
                return source.empty;
            }

            @property auto front()
            {
                assert(!empty, "Attempting to fetch the front of an empty cumulativeFold.");
                static if (fun.length > 1)
                {
                    import std.typecons : tuple;
                    return tuple(state);
                }
                else
                {
                    return state[0];
                }
            }

            void popFront()
            {
                assert(!empty, "Attempting to popFront an empty cumulativeFold.");
                source.popFront;

                if (source.empty)
                    return;

                foreach (i, f; binfuns)
                    state[i] = f(state[i], source.front);
            }

            static if (isForwardRange!R)
            {
                @property auto save()
                {
                    auto result = this;
                    result.source = source.save;
                    return result;
                }
            }

            mixin ImplementLength!source;
        }

        return Result(range, args);
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.array : array;
    import std.math.operations : isClose;
    import std.range : chain;

    int[] arr = [1, 2, 3, 4, 5];
    // Partial sum of all elements
    auto sum = cumulativeFold!((a, b) => a + b)(arr, 0);
    assert(sum.array == [1, 3, 6, 10, 15]);

    // Partial sum again, using a string predicate with "a" and "b"
    auto sum2 = cumulativeFold!"a + b"(arr, 0);
    assert(sum2.array == [1, 3, 6, 10, 15]);

    // Compute the partial maximum of all elements
    auto largest = cumulativeFold!max(arr);
    assert(largest.array == [1, 2, 3, 4, 5]);

    // Partial max again, but with Uniform Function Call Syntax (UFCS)
    largest = arr.cumulativeFold!max;
    assert(largest.array == [1, 2, 3, 4, 5]);

    // Partial count of odd elements
    auto odds = arr.cumulativeFold!((a, b) => a + (b & 1))(0);
    assert(odds.array == [1, 1, 2, 2, 3]);

    // Compute the partial sum of squares
    auto ssquares = arr.cumulativeFold!((a, b) => a + b * b)(0);
    assert(ssquares.array == [1, 5, 14, 30, 55]);

    // Chain multiple ranges into seed
    int[] a = [3, 4];
    int[] b = [100];
    auto r = cumulativeFold!"a + b"(chain(a, b));
    assert(r.array == [3, 7, 107]);

    // Mixing convertible types is fair game, too
    double[] c = [2.5, 3.0];
    auto r1 = cumulativeFold!"a + b"(chain(a, b, c));
    assert(isClose(r1, [3, 7, 107, 109.5, 112.5]));

    // To minimize nesting of parentheses, Uniform Function Call Syntax can be used
    auto r2 = chain(a, b, c).cumulativeFold!"a + b";
    assert(isClose(r2, [3, 7, 107, 109.5, 112.5]));
}

/**
Sometimes it is very useful to compute multiple aggregates in one pass.
One advantage is that the computation is faster because the looping overhead
is shared. That's why `cumulativeFold` accepts multiple functions.
If two or more functions are passed, `cumulativeFold` returns a $(REF Tuple,
std,typecons) object with one member per passed-in function.
The number of seeds must be correspondingly increased.
*/
@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.algorithm.iteration : map;
    import std.math.operations : isClose;
    import std.typecons : tuple;

    double[] a = [3.0, 4, 7, 11, 3, 2, 5];
    // Compute minimum and maximum in one pass
    auto r = a.cumulativeFold!(min, max);
    // The type of r is Tuple!(int, int)
    assert(isClose(r.map!"a[0]", [3, 3, 3, 3, 3, 2, 2]));     // minimum
    assert(isClose(r.map!"a[1]", [3, 4, 7, 11, 11, 11, 11])); // maximum

    // Compute sum and sum of squares in one pass
    auto r2 = a.cumulativeFold!("a + b", "a + b * b")(tuple(0.0, 0.0));
    assert(isClose(r2.map!"a[0]", [3, 7, 14, 25, 28, 30, 35]));      // sum
    assert(isClose(r2.map!"a[1]", [9, 25, 74, 195, 204, 208, 233])); // sum of squares
}

@safe unittest
{
    import std.algorithm.comparison : equal, max, min;
    import std.conv : to;
    import std.range : chain;
    import std.typecons : tuple;

    double[] a = [3, 4];
    auto r = a.cumulativeFold!("a + b")(0.0);
    assert(r.equal([3, 7]));
    auto r2 = cumulativeFold!("a + b")(a);
    assert(r2.equal([3, 7]));
    auto r3 = cumulativeFold!(min)(a);
    assert(r3.equal([3, 3]));
    double[] b = [100];
    auto r4 = cumulativeFold!("a + b")(chain(a, b));
    assert(r4.equal([3, 7, 107]));

    // two funs
    auto r5 = cumulativeFold!("a + b", "a - b")(a, tuple(0.0, 0.0));
    assert(r5.equal([tuple(3, -3), tuple(7, -7)]));
    auto r6 = cumulativeFold!("a + b", "a - b")(a);
    assert(r6.equal([tuple(3, 3), tuple(7, -1)]));

    a = [1, 2, 3, 4, 5];
    // Stringize with commas
    auto rep = cumulativeFold!("a ~ `, ` ~ to!string(b)")(a, "");
    assert(rep.map!"a[2 .. $]".equal(["1", "1, 2", "1, 2, 3", "1, 2, 3, 4", "1, 2, 3, 4, 5"]));

    // Test for empty range
    a = [];
    assert(a.cumulativeFold!"a + b".empty);
    assert(a.cumulativeFold!"a + b"(2.0).empty);
}

@safe unittest
{
    import std.algorithm.comparison : max, min;
    import std.array : array;
    import std.math.operations : isClose;
    import std.typecons : tuple;

    const float a = 0.0;
    const float[] b = [1.2, 3, 3.3];
    float[] c = [1.2, 3, 3.3];

    auto r = cumulativeFold!"a + b"(b, a);
    assert(isClose(r, [1.2, 4.2, 7.5]));

    auto r2 = cumulativeFold!"a + b"(c, a);
    assert(isClose(r2, [1.2, 4.2, 7.5]));

    const numbers = [10, 30, 20];
    enum m = numbers.cumulativeFold!(min).array;
    assert(m == [10, 10, 10]);
    enum minmax = numbers.cumulativeFold!(min, max).array;
    assert(minmax == [tuple(10, 10), tuple(10, 30), tuple(10, 30)]);
}

@safe unittest
{
    import std.math.operations : isClose;
    import std.typecons : tuple;

    enum foo = "a + 0.5 * b";
    auto r = [0, 1, 2, 3];
    auto r1 = r.cumulativeFold!foo;
    auto r2 = r.cumulativeFold!(foo, foo);
    assert(isClose(r1, [0, 0.5, 1.5, 3]));
    assert(isClose(r2.map!"a[0]", [0, 0.5, 1.5, 3]));
    assert(isClose(r2.map!"a[1]", [0, 0.5, 1.5, 3]));
}

@safe unittest
{
    import std.algorithm.comparison : equal, max, min;
    import std.array : array;
    import std.typecons : tuple;

    //Seed is tuple of const.
    static auto minmaxElement(alias F = min, alias G = max, R)(in R range)
    @safe pure nothrow
    if (isInputRange!R)
    {
        return range.cumulativeFold!(F, G)(tuple(ElementType!R.max, ElementType!R.min));
    }

    assert(minmaxElement([1, 2, 3]).equal([tuple(1, 1), tuple(1, 2), tuple(1, 3)]));
}

// https://issues.dlang.org/show_bug.cgi?id=12569
@safe unittest
{
    import std.algorithm.comparison : equal, max, min;
    import std.typecons : tuple;

    dchar c = 'a';

    assert(cumulativeFold!(min, max)("hello", tuple(c, c)).equal([tuple('a', 'h'),
        tuple('a', 'h'), tuple('a', 'l'), tuple('a', 'l'), tuple('a', 'o')]));
    static assert(!__traits(compiles, cumulativeFold!(min, max)("hello", tuple(c))));
    static assert(!__traits(compiles, cumulativeFold!(min, max)("hello", tuple(c, c, c))));

    //"Seed dchar should be a Tuple"
    static assert(!__traits(compiles, cumulativeFold!(min, max)("hello", c)));
    //"Seed (dchar) does not have the correct amount of fields (should be 2)"
    static assert(!__traits(compiles, cumulativeFold!(min, max)("hello", tuple(c))));
    //"Seed (dchar, dchar, dchar) does not have the correct amount of fields (should be 2)"
    static assert(!__traits(compiles, cumulativeFold!(min, max)("hello", tuple(c, c, c))));
    //"Incompatible function/seed/element: all(alias pred = "a")/int/dchar"
    static assert(!__traits(compiles, cumulativeFold!all("hello", 1)));
    static assert(!__traits(compiles, cumulativeFold!(all, all)("hello", tuple(1, 1))));
}

// https://issues.dlang.org/show_bug.cgi?id=13304
@safe unittest
{
    int[] data;
    assert(data.cumulativeFold!((a, b) => a + b).empty);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.internal.test.dummyrange : AllDummyRanges, propagatesLength,
        propagatesRangeType, RangeType;

    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        auto m = d.cumulativeFold!"a * b";

        static assert(propagatesLength!(typeof(m), DummyType));
        static if (DummyType.rt <= RangeType.Forward)
            static assert(propagatesRangeType!(typeof(m), DummyType));

        assert(m.equal([1, 2, 6, 24, 120, 720, 5040, 40_320, 362_880, 3_628_800]));
    }
}

// splitter
/**
Lazily splits a range using an element or range as a separator.
Separator ranges can be any narrow string type or sliceable range type.

Two adjacent separators are considered to surround an empty element in
the split range. Use `filter!(a => !a.empty)` on the result to compress
empty elements.

The predicate is passed to $(REF binaryFun, std,functional) and accepts
any callable function that can be executed via `pred(element, s)`.

Note:
    If splitting a string on whitespace and token compression is desired,
    consider using the `splitter(r)` overload.

Params:
    pred = The predicate for comparing each element with the separator,
        defaulting to `"a == b"`.
    r = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to be
        split. Must support slicing and `.length` or be a narrow string type.
    s = The element (or range) to be treated as the separator
        between range segments to be split.
    keepSeparators = The flag for deciding if the separators are kept

Constraints:
    The predicate `pred` needs to accept an element of `r` and the
    separator `s`.

Returns:
    An input range of the subranges of elements between separators. If `r`
    is a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
    or $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives),
    the returned range will be likewise.
    When a range is used a separator, bidirectionality isn't possible.

    If `keepSeparators` is equal to `Yes.keepSeparators` the output will also contain the
    separators.

    If an empty range is given, the result is an empty range. If a range with
    one separator is given, the result is a range with two empty elements.

See_Also:
 - $(REF _splitter, std,regex) for a version that splits using a regular expression defined separator.
 - $(REF _split, std,array) for a version that splits eagerly.
 - $(LREF splitWhen), which compares adjacent elements instead of element against separator.
*/
auto splitter(alias pred = "a == b",
              Flag!"keepSeparators" keepSeparators = No.keepSeparators,
              Range,
              Separator)(Range r, Separator s)
if (is(typeof(binaryFun!pred(r.front, s)) : bool)
        && ((hasSlicing!Range && hasLength!Range) || isNarrowString!Range)
        && (is(ElementType!Range : Separator)
        || !(isForwardRange!Separator && (hasLength!Separator
        || isNarrowString!Separator))))
{
    import std.algorithm.searching : find;
    import std.conv : unsigned;

    struct Result
    {
    private:
        Range _input;
        Separator _separator;
        // Do we need hasLength!Range? popFront uses _input.length...
        enum size_t _unComputed = size_t.max - 1, _atEnd = size_t.max;
        size_t _frontLength = _unComputed;
        size_t _backLength = _unComputed;

        static if (isNarrowString!Range)
        {
            size_t _separatorLength;
        }
        else
        {
            enum _separatorLength = 1;
        }

        static if (keepSeparators)
        {
            bool _wasSeparator = true;
        }

        static if (isBidirectionalRange!Range)
        {
            size_t lastIndexOf(Range haystack, Separator needle)
            {
                import std.range : retro;
                auto r = haystack.retro().find!pred(needle);
                return r.retro().length - 1;
            }
        }

    public:
        this(Range input, Separator separator)
        {
            _input = input;
            _separator = separator;

            static if (isNarrowString!Range)
            {
                import std.utf : codeLength;

                _separatorLength = codeLength!(ElementEncodingType!Range)(separator);
            }
            if (_input.empty)
                _frontLength = _atEnd;
        }

        static if (isInfinite!Range)
        {
            enum bool empty = false;
        }
        else
        {
            @property bool empty()
            {
                return _frontLength == _atEnd;
            }
        }

        @property Range front()
        {
            assert(!empty, "Attempting to fetch the front of an empty splitter.");
            static if (keepSeparators)
            {
                if (_frontLength != _unComputed && !_wasSeparator) return _input[0 .. _frontLength];
                if (!_wasSeparator)
                {
                    _frontLength = _separatorLength;
                    _wasSeparator = true;
                }
                else if (_frontLength == _unComputed)
                {
                    auto r = _input.find!pred(_separator);
                    _frontLength = _input.length - r.length;
                    _wasSeparator = false;
                }
            }
            else
            {
                if (_frontLength == _unComputed)
                {
                    auto r = _input.find!pred(_separator);
                    _frontLength = _input.length - r.length;
                }
            }
            return _input[0 .. _frontLength];
        }

        void popFront()
        {
            assert(!empty, "Attempting to popFront an empty splitter.");
            if (_frontLength == _unComputed)
            {
                front;
            }
            assert(_frontLength <= _input.length, "The front position must"
                    ~ " not exceed the input.length");
            static if (keepSeparators)
            {
                if (_frontLength == _input.length && !_wasSeparator)
                {
                    _frontLength = _atEnd;

                    _backLength = _atEnd;
                }
                else
                {
                    _input = _input[_frontLength .. _input.length];
                    _frontLength = _unComputed;
                }
            }
            else
            {
                if (_frontLength == _input.length)
                {
                    // no more input and need to fetch => done
                    _frontLength = _atEnd;

                    // Probably don't need this, but just for consistency:
                    _backLength = _atEnd;
                }
                else
                {
                    _input = _input[_frontLength + _separatorLength .. _input.length];
                    _frontLength = _unComputed;
                }
            }
        }

        static if (isForwardRange!Range)
        {
            @property typeof(this) save()
            {
                auto ret = this;
                ret._input = _input.save;
                return ret;
            }
        }

        static if (isBidirectionalRange!Range)
        {
            @property Range back()
            {
                assert(!empty, "Attempting to fetch the back of an empty splitter.");
                static if (keepSeparators)
                {
                    if (!_wasSeparator)
                    {
                        _backLength = _separatorLength;
                        _wasSeparator = true;
                    }
                    else if (_backLength == _unComputed)
                    {
                        immutable lastIndex = lastIndexOf(_input, _separator);
                        if (lastIndex == -1)
                        {
                            _backLength = _input.length;
                        }
                        else
                        {
                            _backLength = _input.length - lastIndex - 1;
                        }
                        _wasSeparator = false;
                    }
                }
                else
                {
                    if (_backLength == _unComputed)
                    {
                        immutable lastIndex = lastIndexOf(_input, _separator);
                        if (lastIndex == -1)
                        {
                            _backLength = _input.length;
                        }
                        else
                        {
                            _backLength = _input.length - lastIndex - 1;
                        }
                    }
                }
                return _input[_input.length - _backLength .. _input.length];
            }

            void popBack()
            {
                assert(!empty, "Attempting to popBack an empty splitter.");
                if (_backLength == _unComputed)
                {
                    // evaluate back to make sure it's computed
                    back;
                }
                assert(_backLength <= _input.length, "The end index must not"
                        ~ " exceed the length of the input");
                static if (keepSeparators)
                {
                    if (_backLength == _input.length && !_wasSeparator)
                    {
                        _frontLength = _atEnd;
                        _backLength = _atEnd;
                    }
                    else
                    {
                        _input = _input[0 .. _input.length - _backLength];
                        _backLength = _unComputed;
                    }
                }
                else
                {
                    if (_backLength == _input.length)
                    {
                        // no more input and need to fetch => done
                        _frontLength = _atEnd;
                        _backLength = _atEnd;
                    }
                    else
                    {
                        _input = _input[0 .. _input.length - _backLength - _separatorLength];
                        _backLength = _unComputed;
                    }
                }
            }
        }
    }

    return Result(r, s);
}

/// Basic splitting with characters and numbers.
@safe unittest
{
    import std.algorithm.comparison : equal;

    assert("a|bc|def".splitter('|').equal([ "a", "bc", "def" ]));

    int[] a = [1, 0, 2, 3, 0, 4, 5, 6];
    int[][] w = [ [1], [2, 3], [4, 5, 6] ];
    assert(a.splitter(0).equal(w));
}

/// Basic splitting with characters and numbers and keeping sentinels.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;

    assert("a|bc|def".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "a", "|", "bc", "|", "def" ]));

    int[] a = [1, 0, 2, 3, 0, 4, 5, 6];
    int[][] w = [ [1], [0], [2, 3], [0], [4, 5, 6] ];
    assert(a.splitter!("a == b", Yes.keepSeparators)(0).equal(w));
}

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

    assert("|ab|".splitter('|').equal([ "", "ab", "" ]));
    assert("ab".splitter('|').equal([ "ab" ]));

    assert("a|b||c".splitter('|').equal([ "a", "b", "", "c" ]));
    assert("hello  world".splitter(' ').equal([ "hello", "", "world" ]));

    auto a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
    auto w = [ [1, 2], [], [3], [4, 5], [] ];
    assert(a.splitter(0).equal(w));
}

/// Adjacent separators and keeping sentinels.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;

    assert("|ab|".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "", "|", "ab", "|", "" ]));
    assert("ab".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "ab" ]));

    assert("a|b||c".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "a", "|", "b", "|", "", "|", "c" ]));
    assert("hello  world".splitter!("a == b", Yes.keepSeparators)(' ')
        .equal([ "hello", " ", "", " ", "world" ]));

    auto a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
    auto w = [ [1, 2], [0], [], [0], [3], [0], [4, 5], [0], [] ];
    assert(a.splitter!("a == b", Yes.keepSeparators)(0).equal(w));
}

/// Empty and separator-only ranges.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : empty;

    assert("".splitter('|').empty);
    assert("|".splitter('|').equal([ "", "" ]));
    assert("||".splitter('|').equal([ "", "", "" ]));
}

/// Empty and separator-only ranges and keeping sentinels.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;
    import std.range : empty;

    assert("".splitter!("a == b", Yes.keepSeparators)('|').empty);
    assert("|".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "", "|", "" ]));
    assert("||".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "", "|", "", "|", "" ]));
}

/// Use a range for splitting
@safe unittest
{
    import std.algorithm.comparison : equal;

    assert("a=>bc=>def".splitter("=>").equal([ "a", "bc", "def" ]));
    assert("a|b||c".splitter("||").equal([ "a|b", "c" ]));
    assert("hello  world".splitter("  ").equal([ "hello", "world" ]));

    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
    int[][] w = [ [1, 2], [3, 0, 4, 5, 0] ];
    assert(a.splitter([0, 0]).equal(w));

    a = [ 0, 0 ];
    assert(a.splitter([0, 0]).equal([ (int[]).init, (int[]).init ]));

    a = [ 0, 0, 1 ];
    assert(a.splitter([0, 0]).equal([ [], [1] ]));
}

/// Use a range for splitting
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;

    assert("a=>bc=>def".splitter!("a == b", Yes.keepSeparators)("=>")
        .equal([ "a", "=>", "bc", "=>", "def" ]));
    assert("a|b||c".splitter!("a == b", Yes.keepSeparators)("||")
        .equal([ "a|b", "||", "c" ]));
    assert("hello  world".splitter!("a == b", Yes.keepSeparators)("  ")
        .equal([ "hello", "  ",  "world" ]));

    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
    int[][] w = [ [1, 2], [0, 0], [3, 0, 4, 5, 0] ];
    assert(a.splitter!("a == b", Yes.keepSeparators)([0, 0]).equal(w));

    a = [ 0, 0 ];
    assert(a.splitter!("a == b", Yes.keepSeparators)([0, 0])
        .equal([ (int[]).init, [0, 0], (int[]).init ]));

    a = [ 0, 0, 1 ];
    assert(a.splitter!("a == b", Yes.keepSeparators)([0, 0])
        .equal([ [], [0, 0], [1] ]));
}

/// Custom predicate functions.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.ascii : toLower;

    assert("abXcdxef".splitter!"a.toLower == b"('x').equal(
                 [ "ab", "cd", "ef" ]));

    auto w = [ [0], [1], [2] ];
    assert(w.splitter!"a.front == b"(1).equal([ [[0]], [[2]] ]));
}

/// Custom predicate functions.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;
    import std.ascii : toLower;

    assert("abXcdxef".splitter!("a.toLower == b", Yes.keepSeparators)('x')
        .equal([ "ab", "X", "cd", "x", "ef" ]));

    auto w = [ [0], [1], [2] ];
    assert(w.splitter!("a.front == b", Yes.keepSeparators)(1)
        .equal([ [[0]], [[1]], [[2]] ]));
}

/// Leading separators, trailing separators, or no separators.
@safe unittest
{
    import std.algorithm.comparison : equal;

    assert("|ab|".splitter('|').equal([ "", "ab", "" ]));
    assert("ab".splitter('|').equal([ "ab" ]));
}

/// Leading separators, trailing separators, or no separators.
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;

    assert("|ab|".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "", "|", "ab", "|", "" ]));
    assert("ab".splitter!("a == b", Yes.keepSeparators)('|')
        .equal([ "ab" ]));
}

/// Splitter returns bidirectional ranges if the delimiter is a single element
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : retro;
    assert("a|bc|def".splitter('|').retro.equal([ "def", "bc", "a" ]));
}

/// Splitter returns bidirectional ranges if the delimiter is a single element
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : Yes;
    import std.range : retro;
    assert("a|bc|def".splitter!("a == b", Yes.keepSeparators)('|')
        .retro.equal([ "def", "|", "bc", "|", "a" ]));
}

@safe unittest
{
    import std.algorithm;
    import std.array : array;
    import std.internal.test.dummyrange;
    import std.range : retro;

    assert(equal(splitter("hello  world", ' '), [ "hello", "", "world" ]));
    assert(equal(splitter("žlutoučkýřkůň", 'ř'), [ "žlutoučký", "kůň" ]));
    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
    int[][] w = [ [1, 2], [], [3], [4, 5], [] ];
    static assert(isForwardRange!(typeof(splitter(a, 0))));

    assert(equal(splitter(a, 0), w));
    a = null;
    assert(equal(splitter(a, 0),  (int[][]).init));
    a = [ 0 ];
    assert(equal(splitter(a, 0), [ (int[]).init, (int[]).init ][]));
    a = [ 0, 1 ];
    assert(equal(splitter(a, 0), [ [], [1] ]));
    assert(equal(splitter(a, 0), [ [], [1] ][]));

    // Thoroughly exercise the bidirectional stuff.
    auto str = "abc abcd abcde ab abcdefg abcdefghij ab ac ar an at ada";
    assert(equal(
        retro(splitter(str, 'a')),
        retro(array(splitter(str, 'a')))
    ));

    // Test interleaving front and back.
    auto split = splitter(str, 'a');
    assert(split.front == "");
    assert(split.back == "");
    split.popBack();
    assert(split.back == "d");
    split.popFront();
    assert(split.front == "bc ");
    assert(split.back == "d");
    split.popFront();
    split.popBack();
    assert(split.back == "t ");
    split.popBack();
    split.popBack();
    split.popFront();
    split.popFront();
    assert(split.front == "b ");
    assert(split.back == "r ");

    // https://issues.dlang.org/show_bug.cgi?id=4408
    foreach (DummyType; AllDummyRanges)
    {
        static if (isRandomAccessRange!DummyType)
        {
            static assert(isBidirectionalRange!DummyType);
            DummyType d;
            auto s = splitter(d, 5);
            assert(equal(s.front, [1,2,3,4]));
            assert(equal(s.back, [6,7,8,9,10]));

            auto s2 = splitter(d, [4, 5]);
            assert(equal(s2.front, [1,2,3]));
        }
    }
}
@safe unittest
{
    import std.algorithm;
    import std.range;
    auto L = retro(iota(1L, 10L));
    auto s = splitter(L, 5L);
    assert(equal(s.front, [9L, 8L, 7L, 6L]));
    s.popFront();
    assert(equal(s.front, [4L, 3L, 2L, 1L]));
    s.popFront();
    assert(s.empty);
}

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

    const w = [[0], [1], [2]];
    assert(w.splitter!((a, b) => a.front() == b)(1).equal([[[0]], [[2]]]));
}

// https://issues.dlang.org/show_bug.cgi?id=18470
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.ascii : toLower;

    assert("abXcdxef".splitter!"a.toLower == b"('x').equal(["ab", "cd", "ef"]));
    assert("abXcdxef".splitter!((a, b) => a.toLower == b)('x').equal(["ab", "cd", "ef"]));
}

// https://github.com/dlang/phobos/issues/10759
@safe unittest
{
    import std.algorithm.iteration : splitter;
    import std.algorithm.searching : canFind;
    import std.range.primitives;
    import std.typecons : Yes;

    auto range = "16x13+0-2".splitter!((a, b) => "x+-".canFind(a), Yes.keepSeparators)(0);
    assert(range.front == "16");
    assert(range.front == "16");
    assert(range.front == "16");
}

/// ditto
auto splitter(alias pred = "a == b",
              Flag!"keepSeparators" keepSeparators = No.keepSeparators,
              Range,
              Separator)(Range r, Separator s)
if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
        && (hasSlicing!Range || isNarrowString!Range)
        && isForwardRange!Separator
        && (hasLength!Separator || isNarrowString!Separator))
{
    import std.algorithm.searching : find;
    import std.conv : unsigned;

    struct Result
    {
    private:
        Range _input;
        Separator _separator;
        // _frontLength == size_t.max means empty
        size_t _frontLength = size_t.max;

        static if (keepSeparators)
        {
            bool _wasSeparator = true;
        }

        @property auto separatorLength() { return _separator.length; }

        void ensureFrontLength()
        {
            if (_frontLength != _frontLength.max) return;
            static if (keepSeparators)
            {
                assert(!_input.empty || _wasSeparator, "The input must not be empty");
                if (_wasSeparator)
                {
                    _frontLength = _input.length -
                        find!pred(_input, _separator).length;
                    _wasSeparator = false;
                }
                else
                {
                    _frontLength = separatorLength();
                    _wasSeparator = true;
                }
            }
            else
            {
                assert(!_input.empty, "The input must not be empty");
                // compute front length
                _frontLength = (_separator.empty) ? 1 :
                           _input.length - find!pred(_input, _separator).length;
            }
        }

    public:
        this(Range input, Separator separator)
        {
            _input = input;
            _separator = separator;
        }

        @property Range front()
        {
            assert(!empty, "Attempting to fetch the front of an empty splitter.");
            ensureFrontLength();
            return _input[0 .. _frontLength];
        }

        static if (isInfinite!Range)
        {
            enum bool empty = false;  // Propagate infiniteness
        }
        else
        {
            @property bool empty()
            {
                static if (keepSeparators)
                {
                    return _frontLength == size_t.max && _input.empty && !_wasSeparator;
                }
                else
                {
                    return _frontLength == size_t.max && _input.empty;
                }
            }
        }

        void popFront()
        {
            assert(!empty, "Attempting to popFront an empty splitter.");
            ensureFrontLength();

            static if (keepSeparators)
            {
                _input = _input[_frontLength .. _input.length];
            }
            else
            {
                if (_frontLength == _input.length)
                {
                    // done, there's no separator in sight
                    _input = _input[_frontLength .. _frontLength];
                    _frontLength = _frontLength.max;
                    return;
                }
                if (_frontLength + separatorLength == _input.length)
                {
                    // Special case: popping the first-to-last item; there is
                    // an empty item right after this.
                    _input = _input[_input.length .. _input.length];
                    _frontLength = 0;
                    return;
                }
                // Normal case, pop one item and the separator, get ready for
                // reading the next item
                _input = _input[_frontLength + separatorLength .. _input.length];
            }
            // mark _frontLength as uninitialized
            _frontLength = _frontLength.max;
        }

        static if (isForwardRange!Range)
        {
            @property typeof(this) save()
            {
                auto ret = this;
                ret._input = _input.save;
                return ret;
            }
        }
    }

    return Result(r, s);
}

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

    alias C = Tuple!(int, "x", int, "y");
    auto a = [C(1,0), C(2,0), C(3,1), C(4,0)];
    assert(equal(splitter!"a.x == b"(a, [2, 3]), [ [C(1,0)], [C(4,0)] ]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.array : split;
    import std.conv : text;

    auto s = ",abc, de, fg,hi,";
    auto sp0 = splitter(s, ',');
    assert(equal(sp0, ["", "abc", " de", " fg", "hi", ""][]));

    auto s1 = ", abc, de,  fg, hi, ";
    auto sp1 = splitter(s1, ", ");
    assert(equal(sp1, ["", "abc", "de", " fg", "hi", ""][]));
    static assert(isForwardRange!(typeof(sp1)));

    int[] a = [ 1, 2, 0, 3, 0, 4, 5, 0 ];
    int[][] w = [ [1, 2], [3], [4, 5], [] ];
    uint i;
    foreach (e; splitter(a, 0))
    {
        assert(i < w.length);
        assert(e == w[i++]);
    }
    assert(i == w.length);

    wstring names = ",peter,paul,jerry,";
    auto words = split(names, ",");
    assert(walkLength(words) == 5, text(walkLength(words)));
}

@safe unittest
{
    int[][] a = [ [1], [2], [0], [3], [0], [4], [5], [0] ];
    int[][][] w = [ [[1], [2]], [[3]], [[4], [5]], [] ];
    uint i;
    foreach (e; splitter!"a.front == 0"(a, 0))
    {
        assert(i < w.length);
        assert(e == w[i++]);
    }
    assert(i == w.length);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    auto s6 = ",";
    auto sp6 = splitter(s6, ',');
    foreach (e; sp6) {}
    assert(equal(sp6, ["", ""][]));
}

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

    auto s = splitter("abc", "");
    assert(s.equal(["a", "b", "c"]));
}

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

    // Test by-reference separator
    static class RefSep {
    @safe:
        string _impl;
        this(string s) { _impl = s; }
        @property empty() { return _impl.empty; }
        @property auto front() { return _impl.front; }
        void popFront() { _impl = _impl[1..$]; }
        @property RefSep save() scope { return new RefSep(_impl); }
        @property auto length() { return _impl.length; }
    }
    auto sep = new RefSep("->");
    auto data = "i->am->pointing";
    auto words = splitter(data, sep);
    assert(words.equal([ "i", "am", "pointing" ]));
}

// https://github.com/dlang/phobos/issues/10760
@safe unittest
{
    import std.algorithm.searching : canFind;
    import std.typecons : Yes;
    import std.algorithm.comparison : equal;

    auto r = "16x16+0-2".splitter!((a, b) => "x+-".canFind(a), Yes.keepSeparators)("x");
    assert(r.equal(["16", "x", "16", "+", "0", "-", "2"]));
}

/++
Lazily splits a range `r` whenever a predicate `isTerminator` returns true for an element.

As above, two adjacent separators are considered to surround an empty element in
the split range.

Params:
    r = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to be
        split.
    isTerminator = A $(REF_ALTTEXT unary, unaryFun, std,functional) predicate for
        deciding where to split the range.

Returns:
    A forward range of slices of the original range split by whitespace.
 +/
auto splitter(alias isTerminator, Range)(Range r)
if (isForwardRange!Range && is(typeof(unaryFun!isTerminator(r.front))))
{
    return SplitterResult!(unaryFun!isTerminator, Range)(r);
}

///
@safe unittest
{
    import std.ascii : isWhite;
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : splitter;

    string str = "Hello World\t!";
    assert(str.splitter!(isWhite).equal(["Hello", "World", "!"]));
}

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

    assert(equal(splitter!(a => a == '|')("a|bc|def"), [ "a", "bc", "def" ]));
    assert(equal(splitter!(a => a == ' ')("hello  world"), [ "hello", "", "world" ]));

    int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
    int[][] w = [ [1, 2], [], [3], [4, 5], [] ];
    assert(equal(splitter!(a => a == 0)(a), w));

    a = [ 0 ];
    assert(equal(splitter!(a => a == 0)(a), [ (int[]).init, (int[]).init ]));

    a = [ 0, 1 ];
    assert(equal(splitter!(a => a == 0)(a), [ [], [1] ]));

    w = [ [0], [1], [2] ];
    assert(equal(splitter!(a => a.front == 1)(w), [ [[0]], [[2]] ]));
}

private struct SplitterResult(alias isTerminator, Range)
{
    import std.algorithm.searching : find;
    enum fullSlicing = (hasLength!Range && hasSlicing!Range) || isSomeString!Range;

    private Range _input;
    private size_t _end = 0;
    static if (!fullSlicing)
        private Range _next;

    private void findTerminator()
    {
        static if (fullSlicing)
        {
            auto r = find!isTerminator(_input.save);
            _end = _input.length - r.length;
        }
        else
            for ( _end = 0; !_next.empty ; _next.popFront)
            {
                if (isTerminator(_next.front))
                    break;
                ++_end;
            }
    }

    this(Range input)
    {
        _input = input;
        static if (!fullSlicing)
            _next = _input.save;

        if (!_input.empty)
            findTerminator();
        else
            _end = size_t.max;
    }

    static if (fullSlicing)
    {
        private this(Range input, size_t end)
        {
            _input = input;
            _end = end;
        }
    }
    else
    {
        private this(Range input, size_t end, Range next)
        {
            _input = input;
            _end = end;
            _next = next;
        }
    }

    static if (isInfinite!Range)
    {
        enum bool empty = false;  // Propagate infiniteness.
    }
    else
    {
        @property bool empty()
        {
            return _end == size_t.max;
        }
    }

    @property auto front()
    {
        version (assert)
        {
            import core.exception : RangeError;
            if (empty)
                throw new RangeError();
        }
        static if (fullSlicing)
            return _input[0 .. _end];
        else
        {
            import std.range : takeExactly;
            return _input.takeExactly(_end);
        }
    }

    void popFront()
    {
        version (assert)
        {
            import core.exception : RangeError;
            if (empty)
                throw new RangeError();
        }

        static if (fullSlicing)
        {
            _input = _input[_end .. _input.length];
            if (_input.empty)
            {
                _end = size_t.max;
                return;
            }
            _input.popFront();
        }
        else
        {
            if (_next.empty)
            {
                _input = _next;
                _end = size_t.max;
                return;
            }
            _next.popFront();
            _input = _next.save;
        }
        findTerminator();
    }

    @property typeof(this) save()
    {
        static if (fullSlicing)
            return SplitterResult(_input.save, _end);
        else
            return SplitterResult(_input.save, _end, _next.save);
    }
}

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

    auto L = iota(1L, 10L);
    auto s = splitter(L, [5L, 6L]);
    assert(equal(s.front, [1L, 2L, 3L, 4L]));
    s.popFront();
    assert(equal(s.front, [7L, 8L, 9L]));
    s.popFront();
    assert(s.empty);
}

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

    void compare(string sentence, string[] witness)
    {
        auto r = splitter!"a == ' '"(sentence);
        assert(equal(r.save, witness), algoFormat("got: %(%s, %) expected: %(%s, %)", r, witness));
    }

    compare(" Mary  has a little lamb.   ",
            ["", "Mary", "", "has", "a", "little", "lamb.", "", "", ""]);
    compare("Mary  has a little lamb.   ",
            ["Mary", "", "has", "a", "little", "lamb.", "", "", ""]);
    compare("Mary  has a little lamb.",
            ["Mary", "", "has", "a", "little", "lamb."]);
    compare("", (string[]).init);
    compare(" ", ["", ""]);

    static assert(isForwardRange!(typeof(splitter!"a == ' '"("ABC"))));

    foreach (DummyType; AllDummyRanges)
    {
        static if (isRandomAccessRange!DummyType)
        {
            auto rangeSplit = splitter!"a == 5"(DummyType.init);
            assert(equal(rangeSplit.front, [1,2,3,4]));
            rangeSplit.popFront();
            assert(equal(rangeSplit.front, [6,7,8,9,10]));
        }
    }
}

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

    struct Entry
    {
        int low;
        int high;
        int[][] result;
    }
    Entry[] entries = [
        Entry(0, 0, []),
        Entry(0, 1, [[0]]),
        Entry(1, 2, [[], []]),
        Entry(2, 7, [[2], [4], [6]]),
        Entry(1, 8, [[], [2], [4], [6], []]),
    ];
    foreach ( entry ; entries )
    {
        auto a = iota(entry.low, entry.high).filter!"true"();
        auto b = splitter!"a%2"(a);
        assert(equal!equal(b.save, entry.result), algoFormat("got: %(%s, %) expected: %(%s, %)", b, entry.result));
    }
}

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

    // https://issues.dlang.org/show_bug.cgi?id=6791
    assert(equal(
        splitter("là dove terminava quella valle"),
        ["là", "dove", "terminava", "quella", "valle"]
    ));
    assert(equal(
        splitter!(isWhite)("là dove terminava quella valle"),
        ["là", "dove", "terminava", "quella", "valle"]
    ));
    assert(equal(splitter!"a=='本'"("日本語"), ["日", "語"]));
}

// https://issues.dlang.org/show_bug.cgi?id=18657
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : refRange;
    string s = "foobar";
    auto r = refRange(&s).splitter!(c => c == 'b');
    assert(equal!equal(r.save, ["foo", "ar"]));
    assert(equal!equal(r.save, ["foo", "ar"]));
}

/++
Lazily splits the character-based range `s` into words, using whitespace as the
delimiter.

This function is character-range specific and, contrary to
`splitter!(std.uni.isWhite)`, runs of whitespace will be merged together
(no empty tokens will be produced).

Params:
    s = The character-based range to be split. Must be a string, or a
    random-access range of character types.

Returns:
    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of slices of
    the original range split by whitespace.
 +/
auto splitter(Range)(Range s)
if (isSomeString!Range ||
    isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range &&
    !isConvertibleToString!Range &&
    isSomeChar!(ElementEncodingType!Range))
{
    import std.algorithm.searching : find;
    static struct Result
    {
    private:
        import core.exception : RangeError;
        Range _s;
        size_t _frontLength;

        void getFirst()
        {
            import std.uni : isWhite;
            import std.traits : Unqual;

            static if (is(immutable ElementEncodingType!Range == immutable wchar) &&
                       is(immutable ElementType!Range == immutable dchar))
            {
                // all unicode whitespace characters fit into a wchar. However,
                // this range is a wchar array, so we will treat it like a
                // wchar array instead of decoding each code point.
                _frontLength = _s.length; // default condition, no spaces
                foreach (i; 0 .. _s.length)
                    if (isWhite(_s[i]))
                    {
                        _frontLength = i;
                        break;
                    }
            }
            else static if (is(immutable ElementType!Range == immutable dchar) ||
                            is(immutable ElementType!Range == immutable wchar))
            {
                // dchar or wchar range, we can just use find.
                auto r = find!(isWhite)(_s.save);
                _frontLength = _s.length - r.length;
            }
            else
            {
                // need to decode the characters until we find a space. This is
                // ported from std.string.stripLeft.
                static import std.ascii;
                static import std.uni;
                import std.utf : decodeFront;

                auto input = _s.save;
                size_t iLength = input.length;

                while (!input.empty)
                {
                    auto c = input.front;
                    if (std.ascii.isASCII(c))
                    {
                        if (std.ascii.isWhite(c))
                            break;
                        input.popFront();
                        --iLength;
                    }
                    else
                    {
                        auto dc = decodeFront(input);
                        if (std.uni.isWhite(dc))
                            break;
                        iLength = input.length;
                    }
                }

                // sanity check
                assert(iLength <= _s.length, "The current index must not"
                        ~ " exceed the length of the input");

                _frontLength = _s.length - iLength;
            }
        }

    public:
        this(Range s)
        {
            import std.string : stripLeft;
            _s = s.stripLeft();
            getFirst();
        }

        @property auto front()
        {
            version (assert) if (empty) throw new RangeError();
            return _s[0 .. _frontLength];
        }

        void popFront()
        {
            import std.string : stripLeft;
            version (assert) if (empty) throw new RangeError();
            _s = _s[_frontLength .. $].stripLeft();
            getFirst();
        }

        @property bool empty() const
        {
            return _s.empty;
        }

        @property inout(Result) save() inout @safe pure nothrow
        {
            return this;
        }
    }
    return Result(s);
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;
    auto a = " a     bcd   ef gh ";
    assert(equal(splitter(a), ["a", "bcd", "ef", "gh"][]));
}

@safe pure unittest
{
    import std.algorithm.comparison : equal;
    import std.meta : AliasSeq;
    static foreach (S; AliasSeq!(string, wstring, dstring))
    {{
        import std.conv : to;
        S a = " a  \u2028   bcd   ef gh ";
        assert(equal(splitter(a), [to!S("a"), to!S("bcd"), to!S("ef"), to!S("gh")]));
        a = "";
        assert(splitter(a).empty);
    }}

    immutable string s = " a     bcd   ef gh ";
    assert(equal(splitter(s), ["a", "bcd", "ef", "gh"][]));
}

@safe unittest
{
    import std.conv : to;
    import std.string : strip;

    // TDPL example, page 8
    uint[string] dictionary;
    char[][3] lines;
    lines[0] = "line one".dup;
    lines[1] = "line \ttwo".dup;
    lines[2] = "yah            last   line\ryah".dup;
    foreach (line; lines)
    {
       foreach (word; splitter(strip(line)))
       {
            if (word in dictionary) continue; // Nothing to do
            auto newID = dictionary.length;
            dictionary[to!string(word)] = cast(uint) newID;
        }
    }
    assert(dictionary.length == 5);
    assert(dictionary["line"]== 0);
    assert(dictionary["one"]== 1);
    assert(dictionary["two"]== 2);
    assert(dictionary["yah"]== 3);
    assert(dictionary["last"]== 4);

}

@safe unittest
{
    // do it with byCodeUnit
    import std.conv : to;
    import std.string : strip;
    import std.utf : byCodeUnit;

    alias BCU = typeof("abc".byCodeUnit());

    // TDPL example, page 8
    uint[BCU] dictionary;
    BCU[3] lines;
    lines[0] = "line one".byCodeUnit;
    lines[1] = "line \ttwo".byCodeUnit;
    lines[2] = "yah            last   line\ryah".byCodeUnit;
    foreach (line; lines)
    {
       foreach (word; splitter(strip(line)))
       {
           static assert(is(typeof(word) == BCU));
            if (word in dictionary) continue; // Nothing to do
            auto newID = dictionary.length;
            dictionary[word] = cast(uint) newID;
        }
    }
    assert(dictionary.length == 5);
    assert(dictionary["line".byCodeUnit]== 0);
    assert(dictionary["one".byCodeUnit]== 1);
    assert(dictionary["two".byCodeUnit]== 2);
    assert(dictionary["yah".byCodeUnit]== 3);
    assert(dictionary["last".byCodeUnit]== 4);
}

// https://issues.dlang.org/show_bug.cgi?id=19238
@safe pure unittest
{
    import std.utf : byCodeUnit;
    import std.algorithm.comparison : equal;
    auto range = "hello    world".byCodeUnit.splitter;
    static assert(is(typeof(range.front()) == typeof("hello".byCodeUnit())));
    assert(range.equal(["hello".byCodeUnit, "world".byCodeUnit]));

    // test other space types, including unicode
    auto u = " a\t\v\r bcd\u3000 \u2028\t\nef\U00010001 gh";
    assert(equal(splitter(u), ["a", "bcd", "ef\U00010001", "gh"][]));
    assert(equal(splitter(u.byCodeUnit), ["a".byCodeUnit, "bcd".byCodeUnit,
                 "ef\U00010001".byCodeUnit, "gh".byCodeUnit][]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.internal : algoFormat;
    import std.array : split;
    import std.conv : text;

    // Check consistency:
    // All flavors of split should produce the same results
    foreach (input; [(int[]).init,
                     [0],
                     [0, 1, 0],
                     [1, 1, 0, 0, 1, 1],
                    ])
    {
        foreach (s; [0, 1])
        {
            auto result = split(input, s);

            assert(equal(result, split(input, [s])), algoFormat(`"[%(%s,%)]"`, split(input, [s])));
            //assert(equal(result, split(input, [s].filter!"true"())));                          //Not yet implemented
            assert(equal(result, split!((a) => a == s)(input)), text(split!((a) => a == s)(input)));

            //assert(equal!equal(result, split(input.filter!"true"(), s)));                      //Not yet implemented
            //assert(equal!equal(result, split(input.filter!"true"(), [s])));                    //Not yet implemented
            //assert(equal!equal(result, split(input.filter!"true"(), [s].filter!"true"())));    //Not yet implemented
            assert(equal!equal(result, split!((a) => a == s)(input.filter!"true"())));

            assert(equal(result, splitter(input, s)));
            assert(equal(result, splitter(input, [s])));
            //assert(equal(result, splitter(input, [s].filter!"true"())));                       //Not yet implemented
            assert(equal(result, splitter!((a) => a == s)(input)));

            //assert(equal!equal(result, splitter(input.filter!"true"(), s)));                   //Not yet implemented
            //assert(equal!equal(result, splitter(input.filter!"true"(), [s])));                 //Not yet implemented
            //assert(equal!equal(result, splitter(input.filter!"true"(), [s].filter!"true"()))); //Not yet implemented
            assert(equal!equal(result, splitter!((a) => a == s)(input.filter!"true"())));
        }
    }
    foreach (input; [string.init,
                     " ",
                     "  hello ",
                     "hello   hello",
                     " hello   what heck   this ?  "
                    ])
    {
        foreach (s; [' ', 'h'])
        {
            auto result = split(input, s);

            assert(equal(result, split(input, [s])));
            //assert(equal(result, split(input, [s].filter!"true"())));                          //Not yet implemented
            assert(equal(result, split!((a) => a == s)(input)));

            //assert(equal!equal(result, split(input.filter!"true"(), s)));                      //Not yet implemented
            //assert(equal!equal(result, split(input.filter!"true"(), [s])));                    //Not yet implemented
            //assert(equal!equal(result, split(input.filter!"true"(), [s].filter!"true"())));    //Not yet implemented
            assert(equal!equal(result, split!((a) => a == s)(input.filter!"true"())));

            assert(equal(result, splitter(input, s)));
            assert(equal(result, splitter(input, [s])));
            //assert(equal(result, splitter(input, [s].filter!"true"())));                       //Not yet implemented
            assert(equal(result, splitter!((a) => a == s)(input)));

            //assert(equal!equal(result, splitter(input.filter!"true"(), s)));                   //Not yet implemented
            //assert(equal!equal(result, splitter(input.filter!"true"(), [s])));                 //Not yet implemented
            //assert(equal!equal(result, splitter(input.filter!"true"(), [s].filter!"true"()))); //Not yet implemented
            assert(equal!equal(result, splitter!((a) => a == s)(input.filter!"true"())));
        }
    }
}

// In same combinations substitute needs to calculate the auto-decoded length
// of its needles
private template hasDifferentAutodecoding(Range, Needles...)
{
    import std.meta : anySatisfy;
    /* iff
       - the needles needs auto-decoding, but the incoming range doesn't (or vice versa)
       - both (range, needle) need auto-decoding and don't share the same common type
    */
    enum needlesAreNarrow = anySatisfy!(isNarrowString, Needles);
    enum sourceIsNarrow = isNarrowString!Range;
    enum hasDifferentAutodecoding = sourceIsNarrow != needlesAreNarrow ||
                                    (sourceIsNarrow && needlesAreNarrow &&
                                    is(CommonType!(Range, Needles) == void));
}

@safe nothrow @nogc pure unittest
{
    import std.meta : AliasSeq; // used for better clarity

    static assert(!hasDifferentAutodecoding!(string, AliasSeq!(string, string)));
    static assert(!hasDifferentAutodecoding!(wstring, AliasSeq!(wstring, wstring)));
    static assert(!hasDifferentAutodecoding!(dstring, AliasSeq!(dstring, dstring)));

    // the needles needs auto-decoding, but the incoming range doesn't (or vice versa)
    static assert(hasDifferentAutodecoding!(string, AliasSeq!(wstring, wstring)));
    static assert(hasDifferentAutodecoding!(string, AliasSeq!(dstring, dstring)));
    static assert(hasDifferentAutodecoding!(wstring, AliasSeq!(string, string)));
    static assert(hasDifferentAutodecoding!(wstring, AliasSeq!(dstring, dstring)));
    static assert(hasDifferentAutodecoding!(dstring, AliasSeq!(string, string)));
    static assert(hasDifferentAutodecoding!(dstring, AliasSeq!(wstring, wstring)));

    // both (range, needle) need auto-decoding and don't share the same common type
    static foreach (T; AliasSeq!(string, wstring, dstring))
    {
        static assert(hasDifferentAutodecoding!(T, AliasSeq!(wstring, string)));
        static assert(hasDifferentAutodecoding!(T, AliasSeq!(dstring, string)));
        static assert(hasDifferentAutodecoding!(T, AliasSeq!(wstring, dstring)));
    }
}

// substitute
/**
Returns a range with all occurrences of `substs` in `r`.
replaced with their substitution.

Single value replacements (`'ö'.substitute!('ä', 'a', 'ö', 'o', 'ü', 'u)`) are
supported as well and in $(BIGOH 1).

Params:
    r = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    value = a single value which can be substituted in $(BIGOH 1)
    substs = a set of replacements/substitutions
    pred = the equality function to test if element(s) are equal to
    a substitution

Returns: a range with the substitutions replaced.

See_Also:
$(REF replace, std, array) for an eager replace algorithm or
$(REF translate, std, string), and $(REF tr, std, string)
for string algorithms with translation tables.
*/
template substitute(substs...)
if (substs.length >= 2 && isExpressions!substs)
{
    import std.range.primitives : ElementType;
    import std.traits : CommonType;

    static assert(!(substs.length & 1), "The number of substitution parameters must be even");

    /**
      Substitute single values with compile-time substitution mappings.
      Complexity: $(BIGOH 1) due to D's `switch` guaranteeing $(BIGOH 1);
    */
    auto substitute(Value)(Value value)
    if (isInputRange!Value || !is(CommonType!(Value, typeof(substs[0])) == void))
    {
        static if (isInputRange!Value)
        {
            static if (!is(CommonType!(ElementType!Value, typeof(substs[0])) == void))
            {
                // Substitute single range elements with compile-time substitution mappings
                return value.map!(a => substitute(a));
            }
            else static if (isInputRange!Value &&
                    !is(CommonType!(ElementType!Value, ElementType!(typeof(substs[0]))) == void))
            {
                // not implemented yet, fallback to runtime variant for now
                return .substitute(value, substs);
            }
            else
            {
                static assert(0, `Compile-time substitutions must be elements or ranges of the same type of ` ~
                    Value.stringof ~ `.`);
            }
        }
        // Substitute single values with compile-time substitution mappings.
        else // static if (!is(CommonType!(Value, typeof(substs[0])) == void))
        {
            switch (value)
            {
                static foreach (i; 0 .. substs.length / 2)
                    case substs[2 * i]:
                        return substs[2 * i + 1];

                default: return value;
            }
        }
    }
}

/// ditto
auto substitute(alias pred = (a, b) => a == b, R, Substs...)(R r, Substs substs)
if (isInputRange!R && Substs.length >= 2 && !is(CommonType!(Substs) == void))
{
    import std.range.primitives : ElementType;
    import std.meta : allSatisfy;
    import std.traits : CommonType;

    static assert(!(Substs.length & 1), "The number of substitution parameters must be even");

    enum n = Substs.length / 2;

    // Substitute individual elements
    static if (!is(CommonType!(ElementType!R, Substs) == void))
    {
        import std.functional : binaryFun;

        // Imitate a value closure to be @nogc
        static struct ReplaceElement
        {
            private Substs substs;

            this(Substs substs)
            {
                this.substs = substs;
            }

            auto opCall(E)(E e)
            {
                static foreach (i; 0 .. n)
                    if (binaryFun!pred(e, substs[2 * i]))
                        return substs[2 * i + 1];

                return e;
            }
        }
        auto er = ReplaceElement(substs);
        return r.map!er;
    }
    // Substitute subranges
    else static if (!is(CommonType!(ElementType!R, ElementType!(Substs[0])) == void)  &&
                        allSatisfy!(isForwardRange, Substs))
    {
        import std.range : choose, take;
        import std.meta : Stride;

        auto replaceElement(E)(E e)
        {
            alias ReturnA = typeof(e[0]);
            alias ReturnB = typeof(substs[0 .. 1].take(1));

            // 1-based index
            const auto hitNr = e[1];
            switch (hitNr)
            {
                // no hit
                case 0:
                    // use choose trick for non-common range
                    static if (is(CommonType!(ReturnA, ReturnB) == void))
                        return choose(1, e[0], ReturnB.init);
                    else
                        return e[0];

                // all replacements
                static foreach (i; 0 .. n)
                    case i + 1:
                        // use choose trick for non-common ranges
                        static if (is(CommonType!(ReturnA, ReturnB) == void))
                            return choose(0, e[0], substs[2 * i + 1].take(size_t.max));
                        else
                            return substs[2 * i + 1].take(size_t.max);
                default:
                    assert(0, "hitNr should always be found.");
            }
        }

        alias Ins = Stride!(2, Substs);

        static struct SubstituteSplitter
        {
            import std.range : drop;
            import std.typecons : Tuple;

            private
            {
                typeof(R.init.drop(0)) rest;
                Ins needles;

                typeof(R.init.take(0)) skip; // skip before next hit
                alias Hit = size_t; // 0 iff no hit, otherwise hit in needles[index-1]
                alias E = Tuple!(typeof(skip), Hit);
                Hit hitNr; // hit number: 0 means no hit, otherwise index+1 to needles that matched
                bool hasHit; // is there a replacement hit which should be printed?

                enum hasDifferentAutodecoding = .hasDifferentAutodecoding!(typeof(rest), Ins);

                // calculating the needle length for narrow strings might be expensive -> cache it
                 static if (hasDifferentAutodecoding)
                     ptrdiff_t[n] needleLengths = -1;
            }

            this(R haystack, Ins needles)
            {
                this.rest = haystack.drop(0);
                this.needles = needles;
                if (!haystack.empty)
                {
                    hasHit = true;
                    popFront;
                }
                static if (hasNested!(typeof(skip)))
                    skip = rest.take(0);
            }

            /*  If `skip` is non-empty, it's returned as (skip, 0) tuple
                otherwise a similar (<empty>, hitNr) tuple is returned.
                `replaceElement` maps based on the second item (`hitNr`).
            */
            @property auto ref front()
            {
                assert(!empty, "Attempting to fetch the front of an empty substitute.");
                return !skip.empty ? E(skip, 0) : E(typeof(skip).init, hitNr);
            }

            static if (isInfinite!R)
                enum empty = false; // propagate infiniteness
            else
                @property bool empty()
                {
                    return skip.empty && !hasHit;
                }

            /* If currently in a skipping phase => reset.
               Otherwise try to find the next occurrence of `needles`
                  If valid match
                    - if there are elements before the match, set skip with these elements
                      (on the next popFront, the range will be in the skip state once)
                    - `rest`: advance to the end of the match
                    - set hasHit
               Otherwise skip to the end
            */
            void popFront()
            {
                assert(!empty, "Attempting to popFront an empty substitute.");
                if (!skip.empty)
                {
                    skip = typeof(skip).init; // jump over skip
                }
                else
                {
                    import std.algorithm.searching : countUntil, find;

                    auto match = rest.find!pred(needles);

                    static if (needles.length >= 2) // variadic version of find (returns a tuple)
                    {
                        // find with variadic needles returns a (range, needleNr) tuple
                        // needleNr is a 1-based index
                        auto hitValue = match[0];
                        hitNr = match[1];
                    }
                    else
                    {
                        // find with one needle returns the range
                        auto hitValue = match;
                        hitNr = match.empty ? 0 : 1;
                    }

                    if (hitNr == 0) // no more hits
                    {
                        skip = rest.take(size_t.max);
                        hasHit = false;
                        rest = typeof(rest).init;
                    }
                    else
                    {
                        auto hitLength = size_t.max;
                        switchL: switch (hitNr - 1)
                        {
                            static foreach (i; 0 .. n)
                            {
                                case i:
                                    static if (hasDifferentAutodecoding)
                                    {
                                        import std.utf : codeLength;

                                        // cache calculated needle length
                                        if (needleLengths[i] != -1)
                                            hitLength = needleLengths[i];
                                        else
                                            hitLength = needleLengths[i] = codeLength!dchar(needles[i]);
                                    }
                                    else
                                    {
                                        hitLength = needles[i].length;
                                    }
                                    break switchL;
                            }
                            default:
                                assert(0, "hitNr should always be found");
                        }

                        const pos = rest.countUntil(hitValue);
                        if (pos > 0) // match not at start of rest
                            skip = rest.take(pos);

                        hasHit = true;

                        // iff the source range and the substitutions are narrow strings,
                        // we can avoid calling the auto-decoding `popFront` (via drop)
                        static if (isNarrowString!(typeof(hitValue)) && !hasDifferentAutodecoding)
                            rest = hitValue[hitLength .. $];
                        else
                            rest = hitValue.drop(hitLength);
                    }
                }
            }
        }

        // extract inputs
        Ins ins;
        static foreach (i; 0 .. n)
            ins[i] = substs[2 * i];

        return SubstituteSplitter(r, ins)
                .map!(a => replaceElement(a))
                .joiner;
    }
    else
    {
        static assert(0, "The substitutions must either substitute a single element or a save-able subrange.");
    }
}

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

    // substitute single elements
    assert("do_it".substitute('_', ' ').equal("do it"));

    // substitute multiple, single elements
    assert("do_it".substitute('_', ' ',
                               'd', 'g',
                               'i', 't',
                               't', 'o')
                  .equal("go to"));

    // substitute subranges
    assert("do_it".substitute("_", " ",
                              "do", "done")
                  .equal("done it"));

    // substitution works for any ElementType
    int[] x = [1, 2, 3];
    auto y = x.substitute(1, 0.1);
    assert(y.equal([0.1, 2, 3]));
    static assert(is(typeof(y.front) == double));

    import std.range : retro;
    assert([1, 2, 3].substitute(1, 0.1).retro.equal([3, 2, 0.1]));
}

/// Use the faster compile-time overload
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    // substitute subranges of a range
    assert("apple_tree".substitute!("apple", "banana",
                                    "tree", "shrub").equal("banana_shrub"));

    // substitute subranges of a range
    assert("apple_tree".substitute!('a', 'b',
                                    't', 'f').equal("bpple_free"));

    // substitute values
    assert('a'.substitute!('a', 'b', 't', 'f') == 'b');
}

/// Multiple substitutes
@safe pure unittest
{
    import std.algorithm.comparison : equal;
    import std.range.primitives : ElementType;

    int[3] x = [1, 2, 3];
    auto y = x[].substitute(1, 0.1)
                .substitute(0.1, 0.2);
    static assert(is(typeof(y.front) == double));
    assert(y.equal([0.2, 2, 3]));

    auto z = "42".substitute('2', '3')
                 .substitute('3', '1');
    static assert(is(ElementType!(typeof(z)) == dchar));
    assert(equal(z, "41"));
}

// Test the first example with compile-time overloads
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    // substitute single elements
    assert("do_it".substitute!('_', ' ').equal("do it"));

    // substitute multiple, single elements
    assert("do_it".substitute!('_', ' ',
                               'd', 'g',
                               'i', 't',
                               't', 'o')
                  .equal(`go to`));

    // substitute subranges
    assert("do_it".substitute!("_", " ",
                               "do", "done")
                  .equal("done it"));

    // substitution works for any ElementType
    int[3] x = [1, 2, 3];
    auto y = x[].substitute!(1, 0.1);
    assert(y.equal([0.1, 2, 3]));
    static assert(is(typeof(y.front) == double));

    import std.range : retro;
    assert([1, 2, 3].substitute!(1, 0.1).retro.equal([3, 2, 0.1]));
}

// test infinite ranges
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    import std.range : cycle, take;

    int[] x = [1, 2, 3];
    assert(x.cycle.substitute!(1, 0.1).take(4).equal([0.1, 2, 3, 0.1]));
    assert(x.cycle.substitute(1, 0.1).take(4).equal([0.1, 2, 3, 0.1]));
}

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

    foreach (R; AllDummyRanges)
    {
        assert(R.init
                .substitute!(2, 22, 3, 33, 5, 55, 9, 99)
                .equal([1, 22, 33, 4, 55, 6, 7, 8, 99, 10]));

        assert(R.init
                .substitute(2, 22, 3, 33, 5, 55, 9, 99)
                .equal([1, 22, 33, 4, 55, 6, 7, 8, 99, 10]));
    }
}

// test multiple replacements
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert("alpha.beta.gamma"
            .substitute("alpha", "1",
                        "gamma", "3",
                        "beta", "2").equal("1.2.3"));

    assert("alpha.beta.gamma."
            .substitute("alpha", "1",
                        "gamma", "3",
                        "beta", "2").equal("1.2.3."));

    assert("beta.beta.beta"
            .substitute("alpha", "1",
                        "gamma", "3",
                        "beta", "2").equal("2.2.2"));

    assert("alpha.alpha.alpha"
            .substitute("alpha", "1",
                        "gamma", "3",
                        "beta", "2").equal("1.1.1"));
}

// test combination of subrange + element replacement
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert(("abcDe".substitute("a", "AA",
                               "b", "DD")
                   .substitute('A', 'y',
                               'D', 'x',
                               'e', '1'))
           .equal("yyxxcx1"));
}

// test const + immutable storage groups
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    auto xyz_abc(T)(T value)
    {
        immutable a = "a";
        const b = "b";
        auto c = "c";
        return value.substitute!("x", a,
                                 "y", b,
                                 "z", c);
    }
    assert(xyz_abc("_x").equal("_a"));
    assert(xyz_abc(".y.").equal(".b."));
    assert(xyz_abc("z").equal("c"));
    assert(xyz_abc("w").equal("w"));
}

// test with narrow strings (auto-decoding) and subranges
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert("äöü€".substitute("ä", "b", "ü", "u").equal("böu€"));
    assert("äöü€".substitute!("ä", "b", "ü", "u").equal("böu€"));
    assert("ä...öü€".substitute("ä", "b", "ü", "u").equal("b...öu€"));

    auto expected = "emoticons😄😅.😇😈Rock";
    assert("emoticons😄😅😆😇😈rock"
            .substitute("r", "R", "😆", ".").equal(expected));
    assert("emoticons😄😅😆😇😈rock"
            .substitute!("r", "R", "😆", ".").equal(expected));
}

// test with narrow strings (auto-decoding) and single elements
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert("äöü€".substitute('ä', 'b', 'ü', 'u').equal("böu€"));
    assert("äöü€".substitute!('ä', 'b', 'ü', 'u').equal("böu€"));

    auto expected = "emoticons😄😅.😇😈Rock";
    assert("emoticons😄😅😆😇😈rock"
            .substitute('r', 'R', '😆', '.').equal(expected));
    assert("emoticons😄😅😆😇😈rock"
            .substitute!('r', 'R', '😆', '.').equal(expected));
}

// test auto-decoding {n,w,d} strings X {n,w,d} strings
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert("ääöü€".substitute("ä", "b", "ü", "u").equal("bböu€"));
    assert("ääöü€".substitute("ä"w, "b"w, "ü"w, "u"w).equal("bböu€"));
    assert("ääöü€".substitute("ä"d, "b"d, "ü"d, "u"d).equal("bböu€"));

    assert("ääöü€"w.substitute("ä", "b", "ü", "u").equal("bböu€"));
    assert("ääöü€"w.substitute("ä"w, "b"w, "ü"w, "u"w).equal("bböu€"));
    assert("ääöü€"w.substitute("ä"d, "b"d, "ü"d, "u"d).equal("bböu€"));

    assert("ääöü€"d.substitute("ä", "b", "ü", "u").equal("bböu€"));
    assert("ääöü€"d.substitute("ä"w, "b"w, "ü"w, "u"w).equal("bböu€"));
    assert("ääöü€"d.substitute("ä"d, "b"d, "ü"d, "u"d).equal("bböu€"));

    // auto-decoding is done before by a different range
    assert("ääöü€".filter!(a => true).substitute("ä", "b", "ü", "u").equal("bböu€"));
    assert("ääöü€".filter!(a => true).substitute("ä"w, "b"w, "ü"w, "u"w).equal("bböu€"));
    assert("ääöü€".filter!(a => true).substitute("ä"d, "b"d, "ü"d, "u"d).equal("bböu€"));
}

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

    assert([1, 2, 3, 1, 1, 2].substitute(1, 0).equal([0, 2, 3, 0, 0, 2]));
    assert([1, 2, 3, 1, 1, 2].substitute!(1, 0).equal([0, 2, 3, 0, 0, 2]));
    assert([1, 2, 3, 1, 1, 2].substitute(1, 2, 2, 9).equal([2, 9, 3, 2, 2, 9]));
}

// test @nogc for single element replacements
@safe @nogc unittest
{
    import std.algorithm.comparison : equal;

    static immutable arr = [1, 2, 3, 1, 1, 2];
    static immutable expected = [0, 2, 3, 0, 0, 2];

    assert(arr.substitute!(1, 0).equal(expected));
    assert(arr.substitute(1, 0).equal(expected));
}

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

    static foreach (DummyType; AllDummyRanges)
    {{
        DummyType dummyRange;

        // single substitution
        dummyRange.substitute (2, 22).equal([1, 22, 3, 4, 5, 6, 7, 8, 9, 10]);
        dummyRange.substitute!(2, 22).equal([1, 22, 3, 4, 5, 6, 7, 8, 9, 10]);

        // multiple substitution
        dummyRange.substitute (2, 22, 5, 55, 7, 77).equal([1, 22, 3, 4, 55, 6, 77, 8, 9, 10]);
        dummyRange.substitute!(2, 22, 5, 55, 7, 77).equal([1, 22, 3, 4, 55, 6, 77, 8, 9, 10]);
    }}
}

// https://issues.dlang.org/show_bug.cgi?id=19207
@safe pure nothrow unittest
{
    import std.algorithm.comparison : equal;
    assert([1, 2, 3, 4].substitute([1], [7]).equal([7, 2, 3, 4]));
    assert([1, 2, 3, 4].substitute([2], [7]).equal([1, 7, 3, 4]));
    assert([1, 2, 3, 4].substitute([4], [7]).equal([1, 2, 3, 7]));
    assert([1, 2, 3, 4].substitute([2, 3], [7]).equal([1, 7, 4]));
    assert([1, 2, 3, 4].substitute([3, 4], [7, 8]).equal([1, 2, 7, 8]));
}

// tests recognizing empty base ranges
nothrow pure @safe unittest
{
    import std.utf : byCodeUnit;
    import std.algorithm.comparison : equal;

    assert("".byCodeUnit.substitute('4', 'A').empty);
    assert("".byCodeUnit.substitute('0', 'O', '5', 'S', '1', 'l').empty);
    assert("".byCodeUnit.substitute("PKM".byCodeUnit, "PoKeMon".byCodeUnit).empty);
    assert("".byCodeUnit.substitute
    (   "ding".byCodeUnit,
        "dong".byCodeUnit,
        "click".byCodeUnit,
        "clack".byCodeUnit,
        "ping".byCodeUnit,
        "latency".byCodeUnit
    ).empty);
}

// sum
/**
Sums elements of `r`, which must be a finite
$(REF_ALTTEXT input range, isInputRange, std,range,primitives). Although
conceptually `sum(r)` is equivalent to $(LREF fold)!((a, b) => a +
b)(r, 0), `sum` uses specialized algorithms to maximize accuracy,
as follows.

$(UL
$(LI If $(REF ElementType, std,range,primitives)!R is a floating-point
type and `R` is a
$(REF_ALTTEXT random-access range, isRandomAccessRange, std,range,primitives) with
length and slicing, then `sum` uses the
$(HTTP en.wikipedia.org/wiki/Pairwise_summation, pairwise summation)
algorithm.)
$(LI If `ElementType!R` is a floating-point type and `R` is a
finite input range (but not a random-access range with slicing), then
`sum` uses the $(HTTP en.wikipedia.org/wiki/Kahan_summation,
Kahan summation) algorithm.)
$(LI In all other cases, a simple element by element addition is done.)
)

For floating point inputs, calculations are made in
$(DDLINK spec/type, Types, `real`)
precision for `real` inputs and in `double` precision otherwise
(Note this is a special case that deviates from `fold`'s behavior,
which would have kept `float` precision for a `float` range).
For all other types, the calculations are done in the same type obtained
from from adding two elements of the range, which may be a different
type from the elements themselves (for example, in case of
$(DDSUBLINK spec/type,integer-promotions, integral promotion)).

A seed may be passed to `sum`. Not only will this seed be used as an initial
value, but its type will override all the above, and determine the algorithm
and precision used for summation. If a seed is not passed, one is created with
the value of `typeof(r.front + r.front)(0)`, or `typeof(r.front + r.front).zero`
if no constructor exists that takes an int.

Note that these specialized summing algorithms execute more primitive operations
than vanilla summation. Therefore, if in certain cases maximum speed is required
at expense of precision, one can use `fold!((a, b) => a + b)(r, 0)`, which
is not specialized for summation.

Params:
    seed = the initial value of the summation
    r = a finite input range

Returns:
    The sum of all the elements in the range r.
 */
auto sum(R)(R r)
if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front)))
{
    alias E = Unqual!(ElementType!R);
    static if (isFloatingPoint!E)
        alias Seed = typeof(E.init  + 0.0); //biggest of double/real
    else
        alias Seed = typeof(r.front + r.front);
    static if (is(typeof(Unqual!Seed(0))))
        enum seedValue = Unqual!Seed(0);
    else static if (is(typeof({ Unqual!Seed tmp = Seed.zero; })))
        enum Unqual!Seed seedValue = Seed.zero;
    else
        static assert(false,
            "Could not initiate an initial value for " ~ (Unqual!Seed).stringof
            ~ ". Please supply an initial value manually.");
    return sum(r, seedValue);
}
/// ditto
auto sum(R, E)(R r, E seed)
if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front)))
{
    static if (isFloatingPoint!E)
    {
        static if (hasLength!R && hasSlicing!R)
        {
            if (r.empty) return seed;
            return seed + sumPairwise!E(r);
        }
        else
            return sumKahan!E(seed, r);
    }
    else
    {
        return reduce!"a + b"(seed, r);
    }
}

/// Ditto
@safe pure nothrow unittest
{
    import std.range;

    //simple integral sumation
    assert(sum([ 1, 2, 3, 4]) == 10);

    //with integral promotion
    assert(sum([false, true, true, false, true]) == 3);
    assert(sum(ubyte.max.repeat(100)) == 25500);

    //The result may overflow
    assert(uint.max.repeat(3).sum()           ==  4294967293U );
    //But a seed can be used to change the sumation primitive
    assert(uint.max.repeat(3).sum(ulong.init) == 12884901885UL);

    //Floating point sumation
    assert(sum([1.0, 2.0, 3.0, 4.0]) == 10);

    //Floating point operations have double precision minimum
    static assert(is(typeof(sum([1F, 2F, 3F, 4F])) == double));
    assert(sum([1F, 2, 3, 4]) == 10);

    //Force pair-wise floating point sumation on large integers
    import std.math.operations : isClose;
    assert(iota(ulong.max / 2, ulong.max / 2 + 4096).sum(0.0)
               .isClose((ulong.max / 2) * 4096.0 + 4096^^2 / 2));
}

// Pairwise summation http://en.wikipedia.org/wiki/Pairwise_summation
private auto sumPairwise(F, R)(R data)
if (isInputRange!R && !isInfinite!R)
{
    import core.bitop : bsf;
    // Works for r with at least length < 2^^(64 + log2(16)), in keeping with the use of size_t
    // elsewhere in std.algorithm and std.range on 64 bit platforms. The 16 in log2(16) comes
    // from the manual unrolling in sumPairWise16
    F[64] store = void;
    size_t idx = 0;

    void collapseStore(T)(T k)
    {
        auto lastToKeep = idx - cast(uint) bsf(k+1);
        while (idx > lastToKeep)
        {
            store[idx - 1] += store[idx];
            --idx;
        }
    }

    static if (hasLength!R)
    {
        foreach (k; 0 .. data.length / 16)
        {
            static if (isRandomAccessRange!R && hasSlicing!R)
            {
                store[idx] = sumPairwise16!F(data);
                data = data[16 .. data.length];
            }
            else store[idx] = sumPairwiseN!(16, false, F)(data);

            collapseStore(k);
            ++idx;
        }

        size_t i = 0;
        foreach (el; data)
        {
            store[idx] = el;
            collapseStore(i);
            ++idx;
            ++i;
        }
    }
    else
    {
        size_t k = 0;
        while (!data.empty)
        {
            store[idx] = sumPairwiseN!(16, true, F)(data);
            collapseStore(k);
            ++idx;
            ++k;
        }
    }

    F s = store[idx - 1];
    foreach_reverse (j; 0 .. idx - 1)
        s += store[j];

    return s;
}

private auto sumPairwise16(F, R)(R r)
if (isRandomAccessRange!R)
{
    return (((cast(F) r[ 0] + r[ 1]) + (cast(F) r[ 2] + r[ 3]))
          + ((cast(F) r[ 4] + r[ 5]) + (cast(F) r[ 6] + r[ 7])))
         + (((cast(F) r[ 8] + r[ 9]) + (cast(F) r[10] + r[11]))
          + ((cast(F) r[12] + r[13]) + (cast(F) r[14] + r[15])));
}

private auto sumPair(bool needEmptyChecks, F, R)(ref R r)
if (isForwardRange!R && !isRandomAccessRange!R)
{
    static if (needEmptyChecks) if (r.empty) return F(0);
    F s0 = r.front;
    r.popFront();
    static if (needEmptyChecks) if (r.empty) return s0;
    s0 += r.front;
    r.popFront();
    return s0;
}

private auto sumPairwiseN(size_t N, bool needEmptyChecks, F, R)(ref R r)
if (isForwardRange!R && !isRandomAccessRange!R)
{
    import std.math.traits : isPowerOf2;
    static assert(isPowerOf2(N), "N must be a power of 2");
    static if (N == 2) return sumPair!(needEmptyChecks, F)(r);
    else return sumPairwiseN!(N/2, needEmptyChecks, F)(r)
        + sumPairwiseN!(N/2, needEmptyChecks, F)(r);
}

// Kahan algo http://en.wikipedia.org/wiki/Kahan_summation_algorithm
private auto sumKahan(Result, R)(Result result, R r)
{
    static assert(isFloatingPoint!Result && isMutable!Result, "The type of"
            ~ " Result must be a mutable floating point, not "
            ~ Result.stringof);
    Result c = 0;
    for (; !r.empty; r.popFront())
    {
        immutable y = r.front - c;
        immutable t = result + y;
        c = (t - result) - y;
        result = t;
    }
    return result;
}

@safe pure nothrow unittest
{
    static assert(is(typeof(sum([cast( byte) 1])) ==  int));
    static assert(is(typeof(sum([cast(ubyte) 1])) ==  int));
    static assert(is(typeof(sum([  1,   2,   3,   4])) ==  int));
    static assert(is(typeof(sum([ 1U,  2U,  3U,  4U])) == uint));
    static assert(is(typeof(sum([ 1L,  2L,  3L,  4L])) ==  long));
    static assert(is(typeof(sum([1UL, 2UL, 3UL, 4UL])) == ulong));

    int[] empty;
    assert(sum(empty) == 0);
    assert(sum([42]) == 42);
    assert(sum([42, 43]) == 42 + 43);
    assert(sum([42, 43, 44]) == 42 + 43 + 44);
    assert(sum([42, 43, 44, 45]) == 42 + 43 + 44 + 45);
}

@safe pure nothrow unittest
{
    static assert(is(typeof(sum([1.0, 2.0, 3.0, 4.0])) == double));
    static assert(is(typeof(sum([ 1F,  2F,  3F,  4F])) == double));
    const(float[]) a = [1F, 2F, 3F, 4F];
    assert(sum(a) == 10F);
    static assert(is(typeof(sum(a)) == double));

    double[] empty;
    assert(sum(empty) == 0);
    assert(sum([42.]) == 42);
    assert(sum([42., 43.]) == 42 + 43);
    assert(sum([42., 43., 44.]) == 42 + 43 + 44);
    assert(sum([42., 43., 44., 45.5]) == 42 + 43 + 44 + 45.5);
}

@safe pure nothrow unittest
{
    import std.container;
    static assert(is(typeof(sum(SList!float()[])) == double));
    static assert(is(typeof(sum(SList!double()[])) == double));
    static assert(is(typeof(sum(SList!real()[])) == real));

    assert(sum(SList!double()[]) == 0);
    assert(sum(SList!double(1)[]) == 1);
    assert(sum(SList!double(1, 2)[]) == 1 + 2);
    assert(sum(SList!double(1, 2, 3)[]) == 1 + 2 + 3);
    assert(sum(SList!double(1, 2, 3, 4)[]) == 10);
}

// https://issues.dlang.org/show_bug.cgi?id=12434
@safe pure nothrow unittest
{
    immutable a = [10, 20];
    auto s1 = sum(a);
    assert(s1 == 30);
    auto s2 = a.map!(x => x).sum;
    assert(s2 == 30);
}

@system unittest
{
    import std.bigint;
    import std.range;

    immutable BigInt[] a = BigInt("1_000_000_000_000_000_000").repeat(10).array();
    immutable ulong[]  b = (ulong.max/2).repeat(10).array();
    auto sa = a.sum();
    auto sb = b.sum(BigInt(0)); //reduce ulongs into bigint
    assert(sa == BigInt("10_000_000_000_000_000_000"));
    assert(sb == (BigInt(ulong.max/2) * 10));
}

@safe pure nothrow @nogc unittest
{
    import std.range;
    foreach (n; iota(50))
        assert(repeat(1.0, n).sum == n);
}

// Issue 19525
@safe unittest
{
    import std.datetime : Duration, minutes;
    assert([1.minutes].sum() == 1.minutes);
}

/**
Finds the mean (colloquially known as the average) of a range.

For built-in numerical types, accurate Knuth & Welford mean calculation
is used. For user-defined types, element by element summation is used.
Additionally an extra parameter `seed` is needed in order to correctly
seed the summation with the equivalent to `0`.

The first overload of this function will return `T.init` if the range
is empty. However, the second overload will return `seed` on empty ranges.

This function is $(BIGOH r.length).

Params:
    T = The type of the return value.
    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    seed = For user defined types. Should be equivalent to `0`.

Returns:
    The mean of `r` when `r` is non-empty.
*/
T mean(T = double, R)(R r)
if (isInputRange!R &&
    isNumeric!(ElementType!R) &&
    !isInfinite!R)
{
    if (r.empty)
        return T.init;

    Unqual!T meanRes = 0;
    size_t i = 1;

    // Knuth & Welford mean calculation
    // division per element is slower, but more accurate
    for (; !r.empty; r.popFront())
    {
        T delta = r.front - meanRes;
        meanRes += delta / i++;
    }

    return meanRes;
}

/// ditto
auto mean(R, T)(R r, T seed)
if (isInputRange!R &&
    !isNumeric!(ElementType!R) &&
    is(typeof(r.front + seed)) &&
    is(typeof(r.front / size_t(1))) &&
    !isInfinite!R)
{
    import std.algorithm.iteration : sum, reduce;

    // per item division vis-a-vis the previous overload is too
    // inaccurate for integer division, which the user defined
    // types might be representing
    static if (hasLength!R)
    {
        if (r.length == 0)
            return seed;

        return sum(r, seed) / r.length;
    }
    else
    {
        import std.typecons : tuple;

        if (r.empty)
            return seed;

        auto pair = reduce!((a, b) => tuple(a[0] + 1, a[1] + b))
            (tuple(size_t(0), seed), r);
        return pair[1] / pair[0];
    }
}

///
@safe @nogc pure nothrow unittest
{
    import std.math.operations : isClose;
    import std.math.traits : isNaN;

    static immutable arr1 = [1, 2, 3];
    static immutable arr2 = [1.5, 2.5, 12.5];

    assert(arr1.mean.isClose(2));
    assert(arr2.mean.isClose(5.5));

    assert(arr1[0 .. 0].mean.isNaN);
}

@safe pure nothrow unittest
{
    import std.internal.test.dummyrange : ReferenceInputRange;
    import std.math.operations : isClose;

    auto r1 = new ReferenceInputRange!int([1, 2, 3]);
    assert(r1.mean.isClose(2));

    auto r2 = new ReferenceInputRange!double([1.5, 2.5, 12.5]);
    assert(r2.mean.isClose(5.5));
}

// Test user defined types
@system pure unittest
{
    import std.bigint : BigInt;
    import std.internal.test.dummyrange : ReferenceInputRange;
    import std.math.operations : isClose;

    auto bigint_arr = [BigInt("1"), BigInt("2"), BigInt("3"), BigInt("6")];
    auto bigint_arr2 = new ReferenceInputRange!BigInt([
        BigInt("1"), BigInt("2"), BigInt("3"), BigInt("6")
    ]);
    assert(bigint_arr.mean(BigInt(0)) == BigInt("3"));
    assert(bigint_arr2.mean(BigInt(0)) == BigInt("3"));

    BigInt[] bigint_arr3 = [];
    assert(bigint_arr3.mean(BigInt(0)) == BigInt(0));

    struct MyFancyDouble
    {
       double v;
       alias v this;
    }

    // both overloads
    auto d_arr = [MyFancyDouble(10), MyFancyDouble(15), MyFancyDouble(30)];
    assert(mean!(double)(cast(double[]) d_arr).isClose(18.33333333));
    assert(mean(d_arr, MyFancyDouble(0)).isClose(18.33333333));
}

// uniq
/**
Lazily iterates unique consecutive elements of the given range, which is
assumed to be sorted (functionality akin to the
$(HTTP wikipedia.org/wiki/_Uniq, _uniq) system
utility). Equivalence of elements is assessed by using the predicate
`pred`, by default `"a == b"`. The predicate is passed to
$(REF binaryFun, std,functional), and can either accept a string, or any callable
that can be executed via `pred(element, element)`. If the given range is
bidirectional, `uniq` also yields a
$(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives).

Params:
    pred = Predicate for determining equivalence between range elements.
    r = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of
        elements to filter.

Returns:
    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of
    consecutively unique elements in the original range. If `r` is also a
    forward range or bidirectional range, the returned range will be likewise.
*/
auto uniq(alias pred = "a == b", Range)(Range r)
if (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))
{
    return UniqResult!(binaryFun!pred, Range)(r);
}

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

    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
    assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));

    // Filter duplicates in-place using copy
    arr.length -= arr.uniq().copy(arr).length;
    assert(arr == [ 1, 2, 3, 4, 5 ]);

    // Note that uniqueness is only determined consecutively; duplicated
    // elements separated by an intervening different element will not be
    // eliminated:
    assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1]));
}

private struct UniqResult(alias pred, Range)
{
    Range _input;

    this(Range input)
    {
        _input = input;
    }

    auto opSlice()
    {
        return this;
    }

    void popFront()
    {
        assert(!empty, "Attempting to popFront an empty uniq.");
        auto last = _input.front;
        do
        {
            _input.popFront();
        }
        while (!_input.empty && pred(last, _input.front));
    }

    @property ElementType!Range front()
    {
        assert(!empty, "Attempting to fetch the front of an empty uniq.");
        return _input.front;
    }

    static if (isBidirectionalRange!Range)
    {
        void popBack()
        {
            assert(!empty, "Attempting to popBack an empty uniq.");
            auto last = _input.back;
            do
            {
                _input.popBack();
            }
            while (!_input.empty && pred(last, _input.back));
        }

        @property ElementType!Range back()
        {
            assert(!empty, "Attempting to fetch the back of an empty uniq.");
            return _input.back;
        }
    }

    static if (isInfinite!Range)
    {
        enum bool empty = false;  // Propagate infiniteness.
    }
    else
    {
        @property bool empty() { return _input.empty; }
    }

    static if (isForwardRange!Range)
    {
        @property typeof(this) save() {
            return typeof(this)(_input.save);
        }
    }
}

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

    int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
    auto r = uniq(arr);
    static assert(isForwardRange!(typeof(r)));

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

    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        auto u = uniq(d);
        assert(equal(u, [1,2,3,4,5,6,7,8,9,10]));

        static assert(d.rt == RangeType.Input || isForwardRange!(typeof(u)));

        static if (d.rt >= RangeType.Bidirectional)
        {
            assert(equal(retro(u), [10,9,8,7,6,5,4,3,2,1]));
        }
    }
}

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

    const(int)[] var = [0, 1, 1, 2];
    assert(var.uniq.equal([0, 1, 2]));
}

/**
Lazily computes all _permutations of `r` using $(HTTP
en.wikipedia.org/wiki/Heap%27s_algorithm, Heap's algorithm).

Params:
    Range = the range type
    r = the $(REF_ALTTEXT random access range, isRandomAccessRange, std,range,primitives)
    to find the permutations for.
Returns:
    A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
    of elements of which are an $(REF indexed, std,range) view into `r`.

Note:
    The elements of the resulting range reuse the same internal buffer of
    permutations, so each element is invalidated by `popFront`.  If copies of
    intermediate permutations are desired, they need to be individually copied,
    such as using `.map!(e => e.array)` to save them in individual, independent
    arrays.

See_Also:
$(REF nextPermutation, std,algorithm,sorting).
*/
Permutations!Range permutations(Range)(Range r)
{
    static assert(isRandomAccessRange!Range, Range.stringof,
            " must be a RandomAccessRange");
    static assert(hasLength!Range, Range.stringof
            , " must have a length");

    return typeof(return)(r);
}

/// ditto
struct Permutations(Range)
{
    static assert(isRandomAccessRange!Range, Range.stringof,
            " must be a RandomAccessRange");
    static assert(hasLength!Range, Range.stringof
            , " must have a length");

    private size_t[] _indices, _state;
    private Range _r;
    private bool _empty;

    ///
    this(Range r)
    {
        import std.array : array;
        import std.range : iota;

        this._r = r;
        _state = r.length ? new size_t[r.length-1] : null;
        _indices = iota(size_t(r.length)).array;
        _empty = r.length == 0;
    }
    private this(size_t[] indices, size_t[] state, Range r, bool empty_)
    {
        _indices = indices;
        _state = state;
        _r = r;
        _empty = empty_;
    }
    /// Returns: `true` if the range is empty, `false` otherwise.
    @property bool empty() const pure nothrow @safe @nogc
    {
        return _empty;
    }

    /// Returns: the front of the range
    @property auto front()
    {
        import std.range : indexed;
        return _r.indexed(_indices);
    }

    ///
    void popFront()
    {
        void next(int n)
        {
            import std.algorithm.mutation : swap;

            if (n > _indices.length)
            {
                _empty = true;
                return;
            }

            if (n % 2 == 1)
                swap(_indices[0], _indices[n-1]);
            else
                swap(_indices[_state[n-2]], _indices[n-1]);

            if (++_state[n-2] == n)
            {
                _state[n-2] = 0;
                next(n+1);
            }
        }

        next(2);
    }
    /// Returns: an independent copy of the permutations range.
    auto save()
    {
        return typeof(this)(_indices.dup, _state.dup, _r.save, _empty);
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : iota;
    assert(equal!equal(iota(3).permutations,
        [[0, 1, 2],
         [1, 0, 2],
         [2, 0, 1],
         [0, 2, 1],
         [1, 2, 0],
         [2, 1, 0]]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : ElementType;
    import std.array : array;
    auto p = [1, 2, 3].permutations;
    auto x = p.save.front;
    p.popFront;
    auto y = p.front;
    assert(x != y);
}
