Template substitution for function parameters

Nicholas Wilson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Sep 1 18:41:14 PDT 2017


On Friday, 1 September 2017 at 11:33:15 UTC, Biotronic wrote:
> On Friday, 1 September 2017 at 10:15:09 UTC, Nicholas Wilson 
> wrote:
>> So I have the following types
>>
>> struct DevicePointer(T) { T* ptr; }
>>
>> struct Buffer(T)
>> {
>>     void* driverObject;
>>     T[] hostMemory;
>> }
>>
>> and a function
>>
>> auto enqueue(alias k)(HostArgsOf!k) { ... }
>>
>> where k would be a function like
>>
>> void foo( DevicePointer!float a, float b , int c) { ... }
>>
>> How can I write HostArgsOf such that HostArgsOf!foo yields:
>> AliasSeq!(Buffer!float, float, int)
>> preferably in such a way that I can add additional 
>> transformations to it later on?
>>
>> i.e. it substitutes the template DevicePointer for the 
>> template Buffer in Parameters!foo,
>> The templates can be assumed to not be nested templates, i.e. 
>> DevicePointer!(DevicePointer!(float)) will never occur neither 
>> will Buffer!(Buffer!(float) or any cross templates)
>
> template k(alias fn) {
>     import std.meta, std.traits;
>     alias k = staticMap!(ReplaceTemplate!(DevicePointer, 
> Buffer), Parameters!fn);
> }
>
> template ReplaceTemplate(alias needle, alias replacement) {
>     template ReplaceTemplate(alias T) {
>         static if (is(T : needle!Args, Args...)) {
>             alias ReplaceTemplate = replacement!Args;
>         } else {
>             alias ReplaceTemplate = T;
>         }
>     }
> }

Hmm, it seems I oversimplified the example a bit and this doesn't 
quite work for my actual usecase.

struct DevicePointer(int n,T) { T* ptr; }

alias GlobalPointer(T) = DevicePointer!(1,T);

k!foo yields
DevicePointer!(cast(AddrSpace)1u, float), float, int
instead of
Buffer!float, float, int

I think because the is(T : needle!Args, Args...) fails.


More information about the Digitalmars-d-learn mailing list