Thread overview
A small template to simplify COM-interface implementation
Mar 18, 2008
eao197
Mar 18, 2008
lutger
Mar 21, 2008
Anders Bergh
Mar 21, 2008
eao197
March 18, 2008
	Hi!

The following template is a result of my discussion about D's variadic templates and C++0x variadic templates on a Russian programmer's forum (rsdn.ru). One of my opponents showed an example of Boost.MPL usage in COM-objects implementation. Something like:

class Demo : public coclass< mpl::vector< IClassFactory, IDataObject, /*...*/ > > {
  /* QueryInterface, AddRef and Release is already implemented here. */
};

And I had been asked to repeat something like this in D. There is the result of my attempt:

import std.c.windows.windows;
import std.c.windows.com;

/// Main template.
template ComSupport(Base, T...) {
   template FullInheritance(A...) {
      alias A AllTypes;
   }
   /// A helper for declaring inheritance and interfaces implementations.
   alias FullInheritance!(Base, T).AllTypes Inheritance;

   /// CTFE function for QueryInterface implementation.
   /// Should be used inside mixin().
   char[] makeQueryInterface() {
      char[] ifs;
      foreach(t; T) {
         ifs ~= "if(IID_" ~ t.stringof ~ " == *riid)\n"
            "*ppv = cast(void*)cast(" ~ t.stringof ~ ")this;\n"
            "else ";
      }
      return "HRESULT QueryIterface(const(IID)* riid, void ** ppv) {\n"
            "auto b = " ~ Base.stringof ~ ".QueryInterface(riid, ppv);\n"
            "if(S_OK == b) return b;\n" ~
            ifs ~
            "{ *ppv = null; return E_NOINTERFACE; }\n"
            "AddRef();\n"
            "return S_OK;\n"
            "}\n";
   }
}

/// Alias to remove duplications of long template name.
alias ComSupport!(ComObject, IClassFactory, IEnumString) DemoDetails;

class Demo : DemoDetails.Inheritance {
   mixin( DemoDetails.makeQueryInterface );

   /* ...Implementations of IClassFactory and IEnumString methods... */
}

-- 
Regards,
Yauheni Akhotnikau
March 18, 2008
That's a great, small and useful example of what D metaprogramming can buy
you!
It would be interesting to compare it with the C++ implementation.

March 21, 2008
On Tue, Mar 18, 2008 at 4:08 PM, eao197 <eao197@intervale.ru> wrote:
>         Hi!
>
>  The following template is a result of my discussion about D's variadic
>  templates and C++0x variadic templates on a Russian programmer's forum
>  (rsdn.ru). One of my opponents showed an example of Boost.MPL usage in
>  COM-objects implementation. Something like:

Hi,

I spotted a typo in your code:

      return "HRESULT QueryIterface(const(IID)* riid, void ** ppv) {\n"

Probably meant QueryInterface there.

Anders
March 21, 2008
On Fri, 21 Mar 2008 08:33:26 +0300, Anders Bergh <anders1@gmail.com> wrote:

> On Tue, Mar 18, 2008 at 4:08 PM, eao197 <eao197@intervale.ru> wrote:
>>         Hi!
>>
>>  The following template is a result of my discussion about D's variadic
>>  templates and C++0x variadic templates on a Russian programmer's forum
>>  (rsdn.ru). One of my opponents showed an example of Boost.MPL usage in
>>  COM-objects implementation. Something like:
>
> Hi,
>
> I spotted a typo in your code:
>
>       return "HRESULT QueryIterface(const(IID)* riid, void ** ppv) {\n"
>
> Probably meant QueryInterface there.
>
> Anders

Yes it is a type, thank you.

-- 
Regards,
Yauheni Akhotnikau