www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is there a "nice" way to access the names of template parameters

reply Lukas Borin <borin.lukas gmail.com> writes:
Consider the following template

```D
auto foo(T, int W, int H)(T p1, T p2) { }
```

Is there a "nice" way from the outside the get the names of the 
template values?

E.g:
```D
pragma(msg, TemplateParameterNames!(foo)); // AliasSeq!("T", "W", 
"H") or ["T", "W", "H"]
```

I know you can find the names values in a very hacky way. 
(atleast in dmd 2.097.1)

```D
template HackyHack(alias T) {
    enum RawName = T.stringof;
    enum HackyHack = parseRawName(RawName); // Or 
templateParse!RawString;
}

```

I currently have the HackyHack solution *"working"* but I really 
don't like it and I would be supprised if it works on other dmd 
version or other compilers.


I know I can do things like:

```D
template foo(T, int W, int H) {
    enum names = ... // some magic with __traits or just assing it 
to ["T", "W", "H"]
    auto foo(T p1, T p2) { }
}
```

Use template mixins or other solutions to get what I want but if 
possible I prefer to just introspect on the template.

Usecase right now is to do some cuda kernel generation from a D 
shortfunction.

Something like this:

```D
 kernel
auto saxpy(T, int Iters, int N, int Stride)(T a, T* x, T* y, T* 
output) => q{
     int tid = blockIdx.x * blockDim.x + threadIdx.x;
     for(int idx = tid, int i = 0; i < Iters && idx < N; ++i, idx 
+= Stride) {
         output[idx] = a * x[idx] + y[idx];
     }
};
```

Would get transformed to:
```D
template<typename T, int Iters, int N, int Stride>
__global__ void saxpy(T a, T* x, T* y, T* output) {
     //Identical function body / parameters and template arguments 
from the  kernel
     //D function.
     int tid = blockIdx.x * blockDim.x + threadIdx.x;
     for(int idx = tid, int i = 0; i < Iters && idx < N; ++i, idx 
+= Stride) {
         output[idx] = a * x[idx] + y[idx];
     }
}
```

Really need the names to make this translation, correctly.

Just to be clear i'm not interested in getting the arguments a 
template was instantiated with. I can use TemplateArgsOf!T for 
that.
Jul 27 2021
parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 27 July 2021 at 08:15:12 UTC, Lukas  Borin wrote:
 Consider the following template

 ```D
 auto foo(T, int W, int H)(T p1, T p2) { }
 ```

 Is there a "nice" way from the outside the get the names of the 
 template values?
As far as I'm aware there is no way to introspect on template parameters at all.
Jul 27 2021
parent reply Lukas Borin <borin.lukas gmail.com> writes:
On Tuesday, 27 July 2021 at 09:31:07 UTC, Paul Backus wrote:
 On Tuesday, 27 July 2021 at 08:15:12 UTC, Lukas  Borin wrote:
 Consider the following template

 ```D
 auto foo(T, int W, int H)(T p1, T p2) { }
 ```

 Is there a "nice" way from the outside the get the names of 
 the template values?
As far as I'm aware there is no way to introspect on template parameters at all.
Let's say i instantiate the template does that change anything? Can I get the "placeholder" names in any way then?
Jul 27 2021
parent Paul Backus <snarwin gmail.com> writes:
On Tuesday, 27 July 2021 at 10:15:51 UTC, Lukas  Borin wrote:
 On Tuesday, 27 July 2021 at 09:31:07 UTC, Paul Backus wrote:
 On Tuesday, 27 July 2021 at 08:15:12 UTC, Lukas  Borin wrote:
 Consider the following template

 ```D
 auto foo(T, int W, int H)(T p1, T p2) { }
 ```

 Is there a "nice" way from the outside the get the names of 
 the template values?
As far as I'm aware there is no way to introspect on template parameters at all.
Let's say i instantiate the template does that change anything? Can I get the "placeholder" names in any way then?
I don't think instantiating it changes anything. The underlying issue is that `is(symbol == __parameters)` doesn't work on templates.
Jul 27 2021