Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 20, 2007 C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Please have a look on my translation. Problems are 1) porting C++ macros 2) use of delegates within template mixins /* THE C++ Stuff , a fragment class CMsg { public: virtual BOOL NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam,LRESULT lResult) { return FALSE; } }; #define BEGIN_MSG_MAP() \ public: \ virtual BOOL NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam,LRESULT& lResult) \ { \ #define ON_WM_CLOSE(vfunc)\ if (uID == WM_CLOSE) \ { \ lResult =vfunc(); \ return lResult; \ } // and so on ............ class CWin : public CMsg { public: virtual BOOL OnClose() { return TRUE; } BEGIN_MSG_MAP() ON_WM_CLOSE(OnClose) ON_WM_DESTROY(OnDestroy) ON_WM_NCDESTROY(OnNcDestroy) END_MSG_MAP_DEFAULT() } EOF C++ stuff */ THE D port module dgt.win; // All Window's messages will be mapped in this function class CMsg { public: bool NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam,LRESULT lResult) { return false; } } template ON_WM_CLOSE(D) (D delegate() dg) { if (uID == WM_CLOSE) { lResult = dg(); return lResult; } } template ON_MESSAGE_RANGE(M1, M2, D) (M1 MsgF, M2 MsgL, D delegate(...) dg ) { if(uID >= MsgF && uID <= MsgL) { lResult = dg(uID, wParam, lParam); return true; } } // Window class CWin : CMsg { public: bool onClose() { return true; } override bool NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam, ref LRESULT lResult) { mixin ON_WM_CLOSE!(&CWin.OnClose); } } -------------------- Okay, I've ported it as good as I can... the available tutorials are not very helpfull in this case. So please help Bjoern |
September 20, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLS | BLS wrote: > template ON_WM_CLOSE(D) (D delegate() dg) > { > if (uID == WM_CLOSE) > { > lResult = dg(); > return lResult; > } > } This seems to be mixing template syntax (using "template") with template function syntax (using "(D)(D delegate() dg)". I don't think you want a template function so, rather something like: template ON_WM_CLOSE(alias D) { if (uID == WM_CLOSE) { lResult = D(); return lResult; } } (see the duffs_device example here http://www.digitalmars.com/d/template-mixin.html) However this wont work because a template body can only contain 'declarations' which means; Declaration: typedef Decl alias Decl Decl Decl: StorageClasses Decl BasicType Declarators ; BasicType Declarator FunctionBody AutoDeclaration So, you can put typedefs, aliases, variables and functions in a template, but, what you can't do is put an "if" statement in there. So, templates and mixins in D just can't achieve the same effect as the C/C++ define macro can. The planned/propsed D macro feature however, that should do what you want I reckon. Regan |
September 20, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath schrieb:
> BLS wrote:
>> template ON_WM_CLOSE(D) (D delegate() dg)
>> {
>> if (uID == WM_CLOSE)
>> {
>> lResult = dg();
>> return lResult;
>> }
>> }
>
> This seems to be mixing template syntax (using "template") with template function syntax (using "(D)(D delegate() dg)". I don't think you want a template function so, rather something like:
>
> template ON_WM_CLOSE(alias D)
> {
> if (uID == WM_CLOSE)
> {
> lResult = D();
> return lResult;
> }
> }
>
> (see the duffs_device example here http://www.digitalmars.com/d/template-mixin.html)
>
> However this wont work because a template body can only contain 'declarations' which means;
>
> Declaration:
> typedef Decl
> alias Decl
> Decl
>
> Decl:
> StorageClasses Decl
> BasicType Declarators ;
> BasicType Declarator FunctionBody
> AutoDeclaration
>
> So, you can put typedefs, aliases, variables and functions in a template, but, what you can't do is put an "if" statement in there. So, templates and mixins in D just can't achieve the same effect as the C/C++ define macro can.
>
> The planned/propsed D macro feature however, that should do what you want I reckon.
>
> Regan
NOOOOOOOOOOoooooooo, Shi* !
So I guess
template TFoo(D)
{
alias D delegate() dg
}
is also not allowed...
Hell, there should be a way to translate such a simple C++ macro without without having so much trouble!!!
I can not imagine that it is impossible. Probabely there exist a workaround. have to look at the Tango Signal/Slot implementation.. Imean they 've managed it.
However, thanks Regan
Bjoern
|
September 20, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLS | BLS wrote: > Regan Heath schrieb: >> BLS wrote: >>> template ON_WM_CLOSE(D) (D delegate() dg) >>> { >>> if (uID == WM_CLOSE) >>> { >>> lResult = dg(); >>> return lResult; >>> } >>> } >> >> This seems to be mixing template syntax (using "template") with template function syntax (using "(D)(D delegate() dg)". I don't think you want a template function so, rather something like: >> >> template ON_WM_CLOSE(alias D) >> { >> if (uID == WM_CLOSE) >> { >> lResult = D(); >> return lResult; >> } >> } >> >> (see the duffs_device example here http://www.digitalmars.com/d/template-mixin.html) >> >> However this wont work because a template body can only contain 'declarations' which means; >> >> Declaration: >> typedef Decl >> alias Decl >> Decl >> >> Decl: >> StorageClasses Decl >> BasicType Declarators ; >> BasicType Declarator FunctionBody >> AutoDeclaration >> >> So, you can put typedefs, aliases, variables and functions in a template, but, what you can't do is put an "if" statement in there. So, templates and mixins in D just can't achieve the same effect as the C/C++ define macro can. >> >> The planned/propsed D macro feature however, that should do what you want I reckon. >> >> Regan > > NOOOOOOOOOOoooooooo, Shi* ! > So I guess > template TFoo(D) > { > alias D delegate() dg > } > > is also not allowed... This one is allowed, 'alias' is a declaration. > Hell, there should be a way to translate such a simple C++ macro without without having so much trouble!!! The proposed macro feature should be able to do it. > I can not imagine that it is impossible. Probabely there exist a > workaround. have to look at the Tango Signal/Slot implementation.. Imean > they 've managed it. Good idea. I wonder how they're doing it. It's entirely possible that I'm getting something wrong here, I'm no template master. Regan |
September 20, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath schrieb: > BLS wrote: >> Regan Heath schrieb: >>> BLS wrote: >>>> template ON_WM_CLOSE(D) (D delegate() dg) >>>> { >>>> if (uID == WM_CLOSE) >>>> { >>>> lResult = dg(); >>>> return lResult; >>>> } >>>> } >>> >>> This seems to be mixing template syntax (using "template") with template function syntax (using "(D)(D delegate() dg)". I don't think you want a template function so, rather something like: >>> >>> template ON_WM_CLOSE(alias D) >>> { >>> if (uID == WM_CLOSE) >>> { >>> lResult = D(); >>> return lResult; >>> } >>> } >>> >>> (see the duffs_device example here http://www.digitalmars.com/d/template-mixin.html) >>> >>> However this wont work because a template body can only contain 'declarations' which means; >>> >>> Declaration: >>> typedef Decl >>> alias Decl >>> Decl >>> >>> Decl: >>> StorageClasses Decl >>> BasicType Declarators ; >>> BasicType Declarator FunctionBody >>> AutoDeclaration >>> >>> So, you can put typedefs, aliases, variables and functions in a template, but, what you can't do is put an "if" statement in there. So, templates and mixins in D just can't achieve the same effect as the C/C++ define macro can. >>> >>> The planned/propsed D macro feature however, that should do what you want I reckon. >>> >>> Regan >> >> NOOOOOOOOOOoooooooo, Shi* ! >> So I guess >> template TFoo(D) >> { >> alias D delegate() dg >> } >> >> is also not allowed... > > This one is allowed, 'alias' is a declaration. > // Means template ON_WM_CLOSE(D) { alias D delegate() dg; if (uID == WM_CLOSE) { lResult = dg(); return lResult; } } // is legal ? >> Hell, there should be a way to translate such a simple C++ macro without without having so much trouble!!! > > The proposed macro feature should be able to do it. > I am not willing to wait another year. My IDE proj. is allready a never ending story, and now I have to create a GUI for it... >> I can not imagine that it is impossible. Probabely there exist a >> workaround. have to look at the Tango Signal/Slot implementation.. Imean >> they 've managed it. > > Good idea. I wonder how they're doing it. It's entirely possible that I'm getting something wrong here, I'm no template master. > > Regan Well I think I'll ask the Tango folks whether (and how) I can use the Signal/Slot stuff INSTEAD. Bjoern |
September 20, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLS | BLS wrote: > // Means > template ON_WM_CLOSE(D) > { > alias D delegate() dg; > if (uID == WM_CLOSE) > { > lResult = dg(); > return lResult; > } > } > // is legal ? Nope. Only the alias line is legal, the rest is illegal because "if" is not a "declaration", it is a "statement". >>> Hell, there should be a way to translate such a simple C++ macro without without having so much trouble!!! >> >> The proposed macro feature should be able to do it. >> > I am not willing to wait another year. My IDE proj. is allready a never ending story, and now I have to create a GUI for it... I'm hoping it arrives faster than that, but I guess you can't really bank on it. Walters last foray into the forums was about 'const' so I expect he's working on that as a top priority, but I could be wrong. >>> I can not imagine that it is impossible. Probabely there exist a >>> workaround. have to look at the Tango Signal/Slot implementation.. Imean >>> they 've managed it. >> >> Good idea. I wonder how they're doing it. It's entirely possible that I'm getting something wrong here, I'm no template master. >> >> Regan > > Well I think I'll ask the Tango folks whether (and how) I can use the Signal/Slot stuff INSTEAD. I might have a peek in there myself, out of interest :) Regan |
September 20, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLS |
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);
}
--
GPG Public Key: http://keyserver.ganneff.de:11371/pks/lookup?op=get&search=0xDDD6D36D41911851 Fingerprint: 344F 4072 F038 BB9E B35D E6AB DDD6 D36D 4191 1851
|
September 21, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
Posted in reply to Henning Hasemann | 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
|
September 21, 2007 Re: C++ Macro to D mixin template, a solution ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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 |
September 21, 2007 Re: C++ Macro to D mixin template, delegates Please help | ||||
---|---|---|---|---|
| ||||
BLS wrote:
> Regan Heath schrieb:
>> Henning Hasemann wrote:
I don't understand. What doesn't the code Henning posted do, that you need it to do??
class Foo {
void foo() {
writefln("foo called");
}
void bar() {
writefln("bar called");
}
mixin MessageMap!(
OnClose!(foo),
OnRange!(1, 3, bar)
);
}
expands to:
class Foo {
void foo() {
writefln("foo called");
}
void bar() {
writefln("bar called");
}
void newMsgProc(uint uID) { //expands just like "BEGIN_MSG_MAP"
foreach(mapping; Mappings) { //loops 2x
if(mapping.matches(uID)) //just like "if (uID == WM_CLOSE)"
mapping.executeAction(); //just like "vfunc();"
}
}
}
Change MessageMap to expand to the function fignature you want, i.e.
template MessageMap(Mappings ...) {
override BOOL NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam, ref LRESULT lResult) {
foreach(mapping; Mappings) {
if(mapping.matches(uID))
mapping.executeAction();
}
}
}
Change MessageMap to return the result of the mapping.executeAction just like "return lResult;" in the original C++.
template MessageMap(Mappings ...) {
override BOOL NewMsgProc(HWND hWnd, UINT uID, WPARAM wParam, LPARAM lParam, ref LRESULT lResult) {
foreach(mapping; Mappings) {
if(mapping.matches(uID)) {
lResult = mapping.executeAction();
return cast(BOOL)lResult;
}
}
}
}
I think it's ok to use mixins as you're desribing, but why do you need to do it that way?
Regan
|
Copyright © 1999-2021 by the D Language Foundation