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