digitalmars.D.learn - Redirect to different overloads at compile time?
- David Bregman (30/30) Jun 29 2014 Suppose I have a C library which implements a function for
- Steven Schveighoffer (23/52) Jun 29 2014 This is the correct answer. It should be inlined, and inlining should wo...
- Kenji Hara (21/39) Jun 29 2014 In D, you can merge arbitrary overloads by using alias
- David Bregman (8/10) Jun 29 2014 Oh wow, you are right. That's a nice feature!
Suppose I have a C library which implements a function for several types. C doesn't have overloading, so their names will be distinct. extern(C): double foo_double(double); float foo_float(float); Now I want to build a D wrapper, and merge them into a single function with overloading: T foo(T) I could write out the two overloads manually: double foo(double d) { return foo_double(d); } float foo(float f) { return foo_float(f); } but this isn't compile time, it will generate a stub function for each overload, meaning the wrapper will have performance overhead unless inlining can be guaranteed somehow. Is it possible to do something like alias foo = foo_double; alias foo = foo_float; or template(T) foo { static if(T is double) { alias foo = foo_double; } else { // etc. } } These doesn't work of course. I don't fully understand the template syntax yet, but I have a feeling this is possible with templates. Is it possible to do what I'm trying to do?
Jun 29 2014
On Sun, 29 Jun 2014 22:24:09 -0400, David Bregman <drb sfu.ca> wrote:Suppose I have a C library which implements a function for several types. C doesn't have overloading, so their names will be distinct. extern(C): double foo_double(double); float foo_float(float); Now I want to build a D wrapper, and merge them into a single function with overloading: T foo(T) I could write out the two overloads manually: double foo(double d) { return foo_double(d); } float foo(float f) { return foo_float(f); } but this isn't compile time, it will generate a stub function for each overload, meaning the wrapper will have performance overhead unless inlining can be guaranteed somehow.This is the correct answer. It should be inlined, and inlining should work as long as -inline is passed to the compiler. I don't think there is another way.Is it possible to do something like alias foo = foo_double; alias foo = foo_float;Right, you cannot overload aliases as far as I know. foo either refers to foo_double, or foo_float. You can't bring in those as overloads under the name foo.or template(T) foo { static if(T is double) { alias foo = foo_double; } else { // etc. } } These doesn't work of course.This last one looks like it should work. But IFTI ONLY works if you don't do what you did :) Basically, IFTI cannot see through static if to determine how to instantiate. It needs to be a clear single function. For example, how would IFTI figure it out if you did this? template(T) foo { static if(T is double) { alias foo = foo_float; } else { // etc. } } It can't figure out what T is without looking at what the alias would be, but in order to look at the alias, it needs to decide T!I don't fully understand the template syntax yet, but I have a feeling this is possible with templates. Is it possible to do what I'm trying to do?It seems like it should be possible, but I think we would need a new type of implicit determination for templates that was not a function template. -Steve
Jun 29 2014
On Monday, 30 June 2014 at 02:24:10 UTC, David Bregman wrote:Suppose I have a C library which implements a function for several types. C doesn't have overloading, so their names will be distinct. extern(C): double foo_double(double); float foo_float(float); Now I want to build a D wrapper, and merge them into a single function with overloading: T foo(T) I could write out the two overloads manually: double foo(double d) { return foo_double(d); } float foo(float f) { return foo_float(f); } but this isn't compile time, it will generate a stub function for each overload, meaning the wrapper will have performance overhead unless inlining can be guaranteed somehow. Is it possible to do something like alias foo = foo_double; alias foo = foo_float;In D, you can merge arbitrary overloads by using alias declaration. import std.stdio; extern(C) { double foo_double(double a) { writeln(typeof(a).stringof); return a; } float foo_float (float a) { writeln(typeof(a).stringof); return a; } } alias foo = foo_double; alias foo = foo_float; void main() { double d; float f; foo(d); // prints double foo(f); // prints float } Kenji Hara
Jun 29 2014
On Monday, 30 June 2014 at 04:50:05 UTC, Kenji Hara wrote:In D, you can merge arbitrary overloads by using alias declaration.Oh wow, you are right. That's a nice feature! I guess I simplified too much for the sake of making the post, the functions I would actually like to merge are function pointers. I assumed it was the same but I was wrong, sorry. double function(double d) foo_double; float function(float f) foo_float; In this case, trying to use alias to merge them causes an error.
Jun 29 2014