www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How'd I store possible types for each item of a list of Variants ?

reply oleobal <olivier.contrib leobal.eu> writes:
Hello,

I'm writing a small parser for some command line app. A given 
command-line parameter can be of one of multiple types, so I 
thought I'd store this type information somewhere and make use of 
it in a function such as this:

   Algebraic!T parse(T...)(string s)
   {
     foreach(t; T)
     {
       try
         return Algebraic!T(to!t(s));
       catch (Exception e)
       { }
     }
   assert(0);
   }

My issue is storing the that type information in a way that makes 
sense, the compiler can understand, and requires as little change 
as possible when a new one is added. Ideally, I'd have some kind 
of associative array that would direct command-line flags to the 
object:

   Algebraic!(ulong, string) number = "any"; // default value
   Algebraic!T[string] params = ["-n": number, "--number": number];

   // parse the value
   params[args[i]] = 
parse!(params[args[i]].AllowedTypes)(args[i+1]);


But obviously, this is not legal code, as I can't define a 
pointer to "Algebraic!T".

No problem, I thought. Simply define a Parameter class to wrap 
around the variant, and then a templated "TypedParameter" class 
that inherits it. This way, I can define an array of Parameter 
values. Here are some definitions:

   class Parameter
   {
     Variant value;
   }
   class TypedParameter(T...): Parameter
   {
     Algebraic!(T) value;
   }


Let's try it:

   Parameter number = new TypedParameter!(ulong, string)();
   number.value = "any";
   Parameter[string] params = ["-n": number];


This compiles fine. However, parsing..

   params[args[i]].value = 
parse!(params[args[i]].value.AllowedTypes)(args[i+1]);

   > Error: array index [0] is outside array bounds [0 .. 0]


My understanding is D has no dynamic dispatch, so .AllowedTypes 
results in an empty list, because the base "Parameter" class uses 
a generic Variant.


I'm kind of out of ideas at this point. Would anyone have an 
elegant solution to this problem?

Thanks !
Sep 20 2019
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/20/2019 01:58 AM, oleobal wrote:

 My understanding is D has no dynamic dispatch,
That's too general. :) D has dynamic dispatch through virtual functions. I don't understand everything here but I think the 'typeid' expression and the 'TypeInfo' class hierarnhy that it returns can be useful in this case. Ali
Sep 20 2019
parent oleobal <olivier.contrib leobal.eu> writes:
Thanks for the help!

On Friday, 20 September 2019 at 10:13:49 UTC, Ali Çehreli wrote:
 I don't understand everything here
My bad, I guess once one spends too much time on a problem, it gets hard to explain. What if I put it this way ? TypedParameter!(ulong, int, string) p1 = new TypedParameter!(ulong, int, string)(); Parameter p2 = new TypedParameter!(ulong, int, string)(); writeln(typeid(p1.value.AllowedTypes)); // (ulong,int,immutable(char)[]) writeln(typeid(p2.value.AllowedTypes)); // () My dream would be a way to make that last statement return the same thing as the penultimate one.. If that even is possible.
 the 'typeid' expression and the 'TypeInfo' class hierarchy that 
 it returns can be useful in this case.
I can get the correct TypeInfo through virtual functions by adding a method like this to Parameter and its sub-classes: override TypeInfo_Tuple allowedTypes() { return typeid(this.value.AllowedTypes); } But as far as I know, I can't use this for instantiating templates, can I ? Especially since `this` doesn't exist at compile time.
Sep 20 2019
prev sibling parent reply Andrea Fontana <nospam example.com> writes:
On Friday, 20 September 2019 at 08:58:09 UTC, oleobal wrote:
 I'm kind of out of ideas at this point. Would anyone have an 
 elegant solution to this problem?

 Thanks !
Is this ok for you: https://run.dlang.io/is/VllpJk ? Andrea
Sep 20 2019
parent oleobal <olivier.contrib leobal.eu> writes:
On Friday, 20 September 2019 at 12:35:05 UTC, Andrea Fontana 
wrote:
 Is this ok for you: https://run.dlang.io/is/VllpJk ?
This is great, thanks!
Sep 20 2019