#include <iostream>
using namespace std;
#define SUPER_BASE(clazz) using this_class = clazz
#define SUPER(clazz) \
using inherited = this_class; \
using this_class = clazz
struct VeryBase
{
SUPER_BASE(VeryBase);
virtual void foo() { cout << "foo::VeryBase\n"; }
};
struct Derived : public VeryBase
{
SUPER(Derived);
void foo() override { inherited::foo(); }
};
struct MoreDerived : public Derived
{
SUPER(MoreDerived);
MoreDerived()
: inherited()
{}
void foo() override { inherited::foo(); }
};
void f(VeryBase) { cout << "VeryBase\n"; }
void f(Derived) { cout << "Derived\n"; }
void f(MoreDerived) { cout << "MoreDerived\n"; }
int main() {
f(MoreDerived::this_class());
f(MoreDerived::inherited());
f(Derived::this_class());
f(Derived::inherited());
MoreDerived md;
md.foo();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKI2RlZmluZSBTVVBFUl9CQVNFKGNsYXp6KSB1c2luZyB0aGlzX2NsYXNzID0gY2xhenoKCiNkZWZpbmUgU1VQRVIoY2xhenopIFwKCQl1c2luZyBpbmhlcml0ZWQgPSB0aGlzX2NsYXNzOyBcCgkJdXNpbmcgdGhpc19jbGFzcyA9IGNsYXp6CgkKc3RydWN0IFZlcnlCYXNlCnsKCVNVUEVSX0JBU0UoVmVyeUJhc2UpOwoJCgl2aXJ0dWFsIHZvaWQgZm9vKCkgeyBjb3V0IDw8ICJmb286OlZlcnlCYXNlXG4iOyB9Cn07CgpzdHJ1Y3QgRGVyaXZlZCA6IHB1YmxpYyBWZXJ5QmFzZQp7CglTVVBFUihEZXJpdmVkKTsKCQoJdm9pZCBmb28oKSBvdmVycmlkZSB7IGluaGVyaXRlZDo6Zm9vKCk7IH0KfTsKCnN0cnVjdCBNb3JlRGVyaXZlZCA6IHB1YmxpYyBEZXJpdmVkCnsKCVNVUEVSKE1vcmVEZXJpdmVkKTsKCQoJTW9yZURlcml2ZWQoKQoJCTogaW5oZXJpdGVkKCkKCXt9CgkKCXZvaWQgZm9vKCkgb3ZlcnJpZGUgeyBpbmhlcml0ZWQ6OmZvbygpOyB9Cn07Cgp2b2lkIGYoVmVyeUJhc2UpIHsgY291dCA8PCAiVmVyeUJhc2VcbiI7IH0Kdm9pZCBmKERlcml2ZWQpIHsgY291dCA8PCAiRGVyaXZlZFxuIjsgfQp2b2lkIGYoTW9yZURlcml2ZWQpIHsgY291dCA8PCAiTW9yZURlcml2ZWRcbiI7IH0KCmludCBtYWluKCkgewoJCglmKE1vcmVEZXJpdmVkOjp0aGlzX2NsYXNzKCkpOwoJZihNb3JlRGVyaXZlZDo6aW5oZXJpdGVkKCkpOwoJCglmKERlcml2ZWQ6OnRoaXNfY2xhc3MoKSk7CglmKERlcml2ZWQ6OmluaGVyaXRlZCgpKTsKCQoJTW9yZURlcml2ZWQgbWQ7CgltZC5mb28oKTsKCQoJcmV0dXJuIDA7Cn0=