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 !