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

$(SCRIPT inhibitQuickIndex = 1;)
$(BOOKTABLE Cheat Sheet,
$(TR $(TH Function Name) $(TH Description))
$(T2 among,
        Checks if a value is among a set of values, e.g.
        `if (v.among(1, 2, 3)) // `v` is 1, 2 or 3`)
$(T2 castSwitch,
        `(new A()).castSwitch((A a)=>1,(B b)=>2)` returns `1`.)
$(T2 clamp,
        `clamp(1, 3, 6)` returns `3`. `clamp(4, 3, 6)` returns `4`.)
$(T2 cmp,
        `cmp("abc", "abcd")` is `-1`, `cmp("abc", "aba")` is `1`,
        and `cmp("abc", "abc")` is `0`.)
$(T2 either,
        Return first parameter `p` that passes an `if (p)` test, e.g.
        `either(0, 42, 43)` returns `42`.)
$(T2 equal,
        Compares ranges for element-by-element equality, e.g.
        `equal([1, 2, 3], [1.0, 2.0, 3.0])` returns `true`.)
$(T2 isPermutation,
        `isPermutation([1, 2], [2, 1])` returns `true`.)
$(T2 isSameLength,
        `isSameLength([1, 2, 3], [4, 5, 6])` returns `true`.)
$(T2 levenshteinDistance,
        `levenshteinDistance("kitten", "sitting")` returns `3` by using
        the $(LINK2 https://en.wikipedia.org/wiki/Levenshtein_distance,
        Levenshtein distance algorithm).)
$(T2 levenshteinDistanceAndPath,
        `levenshteinDistanceAndPath("kitten", "sitting")` returns
        `tuple(3, "snnnsni")` by using the
        $(LINK2 https://en.wikipedia.org/wiki/Levenshtein_distance,
        Levenshtein distance algorithm).)
$(T2 max,
        `max(3, 4, 2)` returns `4`.)
$(T2 min,
        `min(3, 4, 2)` returns `2`.)
$(T2 mismatch,
        `mismatch("oh hi", "ohayo")` returns `tuple(" hi", "ayo")`.)
$(T2 predSwitch,
        `2.predSwitch(1, "one", 2, "two", 3, "three")` returns `"two"`.)
)

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

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

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

import std.internal.attributes : betterC;

/**
Find `value` _among `values`, returning the 1-based index
of the first matching value in `values`, or `0` if `value`
is not _among `values`. The predicate `pred` is used to
compare values, and uses equality by default.

Params:
    pred = The predicate used to compare the values.
    value = The value to search for.
    values = The values to compare the value to.

Returns:
    0 if value was not found among the values, otherwise the index of the
    found value plus one is returned.

See_Also:
$(REF_ALTTEXT find, find, std,algorithm,searching) and $(REF_ALTTEXT canFind, canFind, std,algorithm,searching) for finding a value in a
range.
*/
uint among(alias pred = (a, b) => a == b, Value, Values...)
    (Value value, Values values)
if (Values.length != 0)
{
    foreach (uint i, ref v; values)
    {
        import std.functional : binaryFun;
        if (binaryFun!pred(value, v)) return i + 1;
    }
    return 0;
}

/// Ditto
template among(values...)
if (isExpressionTuple!values)
{
    uint among(Value)(Value value)
        if (!is(CommonType!(Value, values) == void))
    {
        switch (value)
        {
            foreach (uint i, v; values)
                case v:
                    return i + 1;
            default:
                return 0;
        }
    }
}

///
@safe @nogc @betterC unittest
{
    assert(3.among(1, 42, 24, 3, 2));

    if (auto pos = "bar".among("foo", "bar", "baz"))
        assert(pos == 2);
    else
        assert(false);

    // 42 is larger than 24
    assert(42.among!((lhs, rhs) => lhs > rhs)(43, 24, 100) == 2);
}

/**
Alternatively, `values` can be passed at compile-time, allowing for a more
efficient search, but one that only supports matching on equality:
*/
@safe @nogc @betterC unittest
{
    assert(3.among!(2, 3, 4));
    assert("bar".among!("foo", "bar", "baz") == 2);
}

@safe unittest
{
    import std.meta : AliasSeq;

    if (auto pos = 3.among(1, 2, 3))
        assert(pos == 3);
    else
        assert(false);
    assert(!4.among(1, 2, 3));

    auto position = "hello".among("hello", "world");
    assert(position);
    assert(position == 1);

    alias values = AliasSeq!("foo", "bar", "baz");
    auto arr = [values];
    assert(arr[0 .. "foo".among(values)] == ["foo"]);
    assert(arr[0 .. "bar".among(values)] == ["foo", "bar"]);
    assert(arr[0 .. "baz".among(values)] == arr);
    assert("foobar".among(values) == 0);

    if (auto pos = 3.among!(1, 2, 3))
        assert(pos == 3);
    else
        assert(false);
    assert(!4.among!(1, 2, 3));

    position = "hello".among!("hello", "world");
    assert(position);
    assert(position == 1);

    static assert(!__traits(compiles, "a".among!("a", 42)));
    static assert(!__traits(compiles, (Object.init).among!(42, "a")));
}

// Used in castSwitch to find the first choice that overshadows the last choice
// in a tuple.
private template indexOfFirstOvershadowingChoiceOnLast(choices...)
{
    alias firstParameterTypes = Parameters!(choices[0]);
    alias lastParameterTypes = Parameters!(choices[$ - 1]);

    static if (lastParameterTypes.length == 0)
    {
        // If the last is null-typed choice, check if the first is null-typed.
        enum isOvershadowing = firstParameterTypes.length == 0;
    }
    else static if (firstParameterTypes.length == 1)
    {
        // If the both first and last are not null-typed, check for overshadowing.
        enum isOvershadowing =
            is(firstParameterTypes[0] == Object) // Object overshadows all other classes!(this is needed for interfaces)
            || is(lastParameterTypes[0] : firstParameterTypes[0]);
    }
    else
    {
        // If the first is null typed and the last is not - the is no overshadowing.
        enum isOvershadowing = false;
    }

    static if (isOvershadowing)
    {
        enum indexOfFirstOvershadowingChoiceOnLast = 0;
    }
    else
    {
        enum indexOfFirstOvershadowingChoiceOnLast =
            1 + indexOfFirstOvershadowingChoiceOnLast!(choices[1..$]);
    }
}

/**
Executes and returns one of a collection of handlers based on the type of the
switch object.

The first choice that `switchObject` can be casted to the type
of argument it accepts will be called with `switchObject` casted to that
type, and the value it'll return will be returned by `castSwitch`.

If a choice's return type is void, the choice must throw an exception, unless
all the choices are void. In that case, castSwitch itself will return void.

Throws: If none of the choice matches, a `SwitchError` will be thrown.  $(D
SwitchError) will also be thrown if not all the choices are void and a void
choice was executed without throwing anything.

Params:
    choices = The `choices` needs to be composed of function or delegate
        handlers that accept one argument. There can also be a choice that
        accepts zero arguments. That choice will be invoked if the $(D
        switchObject) is null.
    switchObject = the object against which the tests are being made.

Returns:
    The value of the selected choice.

Note: `castSwitch` can only be used with object types.
*/
auto castSwitch(choices...)(Object switchObject)
{
    import core.exception : SwitchError;
    import std.format : format;

    // Check to see if all handlers return void.
    enum areAllHandlersVoidResult = {
        bool result = true;
        foreach (index, choice; choices)
        {
            result &= is(ReturnType!choice : void); // void or noreturn
        }
        return result;
    }();

    if (switchObject !is null)
    {
        // Checking for exact matches:
        const classInfo = typeid(switchObject);
        foreach (index, choice; choices)
        {
            static assert(isCallable!choice,
                    "A choice handler must be callable");

            alias choiceParameterTypes = Parameters!choice;
            static assert(choiceParameterTypes.length <= 1,
                    "A choice handler can not have more than one argument.");

            static if (choiceParameterTypes.length == 1)
            {
                alias CastClass = choiceParameterTypes[0];
                static assert(is(CastClass == class) || is(CastClass == interface),
                        "A choice handler can have only class or interface typed argument.");

                // Check for overshadowing:
                immutable indexOfOvershadowingChoice =
                    indexOfFirstOvershadowingChoiceOnLast!(choices[0 .. index + 1]);
                static assert(indexOfOvershadowingChoice == index,
                        "choice number %d(type %s) is overshadowed by choice number %d(type %s)".format(
                            index + 1, CastClass.stringof, indexOfOvershadowingChoice + 1,
                            Parameters!(choices[indexOfOvershadowingChoice])[0].stringof));

                if (classInfo == typeid(CastClass))
                {
                    static if (is(ReturnType!(choice) == void))
                    {
                        choice(cast(CastClass) switchObject);
                        static if (areAllHandlersVoidResult)
                        {
                            return;
                        }
                        else
                        {
                            throw new SwitchError("Handlers that return void should throw");
                        }
                    }
                    else
                    {
                        return choice(cast(CastClass) switchObject);
                    }
                }
            }
        }

        // Checking for derived matches:
        foreach (choice; choices)
        {
            alias choiceParameterTypes = Parameters!choice;
            static if (choiceParameterTypes.length == 1)
            {
                if (auto castedObject = cast(choiceParameterTypes[0]) switchObject)
                {
                    static if (is(ReturnType!(choice) == void))
                    {
                        choice(castedObject);
                        static if (areAllHandlersVoidResult)
                        {
                            return;
                        }
                        else
                        {
                            throw new SwitchError("Handlers that return void should throw");
                        }
                    }
                    else
                    {
                        return choice(castedObject);
                    }
                }
            }
        }
    }
    else // If switchObject is null:
    {
        // Checking for null matches:
        foreach (index, choice; choices)
        {
            static if (Parameters!(choice).length == 0)
            {
                immutable indexOfOvershadowingChoice =
                    indexOfFirstOvershadowingChoiceOnLast!(choices[0 .. index + 1]);

                // Check for overshadowing:
                static assert(indexOfOvershadowingChoice == index,
                        "choice number %d(null reference) is overshadowed by choice number %d(null reference)".format(
                            index + 1, indexOfOvershadowingChoice + 1));

                if (switchObject is null)
                {
                    static if (is(ReturnType!(choice) == void))
                    {
                        choice();
                        static if (areAllHandlersVoidResult)
                        {
                            return;
                        }
                        else
                        {
                            throw new SwitchError("Handlers that return void should throw");
                        }
                    }
                    else
                    {
                        return choice();
                    }
                }
            }
        }
    }

    // In case nothing matched:
    throw new SwitchError("Input not matched by any choice");
}

///
@system unittest
{
    import std.algorithm.iteration : map;
    import std.format : format;

    class A
    {
        int a;
        this(int a) {this.a = a;}
        @property int i() { return a; }
    }
    interface I { }
    class B : I { }

    Object[] arr = [new A(1), new B(), null];

    auto results = arr.map!(castSwitch!(
                                (A a) => "A with a value of %d".format(a.a),
                                (I i) => "derived from I",
                                ()    => "null reference",
                            ))();

    // A is handled directly:
    assert(results[0] == "A with a value of 1");
    // B has no handler - it is handled by the handler of I:
    assert(results[1] == "derived from I");
    // null is handled by the null handler:
    assert(results[2] == "null reference");
}

/// Using with void handlers:
@system unittest
{
    import std.exception : assertThrown;

    class A { }
    class B { }
    // Void handlers are allowed if they throw:
    assertThrown!Exception(
        new B().castSwitch!(
            (A a) => 1,
            (B d)    { throw new Exception("B is not allowed!"); }
        )()
    );

    // Void handlers are also allowed if all the handlers are void:
    new A().castSwitch!(
        (A a) { },
        (B b) { assert(false); },
    )();
}

@system unittest
{
    import core.exception : SwitchError;
    import std.exception : assertThrown;

    interface I { }
    class A : I { }
    class B { }

    // Nothing matches:
    assertThrown!SwitchError((new A()).castSwitch!(
                                 (B b) => 1,
                                 () => 2,
                             )());

    // Choices with multiple arguments are not allowed:
    static assert(!__traits(compiles,
                            (new A()).castSwitch!(
                                (A a, B b) => 0,
                            )()));

    // Only callable handlers allowed:
    static assert(!__traits(compiles,
                            (new A()).castSwitch!(
                                1234,
                            )()));

    // Only object arguments allowed:
    static assert(!__traits(compiles,
                            (new A()).castSwitch!(
                                (int x) => 0,
                            )()));

    // Object overshadows regular classes:
    static assert(!__traits(compiles,
                            (new A()).castSwitch!(
                                (Object o) => 0,
                                (A a) => 1,
                            )()));

    // Object overshadows interfaces:
    static assert(!__traits(compiles,
                            (new A()).castSwitch!(
                                (Object o) => 0,
                                (I i) => 1,
                            )()));

    // No multiple null handlers allowed:
    static assert(!__traits(compiles,
                            (new A()).castSwitch!(
                                () => 0,
                                () => 1,
                            )()));

    // No non-throwing void handlers allowed(when there are non-void handlers):
    assertThrown!SwitchError((new A()).castSwitch!(
                                 (A a)    {},
                                 (B b) => 2,
                             )());

    // All-void handlers work for the null case:
    null.castSwitch!(
        (Object o) { assert(false); },
        ()         { },
    )();

    // Throwing void handlers work for the null case:
    assertThrown!Exception(null.castSwitch!(
                               (Object o) => 1,
                               ()            { throw new Exception("null"); },
                           )());
}

@system unittest
{
    interface I { }
    class B : I { }
    class C : I { }

    assert((new B()).castSwitch!(
            (B b) => "class B",
            (I i) => "derived from I",
    ) == "class B");

    assert((new C()).castSwitch!(
            (B b) => "class B",
            (I i) => "derived from I",
    ) == "derived from I");
}

// https://issues.dlang.org/show_bug.cgi?id=22384
@system unittest
{
    // Use explicit methods to enforce return types
    static void objectSkip(Object) {}
    static void defaultSkip() {}

    static noreturn objectError(Object) { assert(false); }
    static noreturn defaultError() { assert(false); }

    {
        alias test = castSwitch!(objectSkip, defaultError);
        static assert(is(ReturnType!test == void));
    }{
        alias test = castSwitch!(objectError, defaultSkip);
        static assert(is(ReturnType!test == void));
    }{
        alias test = castSwitch!(objectError, defaultError);
        static assert(is(ReturnType!test == noreturn));
    }

    // Also works with non-void handlers
    static int objectValue(Object) { return 1;}
    static int defaultValue() { return 2; }

    {
        alias test = castSwitch!(objectValue, defaultError);
        static assert(is(ReturnType!test == int));
    }{
        alias test = castSwitch!(objectError, defaultValue);
        static assert(is(ReturnType!test == int));
    }

    // No confusion w.r.t. void callbacks
    alias FP = void function();
    static FP objectFunc(Object) { return &defaultSkip; }
    static FP defaultFunc() { return &defaultSkip; }

    {
        alias test = castSwitch!(objectFunc, defaultError);
        static assert(is(ReturnType!test == FP));
    }{
        alias test = castSwitch!(objectError, defaultFunc);
        static assert(is(ReturnType!test == FP));
    }
}

/** Clamps `val` into the given bounds. Result has the same type as `val`.

Params:
    val = The value to _clamp.
    lower = The _lower bound of the _clamp.
    upper = The _upper bound of the _clamp.

Returns:
    `lower` if `val` is less than `lower`, `upper` if `val` is greater than
    `upper`, and `val` in all other cases. Comparisons are made
    correctly (using $(REF lessThan, std,functional) and the return value
    is converted to the return type using the standard integer coversion rules
    $(REF greaterThan, std,functional)) even if the signedness of `T1`, `T2`,
    and `T3` are different.
*/
T1 clamp(T1, T2, T3)(T1 val, T2 lower, T3 upper)
if (is(typeof(val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val) : T1))
in
{
    assert(!lower.greaterThan(upper), "Lower can't be greater than upper.");
}
do
{
    return val.lessThan(lower) ? lower : val.greaterThan(upper) ? upper : val;
}

///
@safe @nogc @betterC unittest
{
    assert(clamp(2, 1, 3) == 2);
    assert(clamp(0, 1, 3) == 1);
    assert(clamp(4, 1, 3) == 3);

    assert(clamp(1, 1, 1) == 1);

    assert(clamp(5, -1, 2u) == 2);

    auto x = clamp(42, uint.max, uint.max);
    static assert(is(typeof(x) == int));
    assert(x == -1);
}

@safe unittest
{
    int a = 1;
    short b = 6;
    double c = 2;
    static assert(is(typeof(clamp(c,a,b)) == double));
    assert(clamp(c,   a, b) == c);
    assert(clamp(a-c, a, b) == a);
    assert(clamp(b+c, a, b) == b);
    // mixed sign
    a = -5;
    uint f = 5;
    static assert(is(typeof(clamp(f, a, b)) == uint));
    assert(clamp(f, a, b) == f);
    // similar type deduction for (u)long
    static assert(is(typeof(clamp(-1L, -2L, 2UL)) == long));

    // user-defined types
    import std.datetime : Date;
    assert(clamp(Date(1982, 1, 4), Date(1012, 12, 21), Date(2012, 12, 21)) == Date(1982, 1, 4));
    assert(clamp(Date(1982, 1, 4), Date.min, Date.max) == Date(1982, 1, 4));
    // UFCS style
    assert(Date(1982, 1, 4).clamp(Date.min, Date.max) == Date(1982, 1, 4));

    // Stability
    struct A {
        int x, y;
        int opCmp(ref const A rhs) const { return (x > rhs.x) - (x < rhs.x); }
    }
    A x, lo, hi;
    x.y = 42;
    assert(x.clamp(lo, hi).y == 42);
}

// cmp
/**********************************
Performs a lexicographical comparison on two
$(REF_ALTTEXT input ranges, isInputRange, std,range,primitives).
Iterating `r1` and `r2` in lockstep, `cmp` compares each element
`e1` of `r1` with the corresponding element `e2` in `r2`. If one
of the ranges has been finished, `cmp` returns a negative value
if `r1` has fewer elements than `r2`, a positive value if `r1`
has more elements than `r2`, and `0` if the ranges have the same
number of elements.

If the ranges are strings, `cmp` performs UTF decoding
appropriately and compares the ranges one code point at a time.

A custom predicate may be specified, in which case `cmp` performs
a three-way lexicographical comparison using `pred`. Otherwise
the elements are compared using `opCmp`.

Params:
    pred = Predicate used for comparison. Without a predicate
        specified the ordering implied by `opCmp` is used.
    r1 = The first range.
    r2 = The second range.

Returns:
    `0` if the ranges compare equal. A negative value if `r1` is a prefix of `r2` or
    the first differing element of `r1` is less than the corresponding element of `r2`
    according to `pred`. A positive value if `r2` is a prefix of `r1` or the first
    differing element of `r2` is less than the corresponding element of `r1`
    according to `pred`.

Note:
    An earlier version of the documentation incorrectly stated that `-1` is the
    only negative value returned and `1` is the only positive value returned.
    Whether that is true depends on the types being compared.
*/
auto cmp(R1, R2)(R1 r1, R2 r2)
if (isInputRange!R1 && isInputRange!R2)
{
    alias E1 = ElementEncodingType!R1;
    alias E2 = ElementEncodingType!R2;

    static if (isDynamicArray!R1 && isDynamicArray!R2
        && __traits(isUnsigned, E1) && __traits(isUnsigned, E2)
        && E1.sizeof == 1 && E2.sizeof == 1
        // Both or neither must auto-decode.
        && (is(immutable E1 == immutable char) == is(immutable E2 == immutable char)))
    {
        // dstrcmp algorithm is correct for both ubyte[] and for char[].
        import core.internal.string : dstrcmp;
        return dstrcmp(cast(const char[]) r1, cast(const char[]) r2);
    }
    else static if (!(isSomeString!R1 && isSomeString!R2))
    {
        for (;; r1.popFront(), r2.popFront())
        {
            static if (is(typeof(r1.front.opCmp(r2.front)) R))
                alias Result = R;
            else
                alias Result = int;
            if (r2.empty) return Result(!r1.empty);
            if (r1.empty) return Result(-1);
            static if (is(typeof(r1.front.opCmp(r2.front))))
            {
                auto c = r1.front.opCmp(r2.front);
                if (c != 0) return c;
            }
            else
            {
                auto a = r1.front, b = r2.front;
                if (auto result = (b < a) - (a < b)) return result;
            }
        }
    }
    else
    {
        static if (typeof(r1[0]).sizeof == typeof(r2[0]).sizeof)
        {
            return () @trusted
            {
                auto p1 = r1.ptr, p2 = r2.ptr,
                    pEnd = p1 + min(r1.length, r2.length);
                for (; p1 != pEnd; ++p1, ++p2)
                {
                    if (*p1 != *p2) return cast(int) *p1 - cast(int) *p2;
                }
                static if (typeof(r1[0]).sizeof >= 2 && size_t.sizeof <= uint.sizeof)
                    return cast(int) r1.length - cast(int) r2.length;
                else
                    return int(r1.length > r2.length) - int(r1.length < r2.length);
            }();
        }
        else
        {
            import std.utf : decode;

            for (size_t i1, i2;;)
            {
                if (i1 == r1.length) return -int(i2 < r2.length);
                if (i2 == r2.length) return int(1);
                immutable c1 = decode(r1, i1),
                    c2 = decode(r2, i2);
                if (c1 != c2) return cast(int) c1 - cast(int) c2;
            }
        }
    }
}

/// ditto
int cmp(alias pred, R1, R2)(R1 r1, R2 r2)
if (isInputRange!R1 && isInputRange!R2)
{
    static if (!(isSomeString!R1 && isSomeString!R2))
    {
        for (;; r1.popFront(), r2.popFront())
        {
            if (r2.empty) return !r1.empty;
            if (r1.empty) return -1;
            auto a = r1.front, b = r2.front;
            if (binaryFun!pred(a, b)) return -1;
            if (binaryFun!pred(b, a)) return 1;
        }
    }
    else
    {
        import std.utf : decode;

        for (size_t i1, i2;;)
        {
            if (i1 == r1.length) return -int(i2 < r2.length);
            if (i2 == r2.length) return 1;
            immutable c1 = decode(r1, i1),
                c2 = decode(r2, i2);
            if (c1 != c2)
            {
                if (binaryFun!pred(c2, c1)) return 1;
                if (binaryFun!pred(c1, c2)) return -1;
            }
        }
    }
}

///
pure @safe unittest
{
    int result;

    result = cmp("abc", "abc");
    assert(result == 0);
    result = cmp("", "");
    assert(result == 0);
    result = cmp("abc", "abcd");
    assert(result < 0);
    result = cmp("abcd", "abc");
    assert(result > 0);
    result = cmp("abc"d, "abd");
    assert(result < 0);
    result = cmp("bbc", "abc"w);
    assert(result > 0);
    result = cmp("aaa", "aaaa"d);
    assert(result < 0);
    result = cmp("aaaa", "aaa"d);
    assert(result > 0);
    result = cmp("aaa", "aaa"d);
    assert(result == 0);
    result = cmp("aaa"d, "aaa"d);
    assert(result == 0);
    result = cmp(cast(int[])[], cast(int[])[]);
    assert(result == 0);
    result = cmp([1, 2, 3], [1, 2, 3]);
    assert(result == 0);
    result = cmp([1, 3, 2], [1, 2, 3]);
    assert(result > 0);
    result = cmp([1, 2, 3], [1L, 2, 3, 4]);
    assert(result < 0);
    result = cmp([1L, 2, 3], [1, 2]);
    assert(result > 0);
}

/// Example predicate that compares individual elements in reverse lexical order
pure @safe unittest
{
    int result;

    result = cmp!"a > b"("abc", "abc");
    assert(result == 0);
    result = cmp!"a > b"("", "");
    assert(result == 0);
    result = cmp!"a > b"("abc", "abcd");
    assert(result < 0);
    result = cmp!"a > b"("abcd", "abc");
    assert(result > 0);
    result = cmp!"a > b"("abc"d, "abd");
    assert(result > 0);
    result = cmp!"a > b"("bbc", "abc"w);
    assert(result < 0);
    result = cmp!"a > b"("aaa", "aaaa"d);
    assert(result < 0);
    result = cmp!"a > b"("aaaa", "aaa"d);
    assert(result > 0);
    result = cmp!"a > b"("aaa", "aaa"d);
    assert(result == 0);
    result = cmp("aaa"d, "aaa"d);
    assert(result == 0);
    result = cmp!"a > b"(cast(int[])[], cast(int[])[]);
    assert(result == 0);
    result = cmp!"a > b"([1, 2, 3], [1, 2, 3]);
    assert(result == 0);
    result = cmp!"a > b"([1, 3, 2], [1, 2, 3]);
    assert(result < 0);
    result = cmp!"a > b"([1, 2, 3], [1L, 2, 3, 4]);
    assert(result < 0);
    result = cmp!"a > b"([1L, 2, 3], [1, 2]);
    assert(result > 0);
}

// cmp for string with custom predicate fails if distinct chars can compare equal
// https://issues.dlang.org/show_bug.cgi?id=18286
@nogc nothrow pure @safe unittest
{
    static bool ltCi(dchar a, dchar b)// less than, case insensitive
    {
        import std.ascii : toUpper;
        return toUpper(a) < toUpper(b);
    }
    static assert(cmp!ltCi("apple2", "APPLE1") > 0);
    static assert(cmp!ltCi("apple1", "APPLE2") < 0);
    static assert(cmp!ltCi("apple", "APPLE1") < 0);
    static assert(cmp!ltCi("APPLE", "apple1") < 0);
    static assert(cmp!ltCi("apple", "APPLE") == 0);
}

// for non-string ranges check that opCmp is evaluated only once per pair.
// https://issues.dlang.org/show_bug.cgi?id=18280
@nogc nothrow @safe unittest
{
    static int ctr = 0;
    struct S
    {
        int opCmp(ref const S rhs) const
        {
            ++ctr;
            return 0;
        }
        bool opEquals(T)(T o) const { return false; }
        size_t toHash() const { return 0; }
    }
    immutable S[4] a;
    immutable S[4] b;
    immutable result = cmp(a[], b[]);
    assert(result == 0, "neither should compare greater than the other!");
    assert(ctr == a.length, "opCmp should be called exactly once per pair of items!");
}

nothrow pure @safe @nogc unittest
{
    import std.array : staticArray;
    // Test cmp when opCmp returns float.
    struct F
    {
        float value;
        float opCmp(const ref F rhs) const
        {
            return value - rhs.value;
        }
        bool opEquals(T)(T o) const { return false; }
        size_t toHash() const { return 0; }
    }
    auto result = cmp([F(1), F(2), F(3)].staticArray[], [F(1), F(2), F(3)].staticArray[]);
    assert(result == 0);
    assert(is(typeof(result) == float));
    result = cmp([F(1), F(3), F(2)].staticArray[], [F(1), F(2), F(3)].staticArray[]);
    assert(result > 0);
    result = cmp([F(1), F(2), F(3)].staticArray[], [F(1), F(2), F(3), F(4)].staticArray[]);
    assert(result < 0);
    result = cmp([F(1), F(2), F(3)].staticArray[], [F(1), F(2)].staticArray[]);
    assert(result > 0);
}

nothrow pure @safe unittest
{
    // Parallelism (was broken by inferred return type "immutable int")
    import std.parallelism : task;
    auto t = task!cmp("foo", "bar");
}

// equal
/**
Compares two or more ranges for equality, as defined by predicate `pred`
(which is `==` by default).
*/
template equal(alias pred = "a == b")
{
    /++
    Compares two or more ranges for equality. The ranges may have
    different element types, as long as all are comparable by means of
    the `pred`.
    Performs $(BIGOH min(rs[0].length, rs[1].length, ...)) evaluations of `pred`. However, if
    `equal` is invoked with the default predicate, the implementation may take the liberty
    to use faster implementations that have the theoretical worst-case
    $(BIGOH max(rs[0].length, rs[1].length, ...)).

    At least one of the ranges must be finite. If one range involved is infinite, the result is
    (statically known to be) `false`.

    If the ranges have different kinds of UTF code unit (`char`, `wchar`, or
    `dchar`), then they are compared using UTF decoding to avoid
    accidentally integer-promoting units.

    Params:
        rs = The ranges to be compared.

    Returns:
        `true` if and only if all ranges compare _equal element
        for element, according to binary predicate `pred`.
    +/
    bool equal(Ranges...)(Ranges rs)
    if (rs.length > 1
        && allSatisfy!(isInputRange, Ranges)
        && !allSatisfy!(isInfinite, Ranges)
        && is(typeof(binaryFun!pred(rs[0].front, rs[1].front)))
        && (rs.length == 2 || is(typeof(equal!pred(rs[1 .. $])) == bool))
        )
    {
        alias ElementEncodingTypes = staticMap!(ElementEncodingType, Ranges);
        enum differentSize(T) = T.sizeof != ElementEncodingTypes[0].sizeof;
        enum useCodePoint = allSatisfy!(isSomeChar, ElementEncodingTypes) &&
            anySatisfy!(differentSize, ElementEncodingTypes);
        enum bool comparableWithEq(alias r) = is(typeof(rs[0] == r));

        static if (anySatisfy!(isInfinite, Ranges))
        {
            return false;
        }
        else static if (useCodePoint)
        {
            import std.utf : byDchar;
            static bool allByDchar(size_t done, Ranges...)(auto ref Ranges rs)
            {
                static if (done == rs.length)
                    return equalLoop(rs);
                else
                    return allByDchar!(done + 1)(rs[0 .. done], rs[done].byDchar, rs[done + 1 .. $]);
            }
            return allByDchar!0(rs);
        }
        else static if (is(typeof(pred) == string) && pred == "a == b" &&
                allSatisfy!(isArray, Ranges) && allSatisfy!(comparableWithEq, rs))
        {
            static foreach (r; rs[1 .. $])
                if (rs[0] != r)
                    return false;
            return true;
        }
        // if one of the arguments is a string and the other isn't, then auto-decoding
        // can be avoided if they have the same ElementEncodingType
        // TODO: generalize this
        else static if (rs.length == 2 && is(typeof(pred) == string) && pred == "a == b" &&
                isAutodecodableString!(Ranges[0]) != isAutodecodableString!(Ranges[1]) &&
                is(immutable ElementEncodingType!(Ranges[0]) == immutable ElementEncodingType!(Ranges[1])))
        {
            import std.utf : byCodeUnit;
            static if (isAutodecodableString!(Ranges[0]))
                return equal(rs[0].byCodeUnit, rs[1]);
            else
                return equal(rs[1].byCodeUnit, rs[0]);
        }
        else
        {
            static foreach (i, R; Ranges)
            {
                static if (hasLength!R)
                {
                    static if (!is(typeof(firstLength)))
                    {
                        // Found the first range that has length
                        auto firstLength = rs[i].length;
                    }
                    else
                    {
                        // Compare the length of the current range against the first with length
                        if (firstLength != rs[i].length)
                            return false;
                    }
                }
            }
            return equalLoop(rs);
        }
    }

    private bool equalLoop(Rs...)(ref Rs rs)
    {
        for (; !rs[0].empty; rs[0].popFront)
            static foreach (r; rs[1 .. $])
                if (r.empty || !binaryFun!pred(rs[0].front, r.front))
                    return false;
                else
                    r.popFront;
        static foreach (r; rs[1 .. $])
            if (!r.empty)
                return false;
        return true;
    }
}

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

    int[4] a = [ 1, 2, 4, 3 ];
    assert(!equal(a[], a[1..$]));
    assert(equal(a[], a[]));
    assert(equal!((a, b) => a == b)(a[], a[]));

    // different types
    double[4] b = [ 1.0, 2, 4, 3];
    assert(!equal(a[], b[1..$]));
    assert(equal(a[], b[]));

    // predicated: ensure that two vectors are approximately equal
    double[4] c = [ 1.0000000005, 2, 4, 3];
    assert(equal!isClose(b[], c[]));
}

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

    auto s1 = "abc", s2 = "abc"w;
    assert(equal(s1, s2, s2));
    assert(equal(s1, s2, s2, s1));
    assert(!equal(s1, s2, s2[1 .. $]));

    int[4] a = [ 1, 2, 4, 3 ];
    assert(!equal(a[], a[1..$], a[]));
    assert(equal(a[], a[], a[]));
    assert(equal!((a, b) => a == b)(a[], a[], a[]));

    // different types
    double[4] b = [ 1.0, 2, 4, 3];
    assert(!equal(a[], b[1..$], b[]));
    assert(equal(a[], b[], a[], b[]));

    // predicated: ensure that two vectors are approximately equal
    double[4] c = [ 1.0000000005, 2, 4, 3];
    assert(equal!isClose(b[], c[], b[]));
}

/++
Tip: `equal` can itself be used as a predicate to other functions.
This can be very useful when the element type of a range is itself a
range. In particular, `equal` can be its own predicate, allowing
range of range (of range...) comparisons.
 +/
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : iota, chunks;
    assert(equal!(equal!equal)(
        [[[0, 1], [2, 3]], [[4, 5], [6, 7]]],
        iota(0, 8).chunks(2).chunks(2)
    ));
}

@safe unittest
{
    import std.algorithm.iteration : map;
    import std.internal.test.dummyrange : ReferenceForwardRange,
        ReferenceInputRange, ReferenceInfiniteForwardRange;
    import std.math.operations : isClose;

    // various strings
    assert(equal("æøå", "æøå")); //UTF8 vs UTF8
    assert(!equal("???", "æøå")); //UTF8 vs UTF8
    assert(equal("æøå"w, "æøå"d)); //UTF16 vs UTF32
    assert(!equal("???"w, "æøå"d));//UTF16 vs UTF32
    assert(equal("æøå"d, "æøå"d)); //UTF32 vs UTF32
    assert(!equal("???"d, "æøå"d));//UTF32 vs UTF32
    assert(!equal("hello", "world"));

    // same strings, but "explicit non default" comparison (to test the non optimized array comparison)
    assert( equal!("a == b")("æøå", "æøå")); //UTF8 vs UTF8
    assert(!equal!("a == b")("???", "æøå")); //UTF8 vs UTF8
    assert( equal!("a == b")("æøå"w, "æøå"d)); //UTF16 vs UTF32
    assert(!equal!("a == b")("???"w, "æøå"d));//UTF16 vs UTF32
    assert( equal!("a == b")("æøå"d, "æøå"d)); //UTF32 vs UTF32
    assert(!equal!("a == b")("???"d, "æøå"d));//UTF32 vs UTF32
    assert(!equal!("a == b")("hello", "world"));

    //Array of string
    assert(equal(["hello", "world"], ["hello", "world"]));
    assert(!equal(["hello", "world"], ["hello"]));
    assert(!equal(["hello", "world"], ["hello", "Bob!"]));

    //Should not compile, because "string == dstring" is illegal
    static assert(!is(typeof(equal(["hello", "world"], ["hello"d, "world"d]))));
    //However, arrays of non-matching string can be compared using equal!equal. Neat-o!
    equal!equal(["hello", "world"], ["hello"d, "world"d]);

    //Tests, with more fancy map ranges
    int[] a = [ 1, 2, 4, 3 ];
    assert(equal([2, 4, 8, 6], map!"a*2"(a)));
    double[] b = [ 1.0, 2, 4, 3];
    double[] c = [ 1.0000000005, 2, 4, 3];
    assert(equal!isClose(map!"a*2"(b), map!"a*2"(c)));
    assert(!equal([2, 4, 1, 3], map!"a*2"(a)));
    assert(!equal([2, 4, 1], map!"a*2"(a)));
    assert(!equal!isClose(map!"a*3"(b), map!"a*2"(c)));

    //Tests with some fancy reference ranges.
    ReferenceInputRange!int cir = new ReferenceInputRange!int([1, 2, 4, 3]);
    ReferenceForwardRange!int cfr = new ReferenceForwardRange!int([1, 2, 4, 3]);
    assert(equal(cir, a));
    cir = new ReferenceInputRange!int([1, 2, 4, 3]);
    assert(equal(cir, cfr.save));
    assert(equal(cfr.save, cfr.save));
    cir = new ReferenceInputRange!int([1, 2, 8, 1]);
    assert(!equal(cir, cfr));

    //Test with an infinite range
    auto ifr = new ReferenceInfiniteForwardRange!int;
    assert(!equal(a, ifr));
    assert(!equal(ifr, a));
    //Test InputRange without length
    assert(!equal(ifr, cir));
    assert(!equal(cir, ifr));
}

@safe @nogc pure unittest
{
    import std.utf : byChar, byDchar, byWchar;

    assert(equal("æøå".byChar, "æøå"));
    assert(equal("æøå".byChar, "æøå"w));
    assert(equal("æøå".byChar, "æøå"d));
    assert(equal("æøå", "æøå".byChar));
    assert(equal("æøå"w, "æøå".byChar));
    assert(equal("æøå"d, "æøå".byChar));

    assert(equal("æøå".byWchar, "æøå"));
    assert(equal("æøå".byWchar, "æøå"w));
    assert(equal("æøå".byWchar, "æøå"d));
    assert(equal("æøå", "æøå".byWchar));
    assert(equal("æøå"w, "æøå".byWchar));
    assert(equal("æøå"d, "æøå".byWchar));

    assert(equal("æøå".byDchar, "æøå"));
    assert(equal("æøå".byDchar, "æøå"w));
    assert(equal("æøå".byDchar, "æøå"d));
    assert(equal("æøå", "æøå".byDchar));
    assert(equal("æøå"w, "æøå".byDchar));
    assert(equal("æøå"d, "æøå".byDchar));
}

@safe @nogc pure unittest
{
    struct R(bool _empty) {
        enum empty = _empty;
        @property char front(){assert(0);}
        void popFront(){assert(0);}
    }
    alias I = R!false;
    static assert(!__traits(compiles, I().equal(I())));
    // strings have fixed length so don't need to compare elements
    assert(!I().equal("foo"));
    assert(!"bar".equal(I()));

    alias E = R!true;
    assert(E().equal(E()));
    assert(E().equal(""));
    assert("".equal(E()));
    assert(!E().equal("foo"));
    assert(!"bar".equal(E()));
}

// levenshteinDistance
/**
Encodes $(HTTP realityinteractive.com/rgrzywinski/archives/000249.html,
edit operations) necessary to transform one sequence into
another. Given sequences `s` (source) and `t` (target), a
sequence of `EditOp` encodes the steps that need to be taken to
convert `s` into `t`. For example, if `s = "cat"` and $(D
"cars"), the minimal sequence that transforms `s` into `t` is:
skip two characters, replace 't' with 'r', and insert an 's'. Working
with edit operations is useful in applications such as spell-checkers
(to find the closest word to a given misspelled word), approximate
searches, diff-style programs that compute the difference between
files, efficient encoding of patches, DNA sequence analysis, and
plagiarism detection.
*/

enum EditOp : char
{
    /** Current items are equal; no editing is necessary. */
    none = 'n',
    /** Substitute current item in target with current item in source. */
    substitute = 's',
    /** Insert current item from the source into the target. */
    insert = 'i',
    /** Remove current item from the target. */
    remove = 'r'
}

///
@safe unittest
{
    with(EditOp)
    {
        assert(levenshteinDistanceAndPath("foo", "foobar")[1] == [none, none, none, insert, insert, insert]);
        assert(levenshteinDistanceAndPath("banana", "fazan")[1] == [substitute, none, substitute, none, none, remove]);
    }
}

private struct Levenshtein(Range, alias equals, CostType = size_t)
{
    EditOp[] path()
    {
        import std.algorithm.mutation : reverse;

        EditOp[] result;
        size_t i = rows - 1, j = cols - 1;
        // restore the path
        while (i || j)
        {
            auto cIns = j == 0 ? CostType.max : matrix(i,j - 1);
            auto cDel = i == 0 ? CostType.max : matrix(i - 1,j);
            auto cSub = i == 0 || j == 0
                ? CostType.max
                : matrix(i - 1,j - 1);
            switch (min_index(cSub, cIns, cDel))
            {
            case 0:
                result ~= matrix(i - 1,j - 1) == matrix(i,j)
                    ? EditOp.none
                    : EditOp.substitute;
                --i;
                --j;
                break;
            case 1:
                result ~= EditOp.insert;
                --j;
                break;
            default:
                result ~= EditOp.remove;
                --i;
                break;
            }
        }
        reverse(result);
        return result;
    }

    ~this() {
        FreeMatrix();
    }

private:
    CostType _deletionIncrement = 1,
        _insertionIncrement = 1,
        _substitutionIncrement = 1;
    CostType[] _matrix;
    size_t rows, cols;

    // Treat _matrix as a rectangular array
    ref CostType matrix(size_t row, size_t col) { return _matrix[row * cols + col]; }

    void AllocMatrix(size_t r, size_t c) @trusted {
        import core.checkedint : mulu;
        bool overflow;
        const rc = mulu(r, c, overflow);
        assert(!overflow, "Overflow during multiplication to determine number "
                ~ " of matrix elements");
        rows = r;
        cols = c;
        if (_matrix.length < rc)
        {
            import core.exception : onOutOfMemoryError;
            import core.stdc.stdlib : realloc;
            const nbytes = mulu(rc, _matrix[0].sizeof, overflow);
            assert(!overflow, "Overflow during multiplication to determine "
                ~ " number of bytes of matrix");
            auto m = cast(CostType *) realloc(_matrix.ptr, nbytes);
            if (!m)
                onOutOfMemoryError();
            _matrix = m[0 .. r * c];
            InitMatrix();
        }
    }

    void FreeMatrix() @trusted {
        import core.stdc.stdlib : free;

        free(_matrix.ptr);
        _matrix = null;
    }

    void InitMatrix() {
        foreach (r; 0 .. rows)
            matrix(r,0) = r * _deletionIncrement;
        foreach (c; 0 .. cols)
            matrix(0,c) = c * _insertionIncrement;
    }

    static uint min_index(CostType i0, CostType i1, CostType i2)
    {
        if (i0 <= i1)
        {
            return i0 <= i2 ? 0 : 2;
        }
        else
        {
            return i1 <= i2 ? 1 : 2;
        }
    }

    CostType distanceWithPath(Range s, Range t)
    {
        auto slen = walkLength(s.save), tlen = walkLength(t.save);
        AllocMatrix(slen + 1, tlen + 1);
        foreach (i; 1 .. rows)
        {
            auto sfront = s.front;
            auto tt = t.save;
            foreach (j; 1 .. cols)
            {
                auto cSub = matrix(i - 1,j - 1)
                    + (equals(sfront, tt.front) ? 0 : _substitutionIncrement);
                tt.popFront();
                auto cIns = matrix(i,j - 1) + _insertionIncrement;
                auto cDel = matrix(i - 1,j) + _deletionIncrement;
                switch (min_index(cSub, cIns, cDel))
                {
                case 0:
                    matrix(i,j) = cSub;
                    break;
                case 1:
                    matrix(i,j) = cIns;
                    break;
                default:
                    matrix(i,j) = cDel;
                    break;
                }
            }
            s.popFront();
        }
        return matrix(slen,tlen);
    }

    CostType distanceLowMem(Range s, Range t, CostType slen, CostType tlen)
    {
        CostType lastdiag, olddiag;
        AllocMatrix(slen + 1, 1);
        foreach (y; 1 .. slen + 1)
        {
            _matrix[y] = y;
        }
        foreach (x; 1 .. tlen + 1)
        {
            auto tfront = t.front;
            auto ss = s.save;
            _matrix[0] = x;
            lastdiag = x - 1;
            foreach (y; 1 .. rows)
            {
                olddiag = _matrix[y];
                auto cSub = lastdiag + (equals(ss.front, tfront) ? 0 : _substitutionIncrement);
                ss.popFront();
                auto cIns = _matrix[y - 1] + _insertionIncrement;
                auto cDel = _matrix[y] + _deletionIncrement;
                switch (min_index(cSub, cIns, cDel))
                {
                case 0:
                    _matrix[y] = cSub;
                    break;
                case 1:
                    _matrix[y] = cIns;
                    break;
                default:
                    _matrix[y] = cDel;
                    break;
                }
                lastdiag = olddiag;
            }
            t.popFront();
        }
        return _matrix[slen];
    }
}

/**
Returns the $(HTTP wikipedia.org/wiki/Levenshtein_distance, Levenshtein
distance) between `s` and `t`. The Levenshtein distance computes
the minimal amount of edit operations necessary to transform `s`
into `t`.  Performs $(BIGOH s.length * t.length) evaluations of $(D
equals) and occupies $(BIGOH min(s.length, t.length)) storage.

Params:
    equals = The binary predicate to compare the elements of the two ranges.
    s = The original range.
    t = The transformation target

Returns:
    The minimal number of edits to transform s into t.

Does not allocate GC memory.
*/
size_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)
    (Range1 s, Range2 t)
if (isForwardRange!(Range1) && isForwardRange!(Range2))
{
    alias eq = binaryFun!(equals);

    for (;;)
    {
        if (s.empty) return t.walkLength;
        if (t.empty) return s.walkLength;
        if (eq(s.front, t.front))
        {
            s.popFront();
            t.popFront();
            continue;
        }
        static if (isBidirectionalRange!(Range1) && isBidirectionalRange!(Range2))
        {
            if (eq(s.back, t.back))
            {
                s.popBack();
                t.popBack();
                continue;
            }
        }
        break;
    }

    auto slen = walkLength(s.save);
    auto tlen = walkLength(t.save);

    if (slen == 1 && tlen == 1)
    {
        return eq(s.front, t.front) ? 0 : 1;
    }

    if (slen < tlen)
    {
        Levenshtein!(Range1, eq, size_t) lev;
        return lev.distanceLowMem(s, t, slen, tlen);
    }
    else
    {
        Levenshtein!(Range2, eq, size_t) lev;
        return lev.distanceLowMem(t, s, tlen, slen);
    }
}

///
@safe unittest
{
    import std.algorithm.iteration : filter;
    import std.uni : toUpper;

    assert(levenshteinDistance("cat", "rat") == 1);
    assert(levenshteinDistance("parks", "spark") == 2);
    assert(levenshteinDistance("abcde", "abcde") == 0);
    assert(levenshteinDistance("abcde", "abCde") == 1);
    assert(levenshteinDistance("kitten", "sitting") == 3);
    assert(levenshteinDistance!((a, b) => toUpper(a) == toUpper(b))
        ("parks", "SPARK") == 2);
    assert(levenshteinDistance("parks".filter!"true", "spark".filter!"true") == 2);
    assert(levenshteinDistance("ID", "I♥D") == 1);
}

@safe @nogc nothrow unittest
{
    assert(levenshteinDistance("cat"d, "rat"d) == 1);
}

/// ditto
size_t levenshteinDistance(alias equals = (a,b) => a == b, Range1, Range2)
    (auto ref Range1 s, auto ref Range2 t)
if (isConvertibleToString!Range1 || isConvertibleToString!Range2)
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, Range1, Range2);
    return levenshteinDistance!(equals, Types)(s, t);
}

@safe unittest
{
    static struct S { string s; alias s this; }
    assert(levenshteinDistance(S("cat"), S("rat")) == 1);
    assert(levenshteinDistance("cat", S("rat")) == 1);
    assert(levenshteinDistance(S("cat"), "rat") == 1);
}

@safe @nogc nothrow unittest
{
    static struct S { dstring s; alias s this; }
    assert(levenshteinDistance(S("cat"d), S("rat"d)) == 1);
    assert(levenshteinDistance("cat"d, S("rat"d)) == 1);
    assert(levenshteinDistance(S("cat"d), "rat"d) == 1);
}

/**
Returns the Levenshtein distance and the edit path between `s` and
`t`.

Params:
    equals = The binary predicate to compare the elements of the two ranges.
    s = The original range.
    t = The transformation target

Returns:
    Tuple with the first element being the minimal amount of edits to transform s into t and
    the second element being the sequence of edits to effect this transformation.

Allocates GC memory for the returned EditOp[] array.
*/
Tuple!(size_t, EditOp[])
levenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)
    (Range1 s, Range2 t)
if (isForwardRange!(Range1) && isForwardRange!(Range2))
{
    Levenshtein!(Range1, binaryFun!(equals)) lev;
    auto d = lev.distanceWithPath(s, t);
    return tuple(d, lev.path());
}

///
@safe unittest
{
    string a = "Saturday", b = "Sundays";
    auto p = levenshteinDistanceAndPath(a, b);
    assert(p[0] == 4);
    assert(equal(p[1], "nrrnsnnni"));
}

@safe unittest
{
    assert(levenshteinDistance("a", "a") == 0);
    assert(levenshteinDistance("a", "b") == 1);
    assert(levenshteinDistance("aa", "ab") == 1);
    assert(levenshteinDistance("aa", "abc") == 2);
    assert(levenshteinDistance("Saturday", "Sunday") == 3);
    assert(levenshteinDistance("kitten", "sitting") == 3);
}

/// ditto
Tuple!(size_t, EditOp[])
levenshteinDistanceAndPath(alias equals = (a,b) => a == b, Range1, Range2)
    (auto ref Range1 s, auto ref Range2 t)
if (isConvertibleToString!Range1 || isConvertibleToString!Range2)
{
    import std.meta : staticMap;
    alias Types = staticMap!(convertToString, Range1, Range2);
    return levenshteinDistanceAndPath!(equals, Types)(s, t);
}

@safe unittest
{
    static struct S { string s; alias s this; }
    assert(levenshteinDistanceAndPath(S("cat"), S("rat"))[0] == 1);
    assert(levenshteinDistanceAndPath("cat", S("rat"))[0] == 1);
    assert(levenshteinDistanceAndPath(S("cat"), "rat")[0] == 1);
}


// max
/**
Iterates the passed arguments and returns the maximum value.

Params:
    args = The values to select the maximum from. At least two arguments must
    be passed, and they must be comparable with `<`.

Returns:
    The maximum of the passed-in values. The type of the returned value is
    the type among the passed arguments that is able to store the largest value.
    If at least one of the arguments is NaN, the result is an unspecified value.
    See $(REF maxElement, std,algorithm,searching) for examples on how to cope
    with NaNs.

See_Also:
    $(REF maxElement, std,algorithm,searching)
*/
auto max(T...)(T args)
if (T.length >= 2 && !is(CommonType!T == void))
{
    // Get left-hand side of the comparison.
    static if (T.length == 2)
        alias a = args[0];
    else
        auto a = max(args[0 .. ($ + 1) / 2]);
    alias T0 = typeof(a);

    // Get right-hand side.
    static if (T.length <= 3)
        alias b = args[$ - 1];
    else
        auto b = max(args[($ + 1) / 2 .. $]);
    alias T1 = typeof(b);

    static assert(is(typeof(a < b)),
        "Invalid arguments: Cannot compare types " ~ T0.stringof ~
        " and " ~ T1.stringof ~ " for ordering.");

    // Compute the returned type.
    static if (is(typeof(mostNegative!T0 < mostNegative!T1)))
        // Both are numeric (or character or Boolean), so we choose the one with the highest maximum.
        // (We use mostNegative for num/bool/char testing purposes even if it's not used otherwise.)
        alias Result = Select!(T1.max > T0.max, T1, T0);
    else
        // At least one is non-numeric, so just go with the common type.
        alias Result = CommonType!(T0, T1);

    // Perform the computation.
    import std.functional : lessThan;
    immutable chooseB = lessThan!(T0, T1)(a, b);
    return cast(Result) (chooseB ? b : a);
}

/// ditto
T max(T, U)(T a, U b)
if (is(T == U) && is(typeof(a < b)))
{
   /* Handle the common case without all the template expansions
    * of the general case
    */
    return a < b ? b : a;
}

///
@safe @betterC @nogc unittest
{
    int a = 5;
    short b = 6;
    double c = 2;
    auto d = max(a, b);
    assert(is(typeof(d) == int));
    assert(d == 6);
    auto e = min(a, b, c);
    assert(is(typeof(e) == double));
    assert(e == 2);
}

@safe unittest  // not @nogc due to `Date`
{
    int a = 5;
    short b = 6;
    double c = 2;
    auto d = max(a, b);
    static assert(is(typeof(d) == int));
    assert(d == 6);
    auto e = max(a, b, c);
    static assert(is(typeof(e) == double));
    assert(e == 6);
    // mixed sign
    a = -5;
    uint f = 5;
    static assert(is(typeof(max(a, f)) == uint));
    assert(max(a, f) == 5);

    //Test user-defined types
    import std.datetime : Date;
    assert(max(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(2012, 12, 21));
    assert(max(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(2012, 12, 21));
    assert(max(Date(1982, 1, 4), Date.min) == Date(1982, 1, 4));
    assert(max(Date.min, Date(1982, 1, 4)) == Date(1982, 1, 4));
    assert(max(Date(1982, 1, 4), Date.max) == Date.max);
    assert(max(Date.max, Date(1982, 1, 4)) == Date.max);
    assert(max(Date.min, Date.max) == Date.max);
    assert(max(Date.max, Date.min) == Date.max);
}

// min
/**
Iterates the passed arguments and returns the minimum value.

Params:
    args = The values to select the minimum from. At least two arguments must
    be passed, and they must be comparable with `<`.

Returns:
    The minimum of the passed-in values. The type of the returned value is
    the type among the passed arguments that is able to store the smallest value.
    If at least one of the arguments is NaN, the result is an unspecified value.
    See $(REF minElement, std,algorithm,searching) for examples on how to cope
    with NaNs.

See_Also:
    $(REF minElement, std,algorithm,searching)
*/
auto min(T...)(T args)
if (T.length >= 2 && !is(CommonType!T == void))
{
    // Get the left-hand side of the comparison.
    static if (T.length <= 2)
        alias a = args[0];
    else
        auto a = min(args[0 .. ($ + 1) / 2]);
    alias T0 = typeof(a);

    // Get the right-hand side.
    static if (T.length <= 3)
        alias b = args[$ - 1];
    else
        auto b = min(args[($ + 1) / 2 .. $]);
    alias T1 = typeof(b);

    static assert(is(typeof(a < b)),
        "Invalid arguments: Cannot compare types " ~ T0.stringof ~
        " and " ~ T1.stringof ~ " for ordering.");

    // Compute the returned type.
    static if (is(typeof(mostNegative!T0 < mostNegative!T1)))
        // Both are numeric (or character or Boolean), so we choose the one with the lowest minimum.
        // If they have the same minimum, choose the one with the smallest size.
        // If both mostNegative and sizeof are equal, go for stability: pick the type of the first one.
        alias Result = Select!(mostNegative!T1 < mostNegative!T0 ||
                mostNegative!T1 == mostNegative!T0 && T1.sizeof < T0.sizeof,
            T1, T0);
    else
        // At least one is non-numeric, so just go with the common type.
        alias Result = CommonType!(T0, T1);

    // Engage!
    import std.functional : lessThan;
    immutable chooseB = lessThan!(T1, T0)(b, a);
    return cast(Result) (chooseB ? b : a);
}

/// ditto
T min(T, U)(T a, U b)
if (is(T == U) && is(typeof(a < b)))
{
   /* Handle the common case without all the template expansions
    * of the general case
    */
    return b < a ? b : a;
}


///
@safe @nogc @betterC unittest
{
    int a = 5;
    short b = 6;
    double c = 2;
    auto d = min(a, b);
    static assert(is(typeof(d) == int));
    assert(d == 5);
    auto e = min(a, b, c);
    static assert(is(typeof(e) == double));
    assert(e == 2);
    ulong f = 0xffff_ffff_ffff;
    const uint g = min(f, 0xffff_0000);
    assert(g == 0xffff_0000);
    dchar h = 100;
    uint i = 101;
    static assert(is(typeof(min(h, i)) == dchar));
    static assert(is(typeof(min(i, h)) == uint));
    assert(min(h, i) == 100);
}

/**
With arguments of mixed signedness, the return type is the one that can
store the lowest values.
*/
@safe @nogc @betterC unittest
{
    int a = -10;
    uint f = 10;
    static assert(is(typeof(min(a, f)) == int));
    assert(min(a, f) == -10);
}

/// User-defined types that support comparison with < are supported.
@safe unittest  // not @nogc due to `Date`
{
    import std.datetime;
    assert(min(Date(2012, 12, 21), Date(1982, 1, 4)) == Date(1982, 1, 4));
    assert(min(Date(1982, 1, 4), Date(2012, 12, 21)) == Date(1982, 1, 4));
    assert(min(Date(1982, 1, 4), Date.min) == Date.min);
    assert(min(Date.min, Date(1982, 1, 4)) == Date.min);
    assert(min(Date(1982, 1, 4), Date.max) == Date(1982, 1, 4));
    assert(min(Date.max, Date(1982, 1, 4)) == Date(1982, 1, 4));
    assert(min(Date.min, Date.max) == Date.min);
    assert(min(Date.max, Date.min) == Date.min);
}

// min must be stable: when in doubt, return the first argument.
@safe unittest
{
    assert(min(1.0, double.nan) == 1.0);
    assert(min(double.nan, 1.0) is double.nan);
    static struct A {
        int x;
        string y;
        int opCmp(const A a) const { return int(x > a.x) - int(x < a.x); }
    }
    assert(min(A(1, "first"), A(1, "second")) == A(1, "first"));
}

// mismatch
/**
Sequentially compares elements in `rs` in lockstep, and
stops at the first mismatch (according to `pred`, by default
equality). Returns a tuple with the reduced ranges that start with the
two mismatched values. Performs $(BIGOH min(r[0].length, r[1].length, ...))
evaluations of `pred`.
*/
Tuple!(Ranges)
mismatch(alias pred = (a, b) => a == b, Ranges...)(Ranges rs)
if (rs.length >= 2 && allSatisfy!(isInputRange, Ranges))
{
    loop: for (; !rs[0].empty; rs[0].popFront)
    {
        static foreach (r; rs[1 .. $])
        {
            if (r.empty || !binaryFun!pred(rs[0].front, r.front))
                break loop;
            r.popFront;
        }
    }
    return tuple(rs);
}

///
@safe @nogc unittest
{
    int[6] x = [ 1,   5, 2, 7,   4, 3 ];
    double[6] y = [ 1.0, 5, 2, 7.3, 4, 8 ];
    auto m = mismatch(x[], y[]);
    assert(m[0] == x[3 .. $]);
    assert(m[1] == y[3 .. $]);

    auto m2 = mismatch(x[], y[], x[], y[]);
    assert(m2[0] == x[3 .. $]);
    assert(m2[1] == y[3 .. $]);
    assert(m2[2] == x[3 .. $]);
    assert(m2[3] == y[3 .. $]);
}

@safe @nogc unittest
{
    import std.range : only;

    int[3] a = [ 1, 2, 3 ];
    int[4] b = [ 1, 2, 4, 5 ];
    auto mm = mismatch(a[], b[]);
    assert(equal(mm[0], only(3)));
    assert(equal(mm[1], only(4, 5)));
}

/**
Returns one of a collection of expressions based on the value of the switch
expression.

`choices` needs to be composed of pairs of test expressions and return
expressions. Each test-expression is compared with `switchExpression` using
`pred`(`switchExpression` is the first argument) and if that yields true -
the return expression is returned.

Both the test and the return expressions are lazily evaluated.

Params:

switchExpression = The first argument for the predicate.

choices = Pairs of test expressions and return expressions. The test
expressions will be the second argument for the predicate, and the return
expression will be returned if the predicate yields true with $(D
switchExpression) and the test expression as arguments.  May also have a
default return expression, that needs to be the last expression without a test
expression before it. A return expression may be of void type only if it
always throws.

Returns: The return expression associated with the first test expression that
made the predicate yield true, or the default return expression if no test
expression matched.

Throws: If there is no default return expression and the predicate does not
yield true with any test expression - `SwitchError` is thrown. $(D
SwitchError) is also thrown if a void return expression was executed without
throwing anything.
*/
auto predSwitch(alias pred = "a == b", T, R ...)(T switchExpression, lazy R choices)
{
    import core.exception : SwitchError;
    alias predicate = binaryFun!(pred);

    foreach (index, ChoiceType; R)
    {
        //The even places in `choices` are for the predicate.
        static if (index % 2 == 1)
        {
            if (predicate(switchExpression, choices[index - 1]()))
            {
                static if (is(typeof(choices[index]()) == void))
                {
                    choices[index]();
                    throw new SwitchError("Choices that return void should throw");
                }
                else
                {
                    return choices[index]();
                }
            }
        }
    }

    //In case nothing matched:
    static if (R.length % 2 == 1) //If there is a default return expression:
    {
        static if (is(typeof(choices[$ - 1]()) == void))
        {
            choices[$ - 1]();
            throw new SwitchError("Choices that return void should throw");
        }
        else
        {
            return choices[$ - 1]();
        }
    }
    else //If there is no default return expression:
    {
        throw new SwitchError("Input not matched by any pattern");
    }
}

///
@safe unittest
{
    string res = 2.predSwitch!"a < b"(
        1, "less than 1",
        5, "less than 5",
        10, "less than 10",
        "greater or equal to 10");

    assert(res == "less than 5");

    //The arguments are lazy, which allows us to use predSwitch to create
    //recursive functions:
    int factorial(int n)
    {
        return n.predSwitch!"a <= b"(
            -1, {throw new Exception("Can not calculate n! for n < 0");}(),
            0, 1, // 0! = 1
            n * factorial(n - 1) // n! = n * (n - 1)! for n >= 0
            );
    }
    assert(factorial(3) == 6);

    //Void return expressions are allowed if they always throw:
    import std.exception : assertThrown;
    assertThrown!Exception(factorial(-9));
}

@system unittest
{
    import core.exception : SwitchError;
    import std.exception : assertThrown;

    //Nothing matches - with default return expression:
    assert(20.predSwitch!"a < b"(
        1, "less than 1",
        5, "less than 5",
        10, "less than 10",
        "greater or equal to 10") == "greater or equal to 10");

    //Nothing matches - without default return expression:
    assertThrown!SwitchError(20.predSwitch!"a < b"(
        1, "less than 1",
        5, "less than 5",
        10, "less than 10",
        ));

    //Using the default predicate:
    assert(2.predSwitch(
                1, "one",
                2, "two",
                3, "three",
                ) == "two");

    //Void return expressions must always throw:
    assertThrown!SwitchError(1.predSwitch(
                0, "zero",
                1, {}(), //A void return expression that doesn't throw
                2, "two",
                ));
}

/**
Checks if two or more ranges have the same number of elements. This function is
optimized to always take advantage of the `length` member of either range
if it exists.

If all ranges have a `length` member or at least one is infinite,
`_isSameLength`'s complexity is $(BIGOH 1). Otherwise, complexity is
$(BIGOH n), where `n` is the smallest of the lengths of ranges with unknown
length.

Infinite ranges are considered of the same length. An infinite range has never
the same length as a finite range.

Params:
    rs = two or more $(REF_ALTTEXT input ranges, isInputRange, std,range,primitives)

Returns:
    `true` if both ranges have the same length, `false` otherwise.
*/
bool isSameLength(Ranges...)(Ranges rs)
if (allSatisfy!(isInputRange, Ranges))
{
    static if (anySatisfy!(isInfinite, Ranges))
    {
        return allSatisfy!(isInfinite, Ranges);
    }
    else static if (anySatisfy!(hasLength, Ranges))
    {
        // Compute the O(1) length
        auto baselineLength = size_t.max;
        static foreach (i, R; Ranges)
        {
            static if (hasLength!R)
            {
                if (baselineLength == size_t.max)
                    baselineLength = rs[i].length;
                else if (rs[i].length != baselineLength)
                    return false;
            }
        }
        // Iterate all ranges without known length
        foreach (_; 0 .. baselineLength)
            static foreach (i, R; Ranges)
            {
                static if (!hasLength!R)
                {
                    // All must be non-empty
                    if (rs[i].empty)
                        return false;
                    rs[i].popFront;
                }
            }
        static foreach (i, R; Ranges)
        {
            static if (!hasLength!R)
            {
                // All must be now empty
                if (!rs[i].empty)
                    return false;
            }
        }
        return true;
    }
    else
    {
        // All have unknown length, iterate in lockstep
        for (;;)
            static foreach (i, r; rs)
            {
                if (r.empty)
                {
                    // One is empty, so all must be empty
                    static if (i != 0)
                    {
                        return false;
                    }
                    else
                    {
                        static foreach (j, r1; rs[1 .. $])
                            if (!r1.empty)
                                return false;
                        return true;
                    }
                }
                r.popFront;
            }
    }
}

///
@safe nothrow pure unittest
{
    assert(isSameLength([1, 2, 3], [4, 5, 6]));
    assert(isSameLength([1, 2, 3], [4, 5, 6], [7, 8, 9]));
    assert(isSameLength([0.3, 90.4, 23.7, 119.2], [42.6, 23.6, 95.5, 6.3]));
    assert(isSameLength("abc", "xyz"));
    assert(isSameLength("abc", "xyz", [1, 2, 3]));

    int[] a;
    int[] b;
    assert(isSameLength(a, b));
    assert(isSameLength(a, b, a, a, b, b, b));

    assert(!isSameLength([1, 2, 3], [4, 5]));
    assert(!isSameLength([1, 2, 3], [4, 5, 6], [7, 8]));
    assert(!isSameLength([0.3, 90.4, 23.7], [42.6, 23.6, 95.5, 6.3]));
    assert(!isSameLength("abcd", "xyz"));
    assert(!isSameLength("abcd", "xyz", "123"));
    assert(!isSameLength("abcd", "xyz", "1234"));
}

// Test CTFE
@safe @nogc pure @betterC unittest
{
    static assert(isSameLength([1, 2, 3], [4, 5, 6]));
    static assert(isSameLength([1, 2, 3], [4, 5, 6], [7, 8, 9]));
    static assert(!isSameLength([0.3, 90.4, 23.7], [42.6, 23.6, 95.5, 6.3]));
    static assert(!isSameLength([1], [0.3, 90.4], [42]));
}

@safe @nogc pure unittest
{
    import std.range : only;
    assert(isSameLength(only(1, 2, 3), only(4, 5, 6)));
    assert(isSameLength(only(1, 2, 3), only(4, 5, 6), only(7, 8, 9)));
    assert(isSameLength(only(0.3, 90.4, 23.7, 119.2), only(42.6, 23.6, 95.5, 6.3)));
    assert(!isSameLength(only(1, 3, 3), only(4, 5)));
    assert(!isSameLength(only(1, 3, 3), only(1, 3, 3), only(4, 5)));
    assert(!isSameLength(only(1, 3, 3), only(4, 5), only(1, 3, 3)));
}

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

    auto r1 = new ReferenceInputRange!int([1, 2, 3]);
    auto r2 = new ReferenceInputRange!int([4, 5, 6]);
    assert(isSameLength(r1, r2));

    auto r3 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r4;
    assert(isSameLength(r3, r4));

    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r5;
    auto r6 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    assert(isSameLength(r5, r6));

    auto r7 = new ReferenceInputRange!int([1, 2]);
    auto r8 = new ReferenceInputRange!int([4, 5, 6]);
    assert(!isSameLength(r7, r8));

    auto r9 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8]);
    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r10;
    assert(!isSameLength(r9, r10));

    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Input) r11;
    auto r12 = new ReferenceInputRange!int([1, 2, 3, 4, 5, 6, 7, 8]);
    assert(!isSameLength(r11, r12));

    import std.algorithm.iteration : filter;

    assert(isSameLength(filter!"a >= 1"([1, 2, 3]), [4, 5, 6]));
    assert(!isSameLength(filter!"a > 1"([1, 2, 3]), [4, 5, 6]));

    assert(isSameLength(filter!"a > 1"([1, 2, 3]), filter!"a > 4"([4, 5, 6])));
    assert(isSameLength(filter!"a > 1"([1, 2, 3]),
        filter!"a > 4"([4, 5, 6]), filter!"a >= 5"([4, 5, 6])));
}

// Still functional but not documented anymore.
alias AllocateGC = Flag!"allocateGC";

/**
Checks if both ranges are permutations of each other.

This function can allocate if the `Yes.allocateGC` flag is passed. This has
the benefit of have better complexity than the `Yes.allocateGC` option. However,
this option is only available for ranges whose equality can be determined via each
element's `toHash` method. If customized equality is needed, then the `pred`
template parameter can be passed, and the function will automatically switch to
the non-allocating algorithm. See $(REF binaryFun, std,functional) for more details on
how to define `pred`.

Non-allocating forward range option: $(BIGOH n^2)
Non-allocating forward range option with custom `pred`: $(BIGOH n^2)
Allocating forward range option: amortized $(BIGOH r1.length) + $(BIGOH r2.length)

Params:
    pred = an optional parameter to change how equality is defined
    allocateGC = `Yes.allocateGC`/`No.allocateGC`
    r1 = A finite $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)
    r2 = A finite $(REF_ALTTEXT forward range, isForwardRange, std,range,primitives)

Returns:
    `true` if all of the elements in `r1` appear the same number of times in `r2`.
    Otherwise, returns `false`.
*/

bool isPermutation(Flag!"allocateGC" allocateGC, Range1, Range2)
(Range1 r1, Range2 r2)
if (allocateGC == Yes.allocateGC &&
    isForwardRange!Range1 &&
    isForwardRange!Range2 &&
    !isInfinite!Range1 &&
    !isInfinite!Range2)
{
    alias E1 = Unqual!(ElementType!Range1);
    alias E2 = Unqual!(ElementType!Range2);

    if (!isSameLength(r1.save, r2.save))
    {
        return false;
    }

    // Skip the elements at the beginning where r1.front == r2.front,
    // they are in the same order and don't need to be counted.
    while (!r1.empty && !r2.empty && r1.front == r2.front)
    {
        r1.popFront();
        r2.popFront();
    }

    if (r1.empty && r2.empty)
    {
        return true;
    }

    int[CommonType!(E1, E2)] counts;

    foreach (item; r1)
    {
        ++counts[item];
    }

    foreach (item; r2)
    {
        if (--counts[item] < 0)
        {
            return false;
        }
    }

    return true;
}

/// ditto
bool isPermutation(alias pred = "a == b", Range1, Range2)
(Range1 r1, Range2 r2)
if (is(typeof(binaryFun!(pred))) &&
    isForwardRange!Range1 &&
    isForwardRange!Range2 &&
    !isInfinite!Range1 &&
    !isInfinite!Range2)
{
    import std.algorithm.searching : count;

    alias predEquals = binaryFun!(pred);
    alias E1 = Unqual!(ElementType!Range1);
    alias E2 = Unqual!(ElementType!Range2);

    if (!isSameLength(r1.save, r2.save))
    {
        return false;
    }

    // Skip the elements at the beginning where r1.front == r2.front,
    // they are in the same order and don't need to be counted.
    while (!r1.empty && !r2.empty && predEquals(r1.front, r2.front))
    {
        r1.popFront();
        r2.popFront();
    }

    if (r1.empty && r2.empty)
    {
        return true;
    }

    size_t r1_count;
    size_t r2_count;

    // At each element item, when computing the count of item, scan it while
    // also keeping track of the scanning index. If the first occurrence
    // of item in the scanning loop has an index smaller than the current index,
    // then you know that the element has been seen before
    size_t index;
    outloop: for (auto r1s1 = r1.save; !r1s1.empty; r1s1.popFront, index++)
    {
        auto item = r1s1.front;
        r1_count = 0;
        r2_count = 0;

        size_t i;
        for (auto r1s2 = r1.save; !r1s2.empty; r1s2.popFront, i++)
        {
            auto e = r1s2.front;
            if (predEquals(e, item) && i < index)
            {
                 continue outloop;
            }
            else if (predEquals(e, item))
            {
                ++r1_count;
            }
        }

        r2_count = r2.save.count!pred(item);

        if (r1_count != r2_count)
        {
            return false;
        }
    }

    return true;
}

///
@safe pure unittest
{
    import std.typecons : Yes;

    assert(isPermutation([1, 2, 3], [3, 2, 1]));
    assert(isPermutation([1.1, 2.3, 3.5], [2.3, 3.5, 1.1]));
    assert(isPermutation("abc", "bca"));

    assert(!isPermutation([1, 2], [3, 4]));
    assert(!isPermutation([1, 1, 2, 3], [1, 2, 2, 3]));
    assert(!isPermutation([1, 1], [1, 1, 1]));

    // Faster, but allocates GC handled memory
    assert(isPermutation!(Yes.allocateGC)([1.1, 2.3, 3.5], [2.3, 3.5, 1.1]));
    assert(!isPermutation!(Yes.allocateGC)([1, 2], [3, 4]));
}

// Test @nogc inference
@safe @nogc pure unittest
{
    static immutable arr1 = [1, 2, 3];
    static immutable arr2 = [3, 2, 1];
    assert(isPermutation(arr1, arr2));

    static immutable arr3 = [1, 1, 2, 3];
    static immutable arr4 = [1, 2, 2, 3];
    assert(!isPermutation(arr3, arr4));
}

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

    auto r1 = new ReferenceForwardRange!int([1, 2, 3, 4]);
    auto r2 = new ReferenceForwardRange!int([1, 2, 4, 3]);
    assert(isPermutation(r1, r2));

    auto r3 = new ReferenceForwardRange!int([1, 2, 3, 4]);
    auto r4 = new ReferenceForwardRange!int([4, 2, 1, 3]);
    assert(isPermutation!(Yes.allocateGC)(r3, r4));

    auto r5 = new ReferenceForwardRange!int([1, 2, 3]);
    auto r6 = new ReferenceForwardRange!int([4, 2, 1, 3]);
    assert(!isPermutation(r5, r6));

    auto r7 = new ReferenceForwardRange!int([4, 2, 1, 3]);
    auto r8 = new ReferenceForwardRange!int([1, 2, 3]);
    assert(!isPermutation!(Yes.allocateGC)(r7, r8));

    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r9;
    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r10;
    assert(isPermutation(r9, r10));

    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r11;
    DummyRange!(ReturnBy.Reference, Length.Yes, RangeType.Random) r12;
    assert(isPermutation!(Yes.allocateGC)(r11, r12));

    alias mytuple = Tuple!(int, int);

    assert(isPermutation!"a[0] == b[0]"(
        [mytuple(1, 4), mytuple(2, 5)],
        [mytuple(2, 3), mytuple(1, 2)]
    ));
}

/**
Get the _first argument `a` that passes an `if (unaryFun!pred(a))` test.  If
no argument passes the test, return the last argument.

Similar to behaviour of the `or` operator in dynamic languages such as Lisp's
`(or ...)` and Python's `a or b or ...` except that the last argument is
returned upon no match.

Simplifies logic, for instance, in parsing rules where a set of alternative
matchers are tried. The _first one that matches returns it match result,
typically as an abstract syntax tree (AST).

Bugs:
Lazy parameters are currently, too restrictively, inferred by DMD to
always throw even though they don't need to be. This makes it impossible to
currently mark `either` as `nothrow`. See issue at $(BUGZILLA 12647).

Returns:
    The _first argument that passes the test `pred`.
*/
CommonType!(T, Ts) either(alias pred = a => a, T, Ts...)(T first, lazy Ts alternatives)
if (alternatives.length >= 1 &&
    !is(CommonType!(T, Ts) == void) &&
    allSatisfy!(ifTestable, T, Ts))
{
    alias predFun = unaryFun!pred;

    if (predFun(first)) return first;

    foreach (e; alternatives[0 .. $ - 1])
        if (predFun(e)) return e;

    return alternatives[$ - 1];
}

///
@safe pure @betterC unittest
{
    const a = 1;
    const b = 2;
    auto ab = either(a, b);
    static assert(is(typeof(ab) == const(int)));
    assert(ab == a);

    auto c = 2;
    const d = 3;
    auto cd = either!(a => a == 3)(c, d); // use predicate
    static assert(is(typeof(cd) == int));
    assert(cd == d);

    auto e = 0;
    const f = 2;
    auto ef = either(e, f);
    static assert(is(typeof(ef) == int));
    assert(ef == f);
}

///
@safe pure unittest
{
    immutable p = 1;
    immutable q = 2;
    auto pq = either(p, q);
    static assert(is(typeof(pq) == immutable(int)));
    assert(pq == p);

    assert(either(3, 4) == 3);
    assert(either(0, 4) == 4);
    assert(either(0, 0) == 0);
    assert(either("", "a") == "");
}

///
@safe pure unittest
{
    string r = null;
    assert(either(r, "a") == "a");
    assert(either("a", "") == "a");

    immutable s = [1, 2];
    assert(either(s, s) == s);

    assert(either([0, 1], [1, 2]) == [0, 1]);
    assert(either([0, 1], [1]) == [0, 1]);
    assert(either("a", "b") == "a");

    static assert(!__traits(compiles, either(1, "a")));
    static assert(!__traits(compiles, either(1.0, "a")));
    static assert(!__traits(compiles, either('a', "a")));
}
