Templated structs / variant values
Marek Janukowicz
marek at janukowicz.net
Mon Aug 19 16:09:16 PDT 2013
Jacob Carlborg wrote:
> On 2013-08-15 00:29, Marek Janukowicz wrote:
>> I need to have a generalized "settings" functionality that should work
>> like this:
>> * I need to be able to add this to a class
>> * each setting has its name, description, type and default value
>> * I need to iterate over all settings for given object
>>
>> API would more or less look like:
>> class A {
>> ... here I somehow define a setting called "maxTime"
>> }
>>
>> A a = new A();
>>
>> auto b = a.settings["maxTime"].value; // b would contain default value,
>> because it wasn't set explicitly yet
>> string s = a.settings["maxTime"].description; // s would contain setting
>> description
>> a.settings["maxTime"].value = 10.seconds; // This would only work if
>> maxTime setting is of type duration
>> foreach( name, value; a.settings ) ...
>>
>> Now the problem that I have is with storing those settings. What I've
>> come up with so far are either Variants or templated structs (either
>> really templated and type parametrized structs returned from template
>> functions). The problem with variants is that I don't know how to force
>> the value to be of certain type (variant accepts anything). As for
>> templates and structs I tried something like:
>>
>> auto setting (string name, string description, T, T deflt)() {
>> struct Setting {
>> string name = name;
>> T value;
>> }
>> return Setting(name, deflt);
>> }
>>
>> but then I don't know if there is any way to build an array of those to
>> be able to iterate over them.
>>
>> I know generally there should be some kind of "setting definition"
>> defined on class level that would keep shared information (like names and
>> defaults) and then per-instance data containing just actual values, but I
>> don't really care and any solution where this shared information is
>> copied for every instance would also be fine.
>>
>> I know the description above is a bit messy (it's quite late now), but
>> hopefully you can get the picture. Any ideas how to approach this
>> problem?
>>
>
> Perhaps you can do something like this:
>
> struct Setting (T, string desc)
> {
> T value;
> enum description = desc;
> alias value this;
>
> this (T value)
> {
> this.value = value;
> }
> }
>
> class A
> {
> Setting!(int, "foo bar") bar = 3;
>
> auto settings ()
> {
> return Tuple!(typeof(bar), "bar")(bar);
> }
> }
>
> void main ()
> {
> auto a = new A;
> assert(a.bar.description == "foo bar");
> assert(a.bar.value == 3);
> assert(a.bar == 3);
> assert(a.settings.bar == 3);
> }
Thank you for this code, I narrowed my requirements a bit and ended up with
this:
struct Setting (T, string desc, T deflt)
{
T value = deflt;
string description = desc;
alias value this;
this (T value)
{
this.value = value;
}
}
class A {
Setting!(int, "Some max int", 10) max;
Setting!(string, "name", "default name") name;
}
This looks very neat to me: definition is provided via template parameters
while the actual value is provided via argument.
> In "settings" you should be able to:
>
> 1. Iterate over all fields of the type Setting using
> __tratis(derivedMembers)
How do I do that? My understanding of types in case of templates is really
poor... If I do something like:
foreach( s; __traits(derivedMembers, typeof(this))) {
how do I go from "s" into type of this member (especially that a type is an
instantiated struct template?). And more generally - how do I check the type
of a variable?
> 2. Create and return tuple of all these fields
>
> But then you won't be able to set the value via "settings".
What I really is need is a JSON of name => value pairs and corresponding
method to update the settings from such JSON structure. Or it may be AA with
Variant values, it's really quite straightforward to convert between one and
the other. But I have a problem of how to get a list of all fields of type
Setting (as mentioned above).
--
Marek Janukowicz
More information about the Digitalmars-d-learn
mailing list