// Written in the D programming language.

/++
    This module defines functions related to exceptions and general error
    handling. It also defines functions intended to aid in unit testing.

$(SCRIPT inhibitQuickIndex = 1;)
$(DIVC quickindex,
$(BOOKTABLE,
$(TR $(TH Category) $(TH Functions))
$(TR $(TD Assumptions) $(TD
        $(LREF assertNotThrown)
        $(LREF assertThrown)
        $(LREF assumeUnique)
        $(LREF assumeWontThrow)
        $(LREF mayPointTo)
))
$(TR $(TD Enforce) $(TD
        $(LREF doesPointTo)
        $(LREF enforce)
        $(LREF errnoEnforce)
))
$(TR $(TD Handlers) $(TD
        $(LREF collectException)
        $(LREF collectExceptionMsg)
        $(LREF ifThrown)
        $(LREF handle)
))
$(TR $(TD Other) $(TD
        $(LREF basicExceptionCtors)
        $(LREF emptyExceptionMsg)
        $(LREF ErrnoException)
        $(LREF RangePrimitive)
))
))

    Copyright: Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-.
    License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
    Authors:   $(HTTP erdani.org, Andrei Alexandrescu) and
               $(HTTP jmdavisprog.com, Jonathan M Davis)
    Source:    $(PHOBOSSRC std/exception.d)

 +/
module std.exception;

/// Synopis
@system unittest
{
    import core.stdc.stdlib : malloc, free;
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map, splitter;
    import std.algorithm.searching : endsWith;
    import std.conv : ConvException, to;
    import std.range : front, retro;

    // use enforce like assert
    int a = 3;
    enforce(a > 2, "a needs to be higher than 2.");

    // enforce can throw a custom exception
    enforce!ConvException(a > 2, "a needs to be higher than 2.");

    // enforce will return it's input
    enum size = 42;
    auto memory = enforce(malloc(size), "malloc failed")[0 .. size];
    scope(exit) free(memory.ptr);

    // collectException can be used to test for exceptions
    Exception e = collectException("abc".to!int);
    assert(e.file.endsWith("conv.d"));

    // and just for the exception message
    string msg = collectExceptionMsg("abc".to!int);
    assert(msg == "Unexpected 'a' when converting from type string to type int");

    // assertThrown can be used to assert that an exception is thrown
    assertThrown!ConvException("abc".to!int);

    // ifThrown can be used to provide a default value if an exception is thrown
    assert("x".to!int().ifThrown(0) == 0);

    // handle is a more advanced version of ifThrown for ranges
    auto r = "12,1337z32,54".splitter(',').map!(a => to!int(a));
    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);
    assert(h.equal([12, 0, 54]));
    assertThrown!ConvException(h.retro.equal([54, 0, 12]));

    // basicExceptionCtors avoids the boilerplate when creating custom exceptions
    static class MeaCulpa : Exception
    {
        mixin basicExceptionCtors;
    }
    e = collectException((){throw new MeaCulpa("diagnostic message");}());
    assert(e.msg == "diagnostic message");
    assert(e.file == __FILE__);
    assert(e.line == __LINE__ - 3);

    // assumeWontThrow can be used to cast throwing code into `nothrow`
    void exceptionFreeCode() nothrow
    {
        // auto-decoding only throws if an invalid UTF char is given
        assumeWontThrow("abc".front);
    }

    // assumeUnique can be used to cast mutable instance to an `immutable` one
    // use with care
    char[] str = "  mutable".dup;
    str[0 .. 2] = "im";
    immutable res = assumeUnique(str);
    assert(res == "immutable");
}

import std.range.primitives;
import std.traits;

/++
    Asserts that the given expression does $(I not) throw the given type
    of `Throwable`. If a `Throwable` of the given type is thrown,
    it is caught and does not escape assertNotThrown. Rather, an
    `AssertError` is thrown. However, any other `Throwable`s will escape.

    Params:
        T          = The `Throwable` to test for.
        expression = The expression to test.
        msg        = Optional message to output on test failure.
                     If msg is empty, and the thrown exception has a
                     non-empty msg field, the exception's msg field
                     will be output on test failure.
        file       = The file where the error occurred.
                     Defaults to `__FILE__`.
        line       = The line where the error occurred.
                     Defaults to `__LINE__`.

    Throws:
        `AssertError` if the given `Throwable` is thrown.

    Returns:
        the result of `expression`.
 +/
auto assertNotThrown(T : Throwable = Exception, E)
                    (lazy E expression,
                     string msg = null,
                     string file = __FILE__,
                     size_t line = __LINE__)
{
    import core.exception : AssertError;
    try
    {
        return expression();
    }
    catch (T t)
    {
        immutable message = msg.length == 0 ? t.msg : msg;
        immutable tail = message.length == 0 ? "." : ": " ~ message;
        throw new AssertError("assertNotThrown failed: " ~ T.stringof ~ " was thrown" ~ tail, file, line, t);
    }
}
///
@system unittest
{
    import core.exception : AssertError;

    import std.string;
    assertNotThrown!StringException(enforce!StringException(true, "Error!"));

    //Exception is the default.
    assertNotThrown(enforce!StringException(true, "Error!"));

    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(
               enforce!StringException(false, "Error!"))) ==
           `assertNotThrown failed: StringException was thrown: Error!`);
}
@system unittest
{
    import core.exception : AssertError;
    import std.string;
    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(
               enforce!StringException(false, ""), "Error!")) ==
           `assertNotThrown failed: StringException was thrown: Error!`);

    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(
               enforce!StringException(false, ""))) ==
           `assertNotThrown failed: StringException was thrown.`);

    assert(collectExceptionMsg!AssertError(assertNotThrown!StringException(
               enforce!StringException(false, ""), "")) ==
           `assertNotThrown failed: StringException was thrown.`);
}

@system unittest
{
    import core.exception : AssertError;

    static noreturn throwEx(Throwable t) { throw t; }
    bool nothrowEx() { return true; }

    try
    {
        assert(assertNotThrown!Exception(nothrowEx()));
    }
    catch (AssertError) assert(0);

    try
    {
        assert(assertNotThrown!Exception(nothrowEx(), "It's a message"));
    }
    catch (AssertError) assert(0);

    try
    {
        assert(assertNotThrown!AssertError(nothrowEx()));
    }
    catch (AssertError) assert(0);

    try
    {
        assert(assertNotThrown!AssertError(nothrowEx(), "It's a message"));
    }
    catch (AssertError) assert(0);

    {
        bool thrown = false;
        try
        {
            assertNotThrown!Exception(
                throwEx(new Exception("It's an Exception")));
        }
        catch (AssertError) thrown = true;
        assert(thrown);
    }

    {
        bool thrown = false;
        try
        {
            assertNotThrown!Exception(
                throwEx(new Exception("It's an Exception")), "It's a message");
        }
        catch (AssertError) thrown = true;
        assert(thrown);
    }

    {
        bool thrown = false;
        try
        {
            assertNotThrown!AssertError(
                throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__)));
        }
        catch (AssertError) thrown = true;
        assert(thrown);
    }

    {
        bool thrown = false;
        try
        {
            assertNotThrown!AssertError(
                throwEx(new AssertError("It's an AssertError", __FILE__, __LINE__)),
                        "It's a message");
        }
        catch (AssertError) thrown = true;
        assert(thrown);
    }
}

/++
    Asserts that the given expression throws the given type of `Throwable`.
    The `Throwable` is caught and does not escape assertThrown. However,
    any other `Throwable`s $(I will) escape, and if no `Throwable`
    of the given type is thrown, then an `AssertError` is thrown.

    Params:
        T          = The `Throwable` to test for.
        expression = The expression to test.
        msg        = Optional message to output on test failure.
        file       = The file where the error occurred.
                     Defaults to `__FILE__`.
        line       = The line where the error occurred.
                     Defaults to `__LINE__`.

    Throws:
        `AssertError` if the given `Throwable` is not thrown.
  +/
void assertThrown(T : Throwable = Exception, E)
                 (lazy E expression,
                  string msg = null,
                  string file = __FILE__,
                  size_t line = __LINE__)
{
    import core.exception : AssertError;

    try
        expression();
    catch (T)
        return;

    static if (!is(immutable E == immutable noreturn))
        throw new AssertError("assertThrown failed: No " ~ T.stringof ~ " was thrown"
                                 ~ (msg.length == 0 ? "." : ": ") ~ msg,
                          file, line);
}
///
@system unittest
{
    import core.exception : AssertError;
    import std.string;

    assertThrown!StringException(enforce!StringException(false, "Error!"));

    //Exception is the default.
    assertThrown(enforce!StringException(false, "Error!"));

    assert(collectExceptionMsg!AssertError(assertThrown!StringException(
               enforce!StringException(true, "Error!"))) ==
           `assertThrown failed: No StringException was thrown.`);
}

@system unittest
{
    import core.exception : AssertError;

    static noreturn throwEx(Throwable t) { throw t; }
    void nothrowEx() { }

    try
    {
        assertThrown!Exception(throwEx(new Exception("It's an Exception")));
    }
    catch (AssertError) assert(0);

    try
    {
        assertThrown!Exception(throwEx(new Exception("It's an Exception")),
                               "It's a message");
    }
    catch (AssertError) assert(0);

    try
    {
        assertThrown!AssertError(throwEx(new AssertError("It's an AssertError",
                                                         __FILE__, __LINE__)));
    }
    catch (AssertError) assert(0);

    try
    {
        assertThrown!AssertError(throwEx(new AssertError("It's an AssertError",
                                                         __FILE__, __LINE__)),
                                 "It's a message");
    }
    catch (AssertError) assert(0);


    {
        bool thrown = false;
        try
            assertThrown!Exception(nothrowEx());
        catch (AssertError)
            thrown = true;

        assert(thrown);
    }

    {
        bool thrown = false;
        try
            assertThrown!Exception(nothrowEx(), "It's a message");
        catch (AssertError)
            thrown = true;

        assert(thrown);
    }

    {
        bool thrown = false;
        try
            assertThrown!AssertError(nothrowEx());
        catch (AssertError)
            thrown = true;

        assert(thrown);
    }

    {
        bool thrown = false;
        try
            assertThrown!AssertError(nothrowEx(), "It's a message");
        catch (AssertError)
            thrown = true;

        assert(thrown);
    }
}


/++
    Enforces that the given value is true.
    If the given value is false, an exception is thrown.
    The
    $(UL
        $(LI `msg` - error message as a `string`)
        $(LI `dg` - custom delegate that return a string and is only called if an exception occurred)
        $(LI `ex` - custom exception to be thrown. It is `lazy` and is only created if an exception occurred)
    )

    Params:
        value = The value to test.
        E = Exception type to throw if the value evaluates to false.
        msg = The error message to put in the exception if it is thrown.
        dg = The delegate to be called if the value evaluates to false.
        ex = The exception to throw if the value evaluates to false.
        file = The source file of the caller.
        line = The line number of the caller.

    Returns: `value`, if `cast(bool) value` is true. Otherwise,
    depending on the chosen overload, `new Exception(msg)`, `dg()` or `ex` is thrown.

    Note:
        `enforce` is used to throw exceptions and is therefore intended to
        aid in error handling. It is $(I not) intended for verifying the logic
        of your program. That is what `assert` is for. Also, do not use
        `enforce` inside of contracts (i.e. inside of `in` and `out`
        blocks and `invariant`s), because contracts are compiled out when
        compiling with $(I -release).

        If a delegate is passed, the safety and purity of this function are inferred
        from `Dg`'s safety and purity.
 +/
template enforce(E : Throwable = Exception)
if (is(typeof(new E("", string.init, size_t.init)) : Throwable) ||
    is(typeof(new E(string.init, size_t.init)) : Throwable))
{
    ///
    T enforce(T)(T value, lazy const(char)[] msg = null,
    string file = __FILE__, size_t line = __LINE__)
    if (is(typeof({ if (!value) {} })))
    {
        if (!value) bailOut!E(file, line, msg);
        return value;
    }
}

/// ditto
T enforce(T, Dg, string file = __FILE__, size_t line = __LINE__)
    (T value, scope Dg dg)
if (isSomeFunction!Dg && is(typeof( dg() )) &&
    is(typeof({ if (!value) {} })))
{
    if (!value) dg();
    return value;
}

/// ditto
T enforce(T)(T value, lazy Throwable ex)
{
    if (!value) throw ex();
    return value;
}

///
@system unittest
{
    import core.stdc.stdlib : malloc, free;
    import std.conv : ConvException, to;

    // use enforce like assert
    int a = 3;
    enforce(a > 2, "a needs to be higher than 2.");

    // enforce can throw a custom exception
    enforce!ConvException(a > 2, "a needs to be higher than 2.");

    // enforce will return it's input
    enum size = 42;
    auto memory = enforce(malloc(size), "malloc failed")[0 .. size];
    scope(exit) free(memory.ptr);
}

///
@safe unittest
{
    assertNotThrown(enforce(true, new Exception("this should not be thrown")));
    assertThrown(enforce(false, new Exception("this should be thrown")));
}

///
@safe unittest
{
    assert(enforce(123) == 123);

    try
    {
        enforce(false, "error");
        assert(false);
    }
    catch (Exception e)
    {
        assert(e.msg == "error");
        assert(e.file == __FILE__);
        assert(e.line == __LINE__-7);
    }
}

/// Alias your own enforce function
@safe unittest
{
    import std.conv : ConvException;
    alias convEnforce = enforce!ConvException;
    assertNotThrown(convEnforce(true));
    assertThrown!ConvException(convEnforce(false, "blah"));
}

private noreturn bailOut(E : Throwable = Exception)(string file, size_t line, scope const(char)[] msg)
{
    static if (is(typeof(new E(string.init, string.init, size_t.init))))
    {
        throw new E(msg ? msg.idup : "Enforcement failed", file, line);
    }
    else static if (is(typeof(new E(string.init, size_t.init))))
    {
        throw new E(file, line);
    }
    else
    {
        static assert(0, "Expected this(string, string, size_t) or this(string, size_t)" ~
            " constructor for " ~ __traits(identifier, E));
    }
}

// https://issues.dlang.org/show_bug.cgi?id=10510
@safe unittest
{
    extern(C) void cFoo() { }
    enforce(false, &cFoo);
}

// purity and safety inference test
@system unittest
{
    static foreach (EncloseSafe; [false, true])
    static foreach (EnclosePure; [false, true])
    {
        static foreach (BodySafe; [false, true])
        static foreach (BodyPure; [false, true])
        {{
            enum code =
                "delegate void() " ~
                (EncloseSafe ? "@safe " : "") ~
                (EnclosePure ? "pure " : "") ~
                "{ enforce(true, { " ~
                        "int n; " ~
                        (BodySafe ? "" : "auto p = &n + 10; "    ) ~    // unsafe code
                        (BodyPure ? "" : "static int g; g = 10; ") ~    // impure code
                    "}); " ~
                "}";
            enum expect =
                (BodySafe || !EncloseSafe) && (!EnclosePure || BodyPure);

            version (none)
            pragma(msg, "safe = ", EncloseSafe?1:0, "/", BodySafe?1:0, ", ",
                        "pure = ", EnclosePure?1:0, "/", BodyPure?1:0, ", ",
                        "expect = ", expect?"OK":"NG", ", ",
                        "code = ", code);

            static assert(__traits(compiles, mixin(code)()) == expect);
        }}
    }
}

// Test for https://issues.dlang.org/show_bug.cgi?id=8637
@system unittest
{
    struct S
    {
        static int g;
        ~this() {}  // impure & unsafe destructor
        bool opCast(T:bool)() {
            int* p = cast(int*) 0;   // unsafe operation
            int n = g;              // impure operation
            return true;
        }
    }
    S s;

    enforce(s);
    enforce(s, {});
    enforce(s, new Exception(""));

    errnoEnforce(s);

    alias E1 = Exception;
    static class E2 : Exception
    {
        this(string fn, size_t ln) { super("", fn, ln); }
    }
    static class E3 : Exception
    {
        this(string msg) { super(msg, __FILE__, __LINE__); }
    }
    enforce!E1(s);
    enforce!E2(s);
}

// https://issues.dlang.org/show_bug.cgi?id=14685
@safe unittest
{
    class E : Exception
    {
        this() { super("Not found"); }
    }
    static assert(!__traits(compiles, { enforce!E(false); }));
}

/++
    Enforces that the given value is true, throwing an `ErrnoException` if it
    is not.

    Params:
        value = The value to test.
        msg = The message to include in the `ErrnoException` if it is thrown.

    Returns: `value`, if `cast(bool) value` is true. Otherwise,
    $(D new ErrnoException(msg)) is thrown.  It is assumed that the last
    operation set `errno` to an error code corresponding with the failed
    condition.
 +/
alias errnoEnforce = enforce!ErrnoException;

///
@system unittest
{
    import core.stdc.stdio : fclose, fgets, fopen;
    import std.file : thisExePath;
    import std.string : toStringz;

    auto f = fopen(thisExePath.toStringz, "r").errnoEnforce;
    scope(exit) fclose(f);
    char[100] buf;
    auto line = fgets(buf.ptr, buf.length, f);
    enforce(line !is null); // expect a non-empty line
}

/++
    Catches and returns the exception thrown from the given expression.
    If no exception is thrown, then null is returned and `result` is
    set to the result of the expression.

    Note that while `collectException` $(I can) be used to collect any
    `Throwable` and not just `Exception`s, it is generally ill-advised to
    catch anything that is neither an `Exception` nor a type derived from
    `Exception`. So, do not use `collectException` to collect
    non-`Exception`s unless you're sure that that's what you really want to
    do.

    Params:
        T          = The type of exception to catch.
        expression = The expression which may throw an exception.
        result     = The result of the expression if no exception is thrown.
+/
T collectException(T = Exception, E)(lazy E expression, ref E result)
{
    try
    {
        result = expression();
    }
    catch (T e)
    {
        return e;
    }
    // Avoid "statement not reachable" warning
    static if (!is(immutable E == immutable noreturn))
        return null;
}
///
@system unittest
{
    int b;
    int foo() { throw new Exception("blah"); }
    assert(collectException(foo(), b));

    version (D_NoBoundsChecks) {}
    else
    {
        // check for out of bounds error
        int[] a = new int[3];
        import core.exception : RangeError;
        assert(collectException!RangeError(a[4], b));
    }
}

/++
    Catches and returns the exception thrown from the given expression.
    If no exception is thrown, then null is returned. `E` can be
    `void`.

    Note that while `collectException` $(I can) be used to collect any
    `Throwable` and not just `Exception`s, it is generally ill-advised to
    catch anything that is neither an `Exception` nor a type derived from
    `Exception`. So, do not use `collectException` to collect
    non-`Exception`s unless you're sure that that's what you really want to
    do.

    Params:
        T          = The type of exception to catch.
        expression = The expression which may throw an exception.
+/
T collectException(T : Throwable = Exception, E)(lazy E expression)
{
    try
    {
        expression();
    }
    catch (T t)
    {
        return t;
    }
    // Avoid "statement not reachable" warning
    static if (!is(immutable E == immutable noreturn))
        return null;
}

///
@safe unittest
{
    int foo() { throw new Exception("blah"); }
    assert(collectException(foo()).msg == "blah");
}

/++
    Catches the exception thrown from the given expression and returns the
    msg property of that exception. If no exception is thrown, then null is
    returned. `E` can be `void`.

    If an exception is thrown but it has an empty message, then
    `emptyExceptionMsg` is returned.

    Note that while `collectExceptionMsg` $(I can) be used to collect any
    `Throwable` and not just `Exception`s, it is generally ill-advised to
    catch anything that is neither an `Exception` nor a type derived from
    `Exception`. So, do not use `collectExceptionMsg` to collect
    non-`Exception`s unless you're sure that that's what you really want to
    do.

    Params:
        T          = The type of exception to catch.
        expression = The expression which may throw an exception.
+/
string collectExceptionMsg(T = Exception, E)(lazy E expression)
{
    import std.array : empty;
    try
    {
        expression();

        // Avoid "statement not reachable" warning
        static if (!is(immutable E == immutable noreturn))
            return cast(string) null;
    }
    catch (T e)
        return e.msg.empty ? emptyExceptionMsg : e.msg;
}
///
@safe unittest
{
    void throwFunc() { throw new Exception("My Message."); }
    assert(collectExceptionMsg(throwFunc()) == "My Message.");

    void nothrowFunc() {}
    assert(collectExceptionMsg(nothrowFunc()) is null);

    void throwEmptyFunc() { throw new Exception(""); }
    assert(collectExceptionMsg(throwEmptyFunc()) == emptyExceptionMsg);
}

/++
    Value that collectExceptionMsg returns when it catches an exception
    with an empty exception message.
 +/
enum emptyExceptionMsg = "<Empty Exception Message>";

// https://issues.dlang.org/show_bug.cgi?id=22364
@system unittest
{
    static noreturn foo() { throw new Exception(""); }

    const ex = collectException!(Exception, noreturn)(foo());
    assert(ex);

    const msg = collectExceptionMsg!(Exception, noreturn)(foo());
    assert(msg);

    noreturn n;

    // Triggers a backend assertion failure
    // collectException!(Exception, noreturn)(foo(), n);

    static assert(__traits(compiles, collectException!(Exception, noreturn)(foo(), n)));
}

/**
 * Casts a mutable array to an immutable array in an idiomatic
 * manner. Technically, `assumeUnique` just inserts a cast,
 * but its name documents assumptions on the part of the
 * caller. `assumeUnique(arr)` should only be called when
 * there are no more active mutable aliases to elements of $(D
 * arr). To strengthen this assumption, `assumeUnique(arr)`
 * also clears `arr` before returning. Essentially $(D
 * assumeUnique(arr)) indicates commitment from the caller that there
 * is no more mutable access to any of `arr`'s elements
 * (transitively), and that all future accesses will be done through
 * the immutable array returned by `assumeUnique`.
 *
 * Typically, `assumeUnique` is used to return arrays from
 * functions that have allocated and built them.
 *
 * Params:
 *  array = The array to cast to immutable.
 *
 * Returns: The immutable array.
 *
 * Example:
 *
 * $(RUNNABLE_EXAMPLE
 * ----
 * string letters()
 * {
 *   char[] result = new char['z' - 'a' + 1];
 *   foreach (i, ref e; result)
 *   {
 *     e = cast(char)('a' + i);
 *   }
 *   return assumeUnique(result);
 * }
 * ----
 * )
 *
 * The use in the example above is correct because `result`
 * was private to `letters` and is inaccessible in writing
 * after the function returns. The following example shows an
 * incorrect use of `assumeUnique`.
 *
 * Bad:
 *
 * $(RUNNABLE_EXAMPLE
 * ----
 * private char[] buffer;
 * string letters(char first, char last)
 * {
 *   if (first >= last) return null; // fine
 *   auto sneaky = buffer;
 *   sneaky.length = last - first + 1;
 *   foreach (i, ref e; sneaky)
 *   {
 *     e = cast(char)('a' + i);
 *   }
 *   return assumeUnique(sneaky); // BAD
 * }
 * ----
 * )
 *
 * The example above wreaks havoc on client code because it is
 * modifying arrays that callers considered immutable. To obtain an
 * immutable array from the writable array `buffer`, replace
 * the last line with:
 *
 * ----
 * return to!(string)(sneaky); // not that sneaky anymore
 * ----
 *
 * The call will duplicate the array appropriately.
 *
 * Note that checking for uniqueness during compilation is
 * possible in certain cases, especially when a function is
 * marked as a pure function. The following example does not
 * need to call assumeUnique because the compiler can infer the
 * uniqueness of the array in the pure function:
 *
 * $(RUNNABLE_EXAMPLE
 * ----
 * string letters() pure
 * {
 *   char[] result = new char['z' - 'a' + 1];
 *   foreach (i, ref e; result)
 *   {
 *     e = cast(char)('a' + i);
 *   }
 *   return result;
 * }
 * ----
 * )
 *
 * For more on infering uniqueness see the $(B unique) and
 * $(B lent) keywords in the
 * $(HTTP www.cs.cmu.edu/~aldrich/papers/aldrich-dissertation.pdf, ArchJava)
 * language.
 *
 * The downside of using `assumeUnique`'s
 * convention-based usage is that at this time there is no
 * formal checking of the correctness of the assumption;
 * on the upside, the idiomatic use of `assumeUnique` is
 * simple and rare enough to be tolerable.
 *
 */
immutable(T)[] assumeUnique(T)(T[] array) pure nothrow
{
    return .assumeUnique(array);    // call ref version
}
/// ditto
immutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow
{
    auto result = cast(immutable(T)[]) array;
    array = null;
    return result;
}
/// ditto
immutable(T[U]) assumeUnique(T, U)(ref T[U] array) pure nothrow
{
    auto result = cast(immutable(T[U])) array;
    array = null;
    return result;
}

///
@system unittest
{
    int[] arr = new int[1];
    auto arr1 = arr.assumeUnique;
    static assert(is(typeof(arr1) == immutable(int)[]));
    assert(arr == null);
    assert(arr1 == [0]);
}

///
@system unittest
{
    int[string] arr = ["a":1];
    auto arr1 = arr.assumeUnique;
    static assert(is(typeof(arr1) == immutable(int[string])));
    assert(arr == null);
    assert(arr1.keys == ["a"]);
}

/**
 * Wraps a possibly-throwing expression in a `nothrow` wrapper so that it
 * can be called by a `nothrow` function.
 *
 * This wrapper function documents commitment on the part of the caller that
 * the appropriate steps have been taken to avoid whatever conditions may
 * trigger an exception during the evaluation of `expr`.  If it turns out
 * that the expression $(I does) throw at runtime, the wrapper will throw an
 * `AssertError`.
 *
 * (Note that `Throwable` objects such as `AssertError` that do not
 * subclass `Exception` may be thrown even from `nothrow` functions,
 * since they are considered to be serious runtime problems that cannot be
 * recovered from.)
 *
 * Params:
 *  expr = The expression asserted not to throw.
 *  msg = The message to include in the `AssertError` if the assumption turns
 *      out to be false.
 *  file = The source file name of the caller.
 *  line = The line number of the caller.
 *
 * Returns:
 *  The value of `expr`, if any.
 */
T assumeWontThrow(T)(lazy T expr,
                     string msg = null,
                     string file = __FILE__,
                     size_t line = __LINE__) nothrow
{
    import core.exception : AssertError;
    try
    {
        return expr;
    }
    catch (Exception e)
    {
        import std.range.primitives : empty;
        immutable tail = msg.empty ? "." : ": " ~ msg;
        throw new AssertError("assumeWontThrow failed: Expression did throw" ~
                              tail, file, line);
    }
}

///
@safe unittest
{
    import std.math.algebraic : sqrt;

    // This function may throw.
    int squareRoot(int x)
    {
        if (x < 0)
            throw new Exception("Tried to take root of negative number");
        return cast(int) sqrt(cast(double) x);
    }

    // This function never throws.
    int computeLength(int x, int y) nothrow
    {
        // Since x*x + y*y is always positive, we can safely assume squareRoot
        // won't throw, and use it to implement this nothrow function. If it
        // does throw (e.g., if x*x + y*y overflows a 32-bit value), then the
        // program will terminate.
        return assumeWontThrow(squareRoot(x*x + y*y));
    }

    assert(computeLength(3, 4) == 5);
}

@system unittest
{
    import core.exception : AssertError;

    void alwaysThrows()
    {
        throw new Exception("I threw up");
    }
    void bad() nothrow
    {
        assumeWontThrow(alwaysThrows());
    }
    assertThrown!AssertError(bad());
}

/**
Checks whether a given source object contains pointers or references to a given
target object.

Params:
    source = The source object
    target = The target object

Bugs:
    The function is explicitly annotated `@nogc` because inference could fail,
    see $(LINK2 https://issues.dlang.org/show_bug.cgi?id=17084, issue 17084).

Returns: `true` if `source`'s representation embeds a pointer
that points to `target`'s representation or somewhere inside
it.

If `source` is or contains a dynamic array, then, then these functions will check
if there is overlap between the dynamic array and `target`'s representation.

If `source` is a class, then it will be handled as a pointer.

If `target` is a pointer, a dynamic array or a class, then these functions will only
check if `source` points to `target`, $(I not) what `target` references.

If `source` is or contains a union or `void[n]`, then there may be either false positives or
false negatives:

`doesPointTo` will return `true` if it is absolutely certain
`source` points to `target`. It may produce false negatives, but never
false positives. This function should be prefered when trying to validate
input data.

`mayPointTo` will return `false` if it is absolutely certain
`source` does not point to `target`. It may produce false positives, but never
false negatives. This function should be prefered for defensively choosing a
code path.

Note: Evaluating $(D doesPointTo(x, x)) checks whether `x` has
internal pointers. This should only be done as an assertive test,
as the language is free to assume objects don't have internal pointers
(TDPL 7.1.3.5).
*/
bool doesPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @nogc @trusted pure nothrow
if (__traits(isRef, source) || isDynamicArray!S ||
    isPointer!S || is(S == class))
{
    static if (isPointer!S || is(S == class) || is(S == interface))
    {
        const m = *cast(void**) &source;
        const b = cast(void*) &target;
        const e = b + target.sizeof;
        return b <= m && m < e;
    }
    else static if (is(S == struct) || is(S == union))
    {
        foreach (i, Subobj; typeof(source.tupleof))
            static if (!isUnionAliased!(S, i))
                if (doesPointTo(source.tupleof[i], target)) return true;
        return false;
    }
    else static if (isStaticArray!S)
    {
        static if (!is(S == void[n], size_t n))
        {
            foreach (ref s; source)
                if (doesPointTo(s, target)) return true;
        }
        return false;
    }
    else static if (isDynamicArray!S)
    {
        import std.array : overlap;
        return overlap(cast(void[]) source, cast(void[])(&target)[0 .. 1]).length != 0;
    }
    else
    {
        return false;
    }
}

// for shared objects
/// ditto
bool doesPointTo(S, T)(auto ref const shared S source, ref const shared T target) @trusted pure nothrow
{
    return doesPointTo!(shared S, shared T, void)(source, target);
}

/// ditto
bool mayPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @trusted pure nothrow
if (__traits(isRef, source) || isDynamicArray!S ||
    isPointer!S || is(S == class))
{
    static if (isPointer!S || is(S == class) || is(S == interface))
    {
        const m = *cast(void**) &source;
        const b = cast(void*) &target;
        const e = b + target.sizeof;
        return b <= m && m < e;
    }
    else static if (is(S == struct) || is(S == union))
    {
        foreach (i, Subobj; typeof(source.tupleof))
            if (mayPointTo(source.tupleof[i], target)) return true;
        return false;
    }
    else static if (isStaticArray!S)
    {
        static if (is(S == void[n], size_t n))
        {
            static if (n >= (void[]).sizeof)
            {
                // could contain a slice, which could point at anything.
                // But a void[N] that is all 0 cannot point anywhere
                import std.algorithm.searching : any;
                if (__ctfe || any(cast(ubyte[]) source[]))
                    return true;
            }
            else static if (n >= (void*).sizeof)
            {
                // Reinterpreting cast is impossible during ctfe
                if (__ctfe)
                    return true;

                // Only check for properly aligned pointers
                enum al = (void*).alignof - 1;
                const base = cast(size_t) &source;
                const alBase = (base + al) & ~al;

                if ((n - (alBase - base)) >= (void*).sizeof &&
                    mayPointTo(*(cast(void**) alBase), target))
                    return true;
            }
        }
        else
        {
            foreach (size_t i; 0 .. S.length)
                if (mayPointTo(source[i], target)) return true;
        }

        return false;
    }
    else static if (isDynamicArray!S)
    {
        import std.array : overlap;
        return overlap(cast(void[]) source, cast(void[])(&target)[0 .. 1]).length != 0;
    }
    else
    {
        return false;
    }
}

// for shared objects
/// ditto
bool mayPointTo(S, T)(auto ref const shared S source, ref const shared T target) @trusted pure nothrow
{
    return mayPointTo!(shared S, shared T, void)(source, target);
}

/// Pointers
@system unittest
{
    int  i = 0;
    int* p = null;
    assert(!p.doesPointTo(i));
    p = &i;
    assert( p.doesPointTo(i));
}

/// Structs and Unions
@system unittest
{
    struct S
    {
        int v;
        int* p;
    }
    int i;
    auto s = S(0, &i);

    // structs and unions "own" their members
    // pointsTo will answer true if one of the members pointsTo.
    assert(!s.doesPointTo(s.v)); //s.v is just v member of s, so not pointed.
    assert( s.p.doesPointTo(i)); //i is pointed by s.p.
    assert( s  .doesPointTo(i)); //which means i is pointed by s itself.

    // Unions will behave exactly the same. Points to will check each "member"
    // individually, even if they share the same memory
}

/// Arrays (dynamic and static)
@system unittest
{
    int i;
     // trick the compiler when initializing slice
     // https://issues.dlang.org/show_bug.cgi?id=18637
    int* p = &i;
    int[]  slice = [0, 1, 2, 3, 4];
    int[5] arr   = [0, 1, 2, 3, 4];
    int*[]  slicep = [p];
    int*[1] arrp   = [&i];

    // A slice points to all of its members:
    assert( slice.doesPointTo(slice[3]));
    assert(!slice[0 .. 2].doesPointTo(slice[3])); // Object 3 is outside of the
                                                  // slice [0 .. 2]

    // Note that a slice will not take into account what its members point to.
    assert( slicep[0].doesPointTo(i));
    assert(!slicep   .doesPointTo(i));

    // static arrays are objects that own their members, just like structs:
    assert(!arr.doesPointTo(arr[0])); // arr[0] is just a member of arr, so not
                                      // pointed.
    assert( arrp[0].doesPointTo(i));  // i is pointed by arrp[0].
    assert( arrp   .doesPointTo(i));  // which means i is pointed by arrp
                                      // itself.

    // Notice the difference between static and dynamic arrays:
    assert(!arr  .doesPointTo(arr[0]));
    assert( arr[].doesPointTo(arr[0]));
    assert( arrp  .doesPointTo(i));
    assert(!arrp[].doesPointTo(i));
}

/// Classes
@system unittest
{
    class C
    {
        this(int* p){this.p = p;}
        int* p;
    }
    int i;
    C a = new C(&i);
    C b = a;

    // Classes are a bit particular, as they are treated like simple pointers
    // to a class payload.
    assert( a.p.doesPointTo(i)); // a.p points to i.
    assert(!a  .doesPointTo(i)); // Yet a itself does not point i.

    //To check the class payload itself, iterate on its members:
    ()
    {
        import std.traits : Fields;

        foreach (index, _; Fields!C)
            if (doesPointTo(a.tupleof[index], i))
                return;
        assert(0);
    }();

    // To check if a class points a specific payload, a direct memmory check
    // can be done:
    auto aLoc = cast(ubyte[__traits(classInstanceSize, C)]*) a;
    assert(b.doesPointTo(*aLoc)); // b points to where a is pointing
}


version (StdUnittest)
{
    // https://issues.dlang.org/show_bug.cgi?id=17084
    // the bug doesn't happen if these declarations are in the unittest block
    // (static or not).
    private struct Page17084
    {
        URL17084 url;
        int opCmp(P)(P) { return 0; }
        int opCmp(P)(shared(P)) shared { return 0; }
    }

    private struct URL17084
    {
        int[] queryParams;
        string toString()() const { return ""; }
        alias toString this;
    }
}

// https://issues.dlang.org/show_bug.cgi?id=17084
@system unittest
{
    import std.algorithm.sorting : sort;
    Page17084[] s;
    sort(s);
    shared(Page17084)[] p;
    sort(p);
}

@system unittest
{
    struct S1 { int a; S1 * b; }
    S1 a1;
    S1 * p = &a1;
    assert(doesPointTo(p, a1));

    S1 a2;
    a2.b = &a1;
    assert(doesPointTo(a2, a1));

    struct S3 { int[10] a; }
    S3 a3;
    auto a4 = a3.a[2 .. 3];
    assert(doesPointTo(a4, a3));

    auto a5 = new double[4];
    auto a6 = a5[1 .. 2];
    assert(!doesPointTo(a5, a6));

    auto a7 = new double[3];
    auto a8 = new double[][1];
    a8[0] = a7;
    assert(!doesPointTo(a8[0], a8[0]));

    // don't invoke postblit on subobjects
    {
        static struct NoCopy { this(this) { assert(0); } }
        static struct Holder { NoCopy a, b, c; }
        Holder h;
        cast(void) doesPointTo(h, h);
    }

    shared S3 sh3;
    shared sh3sub = sh3.a[];
    assert(doesPointTo(sh3sub, sh3));

    int[] darr = [1, 2, 3, 4];

    //dynamic arrays don't point to each other, or slices of themselves
    assert(!doesPointTo(darr, darr));
    assert(!doesPointTo(darr[0 .. 1], darr));

    //But they do point their elements
    foreach (i; 0 .. 4)
        assert(doesPointTo(darr, darr[i]));
    assert(doesPointTo(darr[0 .. 3], darr[2]));
    assert(!doesPointTo(darr[0 .. 3], darr[3]));
}

@system unittest
{
    //tests with static arrays
    //Static arrays themselves are just objects, and don't really *point* to anything.
    //They aggregate their contents, much the same way a structure aggregates its attributes.
    //*However* The elements inside the static array may themselves point to stuff.

    //Standard array
    int[2] k;
    assert(!doesPointTo(k, k)); //an array doesn't point to itself
    //Technically, k doesn't point its elements, although it does alias them
    assert(!doesPointTo(k, k[0]));
    assert(!doesPointTo(k, k[1]));
    //But an extracted slice will point to the same array.
    assert(doesPointTo(k[], k));
    assert(doesPointTo(k[], k[1]));

    //An array of pointers
    int*[2] pp;
    int a;
    int b;
    pp[0] = &a;
    assert( doesPointTo(pp, a));  //The array contains a pointer to a
    assert(!doesPointTo(pp, b));  //The array does NOT contain a pointer to b
    assert(!doesPointTo(pp, pp)); //The array does not point itslef

    //A struct containing a static array of pointers
    static struct S
    {
        int*[2] p;
    }
    S s;
    s.p[0] = &a;
    assert( doesPointTo(s, a)); //The struct contains an array that points a
    assert(!doesPointTo(s, b)); //But doesn't point b
    assert(!doesPointTo(s, s)); //The struct doesn't actually point itslef.

    //An array containing structs that have pointers
    static struct SS
    {
        int* p;
    }
    SS[2] ss = [SS(&a), SS(null)];
    assert( doesPointTo(ss, a));  //The array contains a struct that points to a
    assert(!doesPointTo(ss, b));  //The array doesn't contains a struct that points to b
    assert(!doesPointTo(ss, ss)); //The array doesn't point itself.

    // https://issues.dlang.org/show_bug.cgi?id=20426
    align((void*).alignof) void[32] voidArr = void;
    (cast(void*[]) voidArr[])[] = null; // Ensure no false pointers

    // zeroed void ranges can't point at anything
    assert(!mayPointTo(voidArr, a));
    assert(!mayPointTo(voidArr, b));

    *cast(void**) &voidArr[16] = &a; // Pointers should be found

    alias SA = void[size_t.sizeof + 3];
    SA *smallArr1 = cast(SA*)&voidArr;
    SA *smallArr2 = cast(SA*)&(voidArr[16]);

    // But it should only consider properly aligned pointers
    // Write single bytes to avoid issues due to misaligned writes
    void*[1] tmp = [&b];
    (cast(ubyte[]) voidArr[3 .. 3 + (void*).sizeof])[] = cast(ubyte[]) tmp[];


    assert( mayPointTo(*smallArr2, a));
    assert(!mayPointTo(*smallArr1, b));

    assert(!doesPointTo(voidArr, a)); // Value might be a false pointer
    assert(!doesPointTo(voidArr, b));

    SA *smallArr3 = cast(SA *) &voidArr[13]; // Works for weird sizes/alignments
    assert( mayPointTo(*smallArr3, a));
    assert(!mayPointTo(*smallArr3, b));

    assert(!doesPointTo(*smallArr3, a));
    assert(!doesPointTo(*smallArr3, b));

    auto v3 = cast(void[3]*) &voidArr[16]; // Arrays smaller than pointers are ignored
    assert(!mayPointTo(*v3, a));
    assert(!mayPointTo(*v3, b));

    assert(!doesPointTo(*v3, a));
    assert(!doesPointTo(*v3, b));

    assert(mayPointTo(voidArr, a)); // slice-contiaining void[N] might point at anything
    assert(mayPointTo(voidArr, b));

    static assert(() {
        void[16] arr1 = void;
        void[size_t.sizeof] arr2 = void;
        int var;
        return mayPointTo(arr1, var) && !doesPointTo(arr1, var) &&
               mayPointTo(arr2, var) && !doesPointTo(arr2, var);
    }());
}


@system unittest //Unions
{
    int i;
    union U //Named union
    {
        size_t asInt = 0;
        int*   asPointer;
    }
    struct S
    {
        union //Anonymous union
        {
            size_t asInt = 0;
            int*   asPointer;
        }
    }

    U u;
    S s;
    assert(!doesPointTo(u, i));
    assert(!doesPointTo(s, i));
    assert(!mayPointTo(u, i));
    assert(!mayPointTo(s, i));

    u.asPointer = &i;
    s.asPointer = &i;
    assert(!doesPointTo(u, i));
    assert(!doesPointTo(s, i));
    assert( mayPointTo(u, i));
    assert( mayPointTo(s, i));

    u.asInt = cast(size_t)&i;
    s.asInt = cast(size_t)&i;
    assert(!doesPointTo(u, i));
    assert(!doesPointTo(s, i));
    assert( mayPointTo(u, i));
    assert( mayPointTo(s, i));
}

@system unittest //Classes
{
    int i;
    static class A
    {
        int* p;
    }
    A a = new A, b = a;
    assert(!doesPointTo(a, b)); //a does not point to b
    a.p = &i;
    assert(!doesPointTo(a, i)); //a does not point to i
}
@safe unittest //alias this test
{
    static int i;
    static int j;
    struct S
    {
        int* p;
        @property int* foo(){return &i;}
        alias foo this;
    }
    assert(is(S : int*));
    S s = S(&j);
    assert(!doesPointTo(s, i));
    assert( doesPointTo(s, j));
    assert( doesPointTo(cast(int*) s, i));
    assert(!doesPointTo(cast(int*) s, j));
}
@safe unittest //more alias this opCast
{
    void* p;
    class A
    {
        void* opCast(T)() if (is(T == void*))
        {
            return p;
        }
        alias foo = opCast!(void*);
        alias foo this;
    }
    assert(!doesPointTo(A.init, p));
    assert(!mayPointTo(A.init, p));
}

/+
Returns true if the field at index `i` in ($D T) shares its address with another field.

Note: This does not merelly check if the field is a member of an union, but also that
it is not a single child.
+/
package enum isUnionAliased(T, size_t i) = isUnionAliasedImpl!T(T.tupleof[i].offsetof);
private bool isUnionAliasedImpl(T)(size_t offset)
{
    int count = 0;
    foreach (i, U; typeof(T.tupleof))
        if (T.tupleof[i].offsetof == offset)
            ++count;
    return count >= 2;
}
//
@safe unittest
{
    static struct S
    {
        int a0; //Not aliased
        union
        {
            int a1; //Not aliased
        }
        union
        {
            int a2; //Aliased
            int a3; //Aliased
        }
        union A4
        {
            int b0; //Not aliased
        }
        A4 a4;
        union A5
        {
            int b0; //Aliased
            int b1; //Aliased
        }
        A5 a5;
    }

    static assert(!isUnionAliased!(S, 0)); //a0;
    static assert(!isUnionAliased!(S, 1)); //a1;
    static assert( isUnionAliased!(S, 2)); //a2;
    static assert( isUnionAliased!(S, 3)); //a3;
    static assert(!isUnionAliased!(S, 4)); //a4;
        static assert(!isUnionAliased!(S.A4, 0)); //a4.b0;
    static assert(!isUnionAliased!(S, 5)); //a5;
        static assert( isUnionAliased!(S.A5, 0)); //a5.b0;
        static assert( isUnionAliased!(S.A5, 1)); //a5.b1;
}

version (CRuntime_Glibc) version = GNU_STRERROR;
version (CRuntime_UClibc) version = GNU_STRERROR;

package string errnoString(int errno) nothrow @trusted
{
    import core.stdc.string : strlen;
    version (GNU_STRERROR)
    {
        import core.stdc.string : strerror_r;
        char[1024] buf = void;
        auto s = strerror_r(errno, buf.ptr, buf.length);
    }
    else version (Posix)
    {
        // XSI-compliant
        import core.stdc.string : strerror_r;
        char[1024] buf = void;
        const(char)* s;
        if (strerror_r(errno, buf.ptr, buf.length) == 0)
            s = buf.ptr;
        else
            return "Unknown error";
    }
    else
    {
        import core.stdc.string : strerror;
        auto s = strerror(errno);
    }
    return s[0 .. s.strlen].idup;
}

/*********************
 * Thrown if errors that set `errno` occur.
 */
class ErrnoException : Exception
{
    /// Operating system error code.
    final @property uint errno() nothrow pure @nogc @safe { return _errno; }
    private uint _errno;
    /// Constructor which takes an error message. The current global $(REF errno, core,stdc,errno) value is used as error code.
    this(string msg, string file = null, size_t line = 0) @safe
    {
        import core.stdc.errno : errno;
        this(msg, errno, file, line);
    }
    /// Constructor which takes an error message and error code.
    this(string msg, int errno, string file = null, size_t line = 0) @safe
    {
        _errno = errno;
        super(msg ~ " (" ~ errnoString(errno) ~ ")", file, line);
    }
}

///
@safe unittest
{
    import core.stdc.errno : EAGAIN;
    auto ex = new ErrnoException("oh no", EAGAIN);
    assert(ex.errno == EAGAIN);
}

/// errno is used by default if no explicit error code is provided
@safe unittest
{
    import core.stdc.errno : errno, EAGAIN;

    auto old = errno;
    scope(exit) errno = old;

    // fake that errno got set by the callee
    errno = EAGAIN;
    auto ex = new ErrnoException("oh no");
    assert(ex.errno == EAGAIN);
}

/++
    ML-style functional exception handling. Runs the supplied expression and
    returns its result. If the expression throws a `Throwable`, runs the
    supplied error handler instead and return its result. The error handler's
    type must be the same as the expression's type.

    Params:
        E            = The type of `Throwable`s to catch. Defaults to `Exception`
        T1           = The type of the expression.
        T2           = The return type of the error handler.
        expression   = The expression to run and return its result.
        errorHandler = The handler to run if the expression throwed.

    Returns:
        expression, if it does not throw. Otherwise, returns the result of
        errorHandler.
+/
//lazy version
CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy scope T1 expression, lazy scope T2 errorHandler)
{
    static assert(!is(typeof(return) == void),
        "The error handler's return value("
        ~ T2.stringof ~
        ") does not have a common type with the expression("
        ~ T1.stringof ~
        ")."
    );
    try
    {
        return expression();
    }
    catch (E)
    {
        return errorHandler();
    }
}

///ditto
//delegate version
CommonType!(T1, T2) ifThrown(E : Throwable, T1, T2)(lazy scope T1 expression, scope T2 delegate(E) errorHandler)
{
    static assert(!is(typeof(return) == void),
        "The error handler's return value("
        ~ T2.stringof ~
        ") does not have a common type with the expression("
        ~ T1.stringof ~
        ")."
    );
    try
    {
        return expression();
    }
    catch (E e)
    {
        return errorHandler(e);
    }
}

///ditto
//delegate version, general overload to catch any Exception
CommonType!(T1, T2) ifThrown(T1, T2)(lazy scope T1 expression, scope T2 delegate(Exception) errorHandler)
{
    static assert(!is(typeof(return) == void),
        "The error handler's return value("
        ~ T2.stringof ~
        ") does not have a common type with the expression("
        ~ T1.stringof ~
        ")."
    );
    try
    {
        return expression();
    }
    catch (Exception e)
    {
        return errorHandler(e);
    }
}

/// Revert to a default value upon an error:
@safe unittest
{
    import std.conv : to;
    assert("x".to!int.ifThrown(0) == 0);
}

/**
Chain multiple calls to ifThrown, each capturing errors from the
entire preceding expression.
*/
@safe unittest
{
    import std.conv : ConvException, to;
    string s = "true";
    assert(s.to!int.ifThrown(cast(int) s.to!double)
                   .ifThrown(cast(int) s.to!bool) == 1);

    s = "2.0";
    assert(s.to!int.ifThrown(cast(int) s.to!double)
                   .ifThrown(cast(int) s.to!bool) == 2);

    // Respond differently to different types of errors
    alias orFallback = (lazy a)  => a.ifThrown!ConvException("not a number")
                                     .ifThrown!Exception("number too small");

    assert(orFallback(enforce("x".to!int < 1).to!string) == "not a number");
    assert(orFallback(enforce("2".to!int < 1).to!string) == "number too small");
}

/**
The expression and the errorHandler must have a common type they can both
be implicitly casted to, and that type will be the type of the compound
expression.
*/
@safe unittest
{
    // null and new Object have a common type(Object).
    static assert(is(typeof(null.ifThrown(new Object())) == Object));
    static assert(is(typeof((new Object()).ifThrown(null)) == Object));

    // 1 and new Object do not have a common type.
    static assert(!__traits(compiles, 1.ifThrown(new Object())));
    static assert(!__traits(compiles, (new Object()).ifThrown(1)));
}

/// Use a lambda to get the thrown object.
@system unittest
{
    import std.format : format;
    assert("%s".format.ifThrown!Exception(e => e.classinfo.name) == "std.format.FormatException");
}

//Verify Examples
@system unittest
{
    import std.conv;
    import std.string;
    //Revert to a default value upon an error:
    assert("x".to!int().ifThrown(0) == 0);

    //Chaining multiple calls to ifThrown to attempt multiple things in a row:
    string s="true";
    assert(s.to!int().
            ifThrown(cast(int) s.to!double()).
            ifThrown(cast(int) s.to!bool())
            == 1);

    //Respond differently to different types of errors
    assert(enforce("x".to!int() < 1).to!string()
            .ifThrown!ConvException("not a number")
            .ifThrown!Exception("number too small")
            == "not a number");

    //null and new Object have a common type(Object).
    static assert(is(typeof(null.ifThrown(new Object())) == Object));
    static assert(is(typeof((new Object()).ifThrown(null)) == Object));

    //1 and new Object do not have a common type.
    static assert(!__traits(compiles, 1.ifThrown(new Object())));
    static assert(!__traits(compiles, (new Object()).ifThrown(1)));

    //Use a lambda to get the thrown object.
    assert("%s".format().ifThrown(e => e.classinfo.name) == "std.format.FormatException");
}

@system unittest
{
    import core.exception;
    import std.conv;
    import std.string;
    //Basic behaviour - all versions.
    assert("1".to!int().ifThrown(0) == 1);
    assert("x".to!int().ifThrown(0) == 0);
    assert("1".to!int().ifThrown!ConvException(0) == 1);
    assert("x".to!int().ifThrown!ConvException(0) == 0);
    assert("1".to!int().ifThrown(e=>0) == 1);
    assert("x".to!int().ifThrown(e=>0) == 0);
    static if (__traits(compiles, 0.ifThrown!Exception(e => 0))) //This will only work with a fix that was not yet pulled
    {
        assert("1".to!int().ifThrown!ConvException(e=>0) == 1);
        assert("x".to!int().ifThrown!ConvException(e=>0) == 0);
    }

    //Exceptions other than stated not caught.
    assert("x".to!int().ifThrown!StringException(0).collectException!ConvException() !is null);
    static if (__traits(compiles, 0.ifThrown!Exception(e => 0))) //This will only work with a fix that was not yet pulled
    {
        assert("x".to!int().ifThrown!StringException(e=>0).collectException!ConvException() !is null);
    }

    //Default does not include errors.
    int throwRangeError() { throw new RangeError; }
    assert(throwRangeError().ifThrown(0).collectException!RangeError() !is null);
    assert(throwRangeError().ifThrown(e=>0).collectException!RangeError() !is null);

    //Incompatible types are not accepted.
    static assert(!__traits(compiles, 1.ifThrown(new Object())));
    static assert(!__traits(compiles, (new Object()).ifThrown(1)));
    static assert(!__traits(compiles, 1.ifThrown(e=>new Object())));
    static assert(!__traits(compiles, (new Object()).ifThrown(e=>1)));
}

version (StdUnittest) package
void assertCTFEable(alias dg)()
{
    static assert({ cast(void) dg(); return true; }());
    cast(void) dg();
}

/** This `enum` is used to select the primitives of the range to handle by the
  $(LREF handle) range wrapper. The values of the `enum` can be `OR`'d to
  select multiple primitives to be handled.

  `RangePrimitive.access` is a shortcut for the access primitives; `front`,
  `back` and `opIndex`.

  `RangePrimitive.pop` is a shortcut for the mutating primitives;
  `popFront` and `popBack`.
 */
enum RangePrimitive
{
    front    = 0b00_0000_0001, ///
    back     = 0b00_0000_0010, /// Ditto
    popFront = 0b00_0000_0100, /// Ditto
    popBack  = 0b00_0000_1000, /// Ditto
    empty    = 0b00_0001_0000, /// Ditto
    save     = 0b00_0010_0000, /// Ditto
    length   = 0b00_0100_0000, /// Ditto
    opDollar = 0b00_1000_0000, /// Ditto
    opIndex  = 0b01_0000_0000, /// Ditto
    opSlice  = 0b10_0000_0000, /// Ditto
    access   = front | back | opIndex, /// Ditto
    pop      = popFront | popBack, /// Ditto
}

///
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map, splitter;
    import std.conv : to, ConvException;

    auto s = "12,1337z32,54,2,7,9,1z,6,8";

    // The next line composition will throw when iterated
    // as some elements of the input do not convert to integer
    auto r = s.splitter(',').map!(a => to!int(a));

    // Substitute 0 for cases of ConvException
    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);
    assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));
}

///
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : retro;
    import std.utf : UTFException;

    auto str = "hello\xFFworld"; // 0xFF is an invalid UTF-8 code unit

    auto handled = str.handle!(UTFException, RangePrimitive.access,
            (e, r) => ' '); // Replace invalid code points with spaces

    assert(handled.equal("hello world")); // `front` is handled,
    assert(handled.retro.equal("dlrow olleh")); // as well as `back`
}

/** Handle exceptions thrown from range primitives.

Use the $(LREF RangePrimitive) enum to specify which primitives to _handle.
Multiple range primitives can be handled at once by using the `OR` operator
or the pseudo-primitives `RangePrimitive.access` and `RangePrimitive.pop`.
All handled primitives must have return types or values compatible with the
user-supplied handler.

Params:
    E = The type of `Throwable` to _handle.
    primitivesToHandle = Set of range primitives to _handle.
    handler = The callable that is called when a handled primitive throws a
    `Throwable` of type `E`. The handler must accept arguments of
    the form $(D E, ref IRange) and its return value is used as the primitive's
    return value whenever `E` is thrown. For `opIndex`, the handler can
    optionally recieve a third argument; the index that caused the exception.
    input = The range to _handle.

Returns: A wrapper `struct` that preserves the range interface of `input`.

Note:
Infinite ranges with slicing support must return an instance of
$(REF Take, std,range) when sliced with a specific lower and upper
bound (see $(REF hasSlicing, std,range,primitives)); `handle` deals with
this by `take`ing 0 from the return value of the handler function and
returning that when an exception is caught.
*/
auto handle(E : Throwable, RangePrimitive primitivesToHandle, alias handler, Range)(Range input)
if (isInputRange!Range)
{
    static struct Handler
    {
        private Range range;

        static if (isForwardRange!Range)
        {
            @property typeof(this) save()
            {
                static if (primitivesToHandle & RangePrimitive.save)
                {
                    try
                    {
                        return typeof(this)(range.save);
                    }
                    catch (E exception)
                    {
                        return typeof(this)(handler(exception, this.range));
                    }
                }
                else
                    return typeof(this)(range.save);
            }
        }

        static if (isInfinite!Range)
        {
            enum bool empty = false;
        }
        else
        {
            @property bool empty()
            {
                static if (primitivesToHandle & RangePrimitive.empty)
                {
                    try
                    {
                        return this.range.empty;
                    }
                    catch (E exception)
                    {
                        return handler(exception, this.range);
                    }
                }
                else
                    return this.range.empty;
            }
        }

        @property auto ref front()
        {
            static if (primitivesToHandle & RangePrimitive.front)
            {
                try
                {
                    return this.range.front;
                }
                catch (E exception)
                {
                    return handler(exception, this.range);
                }
            }
            else
                return this.range.front;
        }

        void popFront()
        {
            static if (primitivesToHandle & RangePrimitive.popFront)
            {
                try
                {
                    this.range.popFront();
                }
                catch (E exception)
                {
                    handler(exception, this.range);
                }
            }
            else
                this.range.popFront();
        }

        static if (isBidirectionalRange!Range)
        {
            @property auto ref back()
            {
                static if (primitivesToHandle & RangePrimitive.back)
                {
                    try
                    {
                        return this.range.back;
                    }
                    catch (E exception)
                    {
                        return handler(exception, this.range);
                    }
                }
                else
                    return this.range.back;
            }

            void popBack()
            {
                static if (primitivesToHandle & RangePrimitive.popBack)
                {
                    try
                    {
                        this.range.popBack();
                    }
                    catch (E exception)
                    {
                        handler(exception, this.range);
                    }
                }
                else
                    this.range.popBack();
            }
        }

        static if (isRandomAccessRange!Range)
        {
            auto ref opIndex(size_t index)
            {
                static if (primitivesToHandle & RangePrimitive.opIndex)
                {
                    try
                    {
                        return this.range[index];
                    }
                    catch (E exception)
                    {
                        static if (__traits(compiles, handler(exception, this.range, index)))
                            return handler(exception, this.range, index);
                        else
                            return handler(exception, this.range);
                    }
                }
                else
                    return this.range[index];
            }
        }

        static if (hasLength!Range)
        {
            @property auto length()
            {
                static if (primitivesToHandle & RangePrimitive.length)
                {
                    try
                    {
                        return this.range.length;
                    }
                    catch (E exception)
                    {
                        return handler(exception, this.range);
                    }
                }
                else
                    return this.range.length;
            }
        }

        static if (hasSlicing!Range)
        {
            static if (hasLength!Range)
            {
                typeof(this) opSlice(size_t lower, size_t upper)
                {
                    static if (primitivesToHandle & RangePrimitive.opSlice)
                    {
                        try
                        {
                            return typeof(this)(this.range[lower .. upper]);
                        }
                        catch (E exception)
                        {
                            return typeof(this)(handler(exception, this.range));
                        }
                    }
                    else
                        return typeof(this)(this.range[lower .. upper]);
                }
            }
            else static if (is(typeof(Range.init[size_t.init .. $])))
            {
                import std.range : Take, takeExactly;
                static struct DollarToken {}
                enum opDollar = DollarToken.init;

                typeof(this) opSlice(size_t lower, DollarToken)
                {
                    static if (primitivesToHandle & RangePrimitive.opSlice)
                    {
                        try
                        {
                            return typeof(this)(this.range[lower .. $]);
                        }
                        catch (E exception)
                        {
                            return typeof(this)(handler(exception, this.range));
                        }
                    }
                    else
                        return typeof(this)(this.range[lower .. $]);
                }

                Take!Handler opSlice(size_t lower, size_t upper)
                {
                    static if (primitivesToHandle & RangePrimitive.opSlice)
                    {
                        try
                        {
                            return takeExactly(typeof(this)(this.range[lower .. $]), upper - 1);
                        }
                        catch (E exception)
                        {
                            return takeExactly(typeof(this)(handler(exception, this.range)), 0);
                        }
                    }
                    else
                        return takeExactly(typeof(this)(this.range[lower .. $]), upper - 1);
                }
            }
        }
    }

    return Handler(input);
}

///
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map, splitter;
    import std.conv : to, ConvException;

    auto s = "12,1337z32,54,2,7,9,1z,6,8";

    // The next line composition will throw when iterated
    // as some elements of the input do not convert to integer
    auto r = s.splitter(',').map!(a => to!int(a));

    // Substitute 0 for cases of ConvException
    auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);
    assert(h.equal([12, 0, 54, 2, 7, 9, 0, 6, 8]));
}

///
pure @safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range : retro;
    import std.utf : UTFException;

    auto str = "hello\xFFworld"; // 0xFF is an invalid UTF-8 code unit

    auto handled = str.handle!(UTFException, RangePrimitive.access,
            (e, r) => ' '); // Replace invalid code points with spaces

    assert(handled.equal("hello world")); // `front` is handled,
    assert(handled.retro.equal("dlrow olleh")); // as well as `back`
}

pure nothrow @safe unittest
{
    static struct ThrowingRange
    {
        pure @safe:
        @property bool empty()
        {
            throw new Exception("empty has thrown");
        }

        @property int front()
        {
            throw new Exception("front has thrown");
        }

        @property int back()
        {
            throw new Exception("back has thrown");
        }

        void popFront()
        {
            throw new Exception("popFront has thrown");
        }

        void popBack()
        {
            throw new Exception("popBack has thrown");
        }

        int opIndex(size_t)
        {
            throw new Exception("opIndex has thrown");
        }

        ThrowingRange opSlice(size_t, size_t)
        {
            throw new Exception("opSlice has thrown");
        }

        @property size_t length()
        {
            throw new Exception("length has thrown");
        }

        alias opDollar = length;

        @property ThrowingRange save()
        {
            throw new Exception("save has thrown");
        }
    }

    static assert(isInputRange!ThrowingRange);
    static assert(isForwardRange!ThrowingRange);
    static assert(isBidirectionalRange!ThrowingRange);
    static assert(hasSlicing!ThrowingRange);
    static assert(hasLength!ThrowingRange);

    auto f = ThrowingRange();
    auto fb = f.handle!(Exception, RangePrimitive.front | RangePrimitive.back,
            (e, r) => -1)();
    assert(fb.front == -1);
    assert(fb.back == -1);
    assertThrown(fb.popFront());
    assertThrown(fb.popBack());
    assertThrown(fb.empty);
    assertThrown(fb.save);
    assertThrown(fb[0]);

    auto accessRange = f.handle!(Exception, RangePrimitive.access,
            (e, r) => -1);
    assert(accessRange.front == -1);
    assert(accessRange.back == -1);
    assert(accessRange[0] == -1);
    assertThrown(accessRange.popFront());
    assertThrown(accessRange.popBack());

    auto pfb = f.handle!(Exception, RangePrimitive.pop, (e, r) => -1)();

    pfb.popFront(); // this would throw otherwise
    pfb.popBack(); // this would throw otherwise

    auto em = f.handle!(Exception,
            RangePrimitive.empty, (e, r) => false)();

    assert(!em.empty);

    auto arr = f.handle!(Exception,
            RangePrimitive.opIndex, (e, r) => 1337)();

    assert(arr[0] == 1337);

    auto arr2 = f.handle!(Exception,
            RangePrimitive.opIndex, (e, r, i) => i)();

    assert(arr2[0] == 0);
    assert(arr2[1337] == 1337);

    auto save = f.handle!(Exception,
        RangePrimitive.save,
        function(Exception e, ref ThrowingRange r) {
            return ThrowingRange();
        })();

    save.save;

    auto slice = f.handle!(Exception,
        RangePrimitive.opSlice, (e, r) => ThrowingRange())();

    auto sliced = slice[0 .. 1337]; // this would throw otherwise

    static struct Infinite
    {
        import std.range : Take;
        pure @safe:
        enum bool empty = false;
        int front() { assert(false); }
        void popFront() { assert(false); }
        Infinite save() @property { assert(false); }
        static struct DollarToken {}
        enum opDollar = DollarToken.init;
        Take!Infinite opSlice(size_t, size_t) { assert(false); }
        Infinite opSlice(size_t, DollarToken)
        {
            throw new Exception("opSlice has thrown");
        }
    }

    static assert(isInputRange!Infinite);
    static assert(isInfinite!Infinite);
    static assert(hasSlicing!Infinite);

    assertThrown(Infinite()[0 .. $]);

    auto infinite = Infinite.init.handle!(Exception,
        RangePrimitive.opSlice, (e, r) => Infinite())();

    auto infSlice = infinite[0 .. $]; // this would throw otherwise
}


/++
    Convenience mixin for trivially sub-classing exceptions

    Even trivially sub-classing an exception involves writing boilerplate code
    for the constructor to: 1$(RPAREN) correctly pass in the source file and line number
    the exception was thrown from; 2$(RPAREN) be usable with $(LREF enforce) which
    expects exception constructors to take arguments in a fixed order. This
    mixin provides that boilerplate code.

    Note however that you need to mark the $(B mixin) line with at least a
    minimal (i.e. just $(B ///)) DDoc comment if you want the mixed-in
    constructors to be documented in the newly created Exception subclass.

    $(RED Current limitation): Due to
    $(LINK2 https://issues.dlang.org/show_bug.cgi?id=11500, bug #11500),
    currently the constructors specified in this mixin cannot be overloaded with
    any other custom constructors. Thus this mixin can currently only be used
    when no such custom constructors need to be explicitly specified.
 +/
mixin template basicExceptionCtors()
{
    /++
        Params:
            msg  = The message for the exception.
            file = The file where the exception occurred.
            line = The line number where the exception occurred.
            next = The previous exception in the chain of exceptions, if any.
    +/
    this(string msg, string file = __FILE__, size_t line = __LINE__,
         Throwable next = null) @nogc @safe pure nothrow
    {
        super(msg, file, line, next);
    }

    /++
        Params:
            msg  = The message for the exception.
            next = The previous exception in the chain of exceptions.
            file = The file where the exception occurred.
            line = The line number where the exception occurred.
    +/
    this(string msg, Throwable next, string file = __FILE__,
         size_t line = __LINE__) @nogc @safe pure nothrow
    {
        super(msg, file, line, next);
    }
}

///
@safe unittest
{
    class MeaCulpa: Exception
    {
        ///
        mixin basicExceptionCtors;
    }

    try
        throw new MeaCulpa("test");
    catch (MeaCulpa e)
    {
        assert(e.msg == "test");
        assert(e.file == __FILE__);
        assert(e.line == __LINE__ - 5);
    }
}

@safe pure nothrow unittest
{
    class TestException : Exception { mixin basicExceptionCtors; }
    auto e = new Exception("msg");
    auto te1 = new TestException("foo");
    auto te2 = new TestException("foo", e);
}

@safe unittest
{
    class TestException : Exception { mixin basicExceptionCtors; }
    auto e = new Exception("!!!");

    auto te1 = new TestException("message", "file", 42, e);
    assert(te1.msg == "message");
    assert(te1.file == "file");
    assert(te1.line == 42);
    assert(te1.next is e);

    auto te2 = new TestException("message", e, "file", 42);
    assert(te2.msg == "message");
    assert(te2.file == "file");
    assert(te2.line == 42);
    assert(te2.next is e);

    auto te3 = new TestException("foo");
    assert(te3.msg == "foo");
    assert(te3.file == __FILE__);
    assert(te3.line == __LINE__ - 3);
    assert(te3.next is null);

    auto te4 = new TestException("foo", e);
    assert(te4.msg == "foo");
    assert(te4.file == __FILE__);
    assert(te4.line == __LINE__ - 3);
    assert(te4.next is e);
}
