DSL tokens need to be equality comparable

and this adds a twist: conceptually, we identify the token
with the abstract handler function it represents. But C++
does not allow us to compare member pointers to virtual functions,
for good reason: even two pointers with the "same offset" into
the VTable might end up referring to different implementations,
when bound to instances of different subclasses. This is what
polymorphism is all about.

At this point it seems reasonably, albeit a bit uggly, to use the
diagnostic ID as placeholder instead, and just compare these IDs
instead. We assume that in practice tokens will be defined through
the provided helper macro, which ensures unique identifiers.
This commit is contained in:
Fischlurch 2015-01-02 11:31:29 +01:00
parent cd85b3425e
commit ee941996c4

View file

@ -65,6 +65,10 @@ namespace lib {
* as defined in the "receiver" interface (parameter \c REC).
* The token is typically part of a DSL and can be applied
* to a concrete receiver subclass.
* @remarks while the included ID Literal is mostly for diagnostics,
* it also serves as identity for comparisons. Conceptually what
* we want is to compare the function "offset", but this leads
* into relying on implementation defined behaviour.
* @note the #VERB macro simplifies definition of actual tokens
*/
template<class REC, class SIG>
@ -94,6 +98,19 @@ namespace lib {
: handler_(handlerFunction)
, token_(token)
{ }
bool
operator== (VerbToken const& o) const ///< @remarks member pointers to virtual functions aren't comparable, for good reason
{
return token_ == o.token_;
}
bool
operator!= (VerbToken const& o) const
{
return token_ != o.token_;
}
};
#define VERB(RECEIVER, FUN) VERB_##FUN (&RECEIVER::FUN, STRINGIFY(FUN))