C++ Macro to D mixin template, a solution ?

BLS nanali at nospam-wanadoo.fr
Fri Sep 21 02:32:21 PDT 2007


Regan Heath schrieb:
> Henning Hasemann wrote:
>>
>> Does this help you?
>>
>>
>> import std.stdio;
>>
>> template MessageMap(Mappings ...) {
>>   void newMsgProc(uint uID) {
>>      foreach(mapping; Mappings) {
>>        if(mapping.matches(uID))
>>          mapping.executeAction();
>>      }
>>   }
>> }
>>
>> struct OnClose(alias fn) {
>>   alias fn executeAction;
>>   static bool matches(uint uid) { return uid == 5; }
>> }
>>
>> struct OnRange(uint a, uint b, alias fn) {
>>   alias fn executeAction;
>>   static bool matches(uint uid) { return uid >= a && uid <= b; }
>> }
>>
>>
>> class Foo {
>>   void foo() {
>>     writefln("foo called");
>>   }
>>   void bar() {
>>     writefln("bar called");
>>   }
>>
>>   mixin MessageMap!(
>>     OnClose!(foo),
>>     OnRange!(1, 3, bar)
>>   );
>>
>> }
>>
>> void main() {
>>   auto f = new Foo;
>>   f.newMsgProc(5);
>>   f.newMsgProc(2);
>> }
>>
> 
> Genius! :)
> 
> See BLS I told you someone else would come up with something.  Sadly my 
> mind doesn't operate in a very templatey fashion .. yet .. I need more 
> practice.
> 
> Regan
Indeed smart code. Many Thanks Henning ! But it is not what I need.

I really hope that I can use mixins (NOT template mixins) let me show you :

//A C++ fragment from the MSG_MAP macro
#define ON_WM_CLOSE(vfunc)\
     if (uID == WM_CLOSE) \
     { \
         lResult =vfunc(); \
         return lResult; \
     }

// becomes in D
template ON_WM_CLOSE(char[] vfunc)
{
const char[] ON_WM_CLOSE = "if (uID == WM_CLOSE) { lResult = " ~ vfunc ~ 
"; return lResult; }";
}

//use case :
mixin(ON_WM_CLOSE!("onClose()"))

Let's have a look at :
1) The original C++ class

class CWin : public CMsg
{

public:

     virtual BOOL OnClose()
     {
         return TRUE;
     }


     BEGIN_MSG_MAP()
         ON_WM_CLOSE(OnClose)
     END_MSG_MAP_DEFAULT()
]
--------------------------------------------
which expands to
class CWin : public CMsg
{

public:
     virtual BOOL OnClose()
     {
         return TRUE;
     }


// BEGIN_MSG_MAP
virtual BOOL NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, 
LPARAM lParam,LRESULT& lResult)
{

//ON_WM_CLOSE
if (uID == WM_CLOSE)
{
     lResult =onClose();  //     CALL onClose !! AND SET lResult
     return lResult;
}
//END_MSG_MAP_DEFAULT()
// whatever
}

2) The D code
class CWin : CMsg
{
public:
     bool onClose()
     {
         return true;
     }
     // C++ BEGIN_MSG_MAP() becomes
     override bool NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM 
lParam, ref LRESULT lResult)
     {
         mixin(ON_WM_CLOSE!("onClose()")) //C++ ON_WM_CLOSE(OnClose)
     }
}
---------------------------------------------------------------------------
//Again the D ON_WM_CLOSE mixin

template ON_WM_CLOSE(char[] vfunc)
{
const char[] ON_WM_CLOSE = "if (uID == WM_CLOSE) { lResult = " ~ vfunc ~ 
"; return lResult; }";
}

Comments ?
Is it legal to use mixins this way ?
http://www.digitalmars.com/d/mixin.html

It seems that C++ macros are just text substitutions. I was really 
confused about the "lResult = vFunc() stuff within the ON_WM_CLOSE 
#define. Dunno much about C++ but the more I learn the more I hate it. :-)

Bjoern


More information about the Digitalmars-d-learn mailing list