| |
| Posted by Vijay Nayar in reply to Alex | PermalinkReply |
|
Vijay Nayar
| On Wednesday, 27 February 2019 at 20:45:33 UTC, Alex wrote:
> On Wednesday, 27 February 2019 at 20:03:15 UTC, Q. Schroll wrote:
>> For any type constructors like const, I can use ConstOf!T to get `T` with const attached. For a delegate/function type DG, e.g. int delegate(int), how can I get the @safe version of that type, i.e. int delegate(int) @safe?
>>
>> I tried
>>
>> alias SafeOf(DG) = DG @safe;
>>
>> but it didn't compile.
>>
>> The case is not @safe-specific; it's the same for all function attributes.
>
> At https://p0nce.github.io/d-idioms/
>
> there is a demonstration for @nogc:
>
> ´´´
> import std.traits;
>
> // Casts @nogc out of a function or delegate type.
> auto assumeNoGC(T) (T t) if (isFunctionPointer!T || isDelegate!T)
> {
> enum attrs = functionAttributes!T | FunctionAttribute.nogc;
> return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t;
> }
> ´´´
>
> Didn't try this for other cases, however...
When I need particular attributes, such as for a comparator, but also need to pass in a function as a template argument, one approach I've started to adopt is to only call this function from within a wrapper that has all the properties I want.
For example:
import std.stdio;
class MyThing(T, alias LessF) {
// This wrapper defines the conditions for a valid LessF.
@safe @nogc
private static bool less(in T t1, in T t2) {
return LessF(t1, t2);
}
}
void main()
{
MyThing!(int, (a, b) => a < b) a; // Compiles fine!
MyThing!(int, (a, b) {
writeln("Not @nogc!"); // Compiler error!
return a < b;
}) b;
}
The error looks like this, which is fairly readable too.
onlineapp.d(6): Error: `@nogc` function `onlineapp.main.MyThing!(int, (a, b)
{
writeln("Not @nogc!");
return a < b;
}
).MyThing.less` cannot call non-@nogc function
|