www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Confused by struct constructors

reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
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
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
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
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--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">&lt;<a href=3D"mailto:simen.kjaras gmail.com">simen= .kjaras gmail.com</a>&gt;</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 &gt; 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 &gt; 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 &gt;= 0<br>=A0=A0=A0 &amp;&amp; (is(typeof( T( args[ 0..T.tupleof.length ] ) ) )= )<br>=A0=A0=A0 &amp;&amp; ( 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
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
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
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--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, &quot;a&quot; ), =E0=BA=95(= 2, &quot;b&quot; ), =E0=BA=95( 3, &quot;c&quot; ) );<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