Thread overview
Question Re Templates & Tuples
Jan 16, 2007
Daniel Giddings
Jan 16, 2007
Daniel Giddings
January 16, 2007
First there seems to be an issue with copying tuples made from structs with .tupleof (sample code in test.d).

 > dmd -run test.d
12.3
0nan

I'm guessing that this is for similar reasons to tuples not being able to be returned from functions yet?

Which brings me to my question re templates... in pack.d I have templated a Tuple struct which can have varying numbers of properties. Is there a way of doing this where you don't have to write out the maximum number of elements manually?

The names aren't important as you can iterate over them with .tupleof.

template Tuple( T... )
{
	align(1) struct Tuple
	{
		static if( T.length > 0 ) { T[0] first; }
		static if( T.length > 1 ) { T[1] second; }
		static if( T.length > 2 ) { T[2] third; }
		static if( T.length > 3 ) { T[3] fourth; }
		static if( T.length > 4 ) { T[4] fifth; }
		static if( T.length > 5 ) { T[5] sixth; }
		static if( T.length > 6 ) { T[6] seventh; }
		static if( T.length > 7 ) { T[7] eighth; }
		static if( T.length > 8 ) { T[8] ninth; }
		// ... etc if more than 9 elements are needed
	}
}

Running pack.d produces:

 > dmd -run pack.d
a
1
2.3

I'm only interested in packing PoD (plain old data types) at this stage.

Cheers,

:-) Dan




January 16, 2007
Daniel Giddings wrote:
> First there seems to be an issue with copying tuples made from structs with .tupleof (sample code in test.d).
> 
>  > dmd -run test.d
> 12.3
> 0nan
> 
> I'm guessing that this is for similar reasons to tuples not being able to be returned from functions yet?
> 
> Which brings me to my question re templates... in pack.d I have templated a Tuple struct which can have varying numbers of properties. Is there a way of doing this where you don't have to write out the maximum number of elements manually?
> 
> The names aren't important as you can iterate over them with .tupleof.
> 
> template Tuple( T... )
> {
>     align(1) struct Tuple
>     {
>         static if( T.length > 0 ) { T[0] first; }
>         static if( T.length > 1 ) { T[1] second; }
>         static if( T.length > 2 ) { T[2] third; }
>         static if( T.length > 3 ) { T[3] fourth; }
>         static if( T.length > 4 ) { T[4] fifth; }
>         static if( T.length > 5 ) { T[5] sixth; }
>         static if( T.length > 6 ) { T[6] seventh; }
>         static if( T.length > 7 ) { T[7] eighth; }
>         static if( T.length > 8 ) { T[8] ninth; }
>         // ... etc if more than 9 elements are needed
>     }
> }
> 
> Running pack.d produces:
> 
>  > dmd -run pack.d
> a
> 1
> 2.3
> 
> I'm only interested in packing PoD (plain old data types) at this stage.
> 
> Cheers,
> 
> :-) Dan
> 
> 
> 
> ------------------------------------------------------------------------
> 
> import std.stdio;
> 
> void main()
> {
> 	struct S
> 	{
> 		int i = 1;
> 		double j = 2.3;
> 	}
> 	
> 	S s;
> 	
> 	writefln( s.tupleof );
> 	
> 	auto t = s.tupleof;
> 	
> 	writefln( t );
> }
> 
> 
> ------------------------------------------------------------------------
> 
> import std.stdio;
> import std.string;
> 
> template Tuple( T... )
> {
> 	align(1) struct Tuple
> 	{
> 		static if( T.length > 0 ) { T[0] first; }
> 		static if( T.length > 1 ) {	T[1] second; }
> 		static if( T.length > 2 ) {	T[2] third; }
> 		static if( T.length > 3 ) {	T[3] fourth; }
> 		static if( T.length > 4 ) {	T[4] fifth; }
> 		static if( T.length > 5 ) {	T[5] sixth; }
> 		static if( T.length > 6 ) {	T[6] seventh; }
> 		static if( T.length > 7 ) {	T[7] eighth; }
> 		static if( T.length > 8 ) {	T[8] ninth; }
> 		// ... etc if more than 9 elements are needed
> 	}
> }
> 
> byte[] pack(T...)( T tuple )
> {
> 	int size = 0;
> 	
> 	foreach( item; tuple )
> 		size += item.sizeof;
> 	
> 	byte[] result = new byte[size];
> 	
> 	int position = 0;
> 	
> 	foreach( item; tuple )
> 	{
> 		result[position..position+item.sizeof] = (cast(byte*)&item)[0..item.sizeof];
> 		position += item.sizeof;
> 	}
> 	
> 	return result;
> }
> 
> Tuple!(T) unpack(T...)( byte[] data )
> {
> 	Tuple!(T) result;
> 	
> 	assert( data.length == result.sizeof );
> 	
> 	result = *(cast(Tuple!(T)*)data.ptr);
> 	
> 	return result;
> }
> 
> void main()
> {
> 	byte[] packed = pack!(char,short,float)( 'a', 1, 2.3 );
> 	
> 	auto unpacked = unpack!(char,short,float)( packed );
> 	
> 	foreach( i; unpacked.tupleof )
> 		writefln( i );
> }

I did something like the following once:

# struct Foo (T ...) {
#   T fields;
# }

And was later able to access the declared fields via an index.  Aka:
Foo!(int, int, float, bool) myfoo;
myfoo.fields[0] = 42;
myfoo.fields[2] = 3.14;

The following also worked, if I remember right:
myfoo.fields = Tuple!(42, 25, 3.14, true);

-- Chris Nicholson-Sauls
January 16, 2007
Cheers,

align(1) struct Tuple( T... )
{
	T fields;
}

works quite nicely with no other changes!

:-) Dan

Chris Nicholson-Sauls wrote:
> 
> I did something like the following once:
> 
> # struct Foo (T ...) {
> #   T fields;
> # }
> 
> And was later able to access the declared fields via an index.  Aka:
> Foo!(int, int, float, bool) myfoo;
> myfoo.fields[0] = 42;
> myfoo.fields[2] = 3.14;
> 
> The following also worked, if I remember right:
> myfoo.fields = Tuple!(42, 25, 3.14, true);
> 
> -- Chris Nicholson-Sauls