Thread overview
Check Instance of Template for Parameter Type/Value
Oct 19, 2015
Stewart Moth
Oct 19, 2015
anonymous
Oct 19, 2015
Justin Whear
Oct 20, 2015
stew
October 19, 2015
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?
October 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) {...}
    }
----
October 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 {

	}
}
October 20, 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