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:
On Tuesday, 19 July 2016 at 15:55:02 UTC, Rufus Smith wrote:
I have some functions that take other functions. I would like
the attributes to be able to "fall" through so I get overload
like behavior. I only care that I am passing a function, not
if it is shared, extern(C), pure, @nogc, etc.
void foo(R, A...)(R function(A) bar)
{
alias type = typeof(bar);
pragma(msg, type);
// does magic with bar
}
foo never uses the attributes of bar explicitly. It uses type
to instantiate other functions like bar. I have to create a
foo for each attribute combination, which is not worth while.
The code seems to break only for extern, the best I can tell,
most attributes do pass through. But type does not contain
these attributes.
You shall do something like this (please note that I didn't
check the docs while writing this; you shall definitely have a
look at std.traits and consider the following as pseudo-code
and not actual D):
void foo(Fun)(Fun bar)
if (isSomeFunction!Fun) // your constraint that bar is a
function
{
// how to get your R and A types, if you need them:
alias R = ReturnType!bar;
alias A = Parameters!bar;
alias type = Fun;
pragma(msg, type);
// do some magic
}
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.