assert() vs. enforce(), invariant() vs. ... ?

Artur Skawina art.08.09 at gmail.com
Thu Aug 29 07:21:05 PDT 2013


On 08/29/13 15:26, Jacob Carlborg wrote:
> On 2013-08-29 13:19, Joseph Rushton Wakeling wrote:
> 
>> So, I thought I'd throw the idea out there so that others can suggest
>> whether this is potentially useful or whether it's better/safer to
>> hand-code such checks on a function-by-function basis.

Hard-coded unconditional invariants does not seem very useful, and, as
Jacob points out, can be done by wrapping the type. That of course
creates a new type; if the checks are really supposed to be always-on,
then it isn't a problem. 

> You can quite easily create a wrapper for that.
> 
> struct EnforceWrapper (T)
> {
>     T t;
> 
>     auto opDispatch (string name, Args ...) (Args args)
>     {
>         // before code
>         mixin("auto result = " ~ name ~ "(args);");
>         // after code
>         return result;
>     }
> }
> 
> auto obj = EnforceWrapper!(Object)(new Object);
> obj.toString();

In order to handle ref-returns it would have to be more like

   struct EnforceWrapper(T) {
      T t;

      auto ref opDispatch(string M, Args...)(Args args) {
         {/*before code*/}         
         scope (exit) {/*after code*/}
         return mixin("t." ~ M ~ "(args)");
      }
   }

and need another two overloads for property/field getters and
setters. Handling ref-args would add more complexity, but in
many cases ignoring them or using auto-ref is enough.

artur


More information about the Digitalmars-d mailing list