@@ -355,31 +355,36 @@ void assertThrown(T : Throwable = Exception, E)
355
355
356
356
/+ +
357
357
Enforces that the given value is true.
358
+ If the given value is false, an exception is thrown.
359
+ The
360
+ $(UL
361
+ $(LI `msg` - error message as a `string`)
362
+ $(LI `dg` - custom delegate that return a string and is only called if an exception occurred)
363
+ $(LI `ex` - custom exception to be thrown. It is `lazy` and is only created if an exception occurred)
364
+ )
358
365
359
366
Params:
360
367
value = The value to test.
361
- E = Exception type to throw if the value evalues to false.
368
+ E = Exception type to throw if the value evaluates to false.
362
369
msg = The error message to put in the exception if it is thrown.
370
+ dg = The delegate to be called if the value evaluates to false.
371
+ ex = The exception to throw if the value evaluates to false.
363
372
file = The source file of the caller.
364
373
line = The line number of the caller.
365
374
366
- Returns: $(D value) , if `cast(bool) value` is true. Otherwise,
367
- $(D new Exception(msg)) is thrown.
375
+ Returns: ` value` , if `cast(bool) value` is true. Otherwise,
376
+ depending on the chosen overload, ` new Exception(msg)`, `dg()` or `ex` is thrown.
368
377
369
378
Note:
370
- $(D enforce) is used to throw exceptions and is therefore intended to
379
+ ` enforce` is used to throw exceptions and is therefore intended to
371
380
aid in error handling. It is $(I not) intended for verifying the logic
372
381
of your program. That is what $(D assert) is for. Also, do not use
373
- $(D enforce) inside of contracts (i.e. inside of $(D in) and $(D out)
382
+ ` enforce` inside of contracts (i.e. inside of `in` and ` out`
374
383
blocks and $(D invariant)s), because contracts are compiled out when
375
384
compiling with $(I -release).
376
385
377
- Example:
378
- --------------------
379
- auto f = enforce(fopen("data.txt"));
380
- auto line = readln(f);
381
- enforce(line.length, "Expected a non-empty line.");
382
- --------------------
386
+ If a delegate is passed, the safety and purity of this function are inferred
387
+ from `Dg`'s safety and purity.
383
388
+/
384
389
T enforce (E : Throwable = Exception , T)(T value, lazy const (char )[] msg = null ,
385
390
string file = __FILE__ , size_t line = __LINE__ )
@@ -389,21 +394,7 @@ if (is(typeof({ if (!value) {} })))
389
394
return value;
390
395
}
391
396
392
- /+ +
393
- Enforces that the given value is true.
394
-
395
- Params:
396
- value = The value to test.
397
- dg = The delegate to be called if the value evaluates to false.
398
- file = The source file of the caller.
399
- line = The line number of the caller.
400
-
401
- Returns: $(D value), if `cast(bool) value` is true. Otherwise, the given
402
- delegate is called.
403
-
404
- The safety and purity of this function are inferred from $(D Dg)'s safety
405
- and purity.
406
- +/
397
+ // / ditto
407
398
T enforce (T, Dg, string file = __FILE__ , size_t line = __LINE__ )
408
399
(T value, scope Dg dg)
409
400
if (isSomeFunction! Dg && is (typeof ( dg() )) &&
@@ -413,23 +404,40 @@ if (isSomeFunction!Dg && is(typeof( dg() )) &&
413
404
return value;
414
405
}
415
406
416
- private void bailOut (E : Throwable = Exception )(string file, size_t line, in char [] msg)
407
+ // / ditto
408
+ T enforce (T)(T value, lazy Throwable ex)
417
409
{
418
- static if (is (typeof (new E(string .init, string .init, size_t .init))))
419
- {
420
- throw new E(msg ? msg.idup : " Enforcement failed" , file, line);
421
- }
422
- else static if (is (typeof (new E(string .init, size_t .init))))
423
- {
424
- throw new E(file, line);
425
- }
426
- else
427
- {
428
- static assert (0 , " Expected this(string, string, size_t) or this(string, size_t)" ~
429
- " constructor for " ~ __traits(identifier, E));
430
- }
410
+ if (! value) throw ex();
411
+ return value;
412
+ }
413
+
414
+ // /
415
+ unittest
416
+ {
417
+ import core.stdc.stdlib : malloc, free;
418
+ import std.conv : ConvException, to;
419
+
420
+ // use enforce like assert
421
+ int a = 3 ;
422
+ enforce(a > 2 , " a needs to be higher than 2." );
423
+
424
+ // enforce can throw a custom exception
425
+ enforce! ConvException(a > 2 , " a needs to be higher than 2." );
426
+
427
+ // enforce will return it's input
428
+ enum size = 42 ;
429
+ auto memory = enforce(malloc(size), " malloc failed" )[0 .. size];
430
+ scope (exit) free (memory.ptr);
431
+ }
432
+
433
+ // /
434
+ @safe unittest
435
+ {
436
+ assertNotThrown(enforce(true , new Exception (" this should not be thrown" )));
437
+ assertThrown(enforce(false , new Exception (" this should be thrown" )));
431
438
}
432
439
440
+ // /
433
441
@safe unittest
434
442
{
435
443
assert (enforce(123 ) == 123 );
@@ -447,6 +455,23 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
447
455
}
448
456
}
449
457
458
+ private void bailOut (E : Throwable = Exception )(string file, size_t line, in char [] msg)
459
+ {
460
+ static if (is (typeof (new E(string .init, string .init, size_t .init))))
461
+ {
462
+ throw new E(msg ? msg.idup : " Enforcement failed" , file, line);
463
+ }
464
+ else static if (is (typeof (new E(string .init, size_t .init))))
465
+ {
466
+ throw new E(file, line);
467
+ }
468
+ else
469
+ {
470
+ static assert (0 , " Expected this(string, string, size_t) or this(string, size_t)" ~
471
+ " constructor for " ~ __traits(identifier, E));
472
+ }
473
+ }
474
+
450
475
@safe unittest
451
476
{
452
477
// Issue 10510
@@ -532,35 +557,6 @@ private void bailOut(E : Throwable = Exception)(string file, size_t line, in cha
532
557
static assert (! __traits(compiles, { enforce! E(false ); }));
533
558
}
534
559
535
- /+ +
536
- Enforces that the given value is true.
537
-
538
- Params:
539
- value = The value to test.
540
- ex = The exception to throw if the value evaluates to false.
541
-
542
- Returns: $(D value), if `cast(bool) value` is true. Otherwise, $(D ex) is
543
- thrown.
544
-
545
- Example:
546
- --------------------
547
- auto f = enforce(fopen("data.txt"));
548
- auto line = readln(f);
549
- enforce(line.length, new IOException); // expect a non-empty line
550
- --------------------
551
- +/
552
- T enforce (T)(T value, lazy Throwable ex)
553
- {
554
- if (! value) throw ex();
555
- return value;
556
- }
557
-
558
- @safe unittest
559
- {
560
- assertNotThrown(enforce(true , new Exception (" this should not be thrown" )));
561
- assertThrown(enforce(false , new Exception (" this should be thrown" )));
562
- }
563
-
564
560
/+ +
565
561
Enforces that the given value is true, throwing an `ErrnoException` if it
566
562
is not.
0 commit comments