digitalmars.D.learn - Confused by struct constructors
- "Simen kjaeraas" <simen.kjaras gmail.com> Jan 23 2010
- bearophile <bearophileHUGS lycos.com> Jan 23 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Jan 23 2010
- "Simen kjaeraas" <simen.kjaras gmail.com> Jan 23 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Jan 23 2010
In attempting to create a function to initialize any array of structs in a
simple manner, I created this code:
void fillArr( uint n, T, U... )( ref T[] arr, U args ) {
arr[0] = T( U[0..n] );
static if ( U.length > n ) {
fillArr!( n )( arr[ 1..$ ], args[ n..$ ] );
}
}
T[] initArray( T, uint n = U.length, U... )( U args ) if ( n > 0 ) {
static if (
// ( __traits( compiles, T( args[ 0..n ] ) ) ) && // Same as below.
Added for completeness.
( is( typeof( T( args[ 0..n ] ) ) ) ) && // If we can instantiate a
struct with this
( U.length % n == 0 ) // and it matches the
number of arguments,
) {
T[] result = new T[ U.length / n ]; // Create an array
fillArr!( n )( result, args ); // and fill it.
return result;
} else {
return initArray!( T, n-1, U )( args ); // Didn't work. Try
another parameter count.
}
}
However, upon testing it with this code:
struct S {
int n;
string s;
}
auto s = initArray!( S )( 1, "a", 2, "b", 3, "c" );
I get this error:
foo.d(34): Error: cannot implicitly convert expression ((int _param_1,
string _param_2)) of type (int _param_1, string _param_2) to int
The problem is apparently on this line:
arr[0] = T( U[0..n] );
Though I am confuzzled as to why it does not work ( it works in initArray,
line 2 ). Any ideas?
--
Simen
Jan 23 2010
Simen kjaeraas:In attempting to create a function to initialize any array of structs in a simple manner, ... auto s = initArray!( S )( 1, "a", 2, "b", 3, "c" );
That syntax is not useful, if you have few more structs or fields you are lost in the soup of commas and items.. Bye, bearophile
Jan 23 2010
--00032555b2ce963e93047dd7ff7f Content-Type: text/plain; charset=ISO-8859-1 On Sat, Jan 23, 2010 at 14:44, Simen kjaeraas <simen.kjaras gmail.com>wrote:In attempting to create a function to initialize any array of structs in a simple manner, I created this code: void fillArr( uint n, T, U... )( ref T[] arr, U args ) { arr[0] = T( U[0..n] ); static if ( U.length > n ) { fillArr!( n )( arr[ 1..$ ], args[ n..$ ] ); } }
U is a type . U[0..n] is also a type. You should write: arr[0] = T(args[0..n]); Maybe you could also use S.tupleof.length to get the number of fields in S (or maybe there is a __traits which gives this) and avoid the recursion in initArray: void fillArr( T, U... )( ref T[] arr, U args ) { arr[0] = T(args[0..T.tupleof.length]) ; static if ( U.length > T.tupleof.length ) { fillArr( arr[ 1..$ ], args[ T.tupleof.length..$ ] ); } } T[] initArray( T, U... )( U args ) if ( U.length > 0 && (is(typeof( T( args[ 0..T.tupleof.length ] ) ) ) ) && ( U.length % T.tupleof.length == 0 )) { T[] result = new T[ U.length / T.tupleof.length ]; // Create an array fillArr( result, args ); // and fill it. return result; } Philippe --00032555b2ce963e93047dd7ff7f Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Sat, Jan 23, 2010 at 14:44, Simen kja= eraas <span dir=3D"ltr"><<a href=3D"mailto:simen.kjaras gmail.com">simen= .kjaras gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote= " style=3D"border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0= .8ex; padding-left: 1ex;"> In attempting to create a function to initialize any array of structs in a = simple manner, I created this code:<br> <br> void fillArr( uint n, T, U... )( ref T[] arr, U args ) {<br> =A0arr[0] =3D T( U[0..n] );<br> =A0static if ( U.length > n ) {<br> =A0 =A0fillArr!( n )( arr[ 1..$ ], args[ n..$ ] );<br> =A0}<br> }<br></blockquote><div><br>U is a type . U[0..n] is also a type. You should= write:<br><br>arr[0]=A0 =3D T(args[0..n]);<br><br><br>Maybe you could also= use S.tupleof.length to get the number of fields in S (or maybe there is a= __traits which gives this) and avoid the recursion in initArray:<br> <br><br>void fillArr( T, U... )( ref T[] arr, U args ) {<br>=A0arr[0] =3D= =A0 T(args[0..T.tupleof.length]) ;<br>=A0static if ( U.length > T.tupleo= f.length ) {<br>=A0=A0 fillArr( arr[ 1..$ ], args[ T.tupleof.length..$ ] );= <br>=A0}<br> }<br><br>T[] initArray( T, U... )( U args )<br>=A0=A0=A0 if ( U.length >= 0<br>=A0=A0=A0 && (is(typeof( T( args[ 0..T.tupleof.length ] ) ) )= )<br>=A0=A0=A0 && ( U.length % T.tupleof.length =3D=3D 0 ))<br>{<b= r>=A0=A0 T[] result =3D new T[ U.length / T.tupleof.length ];=A0=A0=A0=A0= =A0=A0=A0=A0 // Create an array<br> =A0=A0 fillArr( result, args );=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // a= nd fill it.<br>=A0=A0 return result;<br>}<br><br><font color=3D"#888888"> </font></div></div>Philippe<br><br> --00032555b2ce963e93047dd7ff7f--
Jan 23 2010
On Sat, 23 Jan 2010 18:09:26 +0100, Philippe Sigaud = <philippe.sigaud gmail.com> wrote:On Sat, Jan 23, 2010 at 14:44, Simen kjaeraas =
<simen.kjaras gmail.com>wrote:In attempting to create a function to initialize any array of structs=
in a simple manner, I created this code: void fillArr( uint n, T, U... )( ref T[] arr, U args ) { arr[0] =3D T( U[0..n] ); static if ( U.length > n ) { fillArr!( n )( arr[ 1..$ ], args[ n..$ ] ); } }
U is a type . U[0..n] is also a type. You should write:
Thank you! Darn, I should have been able to see that.Maybe you could also use S.tupleof.length to get the number of fields =
S
Yeah, I could. However, S might use a different constructor, taking a different number of arguments. As for bearophile's concerns: struct simpleTuple( T... ) { T payload; } simpleTuple!( T ) =E0=BA=95( T... )( T args ) { return simpleTuple!( args ); } T[] initArray( T, U... )( U args ) if ( is( typeof( T( args[0].tupleo= f ) = ) ) && allSame!( U ) ) { T[] result =3D new T[ U.length ]; foreach ( i, arg; args ) { result[ i ] =3D T( arg.tupleof ); } return result; } struct S { int n; string s; } auto s =3D initArray!( S )( =E0=BA=95( 1, "a" ), =E0=BA=95( 2, "b" ),= =E0=BA=95( 3, "c" ) ); If =E0=BA=95 is too hard to type, choose another short name. -- = Simen
Jan 23 2010
--0015174ff13cf96a4c047de42b7c Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable auto s =3D initArray!( S )( =E0=BA=95( 1, "a" ), =E0=BA=95( 2, "b" ), =E0= =BA=95( 3, "c" ) );If =E0=BA=95 is too hard to type, choose another short name.
Nice looking character. Indian, hebrew? When I want an almost non-visible char, I tend tu use _, just _. Philippe --0015174ff13cf96a4c047de42b7c Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable =C2=A0auto s =3D initArray!( S )( =E0=BA=95( 1, "a" ), =E0=BA=95(= 2, "b" ), =E0=BA=95( 3, "c" ) );<br><div class=3D"gmai= l_quote"><blockquote class=3D"gmail_quote" style=3D"border-left: 1px solid = rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> <br> If =E0=BA=95 is too hard to type, choose another short name.<br></blockquot= e><div><br>Nice looking character. Indian, hebrew?<br><br>When I want an al= most non-visible char, I tend tu use _, just _.<br><br>Philippe<br><br><br>= =C2=A0<br> </div></div> --0015174ff13cf96a4c047de42b7c--
Jan 23 2010









bearophile <bearophileHUGS lycos.com> 