Thread overview
Learn template by math vector class
Jun 22, 2006
Hasan Aljudy
Jun 22, 2006
Brad Roberts
Jun 22, 2006
Darren
June 22, 2006
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?


June 22, 2006

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
}
June 22, 2006
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
June 22, 2006
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 );