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.

Reply via email to