Dispatching on a variant
Jeremie Pelletier
jeremiep at gmail.com
Sat Sep 26 09:25:23 PDT 2009
Justin Johansson wrote:
> language_fan Wrote:
>
>> Sat, 26 Sep 2009 09:32:55 -0400, Justin Johansson thusly wrote:
>>
>>> I've had a good poke around the forums and couldn't find anything on
>>> this so ...
>>>
>>> What's the recommended method for dispatching code off the runtime type
>>> of a variant variable (Phobos D2 std.variant)?
>>>
>>> Does one use a bunch of
>>>
>>> if ( var.peek!(type1)) { ... }
>>> else if ( var.peek!(type2) { ... }
>>>
>>> for all N possible types, or is there a better & faster way with a
>>> switch or jump table of sorts?
>> If the type count gets large, how fast it is depends on the backend
>> optimizations of the compiler. In the worst case it is a O(n) time linear
>> search. A jump table or almost any other way of dispatching would be
>> faster. If the variant had an integral tag field, it could be used in a
>> switch; that way the compiler could easily optimize it further with the
>> currently available constructs.
>>
>> This problem is solved in higher level languages by providing pattern
>> matching constructs. The compiler is free to optimize the code the way it
>> likes:
>>
>> case var of
>> type1 => ...
>> type2 => ...
>> ...
>>
>> But since no C-like language has ever implemented pattern matching, it
>> might be too radical to add it to D.
>
> Thanks both for replies.
>
> I've got about 2 dozen types in the variant so the O(n) really hurts.
> The variant thing seemed like a really cool idea at the time but now ...
> Without something like suggested above or a computed goto on typeid or Andrei's visitator,
> it almost pushes me to backout from using variants and having to redesign around some common base class or interface and using virtual function dispatch. :-(
>
I see this sort of design in C all the time with event handling,
although its with unions rather than discriminated unions, the same
logic applies.
enum EventType {
Mouse,
Key,
Move,
...
}
struct Event {
EventType type;
union {
MouseEvent mouse;
KeyEvent key;
MoveEvent move;
...
}
}
void dispatchEvent(const(Event)* event) {
...
with(EventType) final switch(event.type) {
case Mouse: ...
case Key: ...
case Move: ...
...
}
...
}
That's the logic with standard unions, you should be able to get
something similar with variants. It's more code to setup, but you end up
with a simple jump table from the switch, and final in D makes it easy
to change EventType without forgetting to update dispatchEvent.
More information about the Digitalmars-d
mailing list