emplace, scope, enforce [Was: Re: Manual...]

Dmitry Olshansky dmitry.olsh at gmail.com
Wed Jul 21 13:35:29 PDT 2010


On 21.07.2010 23:16, Andrei Alexandrescu wrote:
> I compiled and ran the tests myself with -O -release -inline and got 
> 1.95s for Dmitry's implementation and 1.55s for bearophile's.
>
> I optimized Dmitry's implementation in two ways: I replaced the call 
> to clear() with a straight call to the destructor and added = void in 
> two places to avoid double initialization. I got 1.11s, which 
> significantly undercuts the implementation using scope.
>
> Here's the code I used for testing:
>
> struct Scoped(T) {
>     ubyte[__traits(classInstanceSize, Test)] _payload = void;
>     T getPayload(){
>         return cast(T)(_payload.ptr);
>     }
>     alias getPayload this;
>
>     static Scoped opCall(Args...)(Args args)
>     if (is(typeof(T.init.__ctor(args)))) {
>         // TODO: should also provide decent error message
>         Scoped!T s = void;
>         emplace!T(cast(void[])s._payload,args);
>         return s;
>     }
>     ~this() {
>         static if (is(typeof(getPayload.__dtor()))) {
>             getPayload.__dtor();
>         }
>     }
> }
Thanks for kind feedback (and showing some optimization tricks).  Also 
this implementation still has issues with it: it calls dtor twice. Not a 
good trait for RAII technique ! :)
Since it's now considered useful I feel myself obliged to enhance and 
correct it. Sadly enough I still haven't managed to apply an inner 
template trick.
Here's the end result along with a simple unittest:

struct Scoped(T){
     ubyte[__traits(classInstanceSize, T)] _scopedPayload = void;
     T getScopedPayload(){
         return cast(T)(_scopedPayload.ptr);
     }
     alias getScopedPayload this;
     this(Args...)(Args args){
         static if (!is(typeof(getScopedPayload.__ctor(args)))) {
             static assert(false,"Scoped: wrong arguments passed to ctor");
         }else {
             emplace!T(cast(void[])_scopedPayload,args);
         }
      }
     ~this() {
         static if (is(typeof(getScopedPayload.__dtor()))) {
             getScopedPayload.__dtor();
         }
     }
}
//also track down destruction/construction
class A{
     this(int a){ writeln("A with ",a); }
     this(real r){ writeln("A with ",r); }
     ~this(){ writeln("A destroyed");  }
}

unittest{
     {
         auto a = Scoped!A(42);
     }
     {
         auto b = Scoped!A(5.5);
     }
}

-- 
Dmitry Olshansky



More information about the Digitalmars-d mailing list