Templated structs / variant values

Jacob Carlborg doob at me.com
Wed Aug 14 23:55:40 PDT 2013


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);
}

In "settings" you should be able to:

1. Iterate over all fields of the type Setting using 
__tratis(derivedMembers)
2. Create and return tuple of all these fields

But then you won't be able to set the value via "settings".

Perhaps a variant is easier, but then you need to tell it what type to 
return, something like:

auto bar = a.settings["bar"].value!(int);

http://dlang.org/traits.html#derivedMembers

-- 
/Jacob Carlborg


More information about the Digitalmars-d-learn mailing list