What is the "right" way to create a generic type getter (and setter) ?

James Blachly james.blachly at gmail.com
Wed Mar 14 22:13:54 UTC 2018


For context, please keep in mind I am coming from a python 
background, but am very much enjoying strong typing, although it 
is taking some significant adjustment.

Suppose I have a struct (which is really a memory map of a data 
file I am reading in) with too many data members to reasonably 
code getters/setters for by hand.  I wish to either retrieve 
individual values or set individual values, which could be 
numeric, boolean, or string, from the command line, à la:

$ prog -i inputfile.bin get field_name;
(prints "300" or "false" or "Welcome to the jungle")

$ prog -i inputfile.bin set some_field:9000
$ prog -i inputfile.bin set other_field:Whatever_String

Each field itself is strongly typed, for what that's worth.

Approaches I have considered and implemented in part are:
     * templated getter (T get(T)(string field) {...}) but this 
approach requires knowledge of field types which I cannot 
reasonably expect to know at runtime(?)
     *  modification to the above whereby I could have an AA 
holding type information for each field, generated by static 
foreach {mixin ...}, although I cannot get this to work as my 
struct's static constructor complains (rightly) that it cannot 
work without knowing 'this' at compile time. Code: 
`mixin("field_types[\"" ~ prop ~ "\"] = typeid(this." ~ prop ~ 
");");`  Is there another __trait I am missing that will give me 
the type of the struct member without requiring an instance of 
the struct?

I did manage to use metaprogramming inside my templated get 
function to handle numeric values, which was fascinating  
(although this is probably ugly code and it required a large enum 
array FIELDS):

```
         GetterSwitch:
         switch (field)
         {
             static foreach(prop; FIELDS ) {
                 mixin("case \"" ~ prop ~ "\": val = this." ~ prop 
~ "; break GetterSwitch;");
             }
             default:
                 val = 0;
                 assert(0);  // This is to prevent subtle bugs, 
but I need a better error handler
         }
```


Any pointers / design patterns on this particular type of problem 
class would be greatly appreciated.  (Sidenote, I realize I could 
probably use the witchcraft library, but I am also using this as 
exercise to learn D beyond the basics).

Thanks in advance
James




More information about the Digitalmars-d-learn mailing list