Thread overview
How'd I store possible types for each item of a list of Variants ?
Sep 20, 2019
oleobal
Sep 20, 2019
Ali Çehreli
Sep 20, 2019
oleobal
Sep 20, 2019
Andrea Fontana
Sep 20, 2019
oleobal
September 20, 2019
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 !


September 20, 2019
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

September 20, 2019
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.
September 20, 2019
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

September 20, 2019
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!