Tuple enhancement

Idan Arye via Digitalmars-d digitalmars-d at puremagic.com
Tue Oct 18 03:09:07 PDT 2016


On Sunday, 16 October 2016 at 13:58:51 UTC, Andrei Alexandrescu 
wrote:
> I was thinking it would be handy if tuples had a way to access 
> a field by name at runtime. E.g.:
>
> Tuple!(int, "a", double, "b") t;
> string x = condition ? "a" : "b";
> double v = t.get!string(x, 3.14);
>
> The get method takes the field name and the type of the 
> presumed field, and it returns the value of the field in the 
> tuple. If no field by that name and type, return the second 
> argument.
>
> Rquirements:
>
> * Do not throw - allow the second argument to be a throwing 
> delegate
>
> * Do not add overhead if the method is never used
>
> * Figure out a reasonable (but not all too complicated) way to 
> deal with implicit conversions, e.g. if x == "a" in the the 
> code above, should it return 3.14 or convert the int to double?
>
> * Handle qualifiers appropriately
>
>
> Andrei

When I need to choose at runtime a value out of multiple choices 
with different types(all available at compile-time), and handle 
them similarly, I like to use something like this:

     import std.stdio;
     import std.typecons;
     import std.conv;

     auto getAnd(alias dlg, T)(T tup, string key) {
         final switch (key) foreach (fieldName; T.fieldNames) {
             case fieldName:
                 return dlg(__traits(getMember, tup, fieldName));
         }
     }

     void main() {
         Tuple!(int, "a", double, "b") t;

         t.a = 3;
         t.b = 3.14;

         string toString(string key) {
             return t.getAnd!(x => x.to!string)(key);
         }

         assert (toString("a") == "3");
         assert (toString("b") == "3.14");
     }


The idea is to pass a delegate as an "alias", and instantiate it 
multiple times, once for each field. This means that instead of 
being forced to convert them to a common type, we can write once 
code that uses the correct type for each field.


More information about the Digitalmars-d mailing list