// 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: " ~ _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))
{
    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 (!_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"]));
}

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

    static 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" ]));
}

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