
AMDG On 5/12/25 3:10 PM, Jean-Louis Leroy via Boost wrote:
Can we strip off the virtual_?
struct NAME ## _overrider<...> { template<typename T> using virtual_ = T; ... };
You mean allow virtual_ in the overrider's parameters? The macro gets: meet, (virtual_<Dog&> dog, virtual_<Cat&> cat)
...and it changes into: meet(Dog& dog, Cat& cat)
I don't see a way of doing this while carrying the parameter's names.
The above would make virtual_ into an alias that just expands to its argument, but this only works when virtual_ is used unqualified.
<snip>
It took me a while to see how this could work, and now it's taking me a while to see why it doesn't want to - see https://godbolt.org/z/16nensohc. Probably related to your "order of expansion" comment?
It is appealing but it has problems too. Any comma in the parameter's types will break it.
Not necessarily. You snipped the trick I proposed to deal with that.
YOMM2 uses Boost.PP loops over macro arguments to build the forwarding function, so whenever there is a comma in the parameter types, you have to use tricks like BOOST_IDENTITY_TYPE. For OpenMethod, I moved as much macro-magic to TMP as I could.
#define HAS_VIRTUAL_TESTvirtual ~,~ #define HAS_VIRTUAL_II(a, b, r, ...) r #define HAS_VIRTUAL_I(...) HAS_VIRTUAL_II(__VA_ARGS__) #define HAS_VIRTUAL(arg) HAS_VIRTUAL_I(HAS_VIRTUAL_TEST ## arg, 1, 0, ~) #define REMOVE_VIRTUALvirtual #define REMOVE_VIRTUAL(arg) REMOVE_VIRTUAL ## arg #define IDENTITY(arg) arg #define MARK_VIRTUAL(arg) boost::openmethod::detail::virtual_next, REMOVE_VIRTUAL ## arg #define REMOVE_IF_VIRTUAL(arg) \ BOOST_PP_IIF(HAS_VIRTUAL(arg), REMOVE_VIRTUAL, IDENTITY)(arg) #define MARK_IF_VIRTUAL(arg) \ BOOST_PP_IIF(HAS_VIRTUAL(arg), MARK_VIRTUAL, IDENTITY)(arg) MARK_IF_VIRTUAL(virtual test) REMOVE_IF_VIRTUAL(virtual test) MARK_IF_VIRTUAL(nonvirtual) REMOVE_IF_VIRTUAL(nonvirtual) With this (virtual B, int, virtual C), void becomes void(boost::openmethod::detail::virtual_next, B, int, boost::openmethod::detail::virtual_next, C) which can be turned into void(virtual_<B>, int, virtual_<C>) by TMP. In the function definition, we simply remove the virtual, and everything else, including the argument name is preserved. The main problem is that it blows up when a comma is followed by something that can't be token pasted: (::global, templ<I, (X + Y)>) In Christ, Steven Watanabe