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