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 !


Reply via email to