#include <iostream>
#include <type_traits>
#define CREATE_CLALLER( cls, method ) \
struct method { \
void operator()( cls* obj ) { \
obj->method(); \
} \
}
// classes
struct Base {
void BaseMethod1(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
void BaseMethod2(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
void BaseMethod3(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
};
CREATE_CLALLER( Base, BaseMethod1 );
CREATE_CLALLER( Base, BaseMethod2 );
CREATE_CLALLER( Base, BaseMethod3 );
struct A final : Base {
void A_Specific_Operations(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
void doSomething();
};
CREATE_CLALLER( A, A_Specific_Operations );
struct B final : Base {
void B_Specific_Operations(){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
void doSomething();
};
CREATE_CLALLER( B, B_Specific_Operations );
/// utilities
struct a_tag { };
struct b_tag { };
template < typename... Strategy >
struct strategy_list { };
template < typename Target, typename First, typename... Last >
void execute_strategies( Target* target, strategy_list<First,Last...> ) {
First()( target );
execute_strategies( target, strategy_list<Last...>() );
}
template < typename Target >
void execute_strategies( Target* target, strategy_list<> ) { }
template < typename Tag >
using make_steps = strategy_list<
BaseMethod1
, typename std::conditional<
!std::is_same<Tag,b_tag>::value
, BaseMethod2
, B_Specific_Operations
>::type
, typename std::conditional<
!std::is_same<Tag,a_tag>::value
, BaseMethod2
, A_Specific_Operations
>::type
, BaseMethod3
>;
// implement codes
void A::doSomething() {
execute_strategies( this, make_steps<a_tag>() );
}
void B::doSomething() {
execute_strategies( this, make_steps<b_tag>() );
}
int main() {
using namespace std;
A().doSomething();
cout << endl;
B().doSomething();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgojZGVmaW5lIENSRUFURV9DTEFMTEVSKCBjbHMsIG1ldGhvZCApIFwKICAgIHN0cnVjdCBtZXRob2QgeyBcCiAgICAgICAgdm9pZCBvcGVyYXRvcigpKCBjbHMqIG9iaiApIHsgXAogICAgICAgICAgICBvYmotPm1ldGhvZCgpOyBcCiAgICAgICAgfSBcCiAgICB9CgovLyBjbGFzc2VzCnN0cnVjdCBCYXNlIHsKICAgIHZvaWQgQmFzZU1ldGhvZDEoKXsgc3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgc3RkOjplbmRsOyB9CiAgICB2b2lkIEJhc2VNZXRob2QyKCl7IHN0ZDo6Y291dCA8PCBfX1BSRVRUWV9GVU5DVElPTl9fIDw8IHN0ZDo6ZW5kbDsgfQogICAgdm9pZCBCYXNlTWV0aG9kMygpeyBzdGQ6OmNvdXQgPDwgX19QUkVUVFlfRlVOQ1RJT05fXyA8PCBzdGQ6OmVuZGw7IH0KfTsKQ1JFQVRFX0NMQUxMRVIoIEJhc2UsIEJhc2VNZXRob2QxICk7CkNSRUFURV9DTEFMTEVSKCBCYXNlLCBCYXNlTWV0aG9kMiApOwpDUkVBVEVfQ0xBTExFUiggQmFzZSwgQmFzZU1ldGhvZDMgKTsKCnN0cnVjdCBBIGZpbmFsIDogQmFzZSB7CiAgICAgdm9pZCBBX1NwZWNpZmljX09wZXJhdGlvbnMoKXsgc3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgc3RkOjplbmRsOyB9CiAgICAgdm9pZCBkb1NvbWV0aGluZygpOwp9OwpDUkVBVEVfQ0xBTExFUiggQSwgQV9TcGVjaWZpY19PcGVyYXRpb25zICk7CgpzdHJ1Y3QgQiBmaW5hbCA6IEJhc2UgewogICAgIHZvaWQgQl9TcGVjaWZpY19PcGVyYXRpb25zKCl7IHN0ZDo6Y291dCA8PCBfX1BSRVRUWV9GVU5DVElPTl9fIDw8IHN0ZDo6ZW5kbDsgfQogICAgIHZvaWQgZG9Tb21ldGhpbmcoKTsKfTsKQ1JFQVRFX0NMQUxMRVIoIEIsIEJfU3BlY2lmaWNfT3BlcmF0aW9ucyApOwoKLy8vIHV0aWxpdGllcwpzdHJ1Y3QgYV90YWcgeyB9OwpzdHJ1Y3QgYl90YWcgeyB9OwoKdGVtcGxhdGUgPCB0eXBlbmFtZS4uLiBTdHJhdGVneSA+IApzdHJ1Y3Qgc3RyYXRlZ3lfbGlzdCB7IH07Cgp0ZW1wbGF0ZSA8IHR5cGVuYW1lIFRhcmdldCwgdHlwZW5hbWUgRmlyc3QsIHR5cGVuYW1lLi4uIExhc3QgPgp2b2lkIGV4ZWN1dGVfc3RyYXRlZ2llcyggVGFyZ2V0KiB0YXJnZXQsIHN0cmF0ZWd5X2xpc3Q8Rmlyc3QsTGFzdC4uLj4gKSB7CiAgICBGaXJzdCgpKCB0YXJnZXQgKTsKICAgIGV4ZWN1dGVfc3RyYXRlZ2llcyggdGFyZ2V0LCBzdHJhdGVneV9saXN0PExhc3QuLi4+KCkgKTsKfQoKdGVtcGxhdGUgPCB0eXBlbmFtZSBUYXJnZXQgPgp2b2lkIGV4ZWN1dGVfc3RyYXRlZ2llcyggVGFyZ2V0KiB0YXJnZXQsIHN0cmF0ZWd5X2xpc3Q8PiApIHsgfQoKdGVtcGxhdGUgPCB0eXBlbmFtZSBUYWcgPgp1c2luZyBtYWtlX3N0ZXBzID0gc3RyYXRlZ3lfbGlzdDwKICAgIEJhc2VNZXRob2QxCiAgICAsIHR5cGVuYW1lIHN0ZDo6Y29uZGl0aW9uYWw8IAogICAgICAgICFzdGQ6OmlzX3NhbWU8VGFnLGJfdGFnPjo6dmFsdWUKICAgICAgICAsIEJhc2VNZXRob2QyCiAgICAgICAgLCBCX1NwZWNpZmljX09wZXJhdGlvbnMKICAgICAgPjo6dHlwZQogICAgLCB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPCAKICAgICAgICAhc3RkOjppc19zYW1lPFRhZyxhX3RhZz46OnZhbHVlCiAgICAgICAgLCBCYXNlTWV0aG9kMgogICAgICAgICwgQV9TcGVjaWZpY19PcGVyYXRpb25zCiAgICAgID46OnR5cGUKICAgICwgQmFzZU1ldGhvZDMKPjsKCi8vIGltcGxlbWVudCBjb2Rlcwp2b2lkIEE6OmRvU29tZXRoaW5nKCkgewogICAgZXhlY3V0ZV9zdHJhdGVnaWVzKCB0aGlzLCBtYWtlX3N0ZXBzPGFfdGFnPigpICk7Cn0KCnZvaWQgQjo6ZG9Tb21ldGhpbmcoKSB7CiAgICBleGVjdXRlX3N0cmF0ZWdpZXMoIHRoaXMsIG1ha2Vfc3RlcHM8Yl90YWc+KCkgKTsKfQoKaW50IG1haW4oKSB7CiAgICAKICAgIHVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAgICAKICAgIEEoKS5kb1NvbWV0aGluZygpOwogICAgY291dCA8PCBlbmRsOwogICAgQigpLmRvU29tZXRoaW5nKCk7Cn0=