A small template to simplify COM-interface implementation

eao197 eao197 at intervale.ru
Tue Mar 18 08:08:47 PDT 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


More information about the Digitalmars-d-announce mailing list