Thread overview
Structure initialization
May 07, 2007
Sheff
May 07, 2007
Olli Aalto
May 07, 2007
Sheff
May 07, 2007
Daniel Keep
May 08, 2007
Sheff
May 07, 2007
Hi, everyone!
Can anybody tell me how to partially initialize a structure in place, i.e:
I have a structure:

struct Props
{
int flag = 1;
int state = 0;
}
and a function:
void f(Props p);

And I want to pass an instance of Props to f with only some fields initialized, right now I have to write like this:
f(Props(1,1000));
but I want to be able to write something like this:
f(Props(state:1000));
But that doesn't work, is there a way I can make it work ?
May 07, 2007
Sheff wrote:
> Hi, everyone!
> Can anybody tell me how to partially initialize a structure in place, i.e:
> I have a structure:
> 
> struct Props
> {
> int flag = 1;
> int state = 0;
> }
> and a function:
> void f(Props p);
> 
> And I want to pass an instance of Props to f with only some fields initialized, right now I have to write like this:
> f(Props(1,1000));
> but I want to be able to write something like this:
> f(Props(state:1000));
> But that doesn't work, is there a way I can make it work ?

You might want to try something like this:

module props;

import tango.io.Stdout;

struct Props
{
    int flag = 1;
    int state = 0;

    public static Props opCall(int state)
    {
        Props p;
        p.state = state;
        return p;
    }
}

int f(Props props)
{
    return props.state;
}

void main()
{
     int state = f(Props(3));
     Stdout(state).newline;
}

O.
May 07, 2007
Olli Aalto Wrote:

> Sheff wrote:
> > Hi, everyone!
> > Can anybody tell me how to partially initialize a structure in place, i.e:
> > I have a structure:
> > 
> > struct Props
> > {
> > int flag = 1;
> > int state = 0;
> > }
> > and a function:
> > void f(Props p);
> > 
> > And I want to pass an instance of Props to f with only some fields initialized, right now I have to write like this:
> > f(Props(1,1000));
> > but I want to be able to write something like this:
> > f(Props(state:1000));
> > But that doesn't work, is there a way I can make it work ?
> 
> You might want to try something like this:
> 
> module props;
> 
> import tango.io.Stdout;
> 
> struct Props
> {
>      int flag = 1;
>      int state = 0;
> 
>      public static Props opCall(int state)
>      {
>          Props p;
>          p.state = state;
>          return p;
>      }
> }
> 
> int f(Props props)
> {
>      return props.state;
> }
> 
> void main()
> {
>       int state = f(Props(3));
>       Stdout(state).newline;
> }
> 
> O.

Hm, that's not exactly what I meant, you see, there may be hundreds of fields in a structure, and I want to initialize only some of them, for example:
struct A
{
int f1 = default_1;
int f2 = default_2;
...
int f100 = default_100;
}
and what I want is to write
f(A(f3:some_other_value,f50:some_another_value));
instead of
f(A(default_1, default_2, some_other_value, default_4, ..., default_49, some_another_value, ..., default_100));

I mean, there may be different combinations, I want to be able to write like this:
f(A(f3:some_other_value,f50:some_another_value));
or like this:
f(A(f12:some_other_value,f7:some_another_value,f13:some_another_value_2));
or etc...
May 07, 2007

Sheff wrote:
> Olli Aalto Wrote:
> 
>> Sheff wrote:
>>> Hi, everyone!
>>> Can anybody tell me how to partially initialize a structure in place, i.e:
>>> I have a structure:
>>>
>>> struct Props
>>> {
>>> int flag = 1;
>>> int state = 0;
>>> }
>>> and a function:
>>> void f(Props p);
>>>
>>> And I want to pass an instance of Props to f with only some fields initialized, right now I have to write like this:
>>> f(Props(1,1000));
>>> but I want to be able to write something like this:
>>> f(Props(state:1000));
>>> But that doesn't work, is there a way I can make it work ?
>> You might want to try something like this:
>>
>> module props;
>>
>> import tango.io.Stdout;
>>
>> struct Props
>> {
>>      int flag = 1;
>>      int state = 0;
>>
>>      public static Props opCall(int state)
>>      {
>>          Props p;
>>          p.state = state;
>>          return p;
>>      }
>> }
>>
>> int f(Props props)
>> {
>>      return props.state;
>> }
>>
>> void main()
>> {
>>       int state = f(Props(3));
>>       Stdout(state).newline;
>> }
>>
>> O.
> 
> Hm, that's not exactly what I meant, you see, there may be hundreds of fields in a structure, and I want to initialize only some of them, for example:
> struct A
> {
> int f1 = default_1;
> int f2 = default_2;
> ....
> int f100 = default_100;
> }
> and what I want is to write
> f(A(f3:some_other_value,f50:some_another_value));
> instead of
> f(A(default_1, default_2, some_other_value, default_4, ..., default_49, some_another_value, ..., default_100));
> 
> I mean, there may be different combinations, I want to be able to write like this:
> f(A(f3:some_other_value,f50:some_another_value));
> or like this:
> f(A(f12:some_other_value,f7:some_another_value,f13:some_another_value_2));
> or etc...

The only way I can think of doing what you want is to make a template for it.

T make(T)()
{
    return T.init;
}

T make(T, argsT...)(argsT args)
{
    assert( args.length & 1 == 0 );
    T result;

    foreach( i,_ ; args )
        static if( i & 1 == 0 )
	        mixin(`result.`~args[i]~` = args[i+1];`);

    return result;
}

...

f(make!(A,"f3","f50")(some_other_value,some_another_value));

WARNING: I just woke up, and the above has *not* been tested.  YMMV :)

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 08, 2007
Daniel Keep Wrote:

> 
> 
> Sheff wrote:
> > Olli Aalto Wrote:
> > 
> >> Sheff wrote:
> >>> Hi, everyone!
> >>> Can anybody tell me how to partially initialize a structure in place, i.e:
> >>> I have a structure:
> >>>
> >>> struct Props
> >>> {
> >>> int flag = 1;
> >>> int state = 0;
> >>> }
> >>> and a function:
> >>> void f(Props p);
> >>>
> >>> And I want to pass an instance of Props to f with only some fields initialized, right now I have to write like this:
> >>> f(Props(1,1000));
> >>> but I want to be able to write something like this:
> >>> f(Props(state:1000));
> >>> But that doesn't work, is there a way I can make it work ?
> >> You might want to try something like this:
> >>
> >> module props;
> >>
> >> import tango.io.Stdout;
> >>
> >> struct Props
> >> {
> >>      int flag = 1;
> >>      int state = 0;
> >>
> >>      public static Props opCall(int state)
> >>      {
> >>          Props p;
> >>          p.state = state;
> >>          return p;
> >>      }
> >> }
> >>
> >> int f(Props props)
> >> {
> >>      return props.state;
> >> }
> >>
> >> void main()
> >> {
> >>       int state = f(Props(3));
> >>       Stdout(state).newline;
> >> }
> >>
> >> O.
> > 
> > Hm, that's not exactly what I meant, you see, there may be hundreds of fields in a structure, and I want to initialize only some of them, for example:
> > struct A
> > {
> > int f1 = default_1;
> > int f2 = default_2;
> > ....
> > int f100 = default_100;
> > }
> > and what I want is to write
> > f(A(f3:some_other_value,f50:some_another_value));
> > instead of
> > f(A(default_1, default_2, some_other_value, default_4, ..., default_49, some_another_value, ..., default_100));
> > 
> > I mean, there may be different combinations, I want to be able to write like this:
> > f(A(f3:some_other_value,f50:some_another_value));
> > or like this:
> > f(A(f12:some_other_value,f7:some_another_value,f13:some_another_value_2));
> > or etc...
> 
> The only way I can think of doing what you want is to make a template for it.
> 
> T make(T)()
> {
>     return T.init;
> }
> 
> T make(T, argsT...)(argsT args)
> {
>     assert( args.length & 1 == 0 );
>     T result;
> 
>     foreach( i,_ ; args )
>         static if( i & 1 == 0 )
> 	        mixin(`result.`~args[i]~` = args[i+1];`);
> 
>     return result;
> }
> 
> ...
> 
> f(make!(A,"f3","f50")(some_other_value,some_another_value));
> 
> WARNING: I just woke up, and the above has *not* been tested.  YMMV :)
> 
> 	-- Daniel
> 
> -- 
> int getRandomNumber()
> {
>     return 4; // chosen by fair dice roll.
>               // guaranteed to be random.
> }
> 
> http://xkcd.com/
> 
> v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
Ok, thanks for your reply, I'll check this out.