Question Re Templates & Tuples

Chris Nicholson-Sauls ibisbasenji at gmail.com
Mon Jan 15 20:57:29 PST 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


More information about the Digitalmars-d-learn mailing list