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:
parent
cd85b3425e
commit
ee941996c4
1 changed files with 17 additions and 0 deletions
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in a new issue