Explicit cast to @system?

Anonymouse zorael at gmail.com
Sat Oct 8 23:06:13 UTC 2022


I have some nested templated code that takes function pointers. 
In many cases I pass it functions of identical signatures, except 
some are `@safe` and others are `@system`. In those cases the 
templates end up getting instantiated twice. I don't care about 
the `@safe`-ness and I'd really like to just have them all 
treated as `@system`, with one instantiation per unique signature.

To illustrate:

```
void foo(F)(F fun)
{
     pragma(msg, F.stringof);
}

void bar() @safe {}
void baz() @system {}

void main()
{
     foo(&bar);
     foo(&baz);
}
```

Outputs:

```
void function() @safe
void function()
```

I *can* do this by explicitly passing the type as a template 
parameter;

```
void main()
{
     foo!(void function() @system)(&bar);
     foo(&baz);
}
```

...but there are a lot of different signatures and I need a 
general approach. There doesn't seem to be such a thing as 
`cast(@system)fp`.

My current solution involves some very gnarly string mixins.

```
static if (F.stringof.indexOf("@safe") != -1)
{
     mixin("alias SystemF = " ~ F.stringof.replace("@safe", 
"@system") ~ ";");
}
else
{
     alias SystemF = F;
}
```

...where `F` is `void function()`, `@safe` or `@system`. Then I 
can explicitly pass `SystemF` as a compile-time parameter, and I 
get my decreased instantiations.

But surely there has to be a better way?


More information about the Digitalmars-d-learn mailing list