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

$(SCRIPT inhibitQuickIndex = 1;)
$(BOOKTABLE Cheat Sheet,
$(TR $(TH Function Name) $(TH Description))
$(T2 all,
        `all!"a > 0"([1, 2, 3, 4])` returns `true` because all elements
        are positive)
$(T2 any,
        `any!"a > 0"([1, 2, -3, -4])` returns `true` because at least one
        element is positive)
$(T2 balancedParens,
        `balancedParens("((1 + 1) / 2)", '(', ')')` returns `true` because the
        string has balanced parentheses.)
$(T2 boyerMooreFinder,
        `find("hello world", boyerMooreFinder("or"))` returns `"orld"`
        using the $(LINK2 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm,
        Boyer-Moore _algorithm).)
$(T2 canFind,
        `canFind("hello world", "or")` returns `true`.)
$(T2 count,
        Counts all elements or elements matching a predicate, specific element or sub-range.$(BR)
        `count([1, 2, 1])` returns `3`,
        `count([1, 2, 1], 1)` returns `2` and
        `count!"a < 0"([1, -3, 0])` returns `1`.)
$(T2 countUntil,
        `countUntil(a, b)` returns the number of steps taken in `a` to
        reach `b`; for example, `countUntil("hello!", "o")` returns
        `4`.)
$(T2 commonPrefix,
        `commonPrefix("parakeet", "parachute")` returns `"para"`.)
$(T2 endsWith,
        `endsWith("rocks", "ks")` returns `true`.)
$(T2 extrema, `extrema([2, 1, 3, 5, 4])` returns `[1, 5]`.)
$(T2 find,
        `find("hello world", "or")` returns `"orld"` using linear search.
        (For binary search refer to $(REF SortedRange, std,range).))
$(T2 findAdjacent,
        `findAdjacent([1, 2, 3, 3, 4])` returns the subrange starting with
        two equal adjacent elements, i.e. `[3, 3, 4]`.)
$(T2 findAmong,
        `findAmong("abcd", "qcx")` returns `"cd"` because `'c'` is
        among `"qcx"`.)
$(T2 findSkip,
        If `a = "abcde"`, then `findSkip(a, "x")` returns `false` and
        leaves `a` unchanged, whereas `findSkip(a, "c")` advances `a`
        to `"de"` and returns `true`.)
$(T2 findSplit,
        `findSplit("abcdefg", "de")` returns a tuple of three ranges `"abc"`,
        `"de"`, and `"fg"`.)
$(T2 findSplitAfter,
`findSplitAfter("abcdefg", "de")` returns a tuple of two ranges `"abcde"`
        and `"fg"`.)
$(T2 findSplitBefore,
        `findSplitBefore("abcdefg", "de")` returns a tuple of two ranges `"abc"`
        and `"defg"`.)
$(T2 minCount,
        `minCount([2, 1, 1, 4, 1])` returns `tuple(1, 3)`.)
$(T2 maxCount,
        `maxCount([2, 4, 1, 4, 1])` returns `tuple(4, 2)`.)
$(T2 minElement,
        Selects the minimal element of a range.
        `minElement([3, 4, 1, 2])` returns `1`.)
$(T2 maxElement,
        Selects the maximal element of a range.
        `maxElement([3, 4, 1, 2])` returns `4`.)
$(T2 minIndex,
        Index of the minimal element of a range.
        `minIndex([3, 4, 1, 2])` returns `2`.)
$(T2 maxIndex,
        Index of the maximal element of a range.
        `maxIndex([3, 4, 1, 2])` returns `1`.)
$(T2 minPos,
        `minPos([2, 3, 1, 3, 4, 1])` returns the subrange `[1, 3, 4, 1]`,
        i.e., positions the range at the first occurrence of its minimal
        element.)
$(T2 maxPos,
        `maxPos([2, 3, 1, 3, 4, 1])` returns the subrange `[4, 1]`,
        i.e., positions the range at the first occurrence of its maximal
        element.)
$(T2 skipOver,
        Assume `a = "blah"`. Then `skipOver(a, "bi")` leaves `a`
        unchanged and returns `false`, whereas `skipOver(a, "bl")`
        advances `a` to refer to `"ah"` and returns `true`.)
$(T2 startsWith,
        `startsWith("hello, world", "hello")` returns `true`.)
$(T2 until,
        Lazily iterates a range until a specific value is found.)
)

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/searching.d)

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

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

/++
Checks if $(I _all) of the elements satisfy `pred`.
 +/
template all(alias pred = "a")
{
    /++
    Returns `true` if and only if the input range `range` is empty
    or $(I _all) values found in `range` satisfy the predicate `pred`.
    Performs (at most) $(BIGOH range.length) evaluations of `pred`.
     +/
    bool all(Range)(Range range)
    if (isInputRange!Range &&
        (__traits(isTemplate, pred) || is(typeof(unaryFun!pred(range.front)))))
    {
        import std.functional : not;

        return find!(not!(unaryFun!pred))(range).empty;
    }
}

///
@safe unittest
{
    assert( all!"a & 1"([1, 3, 5, 7, 9]));
    assert(!all!"a & 1"([1, 2, 3, 5, 7, 9]));
}

/++
`all` can also be used without a predicate, if its items can be
evaluated to true or false in a conditional statement. This can be a
convenient way to quickly evaluate that $(I _all) of the elements of a range
are true.
 +/
@safe unittest
{
    int[3] vals = [5, 3, 18];
    assert( all(vals[]));
}

@safe unittest
{
    int x = 1;
    assert(all!(a => a > x)([2, 3]));
    assert(all!"a == 0x00c9"("\xc3\x89")); // Test that `all` auto-decodes.
}

/++
Checks if $(I _any) of the elements satisfies `pred`.
`!any` can be used to verify that $(I none) of the elements satisfy
`pred`.
This is sometimes called `exists` in other languages.
 +/
template any(alias pred = "a")
{
    /++
    Returns `true` if and only if the input range `range` is non-empty
    and $(I _any) value found in `range` satisfies the predicate
    `pred`.
    Performs (at most) $(BIGOH range.length) evaluations of `pred`.
     +/
    bool any(Range)(Range range)
    if (isInputRange!Range &&
        (__traits(isTemplate, pred) || is(typeof(unaryFun!pred(range.front)))))
    {
        return !find!pred(range).empty;
    }
}

///
@safe unittest
{
    import std.ascii : isWhite;
    assert( all!(any!isWhite)(["a a", "b b"]));
    assert(!any!(all!isWhite)(["a a", "b b"]));
}

/++
`any` can also be used without a predicate, if its items can be
evaluated to true or false in a conditional statement. `!any` can be a
convenient way to quickly test that $(I none) of the elements of a range
evaluate to true.
 +/
@safe unittest
{
    int[3] vals1 = [0, 0, 0];
    assert(!any(vals1[])); //none of vals1 evaluate to true

    int[3] vals2 = [2, 0, 2];
    assert( any(vals2[]));
    assert(!all(vals2[]));

    int[3] vals3 = [3, 3, 3];
    assert( any(vals3[]));
    assert( all(vals3[]));
}

@safe unittest
{
    auto a = [ 1, 2, 0, 4 ];
    assert(any!"a == 2"(a));
    assert(any!"a == 0x3000"("\xe3\x80\x80")); // Test that `any` auto-decodes.
}

// balancedParens
/**
Checks whether `r` has "balanced parentheses", i.e. all instances
of `lPar` are closed by corresponding instances of `rPar`. The
parameter `maxNestingLevel` controls the nesting level allowed. The
most common uses are the default or `0`. In the latter case, no
nesting is allowed.

Params:
    r = The range to check.
    lPar = The element corresponding with a left (opening) parenthesis.
    rPar = The element corresponding with a right (closing) parenthesis.
    maxNestingLevel = The maximum allowed nesting level.

Returns:
    true if the given range has balanced parenthesis within the given maximum
    nesting level; false otherwise.
*/
bool balancedParens(Range, E)(Range r, E lPar, E rPar,
        size_t maxNestingLevel = size_t.max)
if (isInputRange!(Range) && is(typeof(r.front == lPar)))
{
    size_t count;

    static if (is(immutable ElementEncodingType!Range == immutable E) && isNarrowString!Range)
    {
        import std.utf : byCodeUnit;
        auto rn = r.byCodeUnit;
    }
    else
    {
        alias rn = r;
    }

    for (; !rn.empty; rn.popFront())
    {
        if (rn.front == lPar)
        {
            if (count > maxNestingLevel) return false;
            ++count;
        }
        else if (rn.front == rPar)
        {
            if (!count) return false;
            --count;
        }
    }
    return count == 0;
}

///
@safe pure unittest
{
    auto s = "1 + (2 * (3 + 1 / 2)";
    assert(!balancedParens(s, '(', ')'));
    s = "1 + (2 * (3 + 1) / 2)";
    assert(balancedParens(s, '(', ')'));
    s = "1 + (2 * (3 + 1) / 2)";
    assert(!balancedParens(s, '(', ')', 0));
    s = "1 + (2 * 3 + 1) / (2 - 5)";
    assert(balancedParens(s, '(', ')', 0));
    s = "f(x) = ⌈x⌉";
    assert(balancedParens(s, '⌈', '⌉'));
}

/**
 * Sets up Boyer-Moore matching for use with `find` below.
 * By default, elements are compared for equality.
 *
 * `BoyerMooreFinder` allocates GC memory.
 *
 * Params:
 * pred = Predicate used to compare elements.
 * needle = A random-access range with length and slicing.
 *
 * Returns:
 * An instance of `BoyerMooreFinder` that can be used with `find()` to
 * invoke the Boyer-Moore matching algorithm for finding of `needle` in a
 * given haystack.
 */
struct BoyerMooreFinder(alias pred, Range)
{
private:
    size_t[] skip;                              // GC allocated
    ptrdiff_t[ElementType!(Range)] occ;         // GC allocated
    Range needle;

    ptrdiff_t occurrence(ElementType!(Range) c) scope
    {
        auto p = c in occ;
        return p ? *p : -1;
    }

/*
This helper function checks whether the last "portion" bytes of
"needle" (which is "nlen" bytes long) exist within the "needle" at
offset "offset" (counted from the end of the string), and whether the
character preceding "offset" is not a match.  Notice that the range
being checked may reach beyond the beginning of the string. Such range
is ignored.
 */
    static bool needlematch(R)(R needle,
                              size_t portion, size_t offset)
    {
        import std.algorithm.comparison : equal;
        ptrdiff_t virtual_begin = needle.length - offset - portion;
        ptrdiff_t ignore = 0;
        if (virtual_begin < 0)
        {
            ignore = -virtual_begin;
            virtual_begin = 0;
        }
        if (virtual_begin > 0
            && needle[virtual_begin - 1] == needle[$ - portion - 1])
            return 0;

        immutable delta = portion - ignore;
        return equal(needle[needle.length - delta .. needle.length],
                needle[virtual_begin .. virtual_begin + delta]);
    }

public:
    ///
    this(Range needle)
    {
        if (!needle.length) return;
        this.needle = needle;
        /* Populate table with the analysis of the needle */
        /* But ignoring the last letter */
        foreach (i, n ; needle[0 .. $ - 1])
        {
            this.occ[n] = i;
        }
        /* Preprocess #2: init skip[] */
        /* Note: This step could be made a lot faster.
         * A simple implementation is shown here. */
        this.skip = new size_t[needle.length];
        foreach (a; 0 .. needle.length)
        {
            size_t value = 0;
            while (value < needle.length
                   && !needlematch(needle, a, value))
            {
                ++value;
            }
            this.skip[needle.length - a - 1] = value;
        }
    }

    ///
    Range beFound(Range haystack) scope
    {
        import std.algorithm.comparison : max;

        if (!needle.length) return haystack;
        if (needle.length > haystack.length) return haystack[$ .. $];
        /* Search: */
        immutable limit = haystack.length - needle.length;
        for (size_t hpos = 0; hpos <= limit; )
        {
            size_t npos = needle.length - 1;
            while (pred(needle[npos], haystack[npos+hpos]))
            {
                if (npos == 0) return haystack[hpos .. $];
                --npos;
            }
            hpos += max(skip[npos], cast(ptrdiff_t) npos - occurrence(haystack[npos+hpos]));
        }
        return haystack[$ .. $];
    }

    ///
    @property size_t length()
    {
        return needle.length;
    }

    ///
    alias opDollar = length;
}

/// Ditto
BoyerMooreFinder!(binaryFun!(pred), Range) boyerMooreFinder
(alias pred = "a == b", Range)
(Range needle)
if ((isRandomAccessRange!(Range) && hasSlicing!Range) || isSomeString!Range)
{
    return typeof(return)(needle);
}

///
@safe pure nothrow unittest
{
    auto bmFinder = boyerMooreFinder("TG");

    string r = "TAGTGCCTGA";
    // search for the first match in the haystack r
    r = bmFinder.beFound(r);
    assert(r == "TGCCTGA");

    // continue search in haystack
    r = bmFinder.beFound(r[2 .. $]);
    assert(r == "TGA");
}

/**
Returns the common prefix of two ranges.

Params:
    pred = The predicate to use in comparing elements for commonality. Defaults
        to equality `"a == b"`.

    r1 = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) of
        elements.

    r2 = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of
        elements.

Returns:
A slice of `r1` which contains the characters that both ranges start with,
if the first argument is a string; otherwise, the same as the result of
`takeExactly(r1, n)`, where `n` is the number of elements in the common
prefix of both ranges.

See_Also:
    $(REF takeExactly, std,range)
 */
auto commonPrefix(alias pred = "a == b", R1, R2)(R1 r1, R2 r2)
if (isForwardRange!R1 && isInputRange!R2 &&
    !isNarrowString!R1 &&
    is(typeof(binaryFun!pred(r1.front, r2.front))))
{
    import std.algorithm.comparison : min;
    static if (isRandomAccessRange!R1 && isRandomAccessRange!R2 &&
               hasLength!R1 && hasLength!R2 &&
               hasSlicing!R1)
    {
        immutable limit = min(r1.length, r2.length);
        foreach (i; 0 .. limit)
        {
            if (!binaryFun!pred(r1[i], r2[i]))
            {
                return r1[0 .. i];
            }
        }
        return r1[0 .. limit];
    }
    else
    {
        import std.range : takeExactly;
        auto result = r1.save;
        size_t i = 0;
        for (;
             !r1.empty && !r2.empty && binaryFun!pred(r1.front, r2.front);
             ++i, r1.popFront(), r2.popFront())
        {}
        return takeExactly(result, i);
    }
}

///
@safe unittest
{
    assert(commonPrefix("hello, world", "hello, there") == "hello, ");
}

/// ditto
auto commonPrefix(alias pred, R1, R2)(R1 r1, R2 r2)
if (isNarrowString!R1 && isInputRange!R2 &&
    is(typeof(binaryFun!pred(r1.front, r2.front))))
{
    import std.utf : decode;

    auto result = r1.save;
    immutable len = r1.length;
    size_t i = 0;

    for (size_t j = 0; i < len && !r2.empty; r2.popFront(), i = j)
    {
        immutable f = decode(r1, j);
        if (!binaryFun!pred(f, r2.front))
            break;
    }

    return result[0 .. i];
}

/// ditto
auto commonPrefix(R1, R2)(R1 r1, R2 r2)
if (isNarrowString!R1 && isInputRange!R2 && !isNarrowString!R2 &&
    is(typeof(r1.front == r2.front)))
{
    return commonPrefix!"a == b"(r1, r2);
}

/// ditto
auto commonPrefix(R1, R2)(R1 r1, R2 r2)
if (isNarrowString!R1 && isNarrowString!R2)
{
    import std.algorithm.comparison : min;

    static if (ElementEncodingType!R1.sizeof == ElementEncodingType!R2.sizeof)
    {
        import std.utf : stride, UTFException;

        immutable limit = min(r1.length, r2.length);
        for (size_t i = 0; i < limit;)
        {
            immutable codeLen = stride(r1, i);
            size_t j = 0;

            for (; j < codeLen && i < limit; ++i, ++j)
            {
                if (r1[i] != r2[i])
                    return r1[0 .. i - j];
            }

            if (i == limit && j < codeLen)
                throw new UTFException("Invalid UTF-8 sequence", i);
        }
        return r1[0 .. limit];
    }
    else
        return commonPrefix!"a == b"(r1, r2);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter;
    import std.conv : to;
    import std.exception : assertThrown;
    import std.meta : AliasSeq;
    import std.range;
    import std.utf : UTFException;

    assert(commonPrefix([1, 2, 3], [1, 2, 3, 4, 5]) == [1, 2, 3]);
    assert(commonPrefix([1, 2, 3, 4, 5], [1, 2, 3]) == [1, 2, 3]);
    assert(commonPrefix([1, 2, 3, 4], [1, 2, 3, 4]) == [1, 2, 3, 4]);
    assert(commonPrefix([1, 2, 3], [7, 2, 3, 4, 5]).empty);
    assert(commonPrefix([7, 2, 3, 4, 5], [1, 2, 3]).empty);
    assert(commonPrefix([1, 2, 3], cast(int[]) null).empty);
    assert(commonPrefix(cast(int[]) null, [1, 2, 3]).empty);
    assert(commonPrefix(cast(int[]) null, cast(int[]) null).empty);

    static foreach (S; AliasSeq!(char[], const(char)[], string,
                          wchar[], const(wchar)[], wstring,
                          dchar[], const(dchar)[], dstring))
    {
        static foreach (T; AliasSeq!(string, wstring, dstring))
        {
            assert(commonPrefix(to!S(""), to!T("")).empty);
            assert(commonPrefix(to!S(""), to!T("hello")).empty);
            assert(commonPrefix(to!S("hello"), to!T("")).empty);
            assert(commonPrefix(to!S("hello, world"), to!T("hello, there")) == to!S("hello, "));
            assert(commonPrefix(to!S("hello, there"), to!T("hello, world")) == to!S("hello, "));
            assert(commonPrefix(to!S("hello, "), to!T("hello, world")) == to!S("hello, "));
            assert(commonPrefix(to!S("hello, world"), to!T("hello, ")) == to!S("hello, "));
            assert(commonPrefix(to!S("hello, world"), to!T("hello, world")) == to!S("hello, world"));

            // https://issues.dlang.org/show_bug.cgi?id=8890
            assert(commonPrefix(to!S("Пиво"), to!T("Пони"))== to!S("П"));
            assert(commonPrefix(to!S("Пони"), to!T("Пиво"))== to!S("П"));
            assert(commonPrefix(to!S("Пиво"), to!T("Пиво"))== to!S("Пиво"));
            assert(commonPrefix(to!S("\U0010FFFF\U0010FFFB\U0010FFFE"),
                                to!T("\U0010FFFF\U0010FFFB\U0010FFFC")) == to!S("\U0010FFFF\U0010FFFB"));
            assert(commonPrefix(to!S("\U0010FFFF\U0010FFFB\U0010FFFC"),
                                to!T("\U0010FFFF\U0010FFFB\U0010FFFE")) == to!S("\U0010FFFF\U0010FFFB"));
            assert(commonPrefix!"a != b"(to!S("Пиво"), to!T("онво")) == to!S("Пи"));
            assert(commonPrefix!"a != b"(to!S("онво"), to!T("Пиво")) == to!S("он"));
        }

        static assert(is(typeof(commonPrefix(to!S("Пиво"), filter!"true"("Пони"))) == S));
        assert(equal(commonPrefix(to!S("Пиво"), filter!"true"("Пони")), to!S("П")));

        static assert(is(typeof(commonPrefix(filter!"true"("Пиво"), to!S("Пони"))) ==
                      typeof(takeExactly(filter!"true"("П"), 1))));
        assert(equal(commonPrefix(filter!"true"("Пиво"), to!S("Пони")), takeExactly(filter!"true"("П"), 1)));
    }

    assertThrown!UTFException(commonPrefix("\U0010FFFF\U0010FFFB", "\U0010FFFF\U0010FFFB"[0 .. $ - 1]));

    assert(commonPrefix("12345"d, [49, 50, 51, 60, 60]) == "123"d);
    assert(commonPrefix([49, 50, 51, 60, 60], "12345" ) == [49, 50, 51]);
    assert(commonPrefix([49, 50, 51, 60, 60], "12345"d) == [49, 50, 51]);

    assert(commonPrefix!"a == ('0' + b)"("12345" , [1, 2, 3, 9, 9]) == "123");
    assert(commonPrefix!"a == ('0' + b)"("12345"d, [1, 2, 3, 9, 9]) == "123"d);
    assert(commonPrefix!"('0' + a) == b"([1, 2, 3, 9, 9], "12345" ) == [1, 2, 3]);
    assert(commonPrefix!"('0' + a) == b"([1, 2, 3, 9, 9], "12345"d) == [1, 2, 3]);
}

// count
/**
Counts matches of `needle` in `haystack`.

The first overload counts each element `e` in `haystack` for
which `pred(e, needle)` is `true`. `pred` defaults to
equality. Performs $(BIGOH haystack.length) evaluations of `pred`.

The second overload counts the number of times `needle` was matched in
`haystack`. `pred` compares elements in each range.
Throws an exception if `needle.empty` is `true`, as the _count
of the empty range in any range would be infinite. Overlapped counts
are *not* considered, for example `count("aaa", "aa")` is `1`, not
`2`.

Note: Regardless of the overload, `count` will not accept
infinite ranges for `haystack`.

Params:
    pred = The predicate to compare elements.
    haystack = The range to _count.
    needle = The element or sub-range to _count in `haystack`.

Returns:
    The number of matches in `haystack`.
*/
size_t count(alias pred = "a == b", Range, E)(Range haystack, E needle)
if (isInputRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(haystack.front, needle))))
{
    bool pred2(ElementType!Range a) { return binaryFun!pred(a, needle); }
    return count!pred2(haystack);
}

///
@safe unittest
{
    // count elements in range
    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
    assert(count(a, 2) == 3);
    assert(count!("a > b")(a, 2) == 5);
}

///
@safe unittest
{
    import std.uni : toLower;
    // count range in range
    assert(count("abcadfabf", "ab") == 2);
    assert(count("ababab", "abab") == 1);
    assert(count("ababab", "abx") == 0);
    // fuzzy count range in range
    assert(count!((a, b) => toLower(a) == toLower(b))("AbcAdFaBf", "ab") == 2);
}

@safe unittest
{
    import std.conv : text;

    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
    assert(count(a, 2) == 3, text(count(a, 2)));
    assert(count!("a > b")(a, 2) == 5, text(count!("a > b")(a, 2)));

    // check strings
    assert(count("日本語")  == 3);
    assert(count("日本語"w) == 3);
    assert(count("日本語"d) == 3);

    assert(count!("a == '日'")("日本語")  == 1);
    assert(count!("a == '本'")("日本語"w) == 1);
    assert(count!("a == '語'")("日本語"d) == 1);
}

@safe unittest
{
    string s = "This is a fofofof list";
    string sub = "fof";
    assert(count(s, sub) == 2);
}

/// Ditto
size_t count(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && !isInfinite!R1 &&
    isForwardRange!R2 &&
    is(typeof(binaryFun!pred(haystack.front, needle.front))))
{
    assert(!needle.empty, "Cannot count occurrences of an empty range");

    static if (isInfinite!R2)
    {
        //Note: This is the special case of looking for an infinite inside a finite...
        //"How many instances of the Fibonacci sequence can you count in [1, 2, 3]?" - "None."
        return 0;
    }
    else
    {
        size_t result;
        //Note: haystack is not saved, because findskip is designed to modify it
        for ( ; findSkip!pred(haystack, needle.save) ; ++result)
        {}
        return result;
    }
}

/**
Counts all elements or elements satisfying a predicate in `haystack`.

The first overload counts each element `e` in `haystack` for which `pred(e)` is $(D
true). Performs $(BIGOH haystack.length) evaluations of `pred`.

The second overload counts the number of elements in a range.
If the given range has the `length` property,
that is returned right away, otherwise
performs $(BIGOH haystack.length) to walk the range.

Params:
    pred = Optional predicate to find elements.
    haystack = The range to _count.

Returns:
    The number of elements in `haystack` (for which `pred` returned true).
*/
size_t count(alias pred, R)(R haystack)
if (isInputRange!R && !isInfinite!R &&
    is(typeof(unaryFun!pred(haystack.front))))
{
    size_t result;
    alias T = ElementType!R; //For narrow strings forces dchar iteration
    foreach (T elem; haystack)
        if (unaryFun!pred(elem)) ++result;
    return result;
}

///
@safe unittest
{
    // count elements in range
    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
    assert(count(a) == 9);
    // count predicate in range
    assert(count!("a > 2")(a) == 5);
}

/// Ditto
size_t count(R)(R haystack)
if (isInputRange!R && !isInfinite!R)
{
    return walkLength(haystack);
}

@safe unittest
{
    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
    assert(count!("a == 3")(a) == 2);
    assert(count("日本語") == 3);
}

// https://issues.dlang.org/show_bug.cgi?id=11253
@safe nothrow unittest
{
    assert([1, 2, 3].count([2, 3]) == 1);
}

// https://issues.dlang.org/show_bug.cgi?id=22582
@safe unittest
{
    assert([1, 2, 3].count!"a & 1" == 2);
}

/++
    Counts elements in the given
    $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
    until the given predicate is true for one of the given `needles`.

    Params:
        pred = The predicate for determining when to stop counting.
        haystack = The
            $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to be
            counted.
        needles = Either a single element, or a
            $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
            of elements, to be evaluated in turn against each
            element in `haystack` under the given predicate.

    Returns: The number of elements which must be popped from the front of
    `haystack` before reaching an element for which
    `startsWith!pred(haystack, needles)` is `true`. If
    `startsWith!pred(haystack, needles)` is not `true` for any element in
    `haystack`, then `-1` is returned. If more than one needle is provided,
    `countUntil` will wrap the result     in a tuple similar to
    `Tuple!(ptrdiff_t, "steps", ptrdiff_t needle)`

    See_Also: $(REF indexOf, std,string)
  +/
auto countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles)
if (isForwardRange!R
    && Rs.length > 0
    && isForwardRange!(Rs[0]) == isInputRange!(Rs[0])
    && allSatisfy!(canTestStartsWith!(pred, R), Rs))
{
    static if (needles.length == 1)
    {
        static if (hasLength!R) //Note: Narrow strings don't have length.
        {
            //We delegate to find because find is very efficient.
            //We store the length of the haystack so we don't have to save it.
            auto len = haystack.length;
            auto r2 = find!pred(haystack, needles[0]);
            if (!r2.empty)
                return ptrdiff_t(len - r2.length);
        }
        else
        {
            import std.range : dropOne;

            if (needles[0].empty)
                return ptrdiff_t(0);

            ptrdiff_t result;

            //Default case, slower route doing startsWith iteration
            for ( ; !haystack.empty ; ++result )
            {
                //We compare the first elements of the ranges here before
                //forwarding to startsWith. This avoids making useless saves to
                //haystack/needle if they aren't even going to be mutated anyways.
                //It also cuts down on the amount of pops on haystack.
                if (binaryFun!pred(haystack.front, needles[0].front))
                {
                    //Here, we need to save the needle before popping it.
                    //haystack we pop in all paths, so we do that, and then save.
                    haystack.popFront();
                    if (startsWith!pred(haystack.save, needles[0].save.dropOne()))
                        return result;
                }
                else
                {
                    haystack.popFront();
                }
            }
        }
        return ptrdiff_t(-1);
    }
    else
    {
        static struct Result
        {
            ptrdiff_t steps, needle; // both -1 when nothing was found
            alias steps this; // compatible with previous ptrdiff_t return type
            ptrdiff_t opIndex(size_t idx) // faking a tuple
            {
                assert(idx < 2, "Type has only two members: pos and needle");
                return idx == 0 ? steps : needle;
            }
        }
        Result result;

        foreach (i, Ri; Rs)
        {
            static if (isForwardRange!Ri)
            {
                if (needles[i].empty)
                {
                    result.needle = i;
                    return result;
                }
            }
        }
        Tuple!Rs t;
        foreach (i, Ri; Rs)
        {
            static if (!isForwardRange!Ri)
            {
                t[i] = needles[i];
            }
        }
        for (; !haystack.empty ; ++result.steps, haystack.popFront())
        {
            foreach (i, Ri; Rs)
            {
                static if (isForwardRange!Ri)
                {
                    t[i] = needles[i].save;
                }
            }
            if (auto needle = startsWith!pred(haystack.save, t.expand))
            {
                result.needle = needle - 1;
                return result;
            }
        }

        // no match was found
        result.needle = -1;
        result.steps = -1;
        return result;
    }
}

/// ditto
ptrdiff_t countUntil(alias pred = "a == b", R, N)(R haystack, N needle)
if (isInputRange!R &&
    is(typeof(binaryFun!pred(haystack.front, needle)) : bool))
{
    bool pred2(ElementType!R a) { return binaryFun!pred(a, needle); }
    return countUntil!pred2(haystack);
}

///
@safe unittest
{
    assert(countUntil("hello world", "world") == 6);
    assert(countUntil("hello world", 'r') == 8);
    assert(countUntil("hello world", "programming") == -1);
    assert(countUntil("日本語", "本語") == 1);
    assert(countUntil("日本語", '語')   == 2);
    assert(countUntil("日本語", "五") == -1);
    assert(countUntil("日本語", '五') == -1);
    assert(countUntil([0, 7, 12, 22, 9], [12, 22]) == 2);
    assert(countUntil([0, 7, 12, 22, 9], 9) == 4);
    assert(countUntil!"a > b"([0, 7, 12, 22, 9], 20) == 3);

    // supports multiple needles
    auto res = "...hello".countUntil("ha", "he");
    assert(res.steps == 3);
    assert(res.needle == 1);

    // returns -1 if no needle was found
    res = "hello".countUntil("ha", "hu");
    assert(res.steps == -1);
    assert(res.needle == -1);
}

@safe unittest
{
    import std.algorithm.iteration : filter;
    import std.internal.test.dummyrange;

    assert(countUntil("日本語", "") == 0);
    assert(countUntil("日本語"d, "") == 0);

    assert(countUntil("", "") == 0);
    assert(countUntil("".filter!"true"(), "") == 0);

    auto rf = [0, 20, 12, 22, 9].filter!"true"();
    assert(rf.countUntil!"a > b"((int[]).init) == 0);
    assert(rf.countUntil!"a > b"(20) == 3);
    assert(rf.countUntil!"a > b"([20, 8]) == 3);
    assert(rf.countUntil!"a > b"([20, 10]) == -1);
    assert(rf.countUntil!"a > b"([20, 8, 0]) == -1);

    auto r = new ReferenceForwardRange!int([0, 1, 2, 3, 4, 5, 6]);
    auto r2 = new ReferenceForwardRange!int([3, 4]);
    auto r3 = new ReferenceForwardRange!int([3, 5]);
    assert(r.save.countUntil(3)  == 3);
    assert(r.save.countUntil(r2) == 3);
    assert(r.save.countUntil(7)  == -1);
    assert(r.save.countUntil(r3) == -1);
}

@safe unittest
{
    assert(countUntil("hello world", "world", "asd") == 6);
    assert(countUntil("hello world", "world", "ello") == 1);
    assert(countUntil("hello world", "world", "") == 0);
    assert(countUntil("hello world", "world", 'l') == 2);
}

@safe unittest
{
    auto res = "...hello".countUntil("hella", "hello");
    assert(res == 3);
    assert(res.steps == 3);
    assert(res.needle == 1);
    // test tuple emulation
    assert(res[0] == 3);
    assert(res[1] == 1);

    // the first matching needle is chosen
    res = "...hello".countUntil("hell", "hello");
    assert(res == 3);
    assert(res.needle == 0);

    // no match
    auto noMatch = "hello world".countUntil("ha", "hu");
    assert(noMatch == -1);
    assert(noMatch.steps == -1);
    assert(noMatch.needle  == -1);
    // test tuple emulation
    assert(noMatch[0] == -1);
    assert(noMatch[1] == -1);
}

// test infinite ranges
@safe unittest
{
    import std.algorithm.iteration : joiner;
    import std.range : iota, repeat;
    import std.stdio;
    assert(10.iota.repeat.joiner.countUntil(9) == 9);
    assert(10.iota.repeat.joiner.countUntil(1, 2) == 1);
    assert(10.iota.repeat.joiner.countUntil!(a => a >= 9) == 9);
}

/// ditto
ptrdiff_t countUntil(alias pred, R)(R haystack)
if (isInputRange!R &&
    is(typeof(unaryFun!pred(haystack.front)) : bool))
{
    typeof(return) i;
    static if (isRandomAccessRange!R)
    {
        //Optimized RA implementation. Since we want to count *and* iterate at
        //the same time, it is more efficient this way.
        static if (hasLength!R)
        {
            immutable len = cast(typeof(return)) haystack.length;
            for ( ; i < len ; ++i )
                if (unaryFun!pred(haystack[i])) return i;
        }
        else //if (isInfinite!R)
        {
            for ( ;  ; ++i )
                if (unaryFun!pred(haystack[i])) return i;
        }
    }
    else static if (hasLength!R)
    {
        //For those odd ranges that have a length, but aren't RA.
        //It is faster to quick find, and then compare the lengths
        auto r2 = find!pred(haystack.save);
        if (!r2.empty) return cast(typeof(return)) (haystack.length - r2.length);
    }
    else //Everything else
    {
        alias T = ElementType!R; //For narrow strings forces dchar iteration
        foreach (T elem; haystack)
        {
            if (unaryFun!pred(elem)) return i;
            ++i;
        }
    }

    // Because of https://issues.dlang.org/show_bug.cgi?id=8804
    // Avoids both "unreachable code" or "no return statement"
    static if (isInfinite!R) assert(false, R.stringof ~ " must not be an"
            ~ " inifite range");
    else return -1;
}

///
@safe unittest
{
    import std.ascii : isDigit;
    import std.uni : isWhite;

    assert(countUntil!(isWhite)("hello world") == 5);
    assert(countUntil!(isDigit)("hello world") == -1);
    assert(countUntil!"a > 20"([0, 7, 12, 22, 9]) == 3);
}

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

    // References
    {
        // input
        ReferenceInputRange!int r;
        r = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6]);
        assert(r.countUntil(3) == 3);
        r = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6]);
        assert(r.countUntil(7) == -1);
    }
    {
        // forward
        auto r = new ReferenceForwardRange!int([0, 1, 2, 3, 4, 5, 6]);
        assert(r.save.countUntil([3, 4]) == 3);
        assert(r.save.countUntil(3) == 3);
        assert(r.save.countUntil([3, 7]) == -1);
        assert(r.save.countUntil(7) == -1);
    }
    {
        // infinite forward
        auto r = new ReferenceInfiniteForwardRange!int(0);
        assert(r.save.countUntil([3, 4]) == 3);
        assert(r.save.countUntil(3) == 3);
    }
}

/**
Checks if the given range ends with (one of) the given needle(s).
The reciprocal of `startsWith`.

Params:
    pred = The predicate to use for comparing elements between the range and
        the needle(s).

    doesThisEnd = The
        $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)
        to check.

    withOneOfThese = The needles to check against, which may be single
        elements, or bidirectional ranges of elements.

    withThis = The single element to check.

Returns:
0 if the needle(s) do not occur at the end of the given range;
otherwise the position of the matching needle, that is, 1 if the range ends
with `withOneOfThese[0]`, 2 if it ends with `withOneOfThese[1]`, and so
on.

In the case when no needle parameters are given, return `true` iff back of
`doesThisStart` fulfils predicate `pred`.
*/
uint endsWith(alias pred = "a == b", Range, Needles...)(Range doesThisEnd, Needles withOneOfThese)
if (isBidirectionalRange!Range && Needles.length > 1 &&
    allSatisfy!(canTestStartsWith!(pred, Range), Needles))
{
    alias haystack = doesThisEnd;
    alias needles  = withOneOfThese;

    // Make one pass looking for empty ranges in needles
    foreach (i, Unused; Needles)
    {
        // Empty range matches everything
        static if (!is(typeof(binaryFun!pred(haystack.back, needles[i])) : bool))
        {
            if (needles[i].empty) return i + 1;
        }
    }

    for (; !haystack.empty; haystack.popBack())
    {
        foreach (i, Unused; Needles)
        {
            static if (is(typeof(binaryFun!pred(haystack.back, needles[i])) : bool))
            {
                // Single-element
                if (binaryFun!pred(haystack.back, needles[i]))
                {
                    // found, but continue to account for one-element
                    // range matches (consider endsWith("ab", "b",
                    // 'b') should return 1, not 2).
                    continue;
                }
            }
            else
            {
                if (binaryFun!pred(haystack.back, needles[i].back))
                    continue;
            }

            // This code executed on failure to match
            // Out with this guy, check for the others
            uint result = endsWith!pred(haystack, needles[0 .. i], needles[i + 1 .. $]);
            if (result > i) ++result;
            return result;
        }

        // If execution reaches this point, then the back matches for all
        // needles ranges. What we need to do now is to lop off the back of
        // all ranges involved and recurse.
        foreach (i, Unused; Needles)
        {
            static if (is(typeof(binaryFun!pred(haystack.back, needles[i])) : bool))
            {
                // Test has passed in the previous loop
                return i + 1;
            }
            else
            {
                needles[i].popBack();
                if (needles[i].empty) return i + 1;
            }
        }
    }
    return 0;
}

/// Ditto
bool endsWith(alias pred = "a == b", R1, R2)(R1 doesThisEnd, R2 withThis)
if (isBidirectionalRange!R1 &&
    isBidirectionalRange!R2 &&
    is(typeof(binaryFun!pred(doesThisEnd.back, withThis.back)) : bool))
{
    alias haystack = doesThisEnd;
    alias needle   = withThis;

    static if (is(typeof(pred) : string))
        enum isDefaultPred = pred == "a == b";
    else
        enum isDefaultPred = false;

    static if (isDefaultPred && isArray!R1 && isArray!R2 &&
               is(immutable ElementEncodingType!R1 == immutable ElementEncodingType!R2))
    {
        if (haystack.length < needle.length) return false;

        return haystack[$ - needle.length .. $] == needle;
    }
    else
    {
        import std.range : retro;
        return startsWith!pred(retro(doesThisEnd), retro(withThis));
    }
}

/// Ditto
bool endsWith(alias pred = "a == b", R, E)(R doesThisEnd, E withThis)
if (isBidirectionalRange!R &&
    is(typeof(binaryFun!pred(doesThisEnd.back, withThis)) : bool))
{
    if (doesThisEnd.empty)
        return false;

    static if (is(typeof(pred) : string))
        enum isDefaultPred = pred == "a == b";
    else
        enum isDefaultPred = false;

    alias predFunc = binaryFun!pred;

    // auto-decoding special case
    static if (isNarrowString!R)
    {
        // statically determine decoding is unnecessary to evaluate pred
        static if (isDefaultPred && isSomeChar!E && E.sizeof <= ElementEncodingType!R.sizeof)
            return doesThisEnd[$ - 1] == withThis;
        // specialize for ASCII as to not change previous behavior
        else
        {
            if (withThis <= 0x7F)
                return predFunc(doesThisEnd[$ - 1], withThis);
            else
                return predFunc(doesThisEnd.back, withThis);
        }
    }
    else
    {
        return predFunc(doesThisEnd.back, withThis);
    }
}

/// Ditto
bool endsWith(alias pred, R)(R doesThisEnd)
if (isInputRange!R &&
    ifTestable!(typeof(doesThisEnd.front), unaryFun!pred))
{
    return !doesThisEnd.empty && unaryFun!pred(doesThisEnd.back);
}

///
@safe unittest
{
    import std.ascii : isAlpha;
    assert("abc".endsWith!(a => a.isAlpha));
    assert("abc".endsWith!isAlpha);

    assert(!"ab1".endsWith!(a => a.isAlpha));

    assert(!"ab1".endsWith!isAlpha);
    assert(!"".endsWith!(a => a.isAlpha));

    import std.algorithm.comparison : among;
    assert("abc".endsWith!(a => a.among('c', 'd') != 0));
    assert(!"abc".endsWith!(a => a.among('a', 'b') != 0));

    assert(endsWith("abc", ""));
    assert(!endsWith("abc", "b"));
    assert(endsWith("abc", "a", 'c') == 2);
    assert(endsWith("abc", "c", "a") == 1);
    assert(endsWith("abc", "c", "c") == 1);
    assert(endsWith("abc", "bc", "c") == 2);
    assert(endsWith("abc", "x", "c", "b") == 2);
    assert(endsWith("abc", "x", "aa", "bc") == 3);
    assert(endsWith("abc", "x", "aaa", "sab") == 0);
    assert(endsWith("abc", "x", "aaa", 'c', "sab") == 3);
}

@safe unittest
{
    import std.algorithm.iteration : filterBidirectional;
    import std.conv : to;
    import std.meta : AliasSeq;

    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
    (){ // workaround slow optimizations for large functions
        // https://issues.dlang.org/show_bug.cgi?id=2396
        assert(!endsWith(to!S("abc"), 'a'));
        assert(endsWith(to!S("abc"), 'a', 'c') == 2);
        assert(!endsWith(to!S("abc"), 'x', 'n', 'b'));
        assert(endsWith(to!S("abc"), 'x', 'n', 'c') == 3);
        assert(endsWith(to!S("abc\uFF28"), 'a', '\uFF28', 'c') == 2);

        static foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
        {
            //Lots of strings
            assert(endsWith(to!S("abc"), to!T("")));
            assert(!endsWith(to!S("abc"), to!T("a")));
            assert(!endsWith(to!S("abc"), to!T("b")));
            assert(endsWith(to!S("abc"), to!T("bc"), 'c') == 2);
            assert(endsWith(to!S("abc"), to!T("a"), "c") == 2);
            assert(endsWith(to!S("abc"), to!T("c"), "a") == 1);
            assert(endsWith(to!S("abc"), to!T("c"), "c") == 1);
            assert(endsWith(to!S("abc"), to!T("x"), 'c', "b") == 2);
            assert(endsWith(to!S("abc"), 'x', to!T("aa"), "bc") == 3);
            assert(endsWith(to!S("abc"), to!T("x"), "aaa", "sab") == 0);
            assert(endsWith(to!S("abc"), to!T("x"), "aaa", "c", "sab") == 3);
            assert(endsWith(to!S("\uFF28el\uFF4co"), to!T("l\uFF4co")));
            assert(endsWith(to!S("\uFF28el\uFF4co"), to!T("lo"), to!T("l\uFF4co")) == 2);

            //Unicode
            assert(endsWith(to!S("\uFF28el\uFF4co"), to!T("l\uFF4co")));
            assert(endsWith(to!S("\uFF28el\uFF4co"), to!T("lo"), to!T("l\uFF4co")) == 2);
            assert(endsWith(to!S("日本語"), to!T("本語")));
            assert(endsWith(to!S("日本語"), to!T("日本語")));
            assert(!endsWith(to!S("本語"), to!T("日本語")));

            //Empty
            assert(endsWith(to!S(""),  T.init));
            assert(!endsWith(to!S(""), 'a'));
            assert(endsWith(to!S("a"), T.init));
            assert(endsWith(to!S("a"), T.init, "") == 1);
            assert(endsWith(to!S("a"), T.init, 'a') == 1);
            assert(endsWith(to!S("a"), 'a', T.init) == 2);
        }
    }();

    static foreach (T; AliasSeq!(int, short))
    {{
        immutable arr = cast(T[])[0, 1, 2, 3, 4, 5];

        //RA range
        assert(endsWith(arr, cast(int[]) null));
        assert(!endsWith(arr, 0));
        assert(!endsWith(arr, 4));
        assert(endsWith(arr, 5));
        assert(endsWith(arr, 0, 4, 5) == 3);
        assert(endsWith(arr, [5]));
        assert(endsWith(arr, [4, 5]));
        assert(endsWith(arr, [4, 5], 7) == 1);
        assert(!endsWith(arr, [2, 4, 5]));
        assert(endsWith(arr, [2, 4, 5], [3, 4, 5]) == 2);

        //Normal input range
        assert(!endsWith(filterBidirectional!"true"(arr), 4));
        assert(endsWith(filterBidirectional!"true"(arr), 5));
        assert(endsWith(filterBidirectional!"true"(arr), [5]));
        assert(endsWith(filterBidirectional!"true"(arr), [4, 5]));
        assert(endsWith(filterBidirectional!"true"(arr), [4, 5], 7) == 1);
        assert(!endsWith(filterBidirectional!"true"(arr), [2, 4, 5]));
        assert(endsWith(filterBidirectional!"true"(arr), [2, 4, 5], [3, 4, 5]) == 2);
        assert(endsWith(arr, filterBidirectional!"true"([4, 5])));
        assert(endsWith(arr, filterBidirectional!"true"([4, 5]), 7) == 1);
        assert(!endsWith(arr, filterBidirectional!"true"([2, 4, 5])));
        assert(endsWith(arr, [2, 4, 5], filterBidirectional!"true"([3, 4, 5])) == 2);

        //Non-default pred
        assert(endsWith!("a%10 == b%10")(arr, [14, 15]));
        assert(!endsWith!("a%10 == b%10")(arr, [15, 14]));
    }}
}

@safe pure unittest
{
    //example from https://issues.dlang.org/show_bug.cgi?id=19727
    import std.path : asRelativePath;
    string[] ext = ["abc", "def", "ghi"];
    string path = "/foo/file.def";
    assert(ext.any!(e => path.asRelativePath("/foo").endsWith(e)) == true);
    assert(ext.any!(e => path.asRelativePath("/foo").startsWith(e)) == false);
}

private enum bool hasConstEmptyMember(T) = is(typeof(((const T* a) => (*a).empty)(null)) : bool);

/**
Iterates the passed range and selects the extreme element with `less`.
If the extreme element occurs multiple time, the first occurrence will be
returned.

Params:
    map = custom accessor for the comparison key
    selector = custom mapping for the extrema selection
    r = Range from which the extreme value will be selected
    seedElement = custom seed to use as initial element

Returns:
    The extreme value according to `map` and `selector` of the passed-in values.
*/
private auto extremum(alias map, alias selector = "a < b", Range)(Range r)
if (isInputRange!Range && !isInfinite!Range &&
    is(typeof(unaryFun!map(ElementType!(Range).init))))
in
{
    assert(!r.empty, "r is an empty range");
}
do
{
    import std.typecons : Rebindable2;

    alias Element = ElementType!Range;
    auto seed = Rebindable2!Element(r.front);
    r.popFront();
    return extremum!(map, selector)(r, seed.get);
}

private auto extremum(alias map, alias selector = "a < b", Range,
                      RangeElementType = ElementType!Range)
                     (Range r, RangeElementType seedElement)
if (isInputRange!Range && !isInfinite!Range &&
    !is(CommonType!(ElementType!Range, RangeElementType) == void) &&
     is(typeof(unaryFun!map(ElementType!(Range).init))))
{
    import std.typecons : Rebindable2;

    alias mapFun = unaryFun!map;
    alias selectorFun = binaryFun!selector;

    alias Element = ElementType!Range;
    alias CommonElement = CommonType!(Element, RangeElementType);
    auto extremeElement = Rebindable2!CommonElement(seedElement);

    // if we only have one statement in the loop, it can be optimized a lot better
    static if (__traits(isSame, map, a => a))
    {
        // direct access via a random access range is faster
        static if (isRandomAccessRange!Range)
        {
            foreach (const i; 0 .. r.length)
            {
                if (selectorFun(r[i], extremeElement.get))
                {
                    extremeElement = r[i];
                }
            }
        }
        else
        {
            while (!r.empty)
            {
                if (selectorFun(r.front, extremeElement.get))
                {
                    extremeElement = r.front;
                }
                r.popFront();
            }
        }
    }
    else
    {
        alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
        MapType extremeElementMapped = mapFun(extremeElement.get);

        // direct access via a random access range is faster
        static if (isRandomAccessRange!Range)
        {
            foreach (const i; 0 .. r.length)
            {
                MapType mapElement = mapFun(r[i]);
                if (selectorFun(mapElement, extremeElementMapped))
                {
                    extremeElement = r[i];
                    extremeElementMapped = mapElement;
                }
            }
        }
        else
        {
            while (!r.empty)
            {
                MapType mapElement = mapFun(r.front);
                if (selectorFun(mapElement, extremeElementMapped))
                {
                    extremeElement = r.front;
                    extremeElementMapped = mapElement;
                }
                r.popFront();
            }
        }
    }
    return extremeElement.get;
}

private auto extremum(alias selector = "a < b", Range)(Range r)
if (isInputRange!Range && !isInfinite!Range &&
    !is(typeof(unaryFun!selector(ElementType!(Range).init))))
{
    return extremum!(a => a, selector)(r);
}

// if we only have one statement in the loop it can be optimized a lot better
private auto extremum(alias selector = "a < b", Range,
                      RangeElementType = ElementType!Range)
                     (Range r, RangeElementType seedElement)
if (isInputRange!Range && !isInfinite!Range &&
    !is(CommonType!(ElementType!Range, RangeElementType) == void) &&
    !is(typeof(unaryFun!selector(ElementType!(Range).init))))
{
    return extremum!(a => a, selector)(r, seedElement);
}

@safe pure unittest
{
    // allows a custom map to select the extremum
    assert([[0, 4], [1, 2]].extremum!"a[0]" == [0, 4]);
    assert([[0, 4], [1, 2]].extremum!"a[1]" == [1, 2]);

    // allows a custom selector for comparison
    assert([[0, 4], [1, 2]].extremum!("a[0]", "a > b") == [1, 2]);
    assert([[0, 4], [1, 2]].extremum!("a[1]", "a > b") == [0, 4]);

    // use a custom comparator
    import std.math.operations : cmp;
    assert([-2., 0, 5].extremum!cmp == 5.0);
    assert([-2., 0, 2].extremum!`cmp(a, b) < 0` == -2.0);

    // combine with map
    import std.range : enumerate;
    assert([-3., 0, 5].enumerate.extremum!(`a.value`, cmp) == tuple(2, 5.0));
    assert([-2., 0, 2].enumerate.extremum!(`a.value`, `cmp(a, b) < 0`) == tuple(0, -2.0));

    // seed with a custom value
    int[] arr;
    assert(arr.extremum(1) == 1);
}

@safe pure nothrow unittest
{
    // 2d seeds
    int[][] arr2d;
    assert(arr2d.extremum([1]) == [1]);

    // allow seeds of different types (implicit casting)
    assert(extremum([2, 3, 4], 1.5) == 1.5);
}

@safe pure unittest
{
    import std.range : enumerate, iota;

    // forward ranges
    assert(iota(1, 5).extremum() == 1);
    assert(iota(2, 5).enumerate.extremum!"a.value" == tuple(0, 2));

    // should work with const
    const(int)[] immArr = [2, 1, 3];
    assert(immArr.extremum == 1);

    // should work with immutable
    immutable(int)[] immArr2 = [2, 1, 3];
    assert(immArr2.extremum == 1);

    // with strings
    assert(["b", "a", "c"].extremum == "a");

    // with all dummy ranges
    import std.internal.test.dummyrange;
    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        assert(d.extremum == 1);
        assert(d.extremum!(a => a)  == 1);
        assert(d.extremum!`a > b` == 10);
        assert(d.extremum!(a => a, `a > b`) == 10);
    }

    // compiletime
    enum ctExtremum = iota(1, 5).extremum;
    assert(ctExtremum == 1);
}

@nogc @safe nothrow pure unittest
{
    static immutable arr = [7, 3, 4, 2, 1, 8];
    assert(arr.extremum == 1);

    static immutable arr2d = [[1, 9], [3, 1], [4, 2]];
    assert(arr2d.extremum!"a[1]" == arr2d[1]);
}

// https://issues.dlang.org/show_bug.cgi?id=17982
@safe unittest
{
    class B
    {
        int val;
        this(int val){ this.val = val; }
    }

    const(B) doStuff(const(B)[] v)
    {
        return v.extremum!"a.val";
    }
    assert(doStuff([new B(1), new B(0), new B(2)]).val == 0);

    const(B)[] arr = [new B(0), new B(1)];
    // can't compare directly - https://issues.dlang.org/show_bug.cgi?id=1824
    assert(arr.extremum!"a.val".val == 0);
}

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

    assert([S(5), S(6)].extremum!"a.value" == S(5));
}

// https://issues.dlang.org/show_bug.cgi?id=24027
@safe nothrow unittest
{
    class A
    {
        int a;
        this(int a)
        {
            this.a = a;
        }
    }

    auto test = new A(5);
    A[] arr = [test];
    assert(maxElement!"a.a"(arr) is test);
}

// find
/**
Finds an element `e` of an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
where `pred(e)` is `true`.
$(P
$(PANEL
$(UL
$(LI `find` behaves similarly to `dropWhile` in other languages.)
$(LI To _find the *last* matching element in a
$(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives) `haystack`,
call `find!pred(retro(haystack))`. See $(REF retro, std,range).)
)))

Complexity:
    `find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.

Params:

    pred = The predicate to match an element.
    haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
               searched in.

Returns:
    `haystack` advanced such that the front element satisfies `pred`.
    If no such element exists, returns an empty `haystack`.
*/
InputRange find(alias pred, InputRange)(InputRange haystack)
if (isInputRange!InputRange)
{
    alias R = InputRange;
    alias predFun = unaryFun!pred;
    static if (isNarrowString!R)
    {
        import std.utf : decode;

        immutable len = haystack.length;
        size_t i = 0, next = 0;
        while (next < len)
        {
            if (predFun(decode(haystack, next)))
                return haystack[i .. $];
            i = next;
        }
        return haystack[$ .. $];
    }
    else
    {
        //standard range
        for ( ; !haystack.empty; haystack.popFront() )
        {
            if (predFun(haystack.front))
                break;
        }
        return haystack;
    }
}

///
@safe unittest
{
    auto arr = [ 1, 2, 3, 4, 1 ];
    assert(find!("a > 2")(arr) == [ 3, 4, 1 ]);

    // with predicate alias
    bool pred(int e) => e + 1 > 1.5;
    assert(find!(pred)(arr) == arr);
}

@safe pure unittest
{
    int[] r = [ 1, 2, 3 ];
    assert(find!(a=>a > 2)(r) == [3]);
    bool pred(int x) { return x + 1 > 1.5; }
    assert(find!(pred)(r) == r);

    assert(find!(a=>a > 'v')("hello world") == "world");
    assert(find!(a=>a%4 == 0)("日本語") == "本語");
}

/**
Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives).
Elements of `haystack` are compared with `needle` by using predicate
`pred` with `pred(haystack.front, needle)`.
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 `haystack` is a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives),
`needle` can be a $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) too.
In this case `startsWith!pred(haystack, needle)` is evaluated on each evaluation.

$(NOTE To find the first element $(I not) matching the needle, use predicate `"a != b"`.)

Complexity:
    `find` performs $(BIGOH walkLength(haystack)) evaluations of `pred`.
    There are specializations that improve performance by taking
    advantage of $(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives)
    or $(REF_ALTTEXT random access, isRandomAccessRange, std,range,primitives)
    ranges (where possible).

Params:

    pred = The predicate for comparing each element with the needle, defaulting to equality `"a == b"`.
    haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
               searched in.
    needle = The element searched for.

Returns:
    `haystack` advanced such that the front element is the one searched for;
    that is, until `binaryFun!pred(haystack.front, needle)` is `true`. If no
    such position exists, returns an empty `haystack`.

See_Also: $(LREF findAdjacent), $(LREF findAmong), $(LREF findSkip), $(LREF findSplit), $(LREF startsWith)
*/
InputRange find(alias pred = "a == b", InputRange, Element)(InputRange haystack, scope Element needle)
if (isInputRange!InputRange &&
    is (typeof(binaryFun!pred(haystack.front, needle)) : bool) &&
   !is (typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
{
    alias R = InputRange;
    alias E = Element;
    alias predFun = binaryFun!pred;
    static if (is(typeof(pred == "a == b")))
        enum isDefaultPred = pred == "a == b";
    else
        enum isDefaultPred = false;
    enum  isIntegralNeedle = isSomeChar!E || isIntegral!E || isBoolean!E;

    alias EType  = ElementType!R;

    // If the haystack is a SortedRange we can use binary search to find the needle.
    // Works only for the default find predicate and any SortedRange predicate.
    // https://issues.dlang.org/show_bug.cgi?id=8829
    import std.range : SortedRange;
    static if (is(InputRange : SortedRange!TT, TT) && isDefaultPred)
    {
        auto lb = haystack.lowerBound(needle);
        if (lb.length == haystack.length || haystack[lb.length] != needle)
            return haystack[$ .. $];

        return haystack[lb.length .. $];
    }
    else static if (isNarrowString!R)
    {
        alias EEType = ElementEncodingType!R;
        alias UEEType = Unqual!EEType;

        //These are two special cases which can search without decoding the UTF stream.
        static if (isDefaultPred && isIntegralNeedle)
        {
            import std.utf : canSearchInCodeUnits;

            //This special case deals with UTF8 search, when the needle
            //is represented by a single code point.
            //Note: "needle <= 0x7F" properly handles sign via unsigned promotion
            static if (is(UEEType == char))
            {
                if (!__ctfe && canSearchInCodeUnits!char(needle))
                {
                    static inout(R) trustedMemchr(ref return scope inout(R) haystack,
                                                  ref const scope E needle) @trusted nothrow pure
                    {
                        import core.stdc.string : memchr;
                        auto ptr = memchr(haystack.ptr, needle, haystack.length);
                        return ptr ?
                             haystack[cast(char*) ptr - haystack.ptr .. $] :
                             haystack[$ .. $];
                    }
                    return trustedMemchr(haystack, needle);
                }
            }

            //Ditto, but for UTF16
            static if (is(UEEType == wchar))
            {
                if (canSearchInCodeUnits!wchar(needle))
                {
                    foreach (i, ref EEType e; haystack)
                    {
                        if (e == needle)
                            return haystack[i .. $];
                    }
                    return haystack[$ .. $];
                }
            }
        }

        //Previous conditional optimizations did not succeed. Fallback to
        //unconditional implementations
        static if (isDefaultPred)
        {
            import std.utf : encode;

            //In case of default pred, it is faster to do string/string search.
            UEEType[is(UEEType == char) ? 4 : 2] buf;

            size_t len = encode(buf, needle);
            return find(haystack, buf[0 .. len]);
        }
        else
        {
            import std.utf : decode;

            //Explicit pred: we must test each character by the book.
            //We choose a manual decoding approach, because it is faster than
            //the built-in foreach, or doing a front/popFront for-loop.
            immutable len = haystack.length;
            size_t i = 0, next = 0;
            while (next < len)
            {
                if (predFun(decode(haystack, next), needle))
                    return haystack[i .. $];
                i = next;
            }
            return haystack[$ .. $];
        }
    }
    else static if (isArray!R)
    {
        // https://issues.dlang.org/show_bug.cgi?id=10403 optimization
        static if (isDefaultPred && isIntegral!EType && EType.sizeof == 1 && isIntegralNeedle)
        {
            import std.algorithm.comparison : max, min;

            R findHelper(return scope ref R haystack, ref E needle) @trusted nothrow pure
            {
                import core.stdc.string : memchr;

                EType* ptr = null;
                //Note: we use "min/max" to handle sign mismatch.
                if (min(EType.min, needle) == EType.min &&
                    max(EType.max, needle) == EType.max)
                {
                    ptr = cast(EType*) memchr(haystack.ptr, needle,
                        haystack.length);
                }

                return ptr ?
                    haystack[ptr - haystack.ptr .. $] :
                    haystack[$ .. $];
            }

            if (!__ctfe)
                return findHelper(haystack, needle);
        }

        //Default implementation.
        foreach (i, ref e; haystack)
            if (predFun(e, needle))
                return haystack[i .. $];
        return haystack[$ .. $];
    }
    else
    {
        //Everything else. Walk.
        for ( ; !haystack.empty; haystack.popFront() )
        {
            if (predFun(haystack.front, needle))
                break;
        }
        return haystack;
    }
}

///
@safe unittest
{
    import std.range.primitives;

    auto arr = [1, 2, 4, 4, 4, 4, 5, 6, 9];
    assert(arr.find(4) == [4, 4, 4, 4, 5, 6, 9]);
    assert(arr.find(1) == arr);
    assert(arr.find(9) == [9]);
    assert(arr.find!((e, n) => e > n)(4) == [5, 6, 9]);
    assert(arr.find!((e, n) => e < n)(4) == arr);
    assert(arr.find(0).empty);
    assert(arr.find(10).empty);
    assert(arr.find(8).empty);

    assert(find("hello, world", ',') == ", world");
}

/// Case-insensitive find of a string
@safe unittest
{
    import std.range.primitives;
    import std.uni : toLower;

    string[] s = ["Hello", "world", "!"];
    assert(s.find!((e, n) => toLower(e) == n)("hello") == s);
}

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

    auto lst = SList!int(1, 2, 5, 7, 3);
    assert(lst.front == 1);
    auto r = find(lst[], 5);
    assert(equal(r, SList!int(5, 7, 3)[]));
    assert(find([1, 2, 3, 5], 4).empty);
    assert(equal(find!"a > b"("hello", 'k'), "llo"));
}

@safe pure nothrow unittest
{
    assert(!find              ([1, 2, 3], 2).empty);
    assert(!find!((a,b)=>a == b)([1, 2, 3], 2).empty);
    assert(!find              ([1, 2, 3], 2).empty);
    assert(!find!((a,b)=>a == b)([1, 2, 3], 2).empty);
}

@safe pure unittest
{
    import std.meta : AliasSeq;
    static foreach (R; AliasSeq!(string, wstring, dstring))
    {
        static foreach (E; AliasSeq!(char, wchar, dchar))
        {
            assert(find              ("hello world", 'w') == "world");
            assert(find!((a,b)=>a == b)("hello world", 'w') == "world");
            assert(find              ("日c語", 'c') == "c語");
            assert(find!((a,b)=>a == b)("日c語", 'c') == "c語");
            assert(find              ("0123456789", 'A').empty);
            static if (E.sizeof >= 2)
            {
                assert(find              ("日本語", '本') == "本語");
                assert(find!((a,b)=>a == b)("日本語", '本') == "本語");
            }
        }
    }
}

@safe unittest
{
    //CTFE
    static assert(find("abc", 'b') == "bc");
    static assert(find("日b語", 'b') == "b語");
    static assert(find("日本語", '本') == "本語");
    static assert(find([1, 2, 3], 2)  == [2, 3]);

    static assert(find              ([1, 2, 3], 2));
    static assert(find!((a,b)=>a == b)([1, 2, 3], 2));
    static assert(find              ([1, 2, 3], 2));
    static assert(find!((a,b)=>a == b)([1, 2, 3], 2));
}

@safe unittest
{
    import std.exception : assertCTFEable;
    import std.meta : AliasSeq;

    void dg() @safe pure nothrow
    {
        byte[]  sarr = [1, 2, 3, 4];
        ubyte[] uarr = [1, 2, 3, 4];
        static foreach (arr; AliasSeq!(sarr, uarr))
        {
            static foreach (T; AliasSeq!(byte, ubyte, int, uint))
            {
                assert(find(arr, cast(T) 3) == arr[2 .. $]);
                assert(find(arr, cast(T) 9) == arr[$ .. $]);
            }
            assert(find(arr, 256) == arr[$ .. $]);
        }
    }
    dg();
    assertCTFEable!dg;
}

// https://issues.dlang.org/show_bug.cgi?id=11603
@safe unittest
{
    enum Foo : ubyte { A }
    assert([Foo.A].find(Foo.A).empty == false);

    ubyte x = 0;
    assert([x].find(x).empty == false);
}

/// ditto
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, scope R2 needle)
if (isForwardRange!R1 && isForwardRange!R2
        && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool))
{
    static if (!isRandomAccessRange!R1)
    {
        static if (is(typeof(pred == "a == b")) && pred == "a == b" && isSomeString!R1 && isSomeString!R2
                && haystack[0].sizeof == needle[0].sizeof)
        {
            // return cast(R1) find(representation(haystack), representation(needle));
            // Specialization for simple string search
            alias Representation =
                Select!(haystack[0].sizeof == 1, ubyte[],
                    Select!(haystack[0].sizeof == 2, ushort[], uint[]));
            // Will use the array specialization
            static TO force(TO, T)(inout T r) @trusted { return cast(TO) r; }
            return force!R1(.find!(pred, Representation, Representation)
                (force!Representation(haystack), force!Representation(needle)));
        }
        else
        {
            return simpleMindedFind!pred(haystack, needle);
        }
    }
    else static if (!isBidirectionalRange!R2 || !hasSlicing!R1)
    {
        static if (!is(ElementType!R1 == ElementType!R2))
        {
            return simpleMindedFind!pred(haystack, needle);
        }
        else
        {
            // Prepare the search with needle's first element
            if (needle.empty)
                return haystack;

            haystack = .find!pred(haystack, needle.front);

            static if (hasLength!R1 && hasLength!R2 && is(typeof(takeNone(haystack)) == R1))
            {
                if (needle.length > haystack.length)
                    return takeNone(haystack);
            }
            else
            {
                if (haystack.empty)
                    return haystack;
            }

            needle.popFront();
            size_t matchLen = 1;

            // Loop invariant: haystack[0 .. matchLen] matches everything in
            // the initial needle that was popped out of needle.
            for (;;)
            {
                // Extend matchLength as much as possible
                for (;;)
                {
                    import std.range : takeNone;

                    if (needle.empty || haystack.empty)
                        return haystack;

                    static if (hasLength!R1 && is(typeof(takeNone(haystack)) == R1))
                    {
                        if (matchLen == haystack.length)
                            return takeNone(haystack);
                    }

                    if (!binaryFun!pred(haystack[matchLen], needle.front))
                        break;

                    ++matchLen;
                    needle.popFront();
                }

                auto bestMatch = haystack[0 .. matchLen];
                haystack.popFront();
                haystack = .find!pred(haystack, bestMatch);
            }
        }
    }
    else // static if (hasSlicing!R1 && isBidirectionalRange!R2)
    {
        if (needle.empty) return haystack;

        static if (hasLength!R2)
        {
            immutable needleLength = needle.length;
        }
        else
        {
            immutable needleLength = walkLength(needle.save);
        }
        if (needleLength > haystack.length)
        {
            return haystack[haystack.length .. haystack.length];
        }
        // Optimization in case the ranges are both SortedRanges.
        // Binary search can be used to find the first occurence
        // of the first element of the needle in haystack.
        // When it is found O(walklength(needle)) steps are performed.
        // https://issues.dlang.org/show_bug.cgi?id=8829 enhancement
        import std.algorithm.comparison : mismatch;
        import std.range : SortedRange;
        static if (is(R1 == R2)
                && is(R1 : SortedRange!TT, TT)
                && pred == "a == b")
        {
            auto needleFirstElem = needle[0];
            auto partitions      = haystack.trisect(needleFirstElem);
            auto firstElemLen    = partitions[1].length;
            size_t count         = 0;

            if (firstElemLen == 0)
                return haystack[$ .. $];

            while (needle.front() == needleFirstElem)
            {
                needle.popFront();
                ++count;

                if (count > firstElemLen)
                    return haystack[$ .. $];
            }

            auto m = mismatch(partitions[2], needle);

            if (m[1].empty)
                return haystack[partitions[0].length + partitions[1].length - count .. $];
        }
        else static if (isRandomAccessRange!R2)
        {
            immutable lastIndex = needleLength - 1;
            auto last = needle[lastIndex];
            size_t j = lastIndex, skip = 0;
            for (; j < haystack.length;)
            {
                if (!binaryFun!pred(haystack[j], last))
                {
                    ++j;
                    continue;
                }
                immutable k = j - lastIndex;
                // last elements match
                for (size_t i = 0;; ++i)
                {
                    if (i == lastIndex)
                        return haystack[k .. haystack.length];
                    if (!binaryFun!pred(haystack[k + i], needle[i]))
                        break;
                }
                if (skip == 0)
                {
                    skip = 1;
                    while (skip < needleLength && needle[needleLength - 1 - skip] != needle[needleLength - 1])
                    {
                        ++skip;
                    }
                }
                j += skip;
            }
        }
        else
        {
            // @@@BUG@@@
            // auto needleBack = moveBack(needle);
            // Stage 1: find the step
            size_t step = 1;
            auto needleBack = needle.back;
            needle.popBack();
            for (auto i = needle.save; !i.empty && i.back != needleBack;
                    i.popBack(), ++step)
            {
            }
            // Stage 2: linear find
            size_t scout = needleLength - 1;
            for (;;)
            {
                if (scout >= haystack.length)
                    break;
                if (!binaryFun!pred(haystack[scout], needleBack))
                {
                    ++scout;
                    continue;
                }
                // Found a match with the last element in the needle
                auto cand = haystack[scout + 1 - needleLength .. haystack.length];
                if (startsWith!pred(cand, needle))
                {
                    // found
                    return cand;
                }
                scout += step;
            }
        }
        return haystack[haystack.length .. haystack.length];
    }
}

///
@safe unittest
{
    import std.container : SList;
    import std.range.primitives : empty;
    import std.typecons : Tuple;

    assert(find("hello, world", "World").empty);
    assert(find("hello, world", "wo") == "world");
    assert([1, 2, 3, 4].find(SList!int(2, 3)[]) == [2, 3, 4]);
    alias C = Tuple!(int, "x", int, "y");
    auto a = [C(1,0), C(2,0), C(3,1), C(4,0)];
    assert(a.find!"a.x == b"([2, 3]) == [C(2,0), C(3,1), C(4,0)]);
    assert(a[1 .. $].find!"a.x == b"([2, 3]) == [C(2,0), C(3,1), C(4,0)]);
}

@safe unittest
{
    import std.container : SList;
    alias C = Tuple!(int, "x", int, "y");
    assert([C(1,0), C(2,0), C(3,1), C(4,0)].find!"a.x == b"(SList!int(2, 3)[]) == [C(2,0), C(3,1), C(4,0)]);
}

// https://issues.dlang.org/show_bug.cgi?id=12470
@safe unittest
{
    import std.array : replace;
    inout(char)[] sanitize(inout(char)[] p)
    {
        return p.replace("\0", " ");
    }
    assert(sanitize("O\x00o") == "O o");
}

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

    auto lst = SList!int(1, 2, 5, 7, 3);
    static assert(isForwardRange!(int[]));
    static assert(isForwardRange!(typeof(lst[])));
    auto r = find(lst[], [2, 5]);
    assert(equal(r, SList!int(2, 5, 7, 3)[]));
}

@safe unittest
{
    import std.range : assumeSorted;

    auto r1 = assumeSorted([1, 2, 3, 3, 3, 4, 5, 6, 7, 8, 8, 8, 10]);
    auto r2 = assumeSorted([3, 3, 4, 5, 6, 7, 8, 8]);
    auto r3 = assumeSorted([3, 4, 5, 6, 7, 8]);
    auto r4 = assumeSorted([4, 5, 6]);
    auto r5 = assumeSorted([12, 13]);
    auto r6 = assumeSorted([8, 8, 10, 11]);
    auto r7 = assumeSorted([3, 3, 3, 3, 3, 3, 3]);

    assert(find(r1, r2) == assumeSorted([3, 3, 4, 5, 6, 7, 8, 8, 8, 10]));
    assert(find(r1, r3) == assumeSorted([3, 4, 5, 6, 7, 8, 8, 8, 10]));
    assert(find(r1, r4) == assumeSorted([4, 5, 6, 7, 8, 8, 8, 10]));
    assert(find(r1, r5).empty());
    assert(find(r1, r6).empty());
    assert(find(r1, r7).empty());
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    // @@@BUG@@@ removing static below makes unittest fail
    static struct BiRange
    {
        int[] payload;
        @property bool empty() { return payload.empty; }
        @property BiRange save() { return this; }
        @property ref int front() { return payload[0]; }
        @property ref int back() { return payload[$ - 1]; }
        void popFront() { return payload.popFront(); }
        void popBack() { return payload.popBack(); }
    }
    auto r = BiRange([1, 2, 3, 10, 11, 4]);
    assert(equal(find(r, [10, 11]), [10, 11, 4]));
}

@safe unittest
{
    import std.container : SList;

    assert(find([ 1, 2, 3 ], SList!int(2, 3)[]) == [ 2, 3 ]);
    assert(find([ 1, 2, 1, 2, 3, 3 ], SList!int(2, 3)[]) == [ 2, 3, 3 ]);
}

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

    auto haystack = [1, 2, 3, 4, 1, 9, 12, 42];
    auto needle = [12, 42, 27];

    //different overload of find, but it's the base case.
    assert(find(haystack, needle).empty);

    assert(find(haystack, takeExactly(filter!"true"(needle), 3)).empty);
    assert(find(haystack, filter!"true"(needle)).empty);
}

// https://issues.dlang.org/show_bug.cgi?id=11013
@safe unittest
{
    assert(find!"a == a"("abc","abc") == "abc");
}

// Internally used by some find() overloads above
private R1 simpleMindedFind(alias pred, R1, R2)(R1 haystack, scope R2 needle)
{
    enum estimateNeedleLength = hasLength!R1 && !hasLength!R2;

    static if (hasLength!R1)
    {
        static if (!hasLength!R2)
            size_t estimatedNeedleLength = 0;
        else
            immutable size_t estimatedNeedleLength = needle.length;
    }

    bool haystackTooShort()
    {
        static if (estimateNeedleLength)
        {
            return haystack.length < estimatedNeedleLength;
        }
        else
        {
            return haystack.empty;
        }
    }

  searching:
    for (;; haystack.popFront())
    {
        if (haystackTooShort())
        {
            // Failed search
            static if (hasLength!R1)
            {
                static if (is(typeof(haystack[haystack.length ..
                                                haystack.length]) : R1))
                    return haystack[haystack.length .. haystack.length];
                else
                    return R1.init;
            }
            else
            {
                assert(haystack.empty, "Haystack must be empty by now");
                return haystack;
            }
        }
        static if (estimateNeedleLength)
            size_t matchLength = 0;
        for (auto h = haystack.save, n = needle.save;
             !n.empty;
             h.popFront(), n.popFront())
        {
            if (h.empty || !binaryFun!pred(h.front, n.front))
            {
                // Failed searching n in h
                static if (estimateNeedleLength)
                {
                    if (estimatedNeedleLength < matchLength)
                        estimatedNeedleLength = matchLength;
                }
                continue searching;
            }
            static if (estimateNeedleLength)
                ++matchLength;
        }
        break;
    }
    return haystack;
}

@safe unittest
{
    // Test simpleMindedFind for the case where both haystack and needle have
    // length.
    struct CustomString
    {
    @safe:
        string _impl;

        // This is what triggers https://issues.dlang.org/show_bug.cgi?id=7992.
        @property size_t length() const { return _impl.length; }
        @property void length(size_t len) { _impl.length = len; }

        // This is for conformance to the forward range API (we deliberately
        // make it non-random access so that we will end up in
        // simpleMindedFind).
        @property bool empty() const { return _impl.empty; }
        @property dchar front() const { return _impl.front; }
        void popFront() { _impl.popFront(); }
        @property CustomString save() { return this; }
    }

    // If https://issues.dlang.org/show_bug.cgi?id=7992 occurs, this will throw an exception from calling
    // popFront() on an empty range.
    auto r = find(CustomString("a"), CustomString("b"));
    assert(r.empty);
}

/**
Finds two or more `needles` into a `haystack`. The predicate $(D
pred) is used throughout to compare elements. By default, elements are
compared for equality.

Params:

pred = The predicate to use for comparing elements.

haystack = The target of the search. Must be an input range.
If any of `needles` is a range with elements comparable to
elements in `haystack`, then `haystack` must be a
$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
such that the search can backtrack.

needles = One or more items to search for. Each of `needles` must
be either comparable to one element in `haystack`, or be itself a
forward range with elements comparable with elements in
`haystack`.

Returns:

A tuple containing `haystack` positioned to match one of the
needles and also the 1-based index of the matching element in $(D
needles) (0 if none of `needles` matched, 1 if `needles[0]`
matched, 2 if `needles[1]` matched...). The first needle to be found
will be the one that matches. If multiple needles are found at the
same spot in the range, then the shortest one is the one which matches
(if multiple needles of the same length are found at the same spot (e.g
`"a"` and `'a'`), then the left-most of them in the argument list
matches).

The relationship between `haystack` and `needles` simply means
that one can e.g. search for individual `int`s or arrays of $(D
int)s in an array of `int`s. In addition, if elements are
individually comparable, searches of heterogeneous types are allowed
as well: a `double[]` can be searched for an `int` or a $(D
short[]), and conversely a `long` can be searched for a `float`
or a `double[]`. This makes for efficient searches without the need
to coerce one side of the comparison into the other's side type.

The complexity of the search is $(BIGOH haystack.length *
max(needles.length)). (For needles that are individual items, length
is considered to be 1.) The strategy used in searching several
subranges at once maximizes cache usage by moving in `haystack` as
few times as possible.
 */
Tuple!(Range, size_t) find(alias pred = "a == b", Range, Needles...)
(Range haystack, Needles needles)
if (Needles.length > 1 && is(typeof(startsWith!pred(haystack, needles))))
{
    for (;; haystack.popFront())
    {
        size_t r = startsWith!pred(haystack, needles);
        if (r || haystack.empty)
        {
            return tuple(haystack, r);
        }
    }
}

///
@safe unittest
{
    import std.typecons : tuple;
    int[] a = [ 1, 4, 2, 3 ];
    assert(find(a, 4) == [ 4, 2, 3 ]);
    assert(find(a, [ 1, 4 ]) == [ 1, 4, 2, 3 ]);
    assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2));
    // Mixed types allowed if comparable
    assert(find(a, 5, [ 1.2, 3.5 ], 2.0) == tuple([ 2, 3 ], 3));
}

@safe unittest
{
    auto s1 = "Mary has a little lamb";
    assert(find(s1, "has a", "has an") == tuple("has a little lamb", 1));
    assert(find(s1, 't', "has a", "has an") == tuple("has a little lamb", 2));
    assert(find(s1, 't', "has a", 'y', "has an") == tuple("y has a little lamb", 3));
    assert(find("abc", "bc").length == 2);
}

@safe unittest
{
    import std.algorithm.internal : rndstuff;
    import std.meta : AliasSeq;
    import std.uni : toUpper;

    int[] a = [ 1, 2, 3 ];
    assert(find(a, 5).empty);
    assert(find(a, 2) == [2, 3]);

    foreach (T; AliasSeq!(int, double))
    {
        auto b = rndstuff!(T)();
        if (!b.length) continue;
        b[$ / 2] = 200;
        b[$ / 4] = 200;
        assert(find(b, 200).length == b.length - b.length / 4);
    }

    // Case-insensitive find of a string
    string[] s = [ "Hello", "world", "!" ];
    assert(find!("toUpper(a) == toUpper(b)")(s, "hello").length == 3);

    static bool f(string a, string b) { return toUpper(a) == toUpper(b); }
    assert(find!(f)(s, "hello").length == 3);
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.internal : rndstuff;
    import std.meta : AliasSeq;
    import std.range : retro;

    int[] a = [ 1, 2, 3, 2, 6 ];
    assert(find(retro(a), 5).empty);
    assert(equal(find(retro(a), 2), [ 2, 3, 2, 1 ][]));

    foreach (T; AliasSeq!(int, double))
    {
        auto b = rndstuff!(T)();
        if (!b.length) continue;
        b[$ / 2] = 200;
        b[$ / 4] = 200;
        assert(find(retro(b), 200).length ==
                b.length - (b.length - 1) / 2);
    }
}

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

    int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];
    int[] b = [ 1, 2, 3 ];
    assert(find(a, b) == [ 1, 2, 3, 4, 5 ]);
    assert(find(b, a).empty);

    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        auto findRes = find(d, 5);
        assert(equal(findRes, [5,6,7,8,9,10]));
    }
}

/**
 * Finds `needle` in `haystack` efficiently using the
 * $(LINK2 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm,
 * Boyer-Moore) method.
 *
 * Params:
 * haystack = A random-access range with length and slicing.
 * needle = A $(LREF BoyerMooreFinder).
 *
 * Returns:
 * `haystack` advanced such that `needle` is a prefix of it (if no
 * such position exists, returns `haystack` advanced to termination).
 */
RandomAccessRange find(RandomAccessRange, alias pred, InputRange)(
    RandomAccessRange haystack, scope BoyerMooreFinder!(pred, InputRange) needle)
{
    return needle.beFound(haystack);
}

@safe unittest
{
    string h = "/homes/aalexand/d/dmd/bin/../lib/libphobos.a(dmain2.o)"~
        "(.gnu.linkonce.tmain+0x74): In function `main' undefined reference"~
        " to `_Dmain':";
    string[] ns = ["libphobos", "function", " undefined", "`", ":"];
    foreach (n ; ns)
    {
        auto p = find(h, boyerMooreFinder(n));
        assert(!p.empty);
    }
}

///
@safe unittest
{
    import std.range.primitives : empty;
    int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];
    int[] b = [ 1, 2, 3 ];

    assert(find(a, boyerMooreFinder(b)) == [ 1, 2, 3, 4, 5 ]);
    assert(find(b, boyerMooreFinder(a)).empty);
}

@safe unittest
{
    auto bm = boyerMooreFinder("for");
    auto match = find("Moor", bm);
    assert(match.empty);
}

// canFind
/++
Convenience function. Like find, but only returns whether or not the search
was successful.

For more information about `pred` see $(LREF find).

See_Also:
$(REF among, std,algorithm,comparison) for checking a value against multiple arguments.
 +/
template canFind(alias pred="a == b")
{
    /++
    Returns `true` if and only if `pred(e)` is true for any value `e` in the
    input range `range`.
    Performs (at most) $(BIGOH haystack.length) evaluations of `pred`.
     +/
    bool canFind(Range)(Range haystack)
    if (is(typeof(find!pred(haystack))))
    {
        return any!pred(haystack);
    }

    /++
    Returns `true` if and only if `needle` can be found in $(D
    range). Performs $(BIGOH haystack.length) evaluations of `pred`.
     +/
    bool canFind(Range, Element)(Range haystack, scope Element needle)
    if (is(typeof(find!pred(haystack, needle))))
    {
        return !find!pred(haystack, needle).empty;
    }

    /++
    Returns the 1-based index of the first needle found in `haystack`. If no
    needle is found, then `0` is returned.

    So, if used directly in the condition of an `if` statement or loop, the result
    will be `true` if one of the needles is found and `false` if none are
    found, whereas if the result is used elsewhere, it can either be cast to
    `bool` for the same effect or used to get which needle was found first
    without having to deal with the tuple that $(LREF find) returns for the
    same operation.
     +/
    size_t canFind(Range, Needles...)(Range haystack, scope Needles needles)
    if (Needles.length > 1 &&
        is(typeof(find!pred(haystack, needles))))
    {
        return find!pred(haystack, needles)[1];
    }
}

///
@safe unittest
{
    const arr = [0, 1, 2, 3];
    assert(canFind(arr, 2));
    assert(!canFind(arr, 4));

    // find one of several needles
    assert(arr.canFind(3, 2));
    assert(arr.canFind(3, 2) == 2); // second needle found
    assert(arr.canFind([1, 3], 2) == 2);

    assert(canFind(arr, [1, 2], [2, 3]));
    assert(canFind(arr, [1, 2], [2, 3]) == 1);
    assert(canFind(arr, [1, 7], [2, 3]));
    assert(canFind(arr, [1, 7], [2, 3]) == 2);
    assert(!canFind(arr, [1, 3], [2, 4]));
    assert(canFind(arr, [1, 3], [2, 4]) == 0);
}

/**
 * Example using a custom predicate.
 * Note that the needle appears as the second argument of the predicate.
 */
@safe unittest
{
    auto words = [
        "apple",
        "beeswax",
        "cardboard"
    ];
    assert(!canFind(words, "bees"));
    assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));
}

/// Search for multiple items in an array of items (search for needles in an array of haystacks)
@safe unittest
{
    string s1 = "aaa111aaa";
    string s2 = "aaa222aaa";
    string s3 = "aaa333aaa";
    string s4 = "aaa444aaa";
    const hay = [s1, s2, s3, s4];
    assert(hay.canFind!(e => e.canFind("111", "222")));
}

@safe unittest
{
    import std.algorithm.internal : rndstuff;

    auto a = rndstuff!(int)();
    if (a.length)
    {
        auto b = a[a.length / 2];
        assert(canFind(a, b));
    }
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    assert(equal!(canFind!"a < b")([[1, 2, 3], [7, 8, 9]], [2, 8]));
}

// findAdjacent
/**
Advances `r` until it finds the first two adjacent elements `a`,
`b` that satisfy `pred(a, b)`. Performs $(BIGOH r.length)
evaluations of `pred`.

For more information about `pred` see $(LREF find).

Params:
    pred = The predicate to satisfy.
    r = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to
        search in.

Returns:
`r` advanced to the first occurrence of two adjacent elements that satisfy
the given predicate. If there are no such two elements, returns `r` advanced
until empty.

See_Also:
     $(LINK2 http://en.cppreference.com/w/cpp/algorithm/adjacent_find, STL's `adjacent_find`)
*/
Range findAdjacent(alias pred = "a == b", Range)(Range r)
if (isForwardRange!(Range))
{
    auto ahead = r.save;
    if (!ahead.empty)
    {
        for (ahead.popFront(); !ahead.empty; r.popFront(), ahead.popFront())
        {
            if (binaryFun!(pred)(r.front, ahead.front)) return r;
        }
    }
    static if (!isInfinite!Range)
        return ahead;
    assert(0);
}

///
@safe unittest
{
    int[] a = [ 11, 10, 10, 9, 8, 8, 7, 8, 9 ];
    auto r = findAdjacent(a);
    assert(r == [ 10, 10, 9, 8, 8, 7, 8, 9 ]);
    auto p = findAdjacent!("a < b")(a);
    assert(p == [ 7, 8, 9 ]);

}

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

    int[] a = [ 11, 10, 10, 9, 8, 8, 7, 8, 9 ];
    auto p = findAdjacent(a);
    assert(p == [10, 10, 9, 8, 8, 7, 8, 9 ]);
    p = findAdjacent!("a < b")(a);
    assert(p == [7, 8, 9]);
    // empty
    a = [];
    p = findAdjacent(a);
    assert(p.empty);
    // not found
    a = [ 1, 2, 3, 4, 5 ];
    p = findAdjacent(a);
    assert(p.empty);
    p = findAdjacent!"a > b"(a);
    assert(p.empty);
    ReferenceForwardRange!int rfr = new ReferenceForwardRange!int([1, 2, 3, 2, 2, 3]);
    assert(equal(findAdjacent(rfr), [2, 2, 3]));

    // https://issues.dlang.org/show_bug.cgi?id=9350
    assert(!repeat(1).findAdjacent().empty);
}

// findAmong
/**
Searches the given range for an element that matches one of the given choices.

Advances `seq` by calling `seq.popFront` until either
`find!(pred)(choices, seq.front)` is `true`, or `seq` becomes empty.
Performs $(BIGOH seq.length * choices.length) evaluations of `pred`.

For more information about `pred` see $(LREF find).

Params:
    pred = The predicate to use for determining a match.
    seq = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to
        search.
    choices = A $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
        of possible choices.

Returns:
`seq` advanced to the first matching element, or until empty if there are no
matching elements.

See_Also: $(LREF find), $(REF among, std,algorithm,comparison)
*/
InputRange findAmong(alias pred = "a == b", InputRange, ForwardRange)(
    InputRange seq, ForwardRange choices)
if (isInputRange!InputRange && isForwardRange!ForwardRange)
{
    for (; !seq.empty && find!pred(choices.save, seq.front).empty; seq.popFront())
    {
    }
    return seq;
}

///
@safe unittest
{
    int[] a = [ -1, 0, 1, 2, 3, 4, 5 ];
    int[] b = [ 3, 1, 2 ];
    assert(findAmong(a, b) == a[2 .. $]);
}

@safe unittest
{
    int[] a = [ -1, 0, 2, 1, 2, 3, 4, 5 ];
    int[] b = [ 1, 2, 3 ];
    assert(findAmong(a, b) == [2, 1, 2, 3, 4, 5 ]);
    assert(findAmong(b, [ 4, 6, 7 ][]).empty);
    assert(findAmong!("a == b")(a, b).length == a.length - 2);
    assert(findAmong!("a == b")(b, [ 4, 6, 7 ][]).empty);
}

// https://issues.dlang.org/show_bug.cgi?id=19765
@system unittest
{
    import std.range.interfaces : inputRangeObject;
    auto choices = inputRangeObject("b");
    auto f = "foobar".findAmong(choices);
    assert(f == "bar");
}

// findSkip
/**
 * Finds `needle` in `haystack` and positions `haystack`
 * right after the first occurrence of `needle`.
 *
 * If no needle is provided, the `haystack` is advanced as long as `pred`
 * evaluates to `true`.
 * Similarly, the haystack is positioned so as `pred` evaluates to `false` for
 * `haystack.front`.
 *
 * For more information about `pred` see $(LREF find).

 * Params:
 *  haystack = The
 *   $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to search
 *   in.
 *  needle = The
 *   $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to search
 *   for.
 *  pred = Custom predicate for comparison of haystack and needle
 *
 * Returns: `true` if the needle was found, in which case `haystack` is
 * positioned after the end of the first occurrence of `needle`; otherwise
 * `false`, leaving `haystack` untouched. If no needle is provided, it returns
 *  the number of times `pred(haystack.front)` returned true.
 *
 * See_Also: $(LREF find)
 */
bool findSkip(alias pred = "a == b", R1, R2)(ref R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2
        && is(typeof(binaryFun!pred(haystack.front, needle.front))))
{
    auto parts = findSplit!pred(haystack, needle);
    if (parts[1].empty) return false;
    // found
    haystack = parts[2];
    return true;
}

///
@safe unittest
{
    import std.range.primitives : empty;
    // Needle is found; s is replaced by the substring following the first
    // occurrence of the needle.
    string s = "abcdef";
    assert(findSkip(s, "cd") && s == "ef");

    // Needle is not found; s is left untouched.
    s = "abcdef";
    assert(!findSkip(s, "cxd") && s == "abcdef");

    // If the needle occurs at the end of the range, the range is left empty.
    s = "abcdef";
    assert(findSkip(s, "def") && s.empty);
}

// https://issues.dlang.org/show_bug.cgi?id=19020
@safe unittest
{
    static struct WrapperRange
    {
        string _r;
        @property auto empty() { return _r.empty(); }
        @property auto front() { return _r.front(); }
        auto popFront() { return _r.popFront(); }
        @property auto save() { return WrapperRange(_r.save); }
    }
    auto tmp = WrapperRange("there is a bug here: *");
    assert(!tmp.findSkip("*/"));
    assert(tmp._r == "there is a bug here: *");
}

/// ditto
size_t findSkip(alias pred, R1)(ref R1 haystack)
if (isForwardRange!R1 && ifTestable!(typeof(haystack.front), unaryFun!pred))
{
    size_t result;
    while (!haystack.empty && unaryFun!pred(haystack.front))
    {
        result++;
        haystack.popFront;
    }
    return result;
}

///
@safe unittest
{
    import std.ascii : isWhite;
    string s = "    abc";
    assert(findSkip!isWhite(s) && s == "abc");
    assert(!findSkip!isWhite(s) && s == "abc");

    s = "  ";
    assert(findSkip!isWhite(s) == 2);
}

@safe unittest
{
    import std.ascii : isWhite;

    auto s = "  ";
    assert(findSkip!isWhite(s) == 2);
}

private struct FindSplitResult(ubyte emptyRangeIndex, Types...)
{
    this(Types vals)
    {
        asTuple = typeof(asTuple)(vals);
    }
    void opAssign(typeof(asTuple) rhs)
    {
        asTuple = rhs;
    }
    Tuple!Types asTuple;
    alias asTuple this;

    static if (hasConstEmptyMember!(typeof(asTuple[emptyRangeIndex])))
    {
        bool opCast(T : bool)() const => !asTuple[emptyRangeIndex].empty;
    }
    else
    {
        bool opCast(T : bool)() => !asTuple[emptyRangeIndex].empty;
    }
}

/**
These functions find the first occurrence of `needle` in `haystack` and then
split `haystack` as follows.

$(PANEL
`findSplit` returns a tuple `result` containing $(I three) ranges.
$(UL
$(LI `result[0]` is the portion of `haystack` before `needle`)
$(LI `result[1]` is the portion of
`haystack` that matches `needle`)
$(LI `result[2]` is the portion of `haystack`
after the match.)
)
If `needle` was not found, `result[0]` comprehends `haystack`
entirely and `result[1]` and `result[2]` are empty.

`findSplitBefore` returns a tuple `result` containing two ranges.
$(UL
$(LI `result[0]` is the portion of `haystack` before `needle`)
$(LI `result[1]` is the balance of `haystack` starting with the match.)
)
If `needle` was not found, `result[0]`
comprehends `haystack` entirely and `result[1]` is empty.

`findSplitAfter` returns a tuple `result` containing two ranges.
$(UL
$(LI `result[0]` is the portion of `haystack` up to and including the
match)
$(LI `result[1]` is the balance of `haystack` starting
after the match.)
)
If `needle` was not found, `result[0]` is empty
and `result[1]` is `haystack`.
)
$(P
In all cases, the concatenation of the returned ranges spans the
entire `haystack`.

If `haystack` is a random-access range, all three components of the tuple have
the same type as `haystack`. Otherwise, `haystack` must be a
$(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) and
the type of `result[0]` (and `result[1]` for `findSplit`) is the same as
the result of $(REF takeExactly, std,range).

For more information about `pred` see $(LREF find).
)
Params:
    pred = Predicate to compare 2 elements.
    haystack = The forward range to search.
    needle = The forward range to look for.

Returns:

A sub-type of $(REF Tuple, std, typecons) of the split portions of `haystack` (see above for
details). This sub-type of `Tuple` defines `opCast!bool`, which
returns `true` when the separating `needle` was found and `false` otherwise.

See_Also: $(LREF find)
 */
auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2)
{
    static if (isSomeString!R1 && isSomeString!R2
            || (isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && hasLength!R2))
    {
        auto balance = find!pred(haystack, needle);
        immutable pos1 = haystack.length - balance.length;
        immutable pos2 = balance.empty ? pos1 : pos1 + needle.length;
        alias Slice = typeof(haystack[0 .. pos1]);
        return FindSplitResult!(1, Slice, Slice, Slice)(
            haystack[0 .. pos1], haystack[pos1 .. pos2], haystack[pos2 .. haystack.length]);
    }
    else
    {
        import std.range : takeExactly;
        auto original = haystack.save;
        auto h = haystack.save;
        auto n = needle.save;
        size_t pos1, pos2;
        while (!n.empty && !h.empty)
        {
            if (binaryFun!pred(h.front, n.front))
            {
                h.popFront();
                n.popFront();
                ++pos2;
            }
            else
            {
                haystack.popFront();
                n = needle.save;
                h = haystack.save;
                pos2 = ++pos1;
            }
        }
        if (!n.empty) // incomplete match at the end of haystack
        {
            pos1 = pos2;
        }
        return FindSplitResult!(1,
            typeof(takeExactly(original, pos1)),
            typeof(takeExactly(original, pos1)), typeof(h))(
            takeExactly(original, pos1),
            takeExactly(haystack, pos2 - pos1), h);
    }
}

/// Ditto
auto findSplitBefore(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2)
{
    static if (isSomeString!R1 && isSomeString!R2
            || (isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2))
    {
        auto balance = find!pred(haystack, needle);
        immutable pos = haystack.length - balance.length;
        return FindSplitResult!(1,
            typeof(haystack[0 .. pos]), typeof(haystack[0 .. pos]))(
            haystack[0 .. pos], haystack[pos .. haystack.length]);
    }
    else
    {
        import std.range : takeExactly;
        auto original = haystack.save;
        auto h = haystack.save;
        auto n = needle.save;
        size_t pos1, pos2;
        while (!n.empty && !h.empty)
        {
            if (binaryFun!pred(h.front, n.front))
            {
                h.popFront();
                n.popFront();
                ++pos2;
            }
            else
            {
                haystack.popFront();
                n = needle.save;
                h = haystack.save;
                pos2 = ++pos1;
            }
        }
        if (!n.empty) // incomplete match at the end of haystack
        {
            pos1 = pos2;
            haystack = h;
        }
        return FindSplitResult!(1,
            typeof(takeExactly(original, pos1)), typeof(haystack))(
            takeExactly(original, pos1), haystack);
    }
}

/// Ditto
auto findSplitAfter(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2)
{
    static if (isSomeString!R1 && isSomeString!R2
            || isRandomAccessRange!R1 && hasLength!R1 && hasSlicing!R1 && hasLength!R2)
    {
        auto balance = find!pred(haystack, needle);
        immutable pos = balance.empty ? 0 : haystack.length - balance.length + needle.length;
        return FindSplitResult!(0,
            typeof(haystack[0 .. pos]), typeof(haystack[0 .. pos]))(
            haystack[0 .. pos], haystack[pos .. haystack.length]);
    }
    else
    {
        import std.range : takeExactly;
        alias Res = FindSplitResult!(0, typeof(takeExactly(haystack, 0)), typeof(haystack));
        auto original = haystack.save;
        auto h = haystack.save;
        auto n = needle.save;
        size_t pos1, pos2;
        while (!n.empty)
        {
            if (h.empty)
            {
                // Failed search
                return Res(takeExactly(original, 0), original);
            }
            if (binaryFun!pred(h.front, n.front))
            {
                h.popFront();
                n.popFront();
                ++pos2;
            }
            else
            {
                haystack.popFront();
                n = needle.save;
                h = haystack.save;
                pos2 = ++pos1;
            }
        }
        return Res(takeExactly(original, pos2), h);
    }
}

/// Returning a subtype of $(REF Tuple, std,typecons) enables
/// the following convenient idiom:
@safe pure nothrow unittest
{
    // findSplit returns a triplet
    if (auto split = "dlang-rocks".findSplit("-"))
    {
        assert(split[0] == "dlang");
        assert(split[1] == "-");
        assert(split[2] == "rocks");
    }
    else assert(0);

    // findSplitBefore returns 2 ranges
    if (const split = [2, 3, 2, 3, 4, 1].findSplitBefore!"a > b"([2, 2]))
    {
        assert(split[0] == [2, 3, 2]);
        // [3, 4] each greater than [2, 2]
        assert(split[1] == [3, 4, 1]);
    }
    else assert(0);
}

///
@safe pure nothrow unittest
{
    import std.range.primitives : empty;

    auto a = "Carl Sagan Memorial Station";
    auto r = findSplit(a, "Velikovsky");
    import std.typecons : isTuple;
    static assert(isTuple!(typeof(r.asTuple)));
    static assert(isTuple!(typeof(r)));
    assert(!r);
    assert(r[0] == a);
    assert(r[1].empty);
    assert(r[2].empty);
    r = findSplit(a, " ");
    assert(r[0] == "Carl");
    assert(r[1] == " ");
    assert(r[2] == "Sagan Memorial Station");
    if (const r1 = findSplitBefore(a, "Sagan"))
    {
        assert(r1);
        assert(r1[0] == "Carl ");
        assert(r1[1] == "Sagan Memorial Station");
    }
    if (const r2 = findSplitAfter(a, "Sagan"))
    {
        assert(r2);
        assert(r2[0] == "Carl Sagan");
        assert(r2[1] == " Memorial Station");
    }
}

/// Use $(REF only, std,range) to find single elements:
@safe pure nothrow unittest
{
    import std.range : only;
    assert([1, 2, 3, 4].findSplitBefore(only(3))[0] == [1, 2]);
}

@safe pure nothrow unittest
{
    import std.range.primitives : empty;

    immutable a = [ 1, 2, 3, 4, 5, 6, 7, 8 ];
    auto r = findSplit(a, [9, 1]);
    assert(!r);
    assert(r[0] == a);
    assert(r[1].empty);
    assert(r[2].empty);
    r = findSplit(a, [3]);
    assert(r);
    assert(r[0] == a[0 .. 2]);
    assert(r[1] == a[2 .. 3]);
    assert(r[2] == a[3 .. $]);

    {
        const r1 = findSplitBefore(a, [9, 1]);
        assert(!r1);
        assert(r1[0] == a);
        assert(r1[1].empty);
    }

    if (immutable r1 = findSplitBefore(a, [3, 4]))
    {
        assert(r1);
        assert(r1[0] == a[0 .. 2]);
        assert(r1[1] == a[2 .. $]);
    }
    else assert(0);

    {
        const r2 = findSplitAfter(a, [9, 1]);
        assert(!r2);
        assert(r2[0].empty);
        assert(r2[1] == a);
    }

    if (immutable r3 = findSplitAfter(a, [3, 4]))
    {
        assert(r3);
        assert(r3[0] == a[0 .. 4]);
        assert(r3[1] == a[4 .. $]);
    }
    else assert(0);
}

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

    auto a = [ 1, 2, 3, 4, 5, 6, 7, 8 ];
    auto fwd = filter!"a > 0"(a);
    auto r = findSplit(fwd, [9, 1]);
    assert(!r);
    assert(equal(r[0], a));
    assert(r[1].empty);
    assert(r[2].empty);
    r = findSplit(fwd, [3]);
    assert(r);
    assert(equal(r[0],  a[0 .. 2]));
    assert(equal(r[1], a[2 .. 3]));
    assert(equal(r[2], a[3 .. $]));
    r = findSplit(fwd, [8, 9]);
    assert(!r);
    assert(equal(r[0], a));
    assert(r[1].empty);
    assert(r[2].empty);

    // auto variable `r2` cannot be `const` because `fwd.front` is mutable
    {
        auto r1 = findSplitBefore(fwd, [9, 1]);
        assert(!r1);
        assert(equal(r1[0], a));
        assert(r1[1].empty);
    }

    if (auto r1 = findSplitBefore(fwd, [3, 4]))
    {
        assert(r1);
        assert(equal(r1[0], a[0 .. 2]));
        assert(equal(r1[1], a[2 .. $]));
    }
    else assert(0);

    {
        auto r1 = findSplitBefore(fwd, [8, 9]);
        assert(!r1);
        assert(equal(r1[0], a));
        assert(r1[1].empty);
    }

    {
        auto r2 = findSplitAfter(fwd, [9, 1]);
        assert(!r2);
        assert(r2[0].empty);
        assert(equal(r2[1], a));
    }

    if (auto r2 = findSplitAfter(fwd, [3, 4]))
    {
        assert(r2);
        assert(equal(r2[0], a[0 .. 4]));
        assert(equal(r2[1], a[4 .. $]));
    }
    else assert(0);

    {
        auto r2 = findSplitAfter(fwd, [8, 9]);
        assert(!r2);
        assert(r2[0].empty);
        assert(equal(r2[1], a));
    }
}

@safe pure nothrow @nogc unittest
{
    auto str = "sep,one,sep,two";

    auto split = str.findSplitAfter(",");
    assert(split[0] == "sep,");

    split = split[1].findSplitAfter(",");
    assert(split[0] == "one,");

    split = split[1].findSplitBefore(",");
    assert(split[0] == "sep");
}

@safe pure nothrow @nogc unittest
{
    auto str = "sep,one,sep,two";

    auto split = str.findSplitBefore(",two");
    assert(split[0] == "sep,one,sep");
    assert(split[1] == ",two");

    split = split[0].findSplitBefore(",sep");
    assert(split[0] == "sep,one");
    assert(split[1] == ",sep");

    split = split[0].findSplitAfter(",");
    assert(split[0] == "sep,");
    assert(split[1] == "one");
}

// https://issues.dlang.org/show_bug.cgi?id=11013
@safe pure unittest
{
    auto var = "abc";
    auto split = var.findSplitBefore!q{a == a}(var);
    assert(split[0] == "");
    assert(split[1] == "abc");
}

// minCount
/**

Computes the minimum (respectively maximum) of `range` along with its number of
occurrences. Formally, the minimum is a value `x` in `range` such that $(D
pred(a, x)) is `false` for all values `a` in `range`. Conversely, the maximum is
a value `x` in `range` such that `pred(x, a)` is `false` for all values `a`
in `range` (note the swapped arguments to `pred`).

These functions may be used for computing arbitrary extrema by choosing `pred`
appropriately. For corrrect functioning, `pred` must be a strict partial order,
i.e. transitive (if `pred(a, b) && pred(b, c)` then `pred(a, c)`) and
irreflexive (`pred(a, a)` is `false`). The $(LUCKY trichotomy property of
inequality) is not required: these algorithms consider elements `a` and `b` equal
(for the purpose of counting) if `pred` puts them in the same equivalence class,
i.e. `!pred(a, b) && !pred(b, a)`.

Params:
    pred = The ordering predicate to use to determine the extremum (minimum
        or maximum).
    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to count.

Returns: The minimum, respectively maximum element of a range together with the
number it occurs in the range.

Limitations: If at least one of the arguments is NaN, the result is
an unspecified value. See $(REF maxElement, std,algorithm,searching)
for examples on how to cope with NaNs.

Throws: `Exception` if `range.empty`.

See_Also: $(REF min, std,algorithm,comparison), $(LREF minIndex), $(LREF minElement), $(LREF minPos)
 */
Tuple!(ElementType!Range, size_t)
minCount(alias pred = "a < b", Range)(Range range)
if (isInputRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(range.front, range.front))))
{
    import std.algorithm.internal : algoFormat;
    import std.exception : enforce;

    alias T  = ElementType!Range;
    alias UT = Unqual!T;
    alias RetType = Tuple!(T, size_t);

    static assert(is(typeof(RetType(range.front, 1))),
        algoFormat("Error: Cannot call minCount on a %s, because it is not possible "~
               "to copy the result value (a %s) into a Tuple.", Range.stringof, T.stringof));

    enforce(!range.empty, "Can't count elements from an empty range");
    size_t occurrences = 1;

    static if (isForwardRange!Range)
    {
        Range least = range.save;
        for (range.popFront(); !range.empty; range.popFront())
        {
            if (binaryFun!pred(least.front, range.front))
            {
                assert(!binaryFun!pred(range.front, least.front),
                    "min/maxPos: predicate must be a strict partial order.");
                continue;
            }
            if (binaryFun!pred(range.front, least.front))
            {
                // change the min
                least = range.save;
                occurrences = 1;
            }
            else
                ++occurrences;
        }
        return RetType(least.front, occurrences);
    }
    else static if (isAssignable!(UT, T) || (!hasElaborateAssign!UT && isAssignable!UT))
    {
        UT v = UT.init;
        static if (isAssignable!(UT, T)) v = range.front;
        else                             v = cast(UT) range.front;

        for (range.popFront(); !range.empty; range.popFront())
        {
            if (binaryFun!pred(*cast(T*)&v, range.front)) continue;
            if (binaryFun!pred(range.front, *cast(T*)&v))
            {
                // change the min
                static if (isAssignable!(UT, T)) v = range.front;
                else                             v = cast(UT) range.front; //Safe because !hasElaborateAssign!UT
                occurrences = 1;
            }
            else
                ++occurrences;
        }
        return RetType(*cast(T*)&v, occurrences);
    }
    else static if (hasLvalueElements!Range)
    {
        import std.algorithm.internal : addressOf;
        T* p = addressOf(range.front);
        for (range.popFront(); !range.empty; range.popFront())
        {
            if (binaryFun!pred(*p, range.front)) continue;
            if (binaryFun!pred(range.front, *p))
            {
                // change the min
                p = addressOf(range.front);
                occurrences = 1;
            }
            else
                ++occurrences;
        }
        return RetType(*p, occurrences);
    }
    else
        static assert(false,
            algoFormat("Sorry, can't find the minCount of a %s: Don't know how "~
                   "to keep track of the smallest %s element.", Range.stringof, T.stringof));
}

/// Ditto
Tuple!(ElementType!Range, size_t)
maxCount(alias pred = "a < b", Range)(Range range)
if (isInputRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(range.front, range.front))))
{
    return range.minCount!((a, b) => binaryFun!pred(b, a));
}

///
@safe unittest
{
    import std.conv : text;
    import std.typecons : tuple;

    int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
    // Minimum is 1 and occurs 3 times
    assert(a.minCount == tuple(1, 3));
    // Maximum is 4 and occurs 2 times
    assert(a.maxCount == tuple(4, 2));
}

@system unittest
{
    import std.conv : text;
    import std.exception : assertThrown;
    import std.internal.test.dummyrange;

    int[][] b = [ [4], [2, 4], [4], [4] ];
    auto c = minCount!("a[0] < b[0]")(b);
    assert(c == tuple([2, 4], 1), text(c[0]));

    //Test empty range
    assertThrown(minCount(b[$..$]));

    //test with reference ranges. Test both input and forward.
    assert(minCount(new ReferenceInputRange!int([1, 2, 1, 0, 2, 0])) == tuple(0, 2));
    assert(minCount(new ReferenceForwardRange!int([1, 2, 1, 0, 2, 0])) == tuple(0, 2));
}

@system unittest
{
    import std.conv : text;
    import std.meta : AliasSeq;

    static struct R(T) //input range
    {
        T[] arr;
        alias arr this;
    }

    immutable         a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
    R!(immutable int) b = R!(immutable int)(a);

    assert(minCount(a) == tuple(1, 3));
    assert(minCount(b) == tuple(1, 3));
    assert(minCount!((ref immutable int a, ref immutable int b) => (a > b))(a) == tuple(4, 2));
    assert(minCount!((ref immutable int a, ref immutable int b) => (a > b))(b) == tuple(4, 2));

    immutable(int[])[] c = [ [4], [2, 4], [4], [4] ];
    assert(minCount!("a[0] < b[0]")(c) == tuple([2, 4], 1), text(c[0]));

    static struct S1
    {
        int i;
    }
    alias IS1 = immutable(S1);
    static assert( isAssignable!S1);
    static assert( isAssignable!(S1, IS1));

    static struct S2
    {
        int* p;
        this(ref immutable int i) immutable {p = &i;}
        this(ref int i) {p = &i;}
        @property ref inout(int) i() inout {return *p;}
        bool opEquals(const S2 other) const {return i == other.i;}
    }
    alias IS2 = immutable(S2);
    static assert( isAssignable!S2);
    static assert(!isAssignable!(S2, IS2));
    static assert(!hasElaborateAssign!S2);

    static struct S3
    {
        int i;
        void opAssign(ref S3 other) @disable;
    }
    static assert(!isAssignable!S3);

    static foreach (Type; AliasSeq!(S1, IS1, S2, IS2, S3))
    {{
        static if (is(Type == immutable)) alias V = immutable int;
        else                              alias V = int;
        V one = 1, two = 2;
        auto r1 = [Type(two), Type(one), Type(one)];
        auto r2 = R!Type(r1);
        assert(minCount!"a.i < b.i"(r1) == tuple(Type(one), 2));
        assert(minCount!"a.i < b.i"(r2) == tuple(Type(one), 2));
        assert(one == 1 && two == 2);
    }}
}

/**
Iterates the passed range and returns the minimal element.
A custom mapping function can be passed to `map`.
In other languages this is sometimes called `argmin`.

Complexity: O(n)
    Exactly `n - 1` comparisons are needed.

Params:
    map = custom accessor for the comparison key
    r = range from which the minimal element will be selected
    seed = custom seed to use as initial element

Precondition: If a seed is not given, `r` must not be empty.

Returns: The minimal element of the passed-in range.

Note:
    If at least one of the arguments is NaN, the result is an unspecified value.

    If you want to ignore NaNs, you can use $(REF filter, std,algorithm,iteration)
    and $(REF isNaN, std,math) to remove them, before applying minElement.
    Add a suitable seed, to avoid error messages if all elements are NaNs:

    ---
    <range>.filter!(a=>!a.isNaN).minElement(<seed>);
    ---

    If you want to get NaN as a result if a NaN is present in the range,
    you can use $(REF fold, std,algorithm,iteration) and $(REF isNaN, std,math):

    ---
    <range>.fold!((a,b)=>a.isNaN || b.isNaN ? real.nan : a < b ? a : b);
    ---

See_Also:

    $(LREF extrema), $(LREF maxElement), $(REF min, std,algorithm,comparison), $(LREF minCount),
    $(LREF minIndex), $(LREF minPos)
*/
auto minElement(alias map = (a => a), Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
{
    return extremum!map(r);
}

/// ditto
auto minElement(alias map = (a => a), Range, RangeElementType = ElementType!Range)
               (Range r, RangeElementType seed)
if (isInputRange!Range && !isInfinite!Range &&
    !is(CommonType!(ElementType!Range, RangeElementType) == void))
{
    return extremum!map(r, seed);
}

///
@safe pure unittest
{
    import std.range : enumerate;
    import std.typecons : tuple;

    assert([2, 7, 1, 3].minElement == 1);

    // allows to get the index of an element too
    assert([5, 3, 7, 9].enumerate.minElement!"a.value" == tuple(1, 3));

    // any custom accessor can be passed
    assert([[0, 4], [1, 2]].minElement!"a[1]" == [1, 2]);

    // can be seeded
    int[] arr;
    assert(arr.minElement(1) == 1);
}

@safe pure unittest
{
    import std.range : enumerate, iota;
    // supports mapping
    assert([3, 4, 5, 1, 2].enumerate.minElement!"a.value" == tuple(3, 1));
    assert([5, 2, 4].enumerate.minElement!"a.value" == tuple(1, 2));

    // forward ranges
    assert(iota(1, 5).minElement() == 1);
    assert(iota(2, 5).enumerate.minElement!"a.value" == tuple(0, 2));

    // should work with const
    const(int)[] immArr = [2, 1, 3];
    assert(immArr.minElement == 1);

    // should work with immutable
    immutable(int)[] immArr2 = [2, 1, 3];
    assert(immArr2.minElement == 1);

    // with strings
    assert(["b", "a", "c"].minElement == "a");

    // with all dummy ranges
    import std.internal.test.dummyrange;
    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        assert(d.minElement == 1);
        assert(d.minElement!(a => a) == 1);
        assert(d.minElement!(a => -a) == 10);
    }

    // with empty, but seeded ranges
    int[] arr;
    assert(arr.minElement(42) == 42);
    assert(arr.minElement!(a => a)(42) == 42);
}

@nogc @safe nothrow pure unittest
{
    static immutable arr = [7, 3, 4, 2, 1, 8];
    assert(arr.minElement == 1);

    static immutable arr2d = [[1, 9], [3, 1], [4, 2]];
    assert(arr2d.minElement!"a[1]" == arr2d[1]);
}

// https://issues.dlang.org/show_bug.cgi?id=17982
@safe unittest
{
    struct A
    {
      int val;
    }

    const(A)[] v = [A(0)];
    assert(v.minElement!"a.val" == A(0));
}

// https://issues.dlang.org/show_bug.cgi?id=17982
@safe unittest
{
    class B
    {
        int val;
        this(int val){ this.val = val; }
    }

    const(B) doStuff(const(B)[] v)
    {
        return v.minElement!"a.val";
    }
    assert(doStuff([new B(1), new B(0), new B(2)]).val == 0);

    const(B)[] arr = [new B(0), new B(1)];
    // can't compare directly - https://issues.dlang.org/show_bug.cgi?id=1824
    assert(arr.minElement!"a.val".val == 0);
}

// https://issues.dlang.org/show_bug.cgi?id=24827
@safe unittest
{
    static struct S
    {
        int i;
        bool destroyed;

        this(int i) @safe
        {
            this.i = i;
        }

        ~this() @safe
        {
            destroyed = true;
        }

        bool opEquals()(auto ref S rhs)
        {
            return this.i == rhs.i;
        }

        int opCmp()(auto ref S rhs)
        {
            if (this.i < rhs.i)
                return -1;

            return this.i == rhs.i ? 0 : 1;
        }

        @safe invariant
        {
            assert(!destroyed);
        }
    }

    auto arr = [S(19), S(2), S(145), S(7)];
    assert(minElement(arr) == S(2));
}

/**
Iterates the passed range and returns the maximal element.
A custom mapping function can be passed to `map`.
In other languages this is sometimes called `argmax`.

Complexity: O(n)
    Exactly `n - 1` comparisons are needed.

Params:
    map = custom accessor for the comparison key
    r = range from which the maximum element will be selected
    seed = custom seed to use as initial element

Precondition: If a seed is not given, `r` must not be empty.

Returns: The maximal element of the passed-in range.

Note:
    If at least one of the arguments is NaN, the result is an unspecified value.
    See $(REF minElement, std,algorithm,searching) for examples on how to cope
    with NaNs.

See_Also:

    $(LREF extrema), $(LREF minElement), $(REF max, std,algorithm,comparison), $(LREF maxCount),
    $(LREF maxIndex), $(LREF maxPos)
*/
auto maxElement(alias map = (a => a), Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
{
    return extremum!(map, "a > b")(r);
}

/// ditto
auto maxElement(alias map = (a => a), Range, RangeElementType = ElementType!Range)
               (Range r, RangeElementType seed)
if (isInputRange!Range && !isInfinite!Range &&
    !is(CommonType!(ElementType!Range, RangeElementType) == void))
{
    return extremum!(map, "a > b")(r, seed);
}

///
@safe pure unittest
{
    import std.range : enumerate;
    import std.typecons : tuple;
    assert([2, 1, 4, 3].maxElement == 4);

    // allows to get the index of an element too
    assert([2, 1, 4, 3].enumerate.maxElement!"a.value" == tuple(2, 4));

    // any custom accessor can be passed
    assert([[0, 4], [1, 2]].maxElement!"a[1]" == [0, 4]);

    // can be seeded
    int[] arr;
    assert(arr.minElement(1) == 1);
}

@safe pure unittest
{
    import std.range : enumerate, iota;

    // supports mapping
    assert([3, 4, 5, 1, 2].enumerate.maxElement!"a.value" == tuple(2, 5));
    assert([5, 2, 4].enumerate.maxElement!"a.value" == tuple(0, 5));

    // forward ranges
    assert(iota(1, 5).maxElement() == 4);
    assert(iota(2, 5).enumerate.maxElement!"a.value" == tuple(2, 4));
    assert(iota(4, 14).enumerate.maxElement!"a.value" == tuple(9, 13));

    // should work with const
    const(int)[] immArr = [2, 3, 1];
    assert(immArr.maxElement == 3);

    // should work with immutable
    immutable(int)[] immArr2 = [2, 3, 1];
    assert(immArr2.maxElement == 3);

    // with strings
    assert(["a", "c", "b"].maxElement == "c");

    // with all dummy ranges
    import std.internal.test.dummyrange;
    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        assert(d.maxElement == 10);
        assert(d.maxElement!(a => a) == 10);
        assert(d.maxElement!(a => -a) == 1);
    }

    // with empty, but seeded ranges
    int[] arr;
    assert(arr.maxElement(42) == 42);
    assert(arr.maxElement!(a => a)(42) == 42);

}

@nogc @safe nothrow pure unittest
{
    static immutable arr = [7, 3, 8, 2, 1, 4];
    assert(arr.maxElement == 8);

    static immutable arr2d = [[1, 3], [3, 9], [4, 2]];
    assert(arr2d.maxElement!"a[1]" == arr2d[1]);
}

// https://issues.dlang.org/show_bug.cgi?id=17982
@safe unittest
{
    class B
    {
        int val;
        this(int val){ this.val = val; }
    }

    const(B) doStuff(const(B)[] v)
    {
        return v.maxElement!"a.val";
    }
    assert(doStuff([new B(1), new B(0), new B(2)]).val == 2);

    const(B)[] arr = [new B(0), new B(1)];
    // can't compare directly - https://issues.dlang.org/show_bug.cgi?id=1824
    assert(arr.maxElement!"a.val".val == 1);
}

// https://issues.dlang.org/show_bug.cgi?id=23993
@safe unittest
{
    import std.bigint : BigInt;

    assert([BigInt(2), BigInt(3)].maxElement == BigInt(3));
}

// https://issues.dlang.org/show_bug.cgi?id=24596
@safe unittest
{
    static class A {
        int i;
        int getI() @safe => i;
        this(int i) @safe { this.i = i; }
    }
    auto arr = [new A(2), new A(3)];

    arr.maxElement!(a => a.getI);

    assert(arr[0].getI == 2);
}

// https://issues.dlang.org/show_bug.cgi?id=24827
@safe unittest
{
    static struct S
    {
        int i;
        bool destroyed;

        this(int i) @safe
        {
            this.i = i;
        }

        ~this() @safe
        {
            destroyed = true;
        }

        bool opEquals()(auto ref S rhs)
        {
            return this.i == rhs.i;
        }

        int opCmp()(auto ref S rhs)
        {
            if (this.i < rhs.i)
                return -1;

            return this.i == rhs.i ? 0 : 1;
        }

        @safe invariant
        {
            assert(!destroyed);
        }
    }

    auto arr = [S(19), S(2), S(145), S(7)];
    assert(maxElement(arr) == S(145));
}

/** Returns an array of the minimum and maximum element in `r`.
 * Performs `< 3n/2` comparisons, unlike the naive `< 2n`.
 * Params:
 *  r = The range to traverse.
 */
// TODO alias map = a => a
ElementType!Range[2] extrema(Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
in (!r.empty)
{
    static if (isRandomAccessRange!Range && hasLength!Range)
    {
        if (r.length == 1)
            return [r[0], r[0]];

        typeof(return) result;
        size_t i;
        if (r.length & 1) // odd
        {
            result = [r[0], r[0]];
            i = 1;
        }
        else
        {
            result = (r[0] < r[1]) ? [r[0], r[1]] : [r[1], r[0]];
            i = 2;
        }
        // iterate pairs
        const imax = r.length;
        for (; i != imax; i += 2)
        {
            // save work
            if (r[i] < r[i+1])
            {
                if (r[i] < result[0])
                    result[0] = r[i];
                if (r[i+1] > result[1])
                    result[1] = r[i+1];
            }
            else
            {
                if (r[i+1] < result[0])
                    result[0] = r[i+1];
                if (r[i] > result[1])
                    result[1] = r[i];
            }
        }
        return result;
    }
    else
    {
        auto first = r.front;
        r.popFront;
        if (r.empty)
            return [first, first];

        typeof(return) result = (first < r.front) ? [first, r.front] : [r.front, first];
        // iterate pairs
        while (true)
        {
            r.popFront;
            if (r.empty)
                return result;
            first = r.front;
            r.popFront;
            if (r.empty)
            {
                if (first < result[0])
                    result[0] = first;
                else if (first > result[1])
                    result[1] = first;
                return result;
            }
            // save work
            if (first < r.front)
            {
                if (first < result[0])
                    result[0] = first;
                if (r.front > result[1])
                    result[1] = r.front;
            }
            else
            {
                if (r.front < result[0])
                    result[0] = r.front;
                if (first > result[1])
                    result[1] = first;
            }
        }
    }
}

///
@safe unittest
{
    assert(extrema([5,2,9,4,1]) == [1, 9]);
}

@safe unittest
{
    assert(extrema([8,3,7,4,9]) == [3, 9]);
    assert(extrema([1,5,3,2]) == [1, 5]);
    assert(extrema([2,3,3,2]) == [2, 3]);

    import std.range;
    assert(iota(2, 5).extrema == [2, 4]);
    assert(iota(3, 7).retro.extrema == [3, 6]);

    import std.internal.test.dummyrange;
    foreach (DummyType; AllDummyRanges)
    {
        DummyType d;
        assert(d.extrema == [1, 10]);
    }

    version (StdRandomTests)
    foreach (i; 0 .. 1000)
    {
        import std.random;
        auto arr = generate!(() => uniform(0, 100)).takeExactly(uniform(1, 10)).array;
        auto result = arr.extrema;
        assert(result[0] == arr.minElement);
        assert(result[1] == arr.maxElement);
    }
}

// minPos
/**
Computes a subrange of `range` starting at the first occurrence of `range`'s
minimum (respectively maximum) and with the same ending as `range`, or the
empty range if `range` itself is empty.

Formally, the minimum is a value `x` in `range` such that `pred(a, x)` is
`false` for all values `a` in `range`. Conversely, the maximum is a value `x` in
`range` such that `pred(x, a)` is `false` for all values `a` in `range` (note
the swapped arguments to `pred`).

These functions may be used for computing arbitrary extrema by choosing `pred`
appropriately. For corrrect functioning, `pred` must be a strict partial order,
i.e. transitive (if `pred(a, b) && pred(b, c)` then `pred(a, c)`) and
irreflexive (`pred(a, a)` is `false`).

Params:
    pred = The ordering predicate to use to determine the extremum (minimum or
        maximum) element.
    range = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to search.

Returns: The position of the minimum (respectively maximum) element of forward
range `range`, i.e. a subrange of `range` starting at the position of  its
smallest (respectively largest) element and with the same ending as `range`.

Limitations: If at least one of the arguments is NaN, the result is
an unspecified value. See $(REF maxElement, std,algorithm,searching)
for examples on how to cope with NaNs.

See_Also:
    $(REF max, std,algorithm,comparison), $(LREF minCount), $(LREF minIndex), $(LREF minElement)
*/
Range minPos(alias pred = "a < b", Range)(Range range)
if (isForwardRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(range.front, range.front))))
{
    static if (hasSlicing!Range && isRandomAccessRange!Range && hasLength!Range)
    {
        // Prefer index-based access
        size_t pos = 0;
        foreach (i; 1 .. range.length)
        {
            if (binaryFun!pred(range[i], range[pos]))
            {
                pos = i;
            }
        }
        return range[pos .. range.length];
    }
    else
    {
        auto result = range.save;
        if (range.empty) return result;
        for (range.popFront(); !range.empty; range.popFront())
        {
            // Note: Unlike minCount, we do not care to find equivalence, so a
            // single pred call is enough.
            if (binaryFun!pred(range.front, result.front))
            {
                // change the min
                result = range.save;
            }
        }
        return result;
    }
}

/// Ditto
Range maxPos(alias pred = "a < b", Range)(Range range)
if (isForwardRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(range.front, range.front))))
{
    return range.minPos!((a, b) => binaryFun!pred(b, a));
}

///
@safe unittest
{
    int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
    // Minimum is 1 and first occurs in position 3
    assert(a.minPos == [ 1, 2, 4, 1, 1, 2 ]);
    // Maximum is 4 and first occurs in position 2
    assert(a.maxPos == [ 4, 1, 2, 4, 1, 1, 2 ]);
}

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

    int[] a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
    //Test that an empty range works
    int[] b = a[$..$];
    assert(equal(minPos(b), b));

    //test with reference range.
    assert( equal( minPos(new ReferenceForwardRange!int([1, 2, 1, 0, 2, 0])), [0, 2, 0] ) );
}

@system unittest
{
    //Rvalue range
    import std.algorithm.comparison : equal;
    import std.container : Array;

    assert(Array!int(2, 3, 4, 1, 2, 4, 1, 1, 2)
               []
               .minPos()
               .equal([ 1, 2, 4, 1, 1, 2 ]));
}

@safe unittest
{
    //BUG 9299
    immutable a = [ 2, 3, 4, 1, 2, 4, 1, 1, 2 ];
    // Minimum is 1 and first occurs in position 3
    assert(minPos(a) == [ 1, 2, 4, 1, 1, 2 ]);
    // Maximum is 4 and first occurs in position 5
    assert(minPos!("a > b")(a) == [ 4, 1, 2, 4, 1, 1, 2 ]);

    immutable(int[])[] b = [ [4], [2, 4], [4], [4] ];
    assert(minPos!("a[0] < b[0]")(b) == [ [2, 4], [4], [4] ]);
}

/**
Computes the index of the first occurrence of `range`'s minimum element.

Params:
    pred = The ordering predicate to use to determine the minimum element.
    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    to search.

Complexity: $(BIGOH range.length)
    Exactly `range.length - 1` comparisons are needed.

Returns:
    The index of the first encounter of the minimum element in `range`. If the
    `range` is empty, -1 is returned.

Limitations:
    If at least one of the arguments is NaN, the result is
    an unspecified value. See $(REF maxElement, std,algorithm,searching)
    for examples on how to cope with NaNs.

See_Also:
    $(LREF maxIndex), $(REF min, std,algorithm,comparison), $(LREF minCount), $(LREF minElement), $(LREF minPos)
 */
ptrdiff_t minIndex(alias pred = "a < b", Range)(Range range)
if (isInputRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(range.front, range.front))))
{
    if (range.empty) return -1;

    ptrdiff_t minPos = 0;

    static if (isRandomAccessRange!Range && hasLength!Range)
    {
        foreach (i; 1 .. range.length)
        {
            if (binaryFun!pred(range[i], range[minPos]))
            {
                minPos = i;
            }
        }
    }
    else
    {
        ptrdiff_t curPos = 0;
        Unqual!(typeof(range.front)) min = range.front;
        for (range.popFront(); !range.empty; range.popFront())
        {
            ++curPos;
            if (binaryFun!pred(range.front, min))
            {
                min = range.front;
                minPos = curPos;
            }
        }
    }
    return minPos;
}

///
@safe pure nothrow unittest
{
    int[] a = [2, 3, 4, 1, 2, 4, 1, 1, 2];

    // Minimum is 1 and first occurs in position 3
    assert(a.minIndex == 3);
    // Get maximum index with minIndex
    assert(a.minIndex!"a > b" == 2);

    // Range is empty, so return value is -1
    int[] b;
    assert(b.minIndex == -1);

    // Works with more custom types
    struct Dog { int age; }
    Dog[] dogs = [Dog(10), Dog(5), Dog(15)];
    assert(dogs.minIndex!"a.age < b.age" == 1);
}

@safe pure unittest
{
    // should work with const
    const(int)[] immArr = [2, 1, 3];
    assert(immArr.minIndex == 1);

    // Works for const ranges too
    const int[] c = [2, 5, 4, 1, 2, 3];
    assert(c.minIndex == 3);

    // should work with immutable
    immutable(int)[] immArr2 = [2, 1, 3];
    assert(immArr2.minIndex == 1);

    // with strings
    assert(["b", "a", "c"].minIndex == 1);

    // infinite range
    import std.range : cycle;
    static assert(!__traits(compiles, cycle([1]).minIndex));

    // with all dummy ranges
    import std.internal.test.dummyrange : AllDummyRanges;
    foreach (DummyType; AllDummyRanges)
    {
        static if (isForwardRange!DummyType && !isInfinite!DummyType)
        {
            DummyType d;
            d.arr = [5, 3, 7, 2, 1, 4];
            assert(d.minIndex == 4);

            d.arr = [];
            assert(d.minIndex == -1);
        }
    }
}

@nogc @safe nothrow pure unittest
{
    static immutable arr = [7, 3, 8, 2, 1, 4];
    assert(arr.minIndex == 4);

    static immutable arr2d = [[1, 3], [3, 9], [4, 2]];
    assert(arr2d.minIndex!"a[1] < b[1]" == 2);
}

@safe nothrow pure unittest
{
    // InputRange test

    static struct InRange
    {
        @property int front()
        {
            return arr[index];
        }

        bool empty() const
        {
            return arr.length == index;
        }

        void popFront()
        {
            index++;
        }

        int[] arr;
        size_t index = 0;
    }

    static assert(isInputRange!InRange);

    auto arr1 = InRange([5, 2, 3, 4, 5, 3, 6]);
    auto arr2 = InRange([7, 3, 8, 2, 1, 4]);

    assert(arr1.minIndex == 1);
    assert(arr2.minIndex == 4);
}

/**
Computes the index of the first occurrence of `range`'s maximum element.

Complexity: $(BIGOH range)
    Exactly `range.length - 1` comparisons are needed.

Params:
    pred = The ordering predicate to use to determine the maximum element.
    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to search.

Returns:
    The index of the first encounter of the maximum in `range`. If the
    `range` is empty, -1 is returned.

Limitations:
    If at least one of the arguments is NaN, the result is
    an unspecified value. See $(REF maxElement, std,algorithm,searching)
    for examples on how to cope with NaNs.

See_Also:
    $(LREF minIndex), $(REF max, std,algorithm,comparison), $(LREF maxCount), $(LREF maxElement), $(LREF maxPos)
 */
ptrdiff_t maxIndex(alias pred = "a < b", Range)(Range range)
if (isInputRange!Range && !isInfinite!Range &&
    is(typeof(binaryFun!pred(range.front, range.front))))
{
    return range.minIndex!((a, b) => binaryFun!pred(b, a));
}

///
@safe pure nothrow unittest
{
    // Maximum is 4 and first occurs in position 2
    int[] a = [2, 3, 4, 1, 2, 4, 1, 1, 2];
    assert(a.maxIndex == 2);

    // Empty range
    int[] b;
    assert(b.maxIndex == -1);

    // Works with more custom types
    struct Dog { int age; }
    Dog[] dogs = [Dog(10), Dog(15), Dog(5)];
    assert(dogs.maxIndex!"a.age < b.age" == 1);
}

@safe pure unittest
{
    // should work with const
    const(int)[] immArr = [5, 1, 3];
    assert(immArr.maxIndex == 0);

    // Works for const ranges too
    const int[] c = [2, 5, 4, 1, 2, 3];
    assert(c.maxIndex == 1);


    // should work with immutable
    immutable(int)[] immArr2 = [2, 1, 3];
    assert(immArr2.maxIndex == 2);

    // with strings
    assert(["b", "a", "c"].maxIndex == 2);

    // infinite range
    import std.range : cycle;
    static assert(!__traits(compiles, cycle([1]).maxIndex));

    // with all dummy ranges
    import std.internal.test.dummyrange : AllDummyRanges;
    foreach (DummyType; AllDummyRanges)
    {
        static if (isForwardRange!DummyType && !isInfinite!DummyType)
        {
            DummyType d;

            d.arr = [5, 3, 7, 2, 1, 4];
            assert(d.maxIndex == 2);

            d.arr = [];
            assert(d.maxIndex == -1);
        }
    }
}

@nogc @safe nothrow pure unittest
{
    static immutable arr = [7, 3, 8, 2, 1, 4];
    assert(arr.maxIndex == 2);

    static immutable arr2d = [[1, 3], [3, 9], [4, 2]];
    assert(arr2d.maxIndex!"a[1] < b[1]" == 1);
}

/**
Skip over the initial portion of the first given range (`haystack`) that matches
any of the additionally given ranges (`needles`) fully, or
if no second range is given skip over the elements that fulfill pred.
Do nothing if there is no match.

Params:
    pred = The predicate that determines whether elements from each respective
        range match. Defaults to equality `"a == b"`.
*/
template skipOver(alias pred = (a, b) => a == b)
{
    enum bool isPredComparable(T) = ifTestable!(T, binaryFun!pred);

    /**
    Params:
        haystack = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to
                   move forward.
        needles = The $(REF_ALTTEXT input ranges, isInputRange, std,range,primitives)
                  representing the prefix of `r1` to skip over.
        es = The element to match.

    Returns:
        `true` if the prefix of `haystack` matches any range of `needles` fully
        or `pred` evaluates to true, and `haystack` has been advanced to the point past this segment;
        otherwise false, and `haystack` is left in its original position.

    Note:
        By definition, empty ranges are matched fully and if `needles` contains an empty range,
        `skipOver` will return `true`.
    */
    bool skipOver(Haystack, Needles...)(ref Haystack haystack, Needles needles)
    if (is(typeof(binaryFun!pred(haystack.front, needles[0].front))) &&
        isForwardRange!Haystack &&
        allSatisfy!(isInputRange, Needles) &&
        !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, Needles))) == void))
    {
        static if (__traits(isSame, pred, (a, b) => a == b)
                && is(typeof(haystack[0 .. $] == needles[0]) : bool)
                && is(typeof(haystack = haystack[0 .. $]))
                && hasLength!Haystack && allSatisfy!(hasLength, Needles))
        {
            ptrdiff_t longestMatch = -1;
            static foreach (r2; needles)
            {
                if (r2.length <= haystack.length && longestMatch < ptrdiff_t(r2.length)
                        && (haystack[0 .. r2.length] == r2 || r2.length == 0))
                    longestMatch = r2.length;
            }
            if (longestMatch >= 0)
            {
                if (longestMatch > 0)
                    haystack = haystack[longestMatch .. $];

                return true;
            }
            return false;
        }
        else
        {
            import std.algorithm.comparison : min;
            auto r = haystack.save;

            static if (hasLength!Haystack && allSatisfy!(hasLength, Needles))
            {
                import std.algorithm.iteration : map;
                import std.algorithm.searching : minElement;
                import std.range : only;
                // Shortcut opportunity!
                if (needles.only.map!(a => a.length).minElement > haystack.length)
                    return false;
            }

            // compatibility: return true if any range was empty
            bool hasEmptyRanges;
            static foreach (i, r2; needles)
            {
                if (r2.empty)
                    hasEmptyRanges = true;
            }

            bool hasNeedleMatch;
            size_t inactiveNeedlesLen;
            bool[Needles.length] inactiveNeedles;
            for (; !r.empty; r.popFront)
            {
                static foreach (i, r2; needles)
                {
                    if (!r2.empty && !inactiveNeedles[i])
                    {
                        if (binaryFun!pred(r.front, r2.front))
                        {
                            r2.popFront;
                            if (r2.empty)
                            {
                                // we skipped over a new match
                                hasNeedleMatch = true;
                                inactiveNeedlesLen++;
                                // skip over haystack
                                haystack = r;
                            }
                        }
                        else
                        {
                            inactiveNeedles[i] = true;
                            inactiveNeedlesLen++;
                        }
                    }
                }

                // are we done?
                if (inactiveNeedlesLen == needles.length)
                    break;
            }

            if (hasNeedleMatch)
                haystack.popFront;

            return hasNeedleMatch || hasEmptyRanges;
        }
    }

    /// Ditto
    bool skipOver(R)(ref R r1)
    if (isForwardRange!R &&
        ifTestable!(typeof(r1.front), unaryFun!pred))
    {
        if (r1.empty || !unaryFun!pred(r1.front))
            return false;

        do
            r1.popFront();
        while (!r1.empty && unaryFun!pred(r1.front));
        return true;
    }

    /// Ditto
    bool skipOver(R, Es...)(ref R r, Es es)
    if (isInputRange!R && is(typeof(binaryFun!pred(r.front, es[0]))))
    {
        if (r.empty)
            return false;

        static foreach (e; es)
        {
            if (binaryFun!pred(r.front, e))
            {
                r.popFront();
                return true;
            }
        }
        return false;
    }
}

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

    auto s1 = "Hello world";
    assert(!skipOver(s1, "Ha"));
    assert(s1 == "Hello world");
    assert(skipOver(s1, "Hell") && s1 == "o world", s1);

    string[]  r1 = ["abc", "def", "hij"];
    dstring[] r2 = ["abc"d];
    assert(!skipOver!((a, b) => a.equal(b))(r1, ["def"d]), r1[0]);
    assert(r1 == ["abc", "def", "hij"]);
    assert(skipOver!((a, b) => a.equal(b))(r1, r2));
    assert(r1 == ["def", "hij"]);
}

///
@safe unittest
{
    import std.ascii : isWhite;
    import std.range.primitives : empty;

    auto s2 = "\t\tvalue";
    auto s3 = "";
    auto s4 = "\t\t\t";
    assert(s2.skipOver!isWhite && s2 == "value");
    assert(!s3.skipOver!isWhite);
    assert(s4.skipOver!isWhite && s3.empty);
}

/// Variadic skipOver
@safe unittest
{
    auto s = "Hello world";
    assert(!skipOver(s, "hello", "HellO"));
    assert(s == "Hello world");

    // the range is skipped over the longest matching needle is skipped
    assert(skipOver(s, "foo", "hell", "Hello "));
    assert(s == "world");
}

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

    auto s1 = "Hello world";
    assert(!skipOver(s1, 'a'));
    assert(s1 == "Hello world");
    assert(skipOver(s1, 'H') && s1 == "ello world");

    string[] r = ["abc", "def", "hij"];
    dstring e = "abc"d;
    assert(!skipOver!((a, b) => a.equal(b))(r, "def"d));
    assert(r == ["abc", "def", "hij"]);
    assert(skipOver!((a, b) => a.equal(b))(r, e));
    assert(r == ["def", "hij"]);

    auto s2 = "";
    assert(!s2.skipOver('a'));
}

/// Partial instantiation
@safe unittest
{
    import std.ascii : isWhite;
    import std.range.primitives : empty;

    alias whitespaceSkiper = skipOver!isWhite;

    auto s2 = "\t\tvalue";
    auto s3 = "";
    auto s4 = "\t\t\t";
    assert(whitespaceSkiper(s2) && s2 == "value");
    assert(!whitespaceSkiper(s2));
    assert(whitespaceSkiper(s4) && s3.empty);
}

// variadic skipOver
@safe unittest
{
    auto s = "DLang.rocks";
    assert(!s.skipOver("dlang", "DLF", "DLang "));
    assert(s == "DLang.rocks");

    assert(s.skipOver("dlang", "DLANG", "DLF", "D", "DL", "DLanpp"));
    assert(s == "ang.rocks");
    s = "DLang.rocks";

    assert(s.skipOver("DLang", "DLANG", "DLF", "D", "DL", "DLang "));
    assert(s == ".rocks");
    s = "DLang.rocks";

    assert(s.skipOver("dlang", "DLANG", "DLF", "D", "DL", "DLang."));
    assert(s == "rocks");
}

// variadic with custom pred
@safe unittest
{
    import std.ascii : toLower;

    auto s = "DLang.rocks";
    assert(!s.skipOver("dlang", "DLF", "DLang "));
    assert(s == "DLang.rocks");

    assert(s.skipOver!((a, b) => a.toLower == b.toLower)("dlang", "DLF", "DLang "));
    assert(s == ".rocks");
}

// variadic skipOver with mixed needles
@safe unittest
{
    auto s = "DLang.rocks";
    assert(!s.skipOver("dlang"d, "DLF", "DLang "w));
    assert(s == "DLang.rocks");

    assert(s.skipOver("dlang", "DLANG"d, "DLF"w, "D"d, "DL", "DLanp"));
    assert(s == "ang.rocks");
    s = "DLang.rocks";

    assert(s.skipOver("DLang", "DLANG"w, "DLF"d, "D"d, "DL", "DLang "));
    assert(s == ".rocks");
    s = "DLang.rocks";

    assert(s.skipOver("dlang", "DLANG"w, "DLF", "D"d, "DL"w, "DLang."d));
    assert(s == "rocks");

    import std.algorithm.iteration : filter;
    s = "DLang.rocks";
    assert(s.skipOver("dlang", "DLang".filter!(a => true)));
    assert(s == ".rocks");
}

// variadic skipOver with auto-decoding
@safe unittest
{
    auto s = "☢☣☠.☺";
    assert(s.skipOver("a", "☢", "☢☣☠"));
    assert(s == ".☺");
}

// skipOver with @nogc
@safe @nogc pure nothrow unittest
{
    static immutable s = [0, 1, 2];
    immutable(int)[] s2 = s[];

    static immutable skip1 = [0, 2];
    static immutable skip2 = [0, 1];
    assert(s2.skipOver(skip1, skip2));
    assert(s2 == s[2 .. $]);
}

// variadic skipOver with single elements
@safe unittest
{
    auto s = "DLang.rocks";
    assert(!s.skipOver('a', 'd', 'e'));
    assert(s == "DLang.rocks");

    assert(s.skipOver('a', 'D', 'd', 'D'));
    assert(s == "Lang.rocks");
    s = "DLang.rocks";

    assert(s.skipOver(wchar('a'), dchar('D'), 'd'));
    assert(s == "Lang.rocks");

    dstring dstr = "+Foo";
    assert(!dstr.skipOver('.', '-'));
    assert(dstr == "+Foo");

    assert(dstr.skipOver('+', '-'));
    assert(dstr == "Foo");
}

// skipOver with empty ranges must return true (compatibility)
@safe unittest
{
    auto s = "DLang.rocks";
    assert(s.skipOver(""));
    assert(s.skipOver("", ""));
    assert(s.skipOver("", "foo"));

    auto s2 = "DLang.rocks"d;
    assert(s2.skipOver(""));
    assert(s2.skipOver("", ""));
    assert(s2.skipOver("", "foo"));
}

// dxml regression
@safe unittest
{
    import std.utf : byCodeUnit;
    import std.algorithm.comparison : equal;

    bool stripStartsWith(Text)(ref Text text, string needle)
    {
        return text.skipOver(needle.byCodeUnit());
    }
    auto text = "<xml></xml>"d.byCodeUnit;
    assert(stripStartsWith(text, "<xml>"));
    assert(text.equal("</xml>"));
}

/**
Checks whether the given
$(REF_ALTTEXT input range, isInputRange, std,range,primitives) starts with (one
of) the given needle(s) or, if no needles are given,
if its front element fulfils predicate `pred`.

For more information about `pred` see $(LREF find).

Params:

    pred = Predicate to use in comparing the elements of the haystack and the
        needle(s). Mandatory if no needles are given.

    doesThisStart = The input range to check.

    withOneOfThese = The needles against which the range is to be checked,
        which may be individual elements or input ranges of elements.

    withThis = The single needle to check, which may be either a single element
        or an input range of elements.

Returns:

0 if the needle(s) do not occur at the beginning of the given range;
otherwise the position of the matching needle, that is, 1 if the range starts
with `withOneOfThese[0]`, 2 if it starts with `withOneOfThese[1]`, and so
on.

In the case where `doesThisStart` starts with multiple of the ranges or
elements in `withOneOfThese`, then the shortest one matches (if there are
two which match which are of the same length (e.g. `"a"` and `'a'`), then
the left-most of them in the argument
list matches).

In the case when no needle parameters are given, return `true` iff front of
`doesThisStart` fulfils predicate `pred`.
 */
uint startsWith(alias pred = (a, b) => a == b, Range, Needles...)(Range doesThisStart, Needles withOneOfThese)
if (isInputRange!Range && Needles.length > 1 &&
    allSatisfy!(canTestStartsWith!(pred, Range), Needles))
{
    template checkType(T)
    {
        enum checkType = is(immutable ElementEncodingType!Range == immutable T);
    }

    // auto-decoding special case
    static if (__traits(isSame, binaryFun!pred, (a, b) => a == b) &&
        isNarrowString!Range && allSatisfy!(checkType, Needles))
    {
        import std.utf : byCodeUnit;
        auto haystack = doesThisStart.byCodeUnit;
    }
    else
    {
        alias haystack = doesThisStart;
    }
    alias needles  = withOneOfThese;

    // Make one pass looking for empty ranges in needles
    foreach (i, Unused; Needles)
    {
        // Empty range matches everything
        static if (!is(typeof(binaryFun!pred(haystack.front, needles[i])) : bool))
        {
            if (needles[i].empty) return i + 1;
        }
    }

    for (; !haystack.empty; haystack.popFront())
    {
        foreach (i, Unused; Needles)
        {
            static if (is(typeof(binaryFun!pred(haystack.front, needles[i])) : bool))
            {
                // Single-element
                if (binaryFun!pred(haystack.front, needles[i]))
                {
                    // found, but instead of returning, we just stop searching.
                    // This is to account for one-element
                    // range matches (consider startsWith("ab", "a",
                    // 'a') should return 1, not 2).
                    break;
                }
            }
            else
            {
                if (binaryFun!pred(haystack.front, needles[i].front))
                {
                    continue;
                }
            }

            // This code executed on failure to match
            // Out with this guy, check for the others
            uint result = startsWith!pred(haystack, needles[0 .. i], needles[i + 1 .. $]);
            if (result > i) ++result;
            return result;
        }

        // If execution reaches this point, then the front matches for all
        // needle ranges, or a needle element has been matched.
        // What we need to do now is iterate, lopping off the front of
        // the range and checking if the result is empty, or finding an
        // element needle and returning.
        // If neither happens, we drop to the end and loop.
        foreach (i, Unused; Needles)
        {
            static if (is(typeof(binaryFun!pred(haystack.front, needles[i])) : bool))
            {
                // Test has passed in the previous loop
                return i + 1;
            }
            else
            {
                needles[i].popFront();
                if (needles[i].empty) return i + 1;
            }
        }
    }
    return 0;
}

/// Ditto
bool startsWith(alias pred = "a == b", R1, R2)(R1 doesThisStart, R2 withThis)
if (isInputRange!R1 &&
    isInputRange!R2 &&
    is(typeof(binaryFun!pred(doesThisStart.front, withThis.front)) : bool))
{
    alias haystack = doesThisStart;
    alias needle   = withThis;

    static if (is(typeof(pred) : string))
        enum isDefaultPred = pred == "a == b";
    else
        enum isDefaultPred = false;

    // Note: Although narrow strings don't have a "true" length, for a narrow string to start with another
    // narrow string, it must have *at least* as many code units.
    static if ((hasLength!R1 && hasLength!R2) ||
        ((hasLength!R1 || isNarrowString!R1) && (hasLength!R2 || isNarrowString!R2)
            && (ElementEncodingType!R1.sizeof <= ElementEncodingType!R2.sizeof)))
    {
        if (haystack.length < needle.length)
            return false;
    }

    static if (isDefaultPred && isArray!R1 && isArray!R2 &&
               is(immutable ElementEncodingType!R1 == immutable ElementEncodingType!R2))
    {
        //Array slice comparison mode
        return haystack[0 .. needle.length] == needle;
    }
    else static if (isRandomAccessRange!R1 && isRandomAccessRange!R2 && hasLength!R2)
    {
        //RA dual indexing mode
        foreach (j; 0 .. needle.length)
        {
            if (!binaryFun!pred(haystack[j], needle[j]))
                // not found
                return false;
        }
        // found!
        return true;
    }
    else
    {
        //Standard input range mode
        if (needle.empty) return true;
        static if (hasLength!R1 && hasLength!R2)
        {
            //We have previously checked that haystack.length > needle.length,
            //So no need to check haystack.empty during iteration
            for ( ; ; haystack.popFront() )
            {
                if (!binaryFun!pred(haystack.front, needle.front)) break;
                needle.popFront();
                if (needle.empty) return true;
            }
        }
        else
        {
            for ( ; !haystack.empty ; haystack.popFront() )
            {
                if (!binaryFun!pred(haystack.front, needle.front)) break;
                needle.popFront();
                if (needle.empty) return true;
            }
        }
        return false;
    }
}

/// Ditto
bool startsWith(alias pred = "a == b", R, E)(R doesThisStart, E withThis)
if (isInputRange!R &&
    is(typeof(binaryFun!pred(doesThisStart.front, withThis)) : bool))
{
    if (doesThisStart.empty)
        return false;

    static if (is(typeof(pred) : string))
        enum isDefaultPred = pred == "a == b";
    else
        enum isDefaultPred = false;

    alias predFunc = binaryFun!pred;

    // auto-decoding special case
    static if (isNarrowString!R)
    {
        // statically determine decoding is unnecessary to evaluate pred
        static if (isDefaultPred && isSomeChar!E && E.sizeof <= ElementEncodingType!R.sizeof)
            return doesThisStart[0] == withThis;
        // specialize for ASCII as to not change previous behavior
        else
        {
            if (withThis <= 0x7F)
                return predFunc(doesThisStart[0], withThis);
            else
                return predFunc(doesThisStart.front, withThis);
        }
    }
    else
    {
        return predFunc(doesThisStart.front, withThis);
    }
}

/// Ditto
bool startsWith(alias pred, R)(R doesThisStart)
if (isInputRange!R &&
    ifTestable!(typeof(doesThisStart.front), unaryFun!pred))
{
    return !doesThisStart.empty && unaryFun!pred(doesThisStart.front);
}

///
@safe unittest
{
    import std.ascii : isAlpha;

    assert("abc".startsWith!(a => a.isAlpha));
    assert("abc".startsWith!isAlpha);
    assert(!"1ab".startsWith!(a => a.isAlpha));
    assert(!"".startsWith!(a => a.isAlpha));

    import std.algorithm.comparison : among;
    assert("abc".startsWith!(a => a.among('a', 'b') != 0));
    assert(!"abc".startsWith!(a => a.among('b', 'c') != 0));

    assert(startsWith("abc", ""));
    assert(startsWith("abc", "a"));
    assert(!startsWith("abc", "b"));
    assert(startsWith("abc", 'a', "b") == 1);
    assert(startsWith("abc", "b", "a") == 2);
    assert(startsWith("abc", "a", "a") == 1);
    assert(startsWith("abc", "ab", "a") == 2);
    assert(startsWith("abc", "x", "a", "b") == 2);
    assert(startsWith("abc", "x", "aa", "ab") == 3);
    assert(startsWith("abc", "x", "aaa", "sab") == 0);
    assert(startsWith("abc", "x", "aaa", "a", "sab") == 3);

    import std.typecons : Tuple;
    alias C = Tuple!(int, "x", int, "y");
    assert(startsWith!"a.x == b"([ C(1,1), C(1,2), C(2,2) ], [1, 1]));
    assert(startsWith!"a.x == b"([ C(1,1), C(2,1), C(2,2) ], [1, 1], [1, 2], [1, 3]) == 2);
}

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

    static foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
    (){ // workaround slow optimizations for large functions
        // https://issues.dlang.org/show_bug.cgi?id=2396
        assert(!startsWith(to!S("abc"), 'c'));
        assert(startsWith(to!S("abc"), 'a', 'c') == 1);
        assert(!startsWith(to!S("abc"), 'x', 'n', 'b'));
        assert(startsWith(to!S("abc"), 'x', 'n', 'a') == 3);
        assert(startsWith(to!S("\uFF28abc"), 'a', '\uFF28', 'c') == 2);

        static foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
        {
            //Lots of strings
            assert(startsWith(to!S("abc"), to!T("")));
            assert(startsWith(to!S("ab"), to!T("a")));
            assert(startsWith(to!S("abc"), to!T("a")));
            assert(!startsWith(to!S("abc"), to!T("b")));
            assert(!startsWith(to!S("abc"), to!T("b"), "bc", "abcd", "xyz"));
            assert(startsWith(to!S("abc"), to!T("ab"), 'a') == 2);
            assert(startsWith(to!S("abc"), to!T("a"), "b") == 1);
            assert(startsWith(to!S("abc"), to!T("b"), "a") == 2);
            assert(startsWith(to!S("abc"), to!T("a"), 'a') == 1);
            assert(startsWith(to!S("abc"), 'a', to!T("a")) == 1);
            assert(startsWith(to!S("abc"), to!T("x"), "a", "b") == 2);
            assert(startsWith(to!S("abc"), to!T("x"), "aa", "ab") == 3);
            assert(startsWith(to!S("abc"), to!T("x"), "aaa", "sab") == 0);
            assert(startsWith(to!S("abc"), 'a'));
            assert(!startsWith(to!S("abc"), to!T("sab")));
            assert(startsWith(to!S("abc"), 'x', to!T("aaa"), 'a', "sab") == 3);

            //Unicode
            assert(startsWith(to!S("\uFF28el\uFF4co"), to!T("\uFF28el")));
            assert(startsWith(to!S("\uFF28el\uFF4co"), to!T("Hel"), to!T("\uFF28el")) == 2);
            assert(startsWith(to!S("日本語"), to!T("日本")));
            assert(startsWith(to!S("日本語"), to!T("日本語")));
            assert(!startsWith(to!S("日本"), to!T("日本語")));

            //Empty
            assert(startsWith(to!S(""),  T.init));
            assert(!startsWith(to!S(""), 'a'));
            assert(startsWith(to!S("a"), T.init));
            assert(startsWith(to!S("a"), T.init, "") == 1);
            assert(startsWith(to!S("a"), T.init, 'a') == 1);
            assert(startsWith(to!S("a"), 'a', T.init) == 2);
        }
    }();

    //Length but no RA
    assert(!startsWith("abc".takeExactly(3), "abcd".takeExactly(4)));
    assert(startsWith("abc".takeExactly(3), "abcd".takeExactly(3)));
    assert(startsWith("abc".takeExactly(3), "abcd".takeExactly(1)));

    static foreach (T; AliasSeq!(int, short))
    {{
        immutable arr = cast(T[])[0, 1, 2, 3, 4, 5];

        //RA range
        assert(startsWith(arr, cast(int[]) null));
        assert(!startsWith(arr, 5));
        assert(!startsWith(arr, 1));
        assert(startsWith(arr, 0));
        assert(startsWith(arr, 5, 0, 1) == 2);
        assert(startsWith(arr, [0]));
        assert(startsWith(arr, [0, 1]));
        assert(startsWith(arr, [0, 1], 7) == 1);
        assert(!startsWith(arr, [0, 1, 7]));
        assert(startsWith(arr, [0, 1, 7], [0, 1, 2]) == 2);

        //Normal input range
        assert(!startsWith(filter!"true"(arr), 1));
        assert(startsWith(filter!"true"(arr), 0));
        assert(startsWith(filter!"true"(arr), [0]));
        assert(startsWith(filter!"true"(arr), [0, 1]));
        assert(startsWith(filter!"true"(arr), [0, 1], 7) == 1);
        assert(!startsWith(filter!"true"(arr), [0, 1, 7]));
        assert(startsWith(filter!"true"(arr), [0, 1, 7], [0, 1, 2]) == 2);
        assert(startsWith(arr, filter!"true"([0, 1])));
        assert(startsWith(arr, filter!"true"([0, 1]), 7) == 1);
        assert(!startsWith(arr, filter!"true"([0, 1, 7])));
        assert(startsWith(arr, [0, 1, 7], filter!"true"([0, 1, 2])) == 2);

        //Non-default pred
        assert(startsWith!("a%10 == b%10")(arr, [10, 11]));
        assert(!startsWith!("a%10 == b%10")(arr, [10, 12]));
    }}
}

private template canTestStartsWith(alias pred, Haystack)
{
    enum bool canTestStartsWith(Needle) = is(typeof(
        (ref Haystack h, ref Needle n) => startsWith!pred(h, n)));
}

/* (Not yet documented.)
Consume all elements from `r` that are equal to one of the elements
`es`.
 */
private void skipAll(alias pred = "a == b", R, Es...)(ref R r, Es es)
//if (is(typeof(binaryFun!pred(r1.front, es[0]))))
{
  loop:
    for (; !r.empty; r.popFront())
    {
        foreach (i, E; Es)
        {
            if (binaryFun!pred(r.front, es[i]))
            {
                continue loop;
            }
        }
        break;
    }
}

@safe unittest
{
    auto s1 = "Hello world";
    skipAll(s1, 'H', 'e');
    assert(s1 == "llo world");
}

/**
Interval option specifier for `until` (below) and others.

If set to `OpenRight.yes`, then the interval is open to the right
(last element is not included).

Otherwise if set to `OpenRight.no`, then the interval is closed to the right
including the entire sentinel.
 */
alias OpenRight = Flag!"openRight";

/**
Lazily iterates `range` _until the element `e` for which
`pred(e, sentinel)` is true.

This is similar to `takeWhile` in other languages.

Params:
    pred = Predicate to determine when to stop.
    range = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
    to iterate over.
    sentinel = The element to stop at.
    openRight = Determines whether the element for which the given predicate is
        true should be included in the resulting range (`No.openRight`), or
        not (`Yes.openRight`).

Returns:
    An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) that
    iterates over the original range's elements, but ends when the specified
    predicate becomes true. If the original range is a
    $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) or
    higher, this range will be a forward range.
 */
Until!(pred, Range, Sentinel)
until(alias pred = "a == b", Range, Sentinel)
(Range range, Sentinel sentinel, OpenRight openRight = Yes.openRight)
if (!is(Sentinel == OpenRight))
{
    return typeof(return)(range, sentinel, openRight);
}

/// Ditto
Until!(pred, Range, void)
until(alias pred, Range)
(Range range, OpenRight openRight = Yes.openRight)
{
    return typeof(return)(range, openRight);
}

/// ditto
struct Until(alias pred, Range, Sentinel)
if (isInputRange!Range)
{
    private Range _input;
    static if (!is(Sentinel == void))
        private Sentinel _sentinel;
    private OpenRight _openRight;
    private bool _matchStarted;
    private bool _done;

    static if (!is(Sentinel == void))
    {
        ///
        this(Range input, Sentinel sentinel,
                OpenRight openRight = Yes.openRight)
        {
            _input = input;
            _sentinel = sentinel;
            _openRight = openRight;
            static if (isInputRange!Sentinel
                && is(immutable ElementEncodingType!Sentinel == immutable ElementEncodingType!Range))
            {
                _matchStarted = predSatisfied();
                _done = _input.empty || _sentinel.empty || openRight && _matchStarted;
                if (_matchStarted && !_done && !openRight)
                {
                    _sentinel.popFront;
                }
            }
            else
            {
                _done = _input.empty || openRight && predSatisfied();
            }
        }
        private this(Range input, Sentinel sentinel, OpenRight openRight,
            bool done)
        {
            _input = input;
            _sentinel = sentinel;
            _openRight = openRight;
            _done = done;
        }
    }
    else
    {
        ///
        this(Range input, OpenRight openRight = Yes.openRight)
        {
            _input = input;
            _openRight = openRight;
            _done = _input.empty || openRight && predSatisfied();
        }
        private this(Range input, OpenRight openRight, bool done)
        {
            _input = input;
            _openRight = openRight;
            _done = done;
        }
    }

    ///
    @property bool empty()
    {
        return _done;
    }

    ///
    @property auto ref front()
    {
        assert(!empty, "Can not get the front of an empty Until");
        return _input.front;
    }

    private bool predSatisfied()
    {
        static if (is(Sentinel == void))
            return cast(bool) unaryFun!pred(_input.front);
        else
            return cast(bool) startsWith!pred(_input, _sentinel);
    }

    ///
    void popFront()
    {
        assert(!empty, "Can not popFront of an empty Until");
        if (!_openRight)
        {
            static if (isInputRange!Sentinel
                && is(immutable ElementEncodingType!Sentinel == immutable ElementEncodingType!Range))
            {
                _input.popFront();
                _done = _input.empty || _sentinel.empty;
                if (!_done)
                {
                    if (_matchStarted)
                    {
                        _sentinel.popFront;
                    }
                    else
                    {
                        _matchStarted = predSatisfied();
                        if (_matchStarted)
                        {
                            _sentinel.popFront;
                        }
                    }
                }
            }
            else
            {
                _done = predSatisfied();
                _input.popFront();
                _done = _done || _input.empty;
            }
        }
        else
        {
            _input.popFront();
            _done = _input.empty || predSatisfied();
        }
    }

    static if (isForwardRange!Range)
    {
        ///
        @property Until save()
        {
            static if (is(Sentinel == void))
                return Until(_input.save, _openRight, _done);
            else
                return Until(_input.save, _sentinel, _openRight, _done);
        }
    }
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : No;
    int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];
    assert(equal(a.until(7), [1, 2, 4]));
    assert(equal(a.until(7, No.openRight), [1, 2, 4, 7]));
}

@safe unittest
{
    import std.algorithm.comparison : equal;
    int[] a = [ 1, 2, 4, 7, 7, 2, 4, 7, 3, 5];

    static assert(isForwardRange!(typeof(a.until(7))));
    static assert(isForwardRange!(typeof(until!"a == 2"(a, No.openRight))));

    assert(equal(a.until(7), [1, 2, 4]));
    assert(equal(a.until([7, 2]), [1, 2, 4, 7]));
    assert(equal(a.until(7, No.openRight), [1, 2, 4, 7]));
    assert(equal(until!"a == 2"(a, No.openRight), [1, 2]));
}

// https://issues.dlang.org/show_bug.cgi?id=13171
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.range;
    auto a = [1, 2, 3, 4];
    assert(equal(refRange(&a).until(3, No.openRight), [1, 2, 3]));
    assert(a == [4]);
}

// https://issues.dlang.org/show_bug.cgi?id=10460
@safe unittest
{
    import std.algorithm.comparison : equal;
    auto a = [1, 2, 3, 4];
    foreach (ref e; a.until(3))
        e = 0;
    assert(equal(a, [0, 0, 3, 4]));
}

// https://issues.dlang.org/show_bug.cgi?id=13124
@safe unittest
{
    import std.algorithm.comparison : among, equal;
    auto s = "hello how\nare you";
    assert(equal(s.until!(c => c.among!('\n', '\r')), "hello how"));
}

// 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).until("bar");
        assert(equal(r.save, "foo"));
        assert(equal(r.save, "foo"));
    }
    {
        string s = "foobar";
        auto r = refRange(&s).until!(e => e == 'b');
        assert(equal(r.save, "foo"));
        assert(equal(r.save, "foo"));
    }
}

// https://issues.dlang.org/show_bug.cgi?id=14543
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.uni : toUpper;
    assert("one two three".until("two").equal("one "));
    assert("one two three".until("two", OpenRight.no).equal("one two"));

    assert("one two three".until("two", No.openRight).equal("one two"));
    assert("one two three".until("two", Yes.openRight).equal("one "));

    assert("one two three".until('t', Yes.openRight).equal("one "));
    assert("one two three".until("", Yes.openRight).equal(""));
    assert("one two three".until("", No.openRight).equal(""));

    assert("one two three".until("three", No.openRight).equal("one two three"));
    assert("one two three".until("three", Yes.openRight).equal("one two "));

    assert("one two three".until("one", No.openRight).equal("one"));
    assert("one two three".until("one", Yes.openRight).equal(""));

    assert("one two three".until("o", No.openRight).equal("o"));
    assert("one two three".until("o", Yes.openRight).equal(""));

    assert("one two three".until("", No.openRight).equal(""));
    assert("one two three".until("", Yes.openRight).equal(""));

    assert("one two three".until!((a,b)=>a.toUpper == b)("TWO", No.openRight).equal("one two"));
}

// https://issues.dlang.org/show_bug.cgi?id=24342
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    assert(["A", "BC", "D"].until("BC", No.openRight).equal(["A", "BC"]));
    assert([[1], [2, 3], [4]].until([2, 3], No.openRight).equal([[1], [2, 3]]));
}
