digitalmars.D.learn - Check Instance of Template for Parameter Type/Value
- Stewart Moth (22/22) Oct 19 2015 I'm working with a library that has template structs of
- anonymous (8/30) Oct 19 2015 You can use std.traits.TemplateArgsOf:
- Justin Whear (10/35) Oct 19 2015 Pattern matching!
- stew (81/104) Oct 20 2015 I'm not sure if this is exactly what you're after, but with the
I'm working with a library that has template structs of mathematical vectors that can sometimes be the type of an array I'm passing to a function. The definition of the struct is like this: struct Vector(type, int dimension_){ ... } Where type is going to be an int/float/etc and dimension_ is 2/3/4. I could write a bunch of functions for each case, but I'd rather not... I'd like to use something like the following: void foo(T)(Array!T array){ if(isInstanceOf!(Vector, T)){ //get type of T or check it //test if dimension_ is 2 or 3 or 4 ... } else { //Non-vector stuff ... } } But to do that I need to check that parameters of T as if it were an instantiated instance of Vector and I'm not sure how to accomplish that... Can anyone help me out with what I need to do?
Oct 19 2015
On Monday, October 19, 2015 04:51 PM, Stewart Moth wrote:struct Vector(type, int dimension_){ ... } Where type is going to be an int/float/etc and dimension_ is 2/3/4. I could write a bunch of functions for each case, but I'd rather not... I'd like to use something like the following: void foo(T)(Array!T array){ if(isInstanceOf!(Vector, T)){ //get type of T or check it //test if dimension_ is 2 or 3 or 4 ... } else { //Non-vector stuff ... } } But to do that I need to check that parameters of T as if it were an instantiated instance of Vector and I'm not sure how to accomplish that... Can anyone help me out with what I need to do?You can use std.traits.TemplateArgsOf: ---- static if(isInstanceOf!(Vector, T)){ /* note: must be a static if */ enum dimensions = TemplateArgsOf!T[1]; static if(dimensions == 2) {...} } ----
Oct 19 2015
On Mon, 19 Oct 2015 14:51:28 +0000, Stewart Moth wrote:I'm working with a library that has template structs of mathematical vectors that can sometimes be the type of an array I'm passing to a function. The definition of the struct is like this: struct Vector(type, int dimension_){ ... } Where type is going to be an int/float/etc and dimension_ is 2/3/4. I could write a bunch of functions for each case, but I'd rather not... I'd like to use something like the following: void foo(T)(Array!T array){ if(isInstanceOf!(Vector, T)){ //get type of T or check it //test if dimension_ is 2 or 3 or 4 ... } else { //Non-vector stuff ... } } But to do that I need to check that parameters of T as if it were an instantiated instance of Vector and I'm not sure how to accomplish that... Can anyone help me out with what I need to do?Pattern matching! void foo(ArrayT : Array!VectorT, VectorT : Vector!(T, dimension), T, int dimension)(ArrayT arr) { static if (dimension >= 2 && dimension <= 4) { } else { } }
Oct 19 2015
On Monday, 19 October 2015 at 14:51:29 UTC, Stewart Moth wrote:I'm working with a library that has template structs of mathematical vectors that can sometimes be the type of an array I'm passing to a function. The definition of the struct is like this: struct Vector(type, int dimension_){ ... } Where type is going to be an int/float/etc and dimension_ is 2/3/4. I could write a bunch of functions for each case, but I'd rather not... I'd like to use something like the following: void foo(T)(Array!T array){ if(isInstanceOf!(Vector, T)){ //get type of T or check it //test if dimension_ is 2 or 3 or 4 ... } else { //Non-vector stuff ... } } But to do that I need to check that parameters of T as if it were an instantiated instance of Vector and I'm not sure how to accomplish that... Can anyone help me out with what I need to do?I'm not sure if this is exactly what you're after, but with the traits shown below you should be able to perform the following compile time checks. --- void foo(T)(T v){ static if(isVec!(T)){ } // Vec of any type and size static if(isVec!(T, int)){ } // Vec of type 'int' but any size static if(isVec!(T, 3)){ } // Vec of size 3 but any type static if(isVec!(T, 3, int)){ } // Vec of size 3 and type 'int' } --- Traits impl: (this is from memory with no D compiler around so excuse any typos) --- struct Vec(size_t Dim, Type) {} // Vector template parms dimension and type. /** * Is V a Vec of any element type and any size */ template isVec(V) { enum isVec = is(Unqual!V == Vec!(n, U), size_t n, U); } /// unittest { mixin(UT_start); static assert(isVec!(Vec!(2,float))); static assert(isVec!(Vec!(4,int))); mixin(UT_scopeExit); } /** * Is V a Vec of a specific size but any type. */ template isVec(V, size_t n) { static if(is(Unqual!V == Vec!(n2, U), size_t n2, U)) enum isVec = n == n2; else enum isVec = false; } /** * Is V a Vec of any size and specific type T. */ template isVec(V, T) { static if(is(Unqual!V == Vec!(n, U), size_t n, U)) enum isVec = is(T == U); else enum isVec = false; } /// unittest { mixin(UT_start); static assert(isVec!(Vec!(2,int), int)); static assert(isVec!(Vec!(3,int), int)); static assert(!isVec!(Vec!(2,int), float)); static assert(!isVec!(Vec!(3,int), float)); mixin(UT_scopeExit); } /** * Is V a Vec of specific size N and type T */ template isVec(V,size_t N,T) { enum isVec = is(Unqual!V == Vec!(N,T)); } /// unittest { mixin(UT_start); static assert(isVec!(Vec!(2,int), 2, int)); static assert(!isVec!(Vec!(2,int), 3, int)); static assert(!isVec!(Vec!(2,int), 2, float)); static assert(!isVec!(Vec!(2,int), 3, float)); mixin(UT_scopeExit); } --- Cheers, Stew
Oct 20 2015