Check Instance of Template for Parameter Type/Value
stew via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Oct 20 14:59:54 PDT 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
More information about the Digitalmars-d-learn
mailing list