1 /*
2     Asserte functions. This file is part of BioD.
3     Copyright (C) 2018 Pjotr Prins <pjotr.prins@thebird.nl>
4 */
5 
6 // This code is based on 'exception.d' in D's Phobos
7 
8 module bio.core.utils.exception;
9 
10 import std.exception;
11 import std.traits;
12 
13 /++
14     Asserts that the given value is true, but unlike standard assert
15     throws an exception on error.
16 
17     Params:
18         value = The value to test.
19         ex = The exception to throw if the value evaluates to false.
20 
21     Returns: $(D value), if `cast(bool)value` is true. Otherwise, $(D ex) is
22     thrown.
23 
24     Example:
25     --------------------
26     auto f = asserte(fopen("data.txt"));
27     auto line = readln(f);
28     asserte(line.length, new IOException); // expect a non-empty line
29     --------------------
30  +/
31 T asserte(T)(T value, lazy Throwable ex)
32 {
33   version(assert) {
34     if (!value) throw ex();
35   }
36   return value;
37 }
38 
39 T asserte(T)(T value, lazy string msg = "asserte failed")
40 {
41   version(assert) {
42     if (!value) throw new Exception(msg);
43   }
44   return value;
45 }
46 
47 /++
48     Asserts that the given value is true, but unlike standard assert
49     throws an exception on error.
50 
51     Params:
52         value = The value to test.
53         dg = The delegate to be called if the value evaluates to false.
54         file = The source file of the caller.
55         line = The line number of the caller.
56 
57     Returns: $(D value), if `cast(bool)value` is true. Otherwise, the given
58     delegate is called.
59 
60     The safety and purity of this function are inferred from $(D Dg)'s safety
61     and purity.
62  +/
63 T asserte(T, Dg, string file = __FILE__, size_t line = __LINE__)
64     (T value, scope Dg dg)
65     if (isSomeFunction!Dg && is(typeof( dg() )) &&
66         is(typeof({ if (!value) {} })))
67 {
68   version(assert) {
69     if (!value) dg();
70   }
71   return value;
72 }