www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question Re Templates & Tuples

reply Daniel Giddings <dgiddings bigworldtech.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

First there seems to be an issue with copying tuples made from structs 
with .tupleof (sample code in test.d).

 dmd -run test.d

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

1 2.3 I'm only interested in packing PoD (plain old data types) at this stage. Cheers, :-) Dan
Jan 15 2007
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
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
Jan 15 2007
parent Daniel Giddings <dgiddings bigworldtech.com> writes:
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

Jan 15 2007