www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template delegate/function ptr struct member

reply "ed" <sillymongrel gmail.com> writes:
I'm porting some C++ code to D and a struct has the following 
member:

struct S
{
// ...
  //void* (*createMethod)();

void* function() createMethod;

}

I'd like to extend this as little to accept delegates for future 
use without breakage to existing code...

Is it possible to template this so "createMethod" can be a 
delegate() or function() of any type *and* have the compiler 
infer the type from ctor parameters?

For example:
---
struct S(F)
{
     // ...
     F createMethod;
     this(alias F)() {createMethod = &F;}
}
static void* func() {return null;}

void main() {
     auto s1 = S(&func);
     auto s2 = S(&Object.classinfo.create);

     // s1 is S!(void* function())
     // s2 is S!(Object delegate() const);
}
---

Is this a good idea or am I way off?

Thanks,
ed
May 13 2014
parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 13/05/2014 7:28 p.m., ed wrote:
 I'm porting some C++ code to D and a struct has the following member:

 struct S
 {
 // ...
   //void* (*createMethod)();

 void* function() createMethod;

 }

 I'd like to extend this as little to accept delegates for future use
 without breakage to existing code...

 Is it possible to template this so "createMethod" can be a delegate() or
 function() of any type *and* have the compiler infer the type from ctor
 parameters?

 For example:
 ---
 struct S(F)
 {
      // ...
      F createMethod;
      this(alias F)() {createMethod = &F;}
 }
 static void* func() {return null;}

 void main() {
      auto s1 = S(&func);
      auto s2 = S(&Object.classinfo.create);

      // s1 is S!(void* function())
      // s2 is S!(Object delegate() const);
 }
 ---

 Is this a good idea or am I way off?

 Thanks,
 ed
I would recommend going the route of property functions and using delegates as the default. alias createMethodDel = void* delegate(); alias createMethodFunc = void* function(); struct S { private createMethodDel createMethod_; property { createMethodDel createMethod() { return createMethod_; } void createMethod(createMethodDel func) { createMethod_ = func; } void createMethod(createMethodFunc func) { import std.functional : toDelegate; createMethod_ = toDelegate(func); } } } That way you know what you have access to is always callable and won't break any code.
May 13 2014
parent "uri" <gmail gmail.com> writes:
On Tuesday, 13 May 2014 at 07:50:09 UTC, Rikki Cattermole wrote:
 On 13/05/2014 7:28 p.m., ed wrote:
 I'm porting some C++ code to D and a struct has the following 
 member:

 struct S
 {
 // ...
  //void* (*createMethod)();

 void* function() createMethod;

 }

 I'd like to extend this as little to accept delegates for 
 future use
 without breakage to existing code...

 Is it possible to template this so "createMethod" can be a 
 delegate() or
 function() of any type *and* have the compiler infer the type 
 from ctor
 parameters?

 For example:
 ---
 struct S(F)
 {
     // ...
     F createMethod;
     this(alias F)() {createMethod = &F;}
 }
 static void* func() {return null;}

 void main() {
     auto s1 = S(&func);
     auto s2 = S(&Object.classinfo.create);

     // s1 is S!(void* function())
     // s2 is S!(Object delegate() const);
 }
 ---

 Is this a good idea or am I way off?

 Thanks,
 ed
I would recommend going the route of property functions and using delegates as the default. alias createMethodDel = void* delegate(); alias createMethodFunc = void* function(); struct S { private createMethodDel createMethod_; property { createMethodDel createMethod() { return createMethod_; } void createMethod(createMethodDel func) { createMethod_ = func; } void createMethod(createMethodFunc func) { import std.functional : toDelegate; createMethod_ = toDelegate(func); } } } That way you know what you have access to is always callable and won't break any code.
I was so focused on a template solution that I never even thought of doing it that way, nice one :) Thanks, ed
May 13 2014