November 01, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | In article <dk7d63$2pfk$1@digitaldaemon.com>, Bruno Medeiros says... > >Tomás Rossi wrote: >> >> Suppose you have this: >> >> template GenericFunctions(T) >> { >> void doThis() {...} >> void doThat() {...} >> T getFoo() {...} >> void takeFoo(T t) {...} >> void yourSister() {...} >> void myCousin() {...} >> ...etc... >> } >> >> Would you alias one and all? >> Would you write a template with the func. name for everyone? >> Would you explicitly use GenericFunctions!(T).func()? >> >I think I would probably alias the GenericFunctions!(T) part once and use that. The with keyword can also be useful for specifying a template instantiation. /Oskar |
November 01, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oskar Linde | In article <dk7hfu$2sud$1@digitaldaemon.com>, Oskar Linde says... > >In article <dk7d63$2pfk$1@digitaldaemon.com>, Bruno Medeiros says... >> >>Tomás Rossi wrote: >>> >>> Suppose you have this: >>> >>> template GenericFunctions(T) >>> { >>> void doThis() {...} >>> void doThat() {...} >>> T getFoo() {...} >>> void takeFoo(T t) {...} >>> void yourSister() {...} >>> void myCousin() {...} >>> ...etc... >>> } >>> >>> Would you alias one and all? >>> Would you write a template with the func. name for everyone? >>> Would you explicitly use GenericFunctions!(T).func()? >>> >>I think I would probably alias the GenericFunctions!(T) part once and use that. > >The with keyword can also be useful for specifying a template instantiation. Ok with all those solutions, i'm sure they work fine, but i can't see why there can't be anonymous templates. In fact mixins would do similar job, for example: template Generics(T) { T doThis() {return T.max;} void doThat() {} } void someFunc() { mixin Generics!(int); writefln(toString(doThis())); } but it'd be very nice if i just could do this: template(T) { T doThis() {return T.max;} void doThat() {} } void someFunc() { writefln(toString(doThis!(int)())); } >/Oskar > > Tom |
November 01, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomás Rossi | Tomás Rossi wrote:
> In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg@40tude.net>, Derek Parnell says...
>
>>On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote:
>>
>>
>>>In article <dk52us$qpb$1@digitaldaemon.com>, John C says...
>>>
>>>>"Tomás Rossi" <Tomás_member@pathlink.com> wrote in message news:dk50a0$mmk$1@digitaldaemon.com...
>>>>
>>>>>In C++ one could do this:
>>>>>
>>>>>template <class T>
>>>>>void genericFunction<T>(someParam1, someParam2, ..., someParamN)
>>>>>{...generic algorithm...}
>>>>>
>>>>>and then:
>>>>>
>>>>>..
>>>>>genericFunction< list<int> >(blah blah ...);
>>>>>..
>>>>>
>>>>>Is this possible in D?
>>>>
>>>>Yes, it's in the documentation http://www.digitalmars.com/d/template.html
>>>>
>>>>template genericFunction (T) {
>>>> void genericFunction(T p1, T p2, ..., T pN) { }
>>>>}
>>>>
>>>>genericFunction!(list!(int))(...);
>>>>
>>>>
>>>>>Tom
>>>>
>>>>
>>>Ok, I read the docs but the syntax was not so clear to me.
>>>Anyway, the C++ syntax (not referring about <>) is a lot better in the sense
>>>that you are not bound to name your template:
>>>
>>>///////////////////////////////////////
>>>template genericFunctions(T) {
>>>T genericFunction1() {return T.max;}
>>>T genericFunction2() {return T.min;}
>>>..
>>>}
>>>
>>>toString( genericFunctions.genericFunction1!(int)() );
>>>toString( genericFunctions.genericFunction2!(int)() );
>>>..
>>>///////////////////////////////////////
>>>
>>>It just looks ugly!
>>
>>Yes it does. However Walter's suggested solution is to use the 'alias'
>>declaration.
>>
>>template genericFunctions(T) {
>> T genericFunction1() {return T.max;}
>> T genericFunction2() {return T.min;}
>>}
>>
>>// Define some easier names to type and read.
>>alias genericFunctions!(int).genericFunction1 gf1;
>>alias genericFunctions!(int).genericFunction2 gf2;
>>
>>// Show them in use.
>>void main()
>>{
>> gf1();
>> gf2();
>>}
>
>
> The same shit with different color would say my grandfather. :)
> That solution is a little ugly also and very old fashioned. Since D proclaims to
> be the cure for mosts of C++ syntax diseases (well, this is what i got at
> least), i can't see why do i have to appeal to this kind of "C++ style"
> workarounds. Besides, i don't see (and correct me please in other case) a good
> reason to dismiss a more elegant solution (builded in the language itself, like
> other similar problematics were faced), at least in some distant future.
>
> Suppose you have this:
>
> template GenericFunctions(T)
> {
> void doThis() {...}
> void doThat() {...}
> T getFoo() {...}
> void takeFoo(T t) {...}
> void yourSister() {...}
> void myCousin() {...}
> ..etc...
> }
>
> Would you alias one and all?
> Would you write a template with the func. name for everyone? Would you explicitly use GenericFunctions!(T).func()?
>
> Suppose that the language gives you this alternative:
>
> template(T)
> {
> void doThis() {...}
> void doThat() {...}
> T getFoo() {...}
> void takeFoo(T t) {...}
> void yourSister() {...}
> void myCousin() {...}
> ..etc...
> }
>
> All the above problems are resolved.
>
>
>>--
>>Derek Parnell
>>Melbourne, Australia
>>1/11/2005 8:30:53 AM
>
>
> Hope i had maked my point.
>
> Tom
> BsAs, Argentina
> PS: Sorry for my poor English.
One option is simply to mixin the template:
mixin GenericFunctions!(int);
then you can simply call the functions you want.
doThis();
doThat();
Of course with name clashes(like mixing in the template twice) you will need to use with or alias.
-DavidM
|
November 01, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Medlock | In article <dk7n87$ac$1@digitaldaemon.com>, David Medlock says... > >Tomás Rossi wrote: >> In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg@40tude.net>, Derek Parnell says... >> >>>On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote: >>> >>> >>>>In article <dk52us$qpb$1@digitaldaemon.com>, John C says... >>>> >>>>>"Tomás Rossi" <Tomás_member@pathlink.com> wrote in message news:dk50a0$mmk$1@digitaldaemon.com... >>>>> >>>>>>In C++ one could do this: >>>>>> >>>>>>template <class T> >>>>>>void genericFunction<T>(someParam1, someParam2, ..., someParamN) >>>>>>{...generic algorithm...} >>>>>> >>>>>>and then: >>>>>> >>>>>>.. >>>>>>genericFunction< list<int> >(blah blah ...); >>>>>>.. >>>>>> >>>>>>Is this possible in D? >>>>> >>>>>Yes, it's in the documentation http://www.digitalmars.com/d/template.html >>>>> >>>>>template genericFunction (T) { >>>>> void genericFunction(T p1, T p2, ..., T pN) { } >>>>>} >>>>> >>>>>genericFunction!(list!(int))(...); >>>>> >>>>> >>>>>>Tom >>>>> >>>>> >>>>Ok, I read the docs but the syntax was not so clear to me. >>>>Anyway, the C++ syntax (not referring about <>) is a lot better in the sense >>>>that you are not bound to name your template: >>>> >>>>/////////////////////////////////////// >>>>template genericFunctions(T) >>>>{ >>>>T genericFunction1() {return T.max;} >>>>T genericFunction2() {return T.min;} >>>>.. >>>>} >>>> >>>>toString( genericFunctions.genericFunction1!(int)() ); >>>>toString( genericFunctions.genericFunction2!(int)() ); >>>>.. >>>>/////////////////////////////////////// >>>> >>>>It just looks ugly! >>> >>>Yes it does. However Walter's suggested solution is to use the 'alias' declaration. >>> >>>template genericFunctions(T) { >>> T genericFunction1() {return T.max;} >>> T genericFunction2() {return T.min;} >>>} >>> >>>// Define some easier names to type and read. >>>alias genericFunctions!(int).genericFunction1 gf1; >>>alias genericFunctions!(int).genericFunction2 gf2; >>> >>>// Show them in use. >>>void main() >>>{ >>> gf1(); >>> gf2(); >>>} >> >> >> The same shit with different color would say my grandfather. :) >> That solution is a little ugly also and very old fashioned. Since D proclaims to >> be the cure for mosts of C++ syntax diseases (well, this is what i got at >> least), i can't see why do i have to appeal to this kind of "C++ style" >> workarounds. Besides, i don't see (and correct me please in other case) a good >> reason to dismiss a more elegant solution (builded in the language itself, like >> other similar problematics were faced), at least in some distant future. >> >> Suppose you have this: >> >> template GenericFunctions(T) >> { >> void doThis() {...} >> void doThat() {...} >> T getFoo() {...} >> void takeFoo(T t) {...} >> void yourSister() {...} >> void myCousin() {...} >> ..etc... >> } >> >> Would you alias one and all? >> Would you write a template with the func. name for everyone? >> Would you explicitly use GenericFunctions!(T).func()? >> >> Suppose that the language gives you this alternative: >> >> template(T) >> { >> void doThis() {...} >> void doThat() {...} >> T getFoo() {...} >> void takeFoo(T t) {...} >> void yourSister() {...} >> void myCousin() {...} >> ..etc... >> } >> >> All the above problems are resolved. >> >> >>>-- >>>Derek Parnell >>>Melbourne, Australia >>>1/11/2005 8:30:53 AM >> >> >> Hope i had maked my point. >> >> Tom >> BsAs, Argentina >> PS: Sorry for my poor English. > >One option is simply to mixin the template: > >mixin GenericFunctions!(int); > >then you can simply call the functions you want. > >doThis(); >doThat(); > >Of course with name clashes(like mixing in the template twice) you will need to use with or alias. > >-DavidM > Yap... i knew that one :) http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/29592 Tom |
November 04, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tomás Rossi | In article <dk6p11$28p0$1@digitaldaemon.com>, Tomás Rossi says... > >In article <1vo72jbc04tgw.gwxz3kffp4gh.dlg@40tude.net>, Derek Parnell says... >> >>On Mon, 31 Oct 2005 17:55:26 +0000 (UTC), Tomás Rossi wrote: >> >>> In article <dk52us$qpb$1@digitaldaemon.com>, John C says... >>>> >>>>"Tomás Rossi" <Tomás_member@pathlink.com> wrote in message news:dk50a0$mmk$1@digitaldaemon.com... >>>>> In C++ one could do this: >>>>> >>>>> template <class T> >>>>> void genericFunction<T>(someParam1, someParam2, ..., someParamN) >>>>> {...generic algorithm...} >>>>> >>>>> and then: >>>>> >>>>> .. >>>>> genericFunction< list<int> >(blah blah ...); >>>>> .. >>>>> >>>>> Is this possible in D? >>>> >>>>Yes, it's in the documentation http://www.digitalmars.com/d/template.html >>>> >>>>template genericFunction (T) { >>>> void genericFunction(T p1, T p2, ..., T pN) { } >>>>} >>>> >>>>genericFunction!(list!(int))(...); >>>> >>>>> >>>>> Tom >>>> >>>> >>> >>> Ok, I read the docs but the syntax was not so clear to me. >>> Anyway, the C++ syntax (not referring about <>) is a lot better in the sense >>> that you are not bound to name your template: >>> >>> /////////////////////////////////////// >>> template genericFunctions(T) >>> { >>> T genericFunction1() {return T.max;} >>> T genericFunction2() {return T.min;} >>> .. >>> } >>> >>> toString( genericFunctions.genericFunction1!(int)() ); >>> toString( genericFunctions.genericFunction2!(int)() ); >>> .. >>> /////////////////////////////////////// >>> >>> It just looks ugly! >> >>Yes it does. However Walter's suggested solution is to use the 'alias' declaration. >> >>template genericFunctions(T) { >> T genericFunction1() {return T.max;} >> T genericFunction2() {return T.min;} >>} >> >>// Define some easier names to type and read. >>alias genericFunctions!(int).genericFunction1 gf1; >>alias genericFunctions!(int).genericFunction2 gf2; >> >>// Show them in use. >>void main() >>{ >> gf1(); >> gf2(); >>} > >The same shit with different color would say my grandfather. :) >That solution is a little ugly also and very old fashioned. Since D proclaims to >be the cure for mosts of C++ syntax diseases (well, this is what i got at >least), i can't see why do i have to appeal to this kind of "C++ style" >workarounds. Besides, i don't see (and correct me please in other case) a good >reason to dismiss a more elegant solution (builded in the language itself, like >other similar problematics were faced), at least in some distant future. > >Suppose you have this: > >template GenericFunctions(T) >{ >void doThis() {...} >void doThat() {...} >T getFoo() {...} >void takeFoo(T t) {...} >void yourSister() {...} >void myCousin() {...} >..etc... >} > >Would you alias one and all? >Would you write a template with the func. name for everyone? >Would you explicitly use GenericFunctions!(T).func()? > >Suppose that the language gives you this alternative: > >template(T) >{ >void doThis() {...} >void doThat() {...} >T getFoo() {...} >void takeFoo(T t) {...} >void yourSister() {...} >void myCousin() {...} >..etc... >} > >All the above problems are resolved. > >> >>-- >>Derek Parnell >>Melbourne, Australia >>1/11/2005 8:30:53 AM > >Hope i had maked my point. > >Tom >BsAs, Argentina >PS: Sorry for my poor English. I want to write a Delegate class that with multi-dispatch, like C#: Delegate!(void delegate()) dele; dele += obj.func; dele += obj.func1; dele (); Delegate!(void delegate(char[], int, float, short, .......)) dele1; dele1 += obj.funca; dele1 += obj.funca1; dele1 (.........); I think that is difficult. In C++, I can do this: void test(int, int); void test1(short, short); Delegate<void(short, char)> dele; dele += test; dele += test1; The function "operator +=" is a template function, it can deduct the types of arguments, then I can use the types and process them. Of course, that need to use template specialization, it depends on the count of function arguments. In D, I don't know how to do it. PS: Sorry for my poor English too. |
November 04, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to cpunion | > > I want to write a Delegate class that with multi-dispatch, like C#: > > Delegate!(void delegate()) dele; > dele += obj.func; > dele += obj.func1; > dele (); > > Delegate!(void delegate(char[], int, float, short, .......)) dele1; > dele1 += obj.funca; > dele1 += obj.funca1; > dele1 (.........); > > I think that is difficult. > > In C++, I can do this: > > void test(int, int); > void test1(short, short); > Delegate<void(short, char)> dele; > dele += test; > dele += test1; > > The function "operator +=" is a template function, it can deduct the types > of > arguments, then I can use the types and process them. > Of course, that need to use template specialization, it depends on the > count of > function arguments. > > In D, I don't know how to do it. > > PS: Sorry for my poor English too. > > There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. To declare a multicast delegate: alias MulticastDelegate!(void, char[]) StringDisplayHandler; To use it: void stringDisplayFunc(char[] s) { writefln(s); } StringDisplayHandler handler; handler += delegate void(char[] s) { writefln(s); }; handler += &stringDisplayFunc; handler("Hello World"); Source: template MethodWrapperBase(TDelegate, TFunction) { public bool isStatic; package union { TDelegate delegate_; struct { void* p; TFunction function_; } } public static MethodWrapper wrap(TDelegate d) { MethodWrapper m; m.delegate_ = d; return m; } public static MethodWrapper wrap(TFunction f) { MethodWrapper m; m.isStatic = true; m.function_ = f; return m; } void clear() { function_ = null; delegate_ = null; } } struct MethodWrapper(R) { alias R delegate() TDelegate; alias R function() TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall() { if (isStatic) { if (function_ != null) return function_(); return R.init; } if (delegate_ != null) return delegate_(); return R.init; } } struct MethodWrapper(R : void) { alias R delegate() TDelegate; alias R function() TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall() { if (isStatic) { if (function_ != null) function_(); } if (delegate_ != null) delegate_(); } } struct MethodWrapper(R, T) { alias R delegate(T) TDelegate; alias R function(T) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T arg) { if (isStatic) { if (function_ != null) return function_(arg); return R.init; } if (delegate_ != null) return delegate_(arg); return R.init; } } struct MethodWrapper(R : void, T) { alias R delegate(T) TDelegate; alias R function(T) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T arg) { if (isStatic) { if (function_ != null) function_(arg); } if (delegate_ != null) delegate_(arg); } } struct MethodWrapper(R, T0, T1) { alias R delegate(T0, T1) TDelegate; alias R function(T0, T1) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1) { if (isStatic) { if (function_ != null) return function_(arg0, arg1); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1); return R.init; } } struct MethodWrapper(R : void, T0, T1) { alias R delegate(T0, T1) TDelegate; alias R function(T0, T1) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1) { if (isStatic) { if (function_ != null) function_(arg0, arg1); } if (delegate_ != null) delegate_(arg0, arg1); } } struct MethodWrapper(R, T0, T1, T2) { alias R delegate(T0, T1, T2) TDelegate; alias R function(T0, T1, T2) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2) { if (isStatic) { if (function_ != null) return function_(arg0, arg1, arg2); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1, arg2); return R.init; } } struct MethodWrapper(R : void, T0, T1, T2) { alias R delegate(T0, T1, T2) TDelegate; alias R function(T0, T1, T2) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2) { if (isStatic) { if (function_ != null) function_(arg0, arg1, arg2); } if (delegate_ != null) delegate_(arg0, arg1, arg2); } } struct MethodWrapper(R, T0, T1, T2, T3) { alias R delegate(T0, T1, T2, T3) TDelegate; alias R function(T0, T1, T2, T3) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { if (isStatic) { if (function_ != null) return function_(arg0, arg1, arg2, arg3); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1, arg2, arg3); return R.init; } } struct MethodWrapper(R : void, T0, T1, T2, T3) { alias R delegate(T0, T1, T2, T3) TDelegate; alias R function(T0, T1, T2, T3) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { if (isStatic) { if (function_ != null) function_(arg0, arg1, arg2, arg3); } if (delegate_ != null) delegate_(arg0, arg1, arg2, arg3); } } struct MethodWrapper(R, T0, T1, T2, T3, T4) { alias R delegate(T0, T1, T2, T3, T4) TDelegate; alias R function(T0, T1, T2, T3, T4) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { if (isStatic) { if (function_ != null) return function_(arg0, arg1, arg2, arg3, arg4); return R.init; } if (delegate_ != null) return delegate_(arg0, arg1, arg2, arg3, arg4); return R.init; } } struct MethodWrapper(R : void, T0, T1, T2, T3, T4) { alias R delegate(T0, T1, T2, T3, T4) TDelegate; alias R function(T0, T1, T2, T3, T4) TFunction; mixin MethodWrapperBase!(TDelegate, TFunction); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { if (isStatic) { if (function_ != null) function_(arg0, arg1, arg2, arg3, arg4); } if (delegate_ != null) delegate_(arg0, arg1, arg2, arg3, arg4); } } template MulticastDelegateBase() { public void add(TDelegate d) { if (d == null) return; int len = methods_.length; int n = len - 1; while (n >= 0 && methods_[n].delegate_ == null) --n; if (n < len - 1) methods_[n + 1] = TMethodWrapper.wrap(d); else methods_ ~= TMethodWrapper.wrap(d); } public void opAddAssign(TDelegate d) { add(d); } public void remove(TDelegate d) { if (methods_.length == 0) return; bool found; for (int i = 0; i < methods_.length - 1; ++i) { if (!found && methods_[i].delegate_ is d) found = true; if (found) methods_[i] = methods_[i + 1]; if (methods_[i].delegate_ is null) break; } if (found || methods_[length - 1].delegate_ is d) methods_[length - 1].clear(); } public void opSubAssign(TDelegate d) { remove(d); } public void remove(TFunction f) { if (methods_.length == 0) return; bool found; for (int i = 0; i < methods_.length - 1; ++i) { if (!found && methods_[i].function_ is f) found = true; if (found) methods_[i] = methods_[i + 1]; if (methods_[i].delegate_ is null) break; } if (found || methods_[length - 1].function_ is f) methods_[length - 1].clear(); } public void opSubAssign(TFunction f) { remove(f); } public bool isEmpty() { if (methods_.length == 0) return true; else if (methods_[0].delegate_ == null) return true; return false; } } template MulticastDelegateGenericMixins() { alias TMethodWrapper.TDelegate TDelegate; alias TMethodWrapper.TFunction TFunction; package TMethodWrapper[] methods_; mixin MulticastDelegateBase; } template MulticastDelegateMixins(R) { alias MethodWrapper!(R) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T) { alias MethodWrapper!(R, T) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1) { alias MethodWrapper!(R, T0, T1) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1, T2) { alias MethodWrapper!(R, T0, T1, T2) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1, T2, T3) { alias MethodWrapper!(R, T0, T1, T2, T3) TMethodWrapper; mixin MulticastDelegateGenericMixins; } template MulticastDelegateMixins(R, T0, T1, T2, T3, T4) { alias MethodWrapper!(R, T0, T1, T2, T3, T4) TMethodWrapper; mixin MulticastDelegateGenericMixins; } struct MulticastDelegate(R) { mixin MulticastDelegateMixins!(R); public R opCall() { for (int i = 0; i < methods_.length - 1; i++) methods_[i](); return methods_[$ - 1](); } } struct MulticastDelegate(R : void) { mixin MulticastDelegateMixins!(R); public R opCall() { foreach (TMethodWrapper method; methods_) method(); } } struct MulticastDelegate(R, T) { mixin MulticastDelegateMixins!(R, T); public R opCall(T arg) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg); return methods_[$ - 1](arg); } } struct MulticastDelegate(R : void, T) { mixin MulticastDelegateMixins!(R, T); public R opCall(T arg) { foreach (TMethodWrapper method; methods_) method(arg); } } struct MulticastDelegate(R, T0, T1) { mixin MulticastDelegateMixins!(R, T0, T1); public R opCall(T0 arg0, T1 arg1) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1); return methods_[$ - 1](arg0, arg1); } } struct MulticastDelegate(R : void, T0, T1) { mixin MulticastDelegateMixins!(R, T0, T1); public R opCall(T0 arg0, T1 arg1) { foreach (TMethodWrapper method; methods_) method(arg0, arg1); } } struct MulticastDelegate(R, T0, T1, T2) { mixin MulticastDelegateMixins!(R, T0, T1, T2); public R opCall(T0 arg0, T1 arg1, T2 arg2) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1, arg2); return methods_[$ - 1](arg0, arg1, arg2); } } struct MulticastDelegate(R : void, T0, T1, T2) { mixin MulticastDelegateMixins!(R, T0, T1, T2); public R opCall(T0 arg0, T1 arg1, T2 arg2) { foreach (TMethodWrapper method; methods_) method(arg0, arg1, arg2); } } struct MulticastDelegate(R, T0, T1, T2, T3) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1, arg2, arg3); return methods_[$ - 1](arg0, arg1, arg2, arg3); } } struct MulticastDelegate(R : void, T0, T1, T2, T3) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3) { foreach (TMethodWrapper method; methods_) method(arg0, arg1, arg2, arg3); } } struct MulticastDelegate(R, T0, T1, T2, T3, T4) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3, T4); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { for (int i = 0; i < methods_.length - 1; i++) methods_[i](arg0, arg1, arg2, arg3, arg4); return methods_[$ - 1](arg0, arg1, arg2, arg3, arg4); } } struct MulticastDelegate(R : void, T0, T1, T2, T3, T4) { mixin MulticastDelegateMixins!(R, T0, T1, T2, T3, T4); public R opCall(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { foreach (TMethodWrapper method; methods_) method(arg0, arg1, arg2, arg3, arg4); } } |
November 05, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | In article <dkgd5c$2o1d$1@digitaldaemon.com>, John C says... >There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. > >If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. > >To declare a multicast delegate: > > alias MulticastDelegate!(void, char[]) StringDisplayHandler; > >To use it: > > void stringDisplayFunc(char[] s) { > writefln(s); > } > > StringDisplayHandler handler; > handler += delegate void(char[] s) { > writefln(s); > }; > handler += &stringDisplayFunc; > handler("Hello World"); > Thanks. It works well! |
November 05, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to cpunion | In article <dkgtg6$4qr$1@digitaldaemon.com>, cpunion@gmail.com says... > >In article <dkgd5c$2o1d$1@digitaldaemon.com>, John C says... >>There's a few so-called multicast delegate libraries floating around. MinWin contains a good implementation http://home.comcast.net/~benhinkle/minwin/. There are also some signal/slot libraries, for example at http://www.uwesalomon.de/code/indigo/files2/index-txt.html. >> >>If you need the overloaded += behaviour, I've pasted my own version, which extends MinWin's, below. >> >>To declare a multicast delegate: >> >> alias MulticastDelegate!(void, char[]) StringDisplayHandler; >> >>To use it: >> >> void stringDisplayFunc(char[] s) { >> writefln(s); >> } >> >> StringDisplayHandler handler; >> handler += delegate void(char[] s) { >> writefln(s); >> }; >> handler += &stringDisplayFunc; >> handler("Hello World"); >> > >Thanks. It works well! > > The Boost::function can accept the compatible types, for example: int f1(int); // function type: int(int) short f2(double); // function type: short(double) struct functor // functor type: int(int) { int operator()(double){} }; functor f3; // functor object boost::function<int(int)> func; // function object, lick delegate, type: int(int) func = f1; // can accept int(int) func = f2; // can accept short(double) func = f3; // can accept functor(type: int(double)). In D, may be replaced with &f3.opCall? The function object can accept the compatible types, can resolve it in D? Thanks. |
November 05, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to cpunion | <cpunion@gmail.com> wrote in message news:dkhcob$gaa$1@digitaldaemon.com... > In article <dkgtg6$4qr$1@digitaldaemon.com>, cpunion@gmail.com says... >> >>In article <dkgd5c$2o1d$1@digitaldaemon.com>, John C says... >>>There's a few so-called multicast delegate libraries floating around. >>>MinWin >>>contains a good implementation >>>http://home.comcast.net/~benhinkle/minwin/. >>>There are also some signal/slot libraries, for example at >>>http://www.uwesalomon.de/code/indigo/files2/index-txt.html. >>> >>>If you need the overloaded += behaviour, I've pasted my own version, >>>which >>>extends MinWin's, below. >>> >>>To declare a multicast delegate: >>> >>> alias MulticastDelegate!(void, char[]) StringDisplayHandler; >>> >>>To use it: >>> >>> void stringDisplayFunc(char[] s) { >>> writefln(s); >>> } >>> >>> StringDisplayHandler handler; >>> handler += delegate void(char[] s) { >>> writefln(s); >>> }; >>> handler += &stringDisplayFunc; >>> handler("Hello World"); >>> >> >>Thanks. It works well! >> >> > > The Boost::function can accept the compatible types, for example: > > int f1(int); // function type: int(int) > short f2(double); // function type: short(double) > > struct functor // functor type: int(int) > { > int operator()(double){} > }; > > functor f3; // functor object > > boost::function<int(int)> func; // function object, lick delegate, type: > int(int) > func = f1; // can accept int(int) > func = f2; // can accept short(double) > func = f3; // can accept functor(type: int(double)). In D, may be > replaced with > &f3.opCall? > > The function object can accept the compatible types, can resolve it in D? > > Thanks. > That's doubtful. I've not even seen functors in use in D like that, so don't think it's possible. |
November 05, 2005 Re: Templated Functions | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | In article <dkhtuh$1432$1@digitaldaemon.com>, John C says... >That's doubtful. I've not even seen functors in use in D like that, so don't think it's possible. Thanks. I think that not need that in D. :-) |
Copyright © 1999-2021 by the D Language Foundation