digitalmars.D.learn - variadic mixin templates and other stuff
- Martin Drasar (58/58) Apr 20 2012 Hi,
- Timon Gehr (4/60) Apr 20 2012 Because if is a statement and not a declaration.
- Martin Drasar (25/37) Apr 20 2012 Ok.
- John Chapman (6/29) Apr 20 2012 Try this:
- Martin Drasar (8/39) Apr 21 2012 Hi John,
Hi,
I am migrating a C++ project to D and I have hit a roadblock that I hope
you might help me with.
My code is heavily inspired by the COM architecture, so I have naturally
take a look at std/c/windows/com.d, just to find out that it does not
contain all I need.
In the C++ code I have several interfaces and a class. The class
inherits from these interfaces, exposes some of them and it is possible
to get one interface from another using the QueryInterface function by
supplying correct GUID:
class C : IA, IB, IC
{
EXPOSE_INTERFACE(IA, IC);
...
}
where EXPOSE_INTERFACE is macro that expands to something like this:
void QueryInterface (IComponent** comp, GUID* guid)
{
...
if (guid == IAGuid) *comp = ...some casting
if (guid == IBGuid) *comp = ...some casting
...
}
So I was thinking that in D I could use mixin templates with variadic
arguments, so I tried something like that:
string interfaceGuid(string ifaceName)
{
return ifaceName ~ "Guid";
}
mixin template EXPOSE_INTERFACE(string ifaceName)
{
if (mixin(interfaceGuid(ifaceName)) == guid) { ... some casting }
}
mixin template EXPOSE_INTERFACES(T...)(T args)
{
void QueryInterface(ref IComponent comp, string guid)
{
foreach (arg; args)
{
mixin EXPOSE_INTERFACE!arg;
}
}
}
But I got this:
component.d(8): Declaration expected, not 'if'
component.d(15): no identifier for declarator args
component.d(15): semicolon expected, not ')'
component.d(15): Declaration expected, not ')'
component.d(19): unrecognized declaration
Then I got confused and realized that my D is as sharp as is my German -
studied it for some time, but still has a problem to order a bread in a
store...
My questions are following:
- can mixin templates be used this way?
- why are they complaining?
- is there a better way to do this other than reproducing C macros?
Thanks,
Martin
Apr 20 2012
On 04/20/2012 03:23 PM, Martin Drasar wrote:Hi, I am migrating a C++ project to D and I have hit a roadblock that I hope you might help me with. My code is heavily inspired by the COM architecture, so I have naturally take a look at std/c/windows/com.d, just to find out that it does not contain all I need. In the C++ code I have several interfaces and a class. The class inherits from these interfaces, exposes some of them and it is possible to get one interface from another using the QueryInterface function by supplying correct GUID: class C : IA, IB, IC { EXPOSE_INTERFACE(IA, IC); ... } where EXPOSE_INTERFACE is macro that expands to something like this: void QueryInterface (IComponent** comp, GUID* guid) { ... if (guid == IAGuid) *comp = ...some casting if (guid == IBGuid) *comp = ...some casting ... } So I was thinking that in D I could use mixin templates with variadic arguments, so I tried something like that: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACE(string ifaceName) { if (mixin(interfaceGuid(ifaceName)) == guid) { ... some casting } } mixin template EXPOSE_INTERFACES(T...)(T args) { void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args) { mixin EXPOSE_INTERFACE!arg; } } } But I got this: component.d(8): Declaration expected, not 'if' component.d(15): no identifier for declarator args component.d(15): semicolon expected, not ')' component.d(15): Declaration expected, not ')' component.d(19): unrecognized declaration Then I got confused and realized that my D is as sharp as is my German - studied it for some time, but still has a problem to order a bread in a store... My questions are following: - can mixin templates be used this way?They can only mixin declarations.- why are they complaining?Because if is a statement and not a declaration.- is there a better way to do this other than reproducing C macros?Inline EXPOSE_INTERFACE into EXPOSE_INTERFACES and it'll work.
Apr 20 2012
On 20.4.2012 16:09, Timon Gehr wrote: Thanks Timon for the answer.Ok.My questions are following: - can mixin templates be used this way?They can only mixin declarations.- why are they complaining?Because if is a statement and not a declaration.I tried but it still refuses to compile: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACES(T...)(T args) { void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args) { if (mixin(interfaceGuid(arg)) == guid) {} } } } component.d(6): members of template declaration expected component.d(6): Declaration expected, not '(' component.d(10): no identifier for declarator args component.d(10): semicolon expected, not ')' component.d(10): Declaration expected, not ')' I am compiling it with dmd v2.058. Martin- is there a better way to do this other than reproducing C macros?Inline EXPOSE_INTERFACE into EXPOSE_INTERFACES and it'll work.
Apr 20 2012
On Friday, 20 April 2012 at 14:57:03 UTC, Martin Drasar wrote:On 20.4.2012 16:09, Timon Gehr wrote: I tried but it still refuses to compile: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACES(T...)(T args)Try this: mixin template EXPOSE_INTERFACES(T...){ void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args)and this: foreach (arg; T){ if (mixin(interfaceGuid(arg)) == guid) {} } } } component.d(6): members of template declaration expected component.d(6): Declaration expected, not '(' component.d(10): no identifier for declarator args component.d(10): semicolon expected, not ')' component.d(10): Declaration expected, not ')' I am compiling it with dmd v2.058. MartinJohn
Apr 20 2012
On 20.4.2012 19:00, John Chapman wrote:On Friday, 20 April 2012 at 14:57:03 UTC, Martin Drasar wrote:Hi John, thanks very much. That did the trick. I am still wondering - why my previous code did not work? This is the syntax I have adopted from variadic functions in TDPL. Why does it work with functions and not mixin templates? Thanks, MartinOn 20.4.2012 16:09, Timon Gehr wrote: I tried but it still refuses to compile: string interfaceGuid(string ifaceName) { return ifaceName ~ "Guid"; } mixin template EXPOSE_INTERFACES(T...)(T args)Try this: mixin template EXPOSE_INTERFACES(T...){ void QueryInterface(ref IComponent comp, string guid) { foreach (arg; args)and this: foreach (arg; T){ if (mixin(interfaceGuid(arg)) == guid) {} } } }
Apr 21 2012








Martin Drasar <drasar ics.muni.cz>