www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Associative array to Struct at compile time

reply "BlackEdder" <edder tkwsping.nl> writes:
Is it possible to automatically convert an associative array to a
struct?

Basically I want to do the following (for any struct).

struct A {
     double x = 1;
}

double[string] aa = ["x":1];

auto a = toStruct!A( aa );

I've been trying to do this at compile time, but can't work out
how setMembers and or loop over the associative array at compile
time.

Is this possible at all?
Jul 25 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
BlackEdder:

 Is this possible at all?
I think it's possible, as long as your associative array contents are known at compile-time. You can write a function that given the associative array returns a string that mixed-in defines the struct. And then you can define a toStruct template. Bye, bearophile
Jul 25 2014
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Friday, 25 July 2014 at 15:25:43 UTC, BlackEdder wrote:
 Is it possible to automatically convert an associative array to 
 a
 struct?

 Basically I want to do the following (for any struct).

 struct A {
     double x = 1;
 }

 double[string] aa = ["x":1];

 auto a = toStruct!A( aa );

 I've been trying to do this at compile time, but can't work out
 how setMembers and or loop over the associative array at compile
 time.

 Is this possible at all?
one possible way: enum aa = ["x": 1]; import std.traits; struct AAtoStruct(alias aa) if(isAssociativeArray!(typeof(aa)) && isSomeString!(KeyType!(typeof(aa)))) { alias T = ValueType!(typeof(aa)); import std.range, std.algorithm, std.array; mixin(zip(aa.keys, aa.values) .map!`"T " ~ a[0] ~ " = " ~ a[1].to!string ~ ";\n"` .joiner.array); } alias S = AAtoStruct!aa;
Jul 25 2014
parent "BlackEdder" <edder tkwsping.nl> writes:
On Friday, 25 July 2014 at 15:48:54 UTC, John Colvin wrote:
 On Friday, 25 July 2014 at 15:25:43 UTC, BlackEdder wrote:
 Is it possible to automatically convert an associative array 
 to a
 struct?

 Basically I want to do the following (for any struct).

 struct A {
    double x = 1;
 }

 double[string] aa = ["x":1];

 auto a = toStruct!A( aa );

 I've been trying to do this at compile time, but can't work out
 how setMembers and or loop over the associative array at 
 compile
 time.

 Is this possible at all?
one possible way: enum aa = ["x": 1]; import std.traits; struct AAtoStruct(alias aa) if(isAssociativeArray!(typeof(aa)) && isSomeString!(KeyType!(typeof(aa)))) { alias T = ValueType!(typeof(aa)); import std.range, std.algorithm, std.array; mixin(zip(aa.keys, aa.values) .map!`"T " ~ a[0] ~ " = " ~ a[1].to!string ~ ";\n"` .joiner.array); } alias S = AAtoStruct!aa;
The associative array is actually not known at compile time. I got it working though: unittest { T toStruct( T )( double[string] aa ) { T t; foreach (name; __traits(allMembers, T)) { static if( __traits(compiles, __traits(getMember, t, name)) // Skip Functions && !isSomeFunction!(__traits(getMember, t, name) ) ) { mixin( "t." ~ name ~ "= aa[\"" ~ name ~ "\"];" ); } } return t; } struct A { double x = -1; } double[string] aa = ["x":1]; auto a = toStruct!A( aa ); assert( a.x == 1 ); }
Jul 25 2014