www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Learn template by math vector class

reply Darren (dgrant at kerberos-productions dot com) <Darren_member pathlink.com> writes:
I am learning about D template details by implementing a static sized vector
class.  Opinions on this code (like how to solve the obvious errors) or
alternatives that would be better practice in D would be appreciated:

class vector( T, size_t size )
{
private:
T p[ size ];

public:
this()
{
}

this( T[] q )
in
{
assert( q.length > 0 );
}
body
{
foreach ( size_t i, T v; q )
{
p[ i ] = v;
}
}

T opIndex( size_t i ) 
in
{
assert( i >= 0 && i < size );
}
body
{
return p[ i ]; 
}

T opIndexassign( T v, size_t i ) 
in
{
assert( i >= 0 && i < size );
}
body
{
p[ i ] = v;
return p[ i ]; 
}

T x() { return p[ 0 ]; }
T y() { return p[ 1 ]; }
T z() { return p[ 2 ]; }
T w() { return p[ 3 ]; }

void x( T v ) { p[ 0 ] = v; }
void y( T v ) { p[ 1 ] = v; }
void z( T v ) { p[ 2 ] = v; }
void w( T v ) { p[ 3 ] = v; }
}


example:
vector!( float, 2 ) 2d_vector;

So the obvious problem is that upon instantiation in the example, z and w
attributes implicitly generate array bounds errors.  Is there a form of generic
specification in D that can be applied to solve this?
Jun 21 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Darren (dgrant at kerberos-productions dot com) wrote:
 I am learning about D template details by implementing a static sized vector
 class.  Opinions on this code (like how to solve the obvious errors) or
 alternatives that would be better practice in D would be appreciated:
 
 class vector( T, size_t size )
 {
 private:
 T p[ size ];
 
 public:
 this()
 {
 }
 
 this( T[] q )
 in
 {
 assert( q.length > 0 );
 }
 body
 {
 foreach ( size_t i, T v; q )
 {
 p[ i ] = v;
 }
 }
 
 T opIndex( size_t i ) 
 in
 {
 assert( i >= 0 && i < size );
 }
 body
 {
 return p[ i ]; 
 }
 
 T opIndexassign( T v, size_t i ) 
 in
 {
 assert( i >= 0 && i < size );
 }
 body
 {
 p[ i ] = v;
 return p[ i ]; 
 }
 
 T x() { return p[ 0 ]; }
 T y() { return p[ 1 ]; }
 T z() { return p[ 2 ]; }
 T w() { return p[ 3 ]; }
 
 void x( T v ) { p[ 0 ] = v; }
 void y( T v ) { p[ 1 ] = v; }
 void z( T v ) { p[ 2 ] = v; }
 void w( T v ) { p[ 3 ] = v; }
 }
 
 
 example:
 vector!( float, 2 ) 2d_vector;
 
 So the obvious problem is that upon instantiation in the example, z and w
 attributes implicitly generate array bounds errors.  Is there a form of generic
 specification in D that can be applied to solve this?
 
 
I think you can use static if: static if( size < 3 ) //no z component { pragma( msg, "2d vectors don't have a z component" ); //tell compiler to print this msg static assert(false); //halt compiler }
Jun 22 2006
next sibling parent Brad Roberts <braddr puremagic.com> writes:
On Thu, 22 Jun 2006, Hasan Aljudy wrote:

 I think you can use static if:
 
 static if( size < 3 ) //no z component
 {
     pragma( msg, "2d vectors don't have a z component" ); //tell compiler to
 print this msg
     static assert(false); //halt compiler
 }
Or the even simpler: static assert(size < 3, "2d vectors..."); Later, Brad
Jun 22 2006
prev sibling parent Darren <Darren_member pathlink.com> writes:
In article <e7dgpn$5q$1 digitaldaemon.com>, Hasan Aljudy says...
I think you can use static if:

static if( size < 3 ) //no z component
{
     pragma( msg, "2d vectors don't have a z component" ); //tell 
compiler to print this msg
     static assert(false); //halt compiler
}
Wow. Thanks, that just worked, though I did it a bit different... Like this: class vector... { .. static if ( size >= 1 ) { T x() { return p[ 0 ]; } void x( T v ) { p[ 0 ] = v; } } .. } Now is there a way to generalize this pattern with something like mixins? ie. do something like template elementAccessor( name, int index ) { T name() { return p[ index ]; } void name( T v ) { p[ index ] = v; } } mixin elementAccessor!( x, index = 0 ); mixin elementAccessor!( y, index = 1 ); mixin elementAccessor!( z, index = 2 ); mixin elementAccessor!( w, index = 3 );
Jun 22 2006