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