www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Check Instance of Template for Parameter Type/Value

reply Stewart Moth <dfsdfsd dfsd.com> writes:
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
next sibling parent anonymous <anonymous example.com> writes:
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
prev sibling next sibling parent Justin Whear <justin economicmodeling.com> writes:
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
prev sibling parent stew <growlercab gmail.com> writes:
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