diff --git a/changelog/std-exception-enforce.dd b/changelog/std-exception-enforce.dd new file mode 100644 index 000000000..aa355cf50 --- /dev/null +++ b/changelog/std-exception-enforce.dd @@ -0,0 +1,13 @@ +std.exception.enforce can now be used as an eponymous template to create your own enforce function + +$(REF enforce, std,exception) now mirrors the behavior of $(REF enforceEx, std,exception) +and can be used as an eponymous template: + +--- +import std.conv : ConvException; +alias convEnforce = enforce!ConvException; +assertNotThrown(convEnforce(true)); +assertThrown!ConvException(convEnforce(false, "blah")); +--- + +With this change, $(REF enforce, std,exception) is a strict superset of $(REF enforceEx, std,exception), which will be deprecated in 2.079. diff --git a/std/exception.d b/std/exception.d index 544f636ca..ccbb01d09 100644 --- a/std/exception.d +++ b/std/exception.d @@ -17,7 +17,6 @@ $(TR $(TD Assumptions) $(TD $(TR $(TD Enforce) $(TD $(LREF doesPointTo) $(LREF enforce) - $(LREF enforceEx) $(LREF errnoEnforce) )) $(TR $(TD Handlers) $(TD @@ -386,12 +385,17 @@ void assertThrown(T : Throwable = Exception, E) If a delegate is passed, the safety and purity of this function are inferred from `Dg`'s safety and purity. +/ -T enforce(E : Throwable = Exception, T)(T value, lazy const(char)[] msg = null, -string file = __FILE__, size_t line = __LINE__) -if (is(typeof({ if (!value) {} }))) +template enforce(E : Throwable = Exception) +if (is(typeof(new E("", __FILE__, __LINE__)) : Throwable) || is(typeof(new E(__FILE__, __LINE__)) : Throwable)) { - if (!value) bailOut!E(file, line, msg); - return value; + + 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 @@ -455,6 +459,15 @@ unittest } } +/// Alias your own enforce function +@safe unittest +{ + import std.conv : ConvException; + alias convEnforce = enforce!ConvException; + assertNotThrown(convEnforce(true)); + assertThrown!ConvException(convEnforce(false, "blah")); +} + private void bailOut(E : Throwable = Exception)(string file, size_t line, in char[] msg) { static if (is(typeof(new E(string.init, string.init, size_t.init)))) @@ -584,8 +597,10 @@ T errnoEnforce(T, string file = __FILE__, size_t line = __LINE__) return value; } - +// @@@DEPRECATED_2.084@@@ /++ + $(RED Deprecated. Please use $(LREF enforce) instead. This function will be removed 2.084.) + If $(D !value) is $(D false), $(D value) is returned. Otherwise, $(D new E(msg, file, line)) is thrown. Or if $(D E) doesn't take a message and can be constructed with $(D new E(file, line)), then @@ -600,6 +615,7 @@ T errnoEnforce(T, string file = __FILE__, size_t line = __LINE__) enforceEx!DataCorruptionException(line.length); -------------------- +/ +//deprecated("Please use enforce instead") template enforceEx(E : Throwable) if (is(typeof(new E("", string.init, size_t.init)))) { @@ -611,7 +627,8 @@ if (is(typeof(new E("", string.init, size_t.init)))) } } -/++ Ditto +/ +/+ Ditto +/ +//deprecated("Please use enforce instead") template enforceEx(E : Throwable) if (is(typeof(new E(string.init, size_t.init))) && !is(typeof(new E("", string.init, size_t.init)))) { @@ -623,6 +640,7 @@ if (is(typeof(new E(string.init, size_t.init))) && !is(typeof(new E("", string.i } } +//deprecated @system unittest { import core.exception : OutOfMemoryError; @@ -666,6 +684,7 @@ if (is(typeof(new E(string.init, size_t.init))) && !is(typeof(new E("", string.i static assert(!is(typeof(enforceEx!int(true)))); } +//deprecated @safe unittest { alias enf = enforceEx!Exception; diff --git a/std/format.d b/std/format.d index 18e5c74ea..2cfba740f 100644 --- a/std/format.d +++ b/std/format.d @@ -82,7 +82,7 @@ class FormatException : Exception } } -private alias enforceFmt = enforceEx!FormatException; +private alias enforceFmt = enforce!FormatException; /********************************************************************** diff --git a/std/json.d b/std/json.d index 0ef23a1c5..2da383af3 100644 --- a/std/json.d +++ b/std/json.d @@ -101,7 +101,7 @@ JSON value node */ struct JSONValue { - import std.exception : enforceEx, enforce; + import std.exception : enforce; union Store { @@ -472,7 +472,7 @@ struct JSONValue ref inout(JSONValue) opIndex(size_t i) inout pure @safe { auto a = this.arrayNoRef; - enforceEx!JSONException(i < a.length, + enforce!JSONException(i < a.length, "JSONValue array index is out of range"); return a[i]; } @@ -512,7 +512,7 @@ struct JSONValue */ void opIndexAssign(T)(auto ref T value, string key) pure { - enforceEx!JSONException(type == JSON_TYPE.OBJECT || type == JSON_TYPE.NULL, + enforce!JSONException(type == JSON_TYPE.OBJECT || type == JSON_TYPE.NULL, "JSONValue must be object or null"); JSONValue[string] aa = null; if (type == JSON_TYPE.OBJECT) @@ -534,7 +534,7 @@ struct JSONValue void opIndexAssign(T)(T arg, size_t i) pure { auto a = this.arrayNoRef; - enforceEx!JSONException(i < a.length, + enforce!JSONException(i < a.length, "JSONValue array index is out of range"); a[i] = arg; this.array = a; diff --git a/std/process.d b/std/process.d index 23b334444..e1d4fd801 100644 --- a/std/process.d +++ b/std/process.d @@ -1507,8 +1507,8 @@ private: version (Posix) int performWait(bool block) @trusted { - import std.exception : enforceEx; - enforceEx!ProcessException(owned, "Can't wait on a detached process"); + import std.exception : enforce; + enforce!ProcessException(owned, "Can't wait on a detached process"); if (_processID == terminated) return _exitCode; int exitCode; while (true) @@ -1557,8 +1557,8 @@ private: { int performWait(bool block) @trusted { - import std.exception : enforceEx; - enforceEx!ProcessException(owned, "Can't wait on a detached process"); + import std.exception : enforce; + enforce!ProcessException(owned, "Can't wait on a detached process"); if (_processID == terminated) return _exitCode; assert(_handle != INVALID_HANDLE_VALUE); if (block) @@ -1803,8 +1803,8 @@ void kill(Pid pid) /// ditto void kill(Pid pid, int codeOrSignal) { - import std.exception : enforceEx; - enforceEx!ProcessException(pid.owned, "Can't kill detached process"); + import std.exception : enforce; + enforce!ProcessException(pid.owned, "Can't kill detached process"); version (Windows) { if (codeOrSignal < 0) throw new ProcessException("Invalid exit code");