Metaprogramming work around
Kenji Hara
k.hara.pg at gmail.com
Tue Apr 17 03:29:54 PDT 2012
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
More information about the Digitalmars-d-learn
mailing list