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

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

/++
Checks if $(I _all) of the elements verify $(D pred).
 +/
template all(alias pred = "a")
{
    /++
    Returns $(D true) if and only if $(I _all) values $(D v) found in the
    input _range $(D range) satisfy the predicate $(D pred).
    Performs (at most) $(BIGOH range.length) evaluations of $(D pred).
     +/
    bool all(Range)(Range range)
    if (isInputRange!Range && 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]));
}

/++
$(D 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]));
}

/++
Checks if $(I _any) of the elements verifies $(D pred).
$(D !any) can be used to verify that $(I none) of the elements verify
$(D pred).
This is sometimes called `exists` in other languages.
 +/
template any(alias pred = "a")
{
    /++
    Returns $(D true) if and only if $(I _any) value $(D v) found in the
    input _range $(D range) satisfies the predicate $(D pred).
    Performs (at most) $(BIGOH range.length) evaluations of $(D pred).
     +/
    bool any(Range)(Range range)
    if (isInputRange!Range && 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"]));
}

/++
$(D any) can also be used without a predicate, if its items can be
evaluated to true or false in a conditional statement. $(D !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));
}

// balancedParens
/**
Checks whether $(D r) has "balanced parentheses", i.e. all instances
of $(D lPar) are closed by corresponding instances of $(D rPar). The
parameter $(D maxNestingLevel) controls the nesting level allowed. The
most common uses are the default or $(D 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;
    for (; !r.empty; r.popFront())
    {
        if (r.front == lPar)
        {
            if (count > maxNestingLevel) return false;
            ++count;
        }
        else if (r.front == rPar)
        {
            if (!count) return false;
            --count;
        }
    }
    return count == 0;
}

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

/**
 * Sets up Boyer-Moore matching for use with $(D find) below.
 * By default, elements are compared for equality.
 *
 * $(D BoyerMooreFinder) allocates GC memory.
 *
 * Params:
 * pred = Predicate used to compare elements.
 * needle = A random-access range with length and slicing.
 *
 * Returns:
 * An instance of $(D BoyerMooreFinder) that can be used with $(D find()) to
 * invoke the Boyer-Moore matching algorithm for finding of $(D 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)
    {
        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)
    {
        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(sizediff_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 $(D "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 $(D r1) which contains the characters that both ranges start with,
if the first argument is a string; otherwise, the same as the result of
$(D takeExactly(r1, n)), where $(D 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);

    foreach (S; AliasSeq!(char[], const(char)[], string,
                          wchar[], const(wchar)[], wstring,
                          dchar[], const(dchar)[], dstring))
    {
        foreach (T; AliasSeq!(string, wstring, dstring))
        (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
            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"));

            //Bug# 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
/**
The first version counts the number of elements $(D x) in $(D r) for
which $(D pred(x, value)) is $(D true). $(D pred) defaults to
equality. Performs $(BIGOH haystack.length) evaluations of $(D pred).

The second version returns the number of times $(D needle) occurs in
$(D haystack). Throws an exception if $(D needle.empty), as the _count
of the empty range in any range would be infinite. Overlapped counts
are not considered, for example $(D count("aaa", "aa")) is $(D 1), not
$(D 2).

The third version counts the elements for which $(D pred(x)) is $(D
true). Performs $(BIGOH haystack.length) evaluations of $(D pred).

The fourth version counts the number of elements in a range. It is
an optimization for the third version: if the given range has the
`length` property the count is returned right away, otherwise
performs $(BIGOH haystack.length) to walk the range.

Note: Regardless of the overload, $(D count) will not accept
infinite ranges for $(D haystack).

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

Returns:
    The number of positions in the `haystack` for which `pred` returned true.
*/
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))
{
    bool pred2(ElementType!Range a) { return binaryFun!pred(a, needle); }
    return count!pred2(haystack);
}

///
@safe unittest
{
    import std.uni : toLower;

    // count elements in range
    int[] a = [ 1, 2, 4, 3, 2, 5, 3, 2, 4 ];
    assert(count(a) == 9);
    assert(count(a, 2) == 3);
    assert(count!("a > b")(a, 2) == 5);
    // 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);
    // count predicate in range
    assert(count!("a > 1")(a) == 8);
}

@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)) : bool))
{
    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;
    }
}

/// Ditto
size_t count(alias pred, R)(R haystack)
if (isInputRange!R && !isInfinite!R &&
    is(typeof(unaryFun!pred(haystack.front)) : bool))
{
    size_t result;
    alias T = ElementType!R; //For narrow strings forces dchar iteration
    foreach (T elem; haystack)
        if (unaryFun!pred(elem)) ++result;
    return result;
}

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

// Issue 11253
@safe nothrow unittest
{
    assert([1, 2, 3].count([2, 3]) == 1);
}

/++
    Counts elements in the given
    $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
    until the given predicate is true for one of the given $(D 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 $(D haystack) under the given predicate.

    Returns: The number of elements which must be popped from the front of
    $(D haystack) before reaching an element for which
    $(D startsWith!pred(haystack, needles)) is $(D true). If
    $(D startsWith!pred(haystack, needles)) is not $(D true) for any element in
    $(D haystack), then $(D -1) is returned.

    See_Also: $(REF indexOf, std,string)
  +/
ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, Rs needles)
if (isForwardRange!R
    && Rs.length > 0
    && isForwardRange!(Rs[0]) == isInputRange!(Rs[0])
    && is(typeof(startsWith!pred(haystack, needles[0])))
    && (Rs.length == 1
    || is(typeof(countUntil!pred(haystack, needles[1 .. $])))))
{
    typeof(return) result;

    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 cast(typeof(return)) (len - r2.length);
        }
        else
        {
            import std.range : dropOne;

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

            //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();
            }
        }
    }
    else
    {
        foreach (i, Ri; Rs)
        {
            static if (isForwardRange!Ri)
            {
                if (needles[i].empty)
                  return 0;
            }
        }
        Tuple!Rs t;
        foreach (i, Ri; Rs)
        {
            static if (!isForwardRange!Ri)
            {
                t[i] = needles[i];
            }
        }
        for (; !haystack.empty ; ++result, haystack.popFront())
        {
            foreach (i, Ri; Rs)
            {
                static if (isForwardRange!Ri)
                {
                    t[i] = needles[i].save;
                }
            }
            if (startsWith!pred(haystack.save, t.expand))
            {
                return result;
            }
        }
    }

    //Because of @@@8804@@@: Avoids both "unreachable code" or "no return statement"
    static if (isInfinite!R) assert(0);
    else return -1;
}

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

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

/++
    Similar to the previous overload of $(D countUntil), except that this one
    evaluates only the predicate $(D pred).

    Params:
        pred = Predicate to when to stop counting.
        haystack = An
          $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of
          elements to be counted.
    Returns: The number of elements which must be popped from $(D haystack)
    before $(D pred(haystack.front)) is $(D true).
  +/
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 @@@8804@@@: Avoids both "unreachable code" or "no return statement"
    static if (isInfinite!R) assert(0);
    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 $(D 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 $(D withOneOfThese[0]), 2 if it ends with $(D withOneOfThese[1]), and so
on.

In the case when no needle parameters are given, return $(D true) iff back of
$(D doesThisStart) fulfils predicate $(D pred).
*/
uint endsWith(alias pred = "a == b", Range, Needles...)(Range doesThisEnd, Needles withOneOfThese)
if (isBidirectionalRange!Range && Needles.length > 1 &&
    is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[0])) : bool) &&
    is(typeof(.endsWith!pred(doesThisEnd, withOneOfThese[1 .. $])) : uint))
{
    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(Unqual!(ElementEncodingType!R1) == Unqual!(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;

    alias predFunc = binaryFun!pred;

    // auto-decoding special case
    static if (isNarrowString!R)
    {
        // specialize for ASCII as to not change previous behavior
        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;

    foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
    {
        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);

        foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
        (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
            //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);
        }();
    }

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

/**
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
    seed = custom seed to use as initial element
    r = Range from which the extreme value will be selected

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");
}
body
{
    alias Element = ElementType!Range;
    Unqual!Element seed = r.front;
    r.popFront();
    return extremum!(map, selector)(r, seed);
}

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))))
{
    alias mapFun = unaryFun!map;
    alias selectorFun = binaryFun!selector;

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

    alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
    MapType extremeElementMapped = mapFun(extremeElement);

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

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

// 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))))
{
    alias Element = ElementType!Range;
    alias CommonElement = CommonType!(Element, RangeElementType);
    Unqual!CommonElement extremeElement = seedElement;
    alias selectorFun = binaryFun!selector;

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

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

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

// find
/**
Finds an individual element in an input range. Elements of $(D
haystack) are compared with $(D needle) by using predicate $(D
pred). Performs $(BIGOH walkLength(haystack)) evaluations of $(D
pred).

To _find the last occurrence of $(D needle) in $(D haystack), call $(D
find(retro(haystack), needle)). See $(REF retro, std,range).

Params:

pred = The predicate for comparing each element with the needle, defaulting to
$(D "a == b").
The negated predicate $(D "a != b") can be used to search instead for the first
element $(I not) matching the needle.

haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
searched in.

needle = The element searched for.

Constraints:

$(D isInputRange!InputRange && is(typeof(binaryFun!pred(haystack.front, needle)
: bool)))

Returns:

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

See_Also:
     $(HTTP sgi.com/tech/stl/_find.html, STL's _find)
 */
InputRange find(alias pred = "a == b", InputRange, Element)(InputRange haystack, scope Element needle)
if (isInputRange!InputRange &&
    is (typeof(binaryFun!pred(haystack.front, needle)) : 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.
    // 8829 enhancement
    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 R trustedMemchr(ref R haystack, ref 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 conditonal 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)
    {
        //10403 optimization
        static if (isDefaultPred && isIntegral!EType && EType.sizeof == 1 && isIntegralNeedle)
        {
            import std.algorithm.comparison : max, min;

            R findHelper(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.algorithm.comparison : equal;
    import std.container : SList;
    import std.range;
    import std.range.primitives : empty;

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

    auto r = assumeSorted!"a > b"([10, 7, 3, 1, 0, 0]);
    assert(find(r, 3) == assumeSorted!"a > b"([3, 1, 0, 0]));
    assert(find!"a > b"(r, 8) == r);
    assert(find!"a < b"(r, 5) == assumeSorted!"a > b"([3, 1, 0, 0]));

    assert(find("hello, world", ',') == ", world");
    assert(find([1, 2, 3, 5], 4) == []);
    assert(equal(find(SList!int(1, 2, 3, 4, 5)[], 4), SList!int(4, 5)[]));
    assert(find!"a > b"([1, 2, 3, 5], 2) == [3, 5]);

    auto a = [ 1, 2, 3 ];
    assert(find(a, 5).empty);       // not found
    assert(!find(a, 2).empty);      // found

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

@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;
    foreach (R; AliasSeq!(string, wstring, dstring))
    {
        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];
        foreach (arr; AliasSeq!(sarr, uarr))
        {
            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;
}

@safe unittest
{
    // Bugzilla 11603
    enum Foo : ubyte { A }
    assert([Foo.A].find(Foo.A).empty == false);

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

/**
Advances the input range $(D haystack) by calling $(D haystack.popFront)
until either $(D pred(haystack.front)), or $(D
haystack.empty). Performs $(BIGOH haystack.length) evaluations of $(D
pred).

To _find the last element of a
$(REF_ALTTEXT bidirectional, isBidirectionalRange, std,range,primitives) $(D haystack) satisfying
$(D pred), call $(D find!(pred)(retro(haystack))). See $(REF retro, std,range).

`find` behaves similar to `dropWhile` in other languages.

Params:

pred = The predicate for determining if a given element is the one being
searched for.

haystack = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to
search in.

Returns:

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

See_Also:
     $(HTTP sgi.com/tech/stl/find_if.html, STL's find_if)
*/
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 x) { return x + 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 the first occurrence of a forward range in another forward range.

Performs $(BIGOH walkLength(haystack) * walkLength(needle)) comparisons in the
worst case.  There are specializations that improve performance by taking
advantage of $(REF_ALTTEXT bidirectional range, isBidirectionalRange, std,range,primitives)
or random access in the given ranges (where possible), depending on the statistics
of the two ranges' content.

Params:

pred = The predicate to use for comparing respective elements from the haystack
and the needle. Defaults to simple equality $(D "a == b").

haystack = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
searched in.

needle = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
searched for.

Returns:

$(D haystack) advanced such that $(D needle) is a prefix of it (if no
such position exists, returns $(D haystack) advanced to termination).
 */
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)(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.
        // 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)]);
}

@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;
    import std.stdio;

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

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

// 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);
                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 issue 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 issue 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 $(D needles) into a $(D 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 $(D needles) is a range with elements comparable to
elements in $(D haystack), then $(D 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 $(D needles) must
be either comparable to one element in $(D haystack), or be itself a
forward range with elements comparable with elements in
$(D haystack).

Returns:

A tuple containing $(D 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 $(D needles) matched, 1 if $(D needles[0])
matched, 2 if $(D 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
$(D "a") and $(D 'a')), then the left-most of them in the argument list
matches).

The relationship between $(D haystack) and $(D needles) simply means
that one can e.g. search for individual $(D int)s or arrays of $(D
int)s in an array of $(D int)s. In addition, if elements are
individually comparable, searches of heterogeneous types are allowed
as well: a $(D double[]) can be searched for an $(D int) or a $(D
short[]), and conversely a $(D long) can be searched for a $(D float)
or a $(D 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 $(D haystack) as
few times as possible.
 */
Tuple!(Range, size_t) find(alias pred = "a == b", Range, Ranges...)
(Range haystack, Ranges needles)
if (Ranges.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 $(D needle) in $(D 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:
 * $(D haystack) advanced such that $(D needle) is a prefix of it (if no
 * such position exists, returns $(D 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.

See_Also:
$(LREF among) for checking a value against multiple possibilities.
 +/
template canFind(alias pred="a == b")
{
    import std.meta : allSatisfy;

    /++
    Returns $(D true) if and only if any value $(D v) found in the
    input range $(D range) satisfies the predicate $(D pred).
    Performs (at most) $(BIGOH haystack.length) evaluations of $(D pred).
     +/
    bool canFind(Range)(Range haystack)
    if (is(typeof(find!pred(haystack))))
    {
        return any!pred(haystack);
    }

    /++
    Returns $(D true) if and only if $(D needle) can be found in $(D
    range). Performs $(BIGOH haystack.length) evaluations of $(D 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 $(D haystack). If no
    needle is found, then $(D 0) is returned.

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

///
@safe unittest
{
    assert(canFind([0, 1, 2, 3], 2) == true);
    assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]));
    assert(canFind([0, 1, 2, 3], [1, 2], [2, 3]) == 1);
    assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]));
    assert(canFind([0, 1, 2, 3], [1, 7], [2, 3]) == 2);

    assert(canFind([0, 1, 2, 3], 4) == false);
    assert(!canFind([0, 1, 2, 3], [1, 3], [2, 4]));
    assert(canFind([0, 1, 2, 3], [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 a, string b) => a.startsWith(b))(words, "bees"));
}

@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 $(D r) until it finds the first two adjacent elements $(D a),
$(D b) that satisfy $(D pred(a, b)). Performs $(BIGOH r.length)
evaluations of $(D pred).

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

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

See_Also:
     $(HTTP sgi.com/tech/stl/adjacent_find.html, 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;
}

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

    // Issue 9350
    assert(!repeat(1).findAdjacent().empty);
}

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

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

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:
$(D seq) advanced to the first matching element, or until empty if there are no
matching elements.

See_Also:
    $(HTTP sgi.com/tech/stl/find_first_of.html, STL's find_first_of)
*/
InputRange findAmong(alias pred = "a == b", InputRange, ForwardRange)(
    InputRange seq, ForwardRange choices)
if (isInputRange!InputRange && isForwardRange!ForwardRange)
{
    for (; !seq.empty && find!pred(choices, 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);
}

// findSkip
/**
 * Finds $(D needle) in $(D haystack) and positions $(D haystack)
 * right after the first occurrence of $(D needle).
 *
 * 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.
 *
 * Returns: $(D true) if the needle was found, in which case $(D haystack) is
 * positioned after the end of the first occurrence of $(D needle); otherwise
 * $(D false), leaving $(D haystack) untouched.
 */
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);
}

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

`findSplit` returns a tuple `result` containing $(I three) ranges. `result[0]`
is the portion of `haystack` before `needle`, `result[1]` is the portion of
`haystack` that matches `needle`, and `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. `result[0]` is
the portion of `haystack` before `needle`, and `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.
`result[0]` is the portion of `haystack` up to and including the
match, and `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`.

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]` is the same as $(REF takeExactly,
std,range).

Params:
    pred = Predicate to use for comparing needle against haystack.
    haystack = The range to search.
    needle = What to look for.

Returns:

A sub-type of `Tuple!()` of the split portions of `haystack` (see above for
details).  This sub-type of `Tuple!()` has `opCast` defined for `bool`.  This
`opCast` returns `true` when the separating `needle` was found
(`!result[1].empty`) and `false` otherwise.  This enables the convenient idiom
shown in the following example.

Example:
---
if (const split = haystack.findSplit(needle))
{
     doSomethingWithSplit(split);
}
---
 */
auto findSplit(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2)
{
    static struct Result(S1, S2) if (isForwardRange!S1 &&
                                     isForwardRange!S2)
    {
        this(S1 pre, S1 separator, S2 post)
        {
            asTuple = typeof(asTuple)(pre, separator, post);
        }
        void opAssign(typeof(asTuple) rhs)
        {
            asTuple = rhs;
        }
        Tuple!(S1, S1, S2) asTuple;
        bool opCast(T : bool)()
        {
            return !asTuple[1].empty;
        }
        alias asTuple this;
    }

    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;
        return Result!(typeof(haystack[0 .. pos1]),
                       typeof(haystack[pos2 .. haystack.length]))(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;
            }
        }
        return Result!(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 struct Result(S1, S2) if (isForwardRange!S1 &&
                                     isForwardRange!S2)
    {
        this(S1 pre, S2 post)
        {
            asTuple = typeof(asTuple)(pre, post);
        }
        void opAssign(typeof(asTuple) rhs)
        {
            asTuple = rhs;
        }
        Tuple!(S1, S2) asTuple;
        bool opCast(T : bool)()
        {
            return !asTuple[0].empty;
        }
        alias asTuple this;
    }

    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 Result!(typeof(haystack[0 .. pos]),
                       typeof(haystack[pos .. haystack.length]))(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 pos;
        while (!n.empty && !h.empty)
        {
            if (binaryFun!pred(h.front, n.front))
            {
                h.popFront();
                n.popFront();
            }
            else
            {
                haystack.popFront();
                n = needle.save;
                h = haystack.save;
                ++pos;
            }
        }
        return Result!(typeof(takeExactly(original, pos)),
                       typeof(haystack))(takeExactly(original, pos),
                                         haystack);
    }
}

/// Ditto
auto findSplitAfter(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if (isForwardRange!R1 && isForwardRange!R2)
{
    static struct Result(S1, S2) if (isForwardRange!S1 &&
                                     isForwardRange!S2)
    {
        this(S1 pre, S2 post)
        {
            asTuple = typeof(asTuple)(pre, post);
        }
        void opAssign(typeof(asTuple) rhs)
        {
            asTuple = rhs;
        }
        Tuple!(S1, S2) asTuple;
        bool opCast(T : bool)()
        {
            return !asTuple[1].empty;
        }
        alias asTuple this;
    }

    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 Result!(typeof(haystack[0 .. pos]),
                       typeof(haystack[pos .. haystack.length]))(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)
        {
            if (h.empty)
            {
                // Failed search
                return Result!(typeof(takeExactly(original, 0)),
                               typeof(original))(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 Result!(typeof(takeExactly(original, pos2)),
                       typeof(h))(takeExactly(original, pos2),
                                  h);
    }
}

///
@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");
    auto r1 = findSplitBefore(a, "Sagan");
    assert(r1);
    assert(r1[0] == "Carl ");
    assert(r1[1] == "Sagan Memorial Station");
    auto 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;

    auto 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 .. $]);

    auto r1 = findSplitBefore(a, [9, 1]);
    assert(r1);
    assert(r1[0] == a);
    assert(r1[1].empty);
    r1 = findSplitBefore(a, [3, 4]);
    assert(r1);
    assert(r1[0] == a[0 .. 2]);
    assert(r1[1] == a[2 .. $]);

    auto r2 = findSplitAfter(a, [9, 1]);
    assert(r2);
    assert(r2[0].empty);
    assert(r2[1] == a);
    r2 = findSplitAfter(a, [3, 4]);
    assert(r2);
    assert(r2[0] == a[0 .. 4]);
    assert(r2[1] == a[4 .. $]);
}

@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 .. $]));

    auto r1 = findSplitBefore(fwd, [9, 1]);
    assert(r1);
    assert(equal(r1[0], a));
    assert(r1[1].empty);
    r1 = findSplitBefore(fwd, [3, 4]);
    assert(r1);
    assert(equal(r1[0], a[0 .. 2]));
    assert(equal(r1[1], a[2 .. $]));

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

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

// 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 $(D 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 $(D pred(a, b) && pred(b, c)) then $(D pred(a, c))) and
irreflexive ($(D pred(a, a)) is `false`). The $(LUCKY trichotomy property of
inequality) is not required: these algoritms consider elements `a` and `b` equal
(for the purpose of counting) if `pred` puts them in the same equivalence class,
i.e. $(D !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.

Throws: `Exception` if `range.empty`.
 */
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);

    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

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

See_Also:
    $(REF min, std,algorithm,comparison)
*/
auto minElement(alias map, Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
{
    return extremum!map(r);
}

/// ditto
auto minElement(Range)(Range r)
    if (isInputRange!Range && !isInfinite!Range)
{
    return extremum(r);
}

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

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

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

    assert([2, 1, 4, 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);
    }

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

/**
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:
    Exactly `n - 1` comparisons are needed.

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

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

See_Also:
    $(REF max, std,algorithm,comparison)
*/
auto maxElement(alias map, Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
{
    return extremum!(map, "a > b")(r);
}

/// ditto
auto maxElement(Range)(Range r)
if (isInputRange!Range && !isInfinite!Range)
{
    return extremum!`a > b`(r);
}

/// ditto
auto maxElement(alias map, 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);
}

/// ditto
auto maxElement(Range, RangeElementType = ElementType!Range)
               (Range r, RangeElementType seed)
if (isInputRange!Range && !isInfinite!Range &&
    !is(CommonType!(ElementType!Range, RangeElementType) == void))
{
    return extremum!`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);
    }

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

// 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 $(D pred(a, x)) is
`false` for all values `a` in `range`. Conversely, the maximum is a value `x` in
`range` such that $(D 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 $(D pred(a, b) && pred(b, c)) then $(D pred(a, c))) and
irreflexive ($(D pred(a, a)) is `false`).

Params:
    pred = The ordering predicate to use to determine the extremum (minimum or
        maximum) element.
    range = The $(REF_ALTTEXT input range, isInputRange, 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`.

*/
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: O(n)
    Exactly `n - 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.

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

    sizediff_t minPos = 0;

    static if (isRandomAccessRange!Range && hasLength!Range)
    {
        foreach (i; 1 .. range.length)
        {
            if (binaryFun!pred(range[i], range[minPos]))
            {
                minPos = i;
            }
        }
    }
    else
    {
        sizediff_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);
}

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

Complexity: O(n)
    Exactly `n - 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.

See_Also:
    $(REF max, std,algorithm,comparison), $(LREF maxCount), $(LREF maxElement), $(LREF maxPos)
 */
sizediff_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 that matches the second
range, or if no second range is given skip over the elements that fullfil pred.
Do nothing if there is no match.

Params:
    pred = The predicate that determines whether elements from each respective
        range match. Defaults to equality $(D "a == b").
    r1 = The $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives) to
        move forward.
    r2 = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
        representing the initial segment of $(D r1) to skip over.

Returns:
true if the initial segment of $(D r1) matches $(D r2) or $(D pred) evaluates to true,
and $(D r1) has been advanced to the point past this segment; otherwise false, and
$(D r1) is left in its original position.
 */
bool skipOver(R1, R2)(ref R1 r1, R2 r2)
if (isForwardRange!R1 && isInputRange!R2
    && is(typeof(r1.front == r2.front)))
{
    static if (is(typeof(r1[0 .. $] == r2) : bool)
        && is(typeof(r2.length > r1.length) : bool)
        && is(typeof(r1 = r1[r2.length .. $])))
    {
        if (r2.length > r1.length || r1[0 .. r2.length] != r2)
        {
            return false;
        }
        r1 = r1[r2.length .. $];
        return true;
    }
    else
    {
        return skipOver!((a, b) => a == b)(r1, r2);
    }
}

/// Ditto
bool skipOver(alias pred, R1, R2)(ref R1 r1, R2 r2)
if (is(typeof(binaryFun!pred(r1.front, r2.front))) &&
    isForwardRange!R1 &&
    isInputRange!R2)
{
    static if (hasLength!R1 && hasLength!R2)
    {
        // Shortcut opportunity!
        if (r2.length > r1.length)
            return false;
    }
    auto r = r1.save;
    while (!r2.empty && !r.empty && binaryFun!pred(r.front, r2.front))
    {
        r.popFront();
        r2.popFront();
    }
    if (r2.empty)
        r1 = r;
    return r2.empty;
}

/// Ditto
bool skipOver(alias pred, 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;
}

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

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

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

/**
Skip over the first element of the given range if it matches the given element,
otherwise do nothing.

Params:
    pred = The predicate that determines whether an element from the range
        matches the given element.

    r = The $(REF_ALTTEXT input range, isInputRange, std,range,primitives) to skip
        over.

    e = The element to match.

Returns:
true if the first element matches the given element according to the given
predicate, and the range has been advanced by one element; otherwise false, and
the range is left untouched.
 */
bool skipOver(R, E)(ref R r, E e)
if (isInputRange!R && is(typeof(r.front == e) : bool))
{
    return skipOver!((a, b) => a == b)(r, e);
}

/// Ditto
bool skipOver(alias pred, R, E)(ref R r, E e)
if (is(typeof(binaryFun!pred(r.front, e))) && isInputRange!R)
{
    if (r.empty || !binaryFun!pred(r.front, e))
        return false;
    r.popFront();
    return true;
}

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

/**
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 $(D pred).

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 $(D withOneOfThese[0]), 2 if it starts with $(D withOneOfThese[1]), and so
on.

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

In the case when no needle parameters are given, return $(D true) iff front of
$(D doesThisStart) fulfils predicate $(D pred).
 */
uint startsWith(alias pred = "a == b", Range, Needles...)(Range doesThisStart, Needles withOneOfThese)
if (isInputRange!Range && Needles.length > 1 &&
    is(typeof(.startsWith!pred(doesThisStart, withOneOfThese[0])) : bool ) &&
    is(typeof(.startsWith!pred(doesThisStart, withOneOfThese[1 .. $])) : uint))
{
    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: While narrow strings don't have a "true" length, for a narrow string to start with another
    //narrow string *of the same type*, it must have *at least* as many code units.
    static if ((hasLength!R1 && hasLength!R2) ||
        (isNarrowString!R1 && isNarrowString!R2 && ElementEncodingType!R1.sizeof == ElementEncodingType!R2.sizeof))
    {
        if (haystack.length < needle.length)
            return false;
    }

    static if (isDefaultPred && isArray!R1 && isArray!R2 &&
               is(Unqual!(ElementEncodingType!R1) == Unqual!(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;

    alias predFunc = binaryFun!pred;

    // auto-decoding special case
    static if (isNarrowString!R)
    {
        // specialize for ASCII as to not change previous behavior
        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;

    foreach (S; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
    {
        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);

        foreach (T; AliasSeq!(char[], wchar[], dchar[], string, wstring, dstring))
        (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
            //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)));

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

/* (Not yet documented.)
Consume all elements from $(D r) that are equal to one of the elements
$(D 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 $(D OpenRight.yes), then the interval is open to the right
(last element is not included).

Otherwise if set to $(D OpenRight.no), then the interval is closed to the right
(last element included).
 */
alias OpenRight = Flag!"openRight";

/**
Lazily iterates $(D range) _until the element $(D e) for which
$(D 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 ($(D No.openRight)), or
        not ($(D 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 _done;

    static if (!is(Sentinel == void))
        ///
        this(Range input, Sentinel sentinel,
                OpenRight openRight = Yes.openRight)
        {
            _input = input;
            _sentinel = sentinel;
            _openRight = openRight;
            _done = _input.empty || openRight && predSatisfied();
        }
    else
        ///
        this(Range input, OpenRight openRight = Yes.openRight)
        {
            _input = input;
            _openRight = openRight;
            _done = _input.empty || openRight && predSatisfied();
        }

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

    ///
    @property auto ref front()
    {
        assert(!empty);
        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);
        if (!_openRight)
        {
            _done = predSatisfied();
            _input.popFront();
            _done = _done || _input.empty;
        }
        else
        {
            _input.popFront();
            _done = _input.empty || predSatisfied();
        }
    }

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

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

@system unittest // bugzilla 13171
{
    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]);
}

@safe unittest // Issue 10460
{
    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]));
}

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