Decision on container design

Simen kjaeraas simen.kjaras at gmail.com
Tue Feb 1 09:46:12 PST 2011


Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:

> I do something similar with RefCounted. There are problems - you need to  
> know in advance which functions you can implement on a null container  
> (empty and length are obvious candidates, but there could be others).

Static functions can safely be called. Hence, this template:


import std.traits;

template isStaticFunc(T, string fn) {
     enum isStaticFunc = is(typeof({
         mixin("alias T."~fn~" func;");
         ParameterTypeTuple!func args;
         mixin("T."~fn~"(args);");
     }));
}


Now, Ref can look like this:


struct Ref(Impl) {
     private Impl* _impl;
     @property ref Impl impl() {
         return *(_impl = (_impl ? _impl : new Impl));
     }
     //alias impl this; // Apparently, alias this takes precedence over  
opDispatch, so
                        // using both doesn't work. Well, unless you put  
opDispatch in Impl.

     auto opDispatch(string name, T...)(T args) if ( isStaticFunc!(Impl,  
name)) {
         mixin("return impl."~name~"(_impl,args);");
     }
}

struct ExampleImpl {
     static int length(ExampleImpl* that) {
         return that ? that.actualLength : 0;
     }
     int actualLength( ) {
         return 42;
     }
}


import std.stdio;

void main( ) {
     Ref!ExampleImpl a;

     writeln( a.length );
}


-- 
Simen


More information about the Digitalmars-d mailing list