View mode: basic / threaded / horizontal-split · Log in · Help
November 01, 2005
Re: Templated Functions
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
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
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
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
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
>
> 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
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
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
<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
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. :-)
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home