On Tuesday, 19 July 2016 at 17:10:35 UTC, Lodovico Giaretta wrote:
On Tuesday, 19 July 2016 at 17:05:55 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:59:48 UTC, Lodovico Giaretta
wrote:
On Tuesday, 19 July 2016 at 16:50:56 UTC, Rufus Smith wrote:
On Tuesday, 19 July 2016 at 16:09:38 UTC, Lodovico Giaretta
wrote:
[...]
But this doesn't create a function with all the attributes
of the original? Just one that has the same return type and
parameters. What if Fun is pure or extern(C) or some other
attributes? I'd like to create a function that is exactly
the same in all regards as the original.
Sorry, I misunderstood your question.
With the method I showed you, if the function is @safe, pure,
@nogc or nothrow, foo will infer those attributes. But only
if the operations you do in foo (apart from calling bar) are
themselves @safe, pure, @nogc or nothrow.
For other things, like extern(C), I don't think there's a
simple solution; but I'm not an expert, so I hope someone
else will give you a better answer.
What is strange is I cannot even pass an extern(C) function to
foo.
void foo(R, A...)(R function(A) bar);
extern(C) void bar();
foo(&bar)
fails. Remove extern and it passes. I have not figured out how
to allow for extern(C) functions to be passed.
That's because an extern function must be called with a
different code. So it cannot be cast to a non-extern(C)
function pointer, which is what your foo accepts. If you follow
my advice, and make the entire function type a parameter of
foo, then foo will at least accept your extern(C) function, but
it will not be extern(C) itself.
I don't want it to be cast to a non-extern function. What I want
to do is create the exact same type of function that is passed to
the template except modify the arguments.
If I use a general parameter for the function, it accepts
extern(C), but I can't construct a function with it.
mixin("alias F = extern("~functionLinkage!Q~")
"~(ReturnType!Q).stringof~"
function"~(Parameters!Q).stringof~";");
gives me a type that looks to be what I want but I can't really
use it unless I want to declare the function that does the work
inside foo as mixin string.
One can't do extern(functionLinkage!Q) void baz() to create baz
with the proper linkage ;/
It looks like I might have to go the mixin way ;/ Going to be
messy ;/