www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Cross product template

reply "Diggory" <diggsey googlemail.com> writes:
I have a vector struct, Vector(T, uint N) templated on the type T 
and number of components, N. I'm trying to write a function 
"cross" which will calculate the cross product of a number of 
vectors.

For a given number of components, N, the cross function should 
take N-1 arguments, each one a Vector!(?, N) and will return a 
vector perpendicular to the vectors passed in. The ? means the 
type is free to be anything.

The problem is that however I try to write it, the template 
argument deduction isn't powerful enough to work out which 
instantiation to use.

I thought something like this would work to deduce the parameters 
and then I could use constraints to enforce the other rules, but 
no:
auto cross(T, N, U...)(Vector!(T, N) a, U b) { return 0; }
May 14 2013
next sibling parent "Diggory" <diggsey googlemail.com> writes:
On Wednesday, 15 May 2013 at 01:31:43 UTC, Diggory wrote:
 I have a vector struct, Vector(T, uint N) templated on the type 
 T and number of components, N. I'm trying to write a function 
 "cross" which will calculate the cross product of a number of 
 vectors.

 For a given number of components, N, the cross function should 
 take N-1 arguments, each one a Vector!(?, N) and will return a 
 vector perpendicular to the vectors passed in. The ? means the 
 type is free to be anything.

 The problem is that however I try to write it, the template 
 argument deduction isn't powerful enough to work out which 
 instantiation to use.

 I thought something like this would work to deduce the 
 parameters and then I could use constraints to enforce the 
 other rules, but no:
 auto cross(T, N, U...)(Vector!(T, N) a, U b) { return 0; }
Well, after much trial and error I ended up with this, which seems to work: template VectorN(T : Vector!(T, N), uint N) { enum VectorN = N; } template isVectorN(uint N) { template isVectorN(T) { enum isVectorN = VectorN!(T) == N; } } auto cross(T...)(T args) if (allSatisfy!(isVectorN!(T.length+1), T) && T.length) { return 0; }
May 14 2013
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 15 May 2013 03:31:40 +0200, Diggory <diggsey googlemail.com> wrote:

 I have a vector struct, Vector(T, uint N) templated on the type T and  
 number of components, N. I'm trying to write a function "cross" which  
 will calculate the cross product of a number of vectors.

 For a given number of components, N, the cross function should take N-1  
 arguments, each one a Vector!(?, N) and will return a vector  
 perpendicular to the vectors passed in. The ? means the type is free to  
 be anything.

 The problem is that however I try to write it, the template argument  
 deduction isn't powerful enough to work out which instantiation to use.

 I thought something like this would work to deduce the parameters and  
 then I could use constraints to enforce the other rules, but no:
 auto cross(T, N, U...)(Vector!(T, N) a, U b) { return 0; }
auto cross(T, uint N, U...)(Vector!(T,N) a, U b) { return 0; } Oughta work. -- Simen
May 14 2013