Allowing "fall through" of attributes

Lodovico Giaretta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jul 19 09:59:48 PDT 2016


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.


More information about the Digitalmars-d-learn mailing list