On Tuesday, 17 April 2012 at 08:28:45 UTC, Erèbe wrote:
Hi,

I'm working on some metaprogramming code which implement a Factory and generate an enum from a list of string.

So here my questions :

1) The documentation say mixin templates could take as TemplateParameterList a "TemplateParameter , TemplateParameterList" but all my tried to instaciate this template failed lamentably.

mixin template Foo(T, R...)
{

   anotherTemplate!(T);
   Foo!(R);

}

mixin Foo!( string, string, string);

Is something wrong with variadic template and mixin, do i miss something ?


2) Below some code I writed and I wanted to know if you have some advice to improve it (Right maner to do it, TypeChecking, Safety, ...) <- variaidc arguments


The code is working is purpose is to create an enum of commands and to create a factory which returns me the command associated to a string.

Thanks !

===========================Code============================================
import std.stdio;
import std.traits;
import std.conv;


//Use to create the enums of every commands
mixin template enumGenerator( T... )
{

    template generate( T... )
    {
enum string value = T[0] ~ ", " ~ generate!( T[2..$] ).value;
    }

    template generate() { enum string value = "UNKNOW"; }


    //Here the creation of the enum
    mixin("enum Command { " ~ generate!(T).value ~ "};");

}

//Generate a function which return a command in regard of a string
mixin template factoryGenerator( T... )
{
    template generate( T... )
    {
        enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
                                ~ "return Command." ~ T[0] ~ ";"
                            ~ "else "
                                ~ generate!(T[2..$]).value;
    }

template generate() { enum string value = "return Command.UNKNOW;"; }

    //The function in question
    auto CommandFactory( string cmd )
    {
            mixin( generate!(T).value );
    }

}


mixin template IrcCommands( T... )
{

   mixin enumGenerator!( T );
   mixin factoryGenerator!( T );

}


void main()
{

                       /*Command*/     /*String associated*/
   mixin IrcCommands!( "Connected",    "001",
                       "NicknameUsed", "433",
                       "Message",      "PRIVMSG",
                       "UserLeaved",   "PART",
                       "UserJoined",   "JOIN",
                       "UserQuit",     "QUIT"

"UserQuit", "QUIT", // lack of comma

                       "Ping",         "PING" );

   writefln( to!string(CommandFactory("001")) );


}

You can debug templates with adding static assertions in some where, like:

mixin template enumGenerator( T... )
{
    template generate( T... )
    {
static assert(T.length%2==0 && is(typeof(T[0]) : string)); // check enum string value = T[0] ~ ", " ~ generate!( T[2..$] ).value;
    }
    //[snip]
}

mixin template factoryGenerator( T... )
{
    template generate( T... )
    {
static assert(T.length%2==0 && is(typeof(T[1]) : string)); // check
        enum string value = "if( cmd == \"" ~ T[1] ~ "\")"
                                ~ "return Command." ~ T[0] ~ ";"
                            ~ "else "
                                ~ generate!(T[2..$]).value;
    }
    //[snip]
}

Bye.

Kenji Hara

Reply via email to