www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - A small template to simplify COM-interface implementation

reply eao197 <eao197 intervale.ru> writes:
	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 implementation=
s.
    alias FullInheritance!(Base, T).AllTypes Inheritance;

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

             "auto b =3D " ~ Base.stringof ~ ".QueryInterface(riid, ppv)=
;\n"
             "if(S_OK =3D=3D b) return b;\n" ~
             ifs ~
             "{ *ppv =3D 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
Mar 18 2008
next sibling parent lutger <lutger.blijdestijn gmail.com> writes:
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. 
Mar 18 2008
prev sibling parent reply "Anders Bergh" <anders1 gmail.com> writes:
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
Mar 20 2008
parent eao197 <eao197 intervale.ru> writes:
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
Mar 21 2008