#include <iostream>
#define declare_member_check(name, ret_type, /*args*/ ...) \
namespace member_check{ \
template <typename T> \
struct has_##name \
{ \
struct Yes{char junk[2];}; \
using No = char; \
\
template <typename U, ret_type (U::*)(__VA_ARGS__)> \
struct Checker { }; \
\
template <typename U> static Yes test(Checker<U, &U::name> *); \
template <typename U> static No test(...); \
static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(Yes); \
};\
}\
struct Test {
const std::string &print(const std::string &str, void *pointer, int *second) {
std::cout<<str<<std::endl;
return str;
}
};
struct Test2 {
void show_msg(){}
};
declare_member_check(show_msg, void);
declare_member_check(print, const std::string &, const std::string &, void *, int *);
int main()
{
std::cout<<"Check show_msg"<<std::endl;
std::cout<<member_check::has_show_msg<Test>::value<<std::endl;
std::cout<<member_check::has_show_msg<Test2>::value<<std::endl;
std::cout<<"Check print msg"<<std::endl;
std::cout<<member_check::has_print<Test>::value<<std::endl;
std::cout<<member_check::has_print<Test2>::value<<std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKI2RlZmluZSBkZWNsYXJlX21lbWJlcl9jaGVjayhuYW1lLCByZXRfdHlwZSwgLyphcmdzKi8gLi4uKSBcCm5hbWVzcGFjZSBtZW1iZXJfY2hlY2t7IFwKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IFwKc3RydWN0IGhhc18jI25hbWUgXAp7IFwKICAgIHN0cnVjdCBZZXN7Y2hhciBqdW5rWzJdO307IFwKICAgIHVzaW5nIE5vID0gY2hhcjsgXAogXAogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFUsIHJldF90eXBlIChVOjoqKShfX1ZBX0FSR1NfXyk+IFwKICAgIHN0cnVjdCBDaGVja2VyIHsgfTsgXApcCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gc3RhdGljIFllcyB0ZXN0KENoZWNrZXI8VSwgJlU6Om5hbWU+ICopOyBcCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVT4gc3RhdGljIE5vIHRlc3QoLi4uKTsgXAogICAgc3RhdGljIGNvbnN0ZXhwciBib29sIHZhbHVlID0gc2l6ZW9mKHRlc3Q8VD4obnVsbHB0cikpID09IHNpemVvZihZZXMpOyBcCn07XAp9XAoKc3RydWN0IFRlc3QgewogICAgY29uc3Qgc3RkOjpzdHJpbmcgJnByaW50KGNvbnN0IHN0ZDo6c3RyaW5nICZzdHIsIHZvaWQgKnBvaW50ZXIsIGludCAqc2Vjb25kKSB7CiAgICAgICAgc3RkOjpjb3V0PDxzdHI8PHN0ZDo6ZW5kbDsKICAgICAgICByZXR1cm4gc3RyOwogICAgfQp9OwpzdHJ1Y3QgVGVzdDIgewogICAgdm9pZCBzaG93X21zZygpe30KfTsKCmRlY2xhcmVfbWVtYmVyX2NoZWNrKHNob3dfbXNnLCB2b2lkKTsKZGVjbGFyZV9tZW1iZXJfY2hlY2socHJpbnQsIGNvbnN0IHN0ZDo6c3RyaW5nICYsIGNvbnN0IHN0ZDo6c3RyaW5nICYsIHZvaWQgKiwgaW50ICopOwoKaW50IG1haW4oKQp7CiAgICBzdGQ6OmNvdXQ8PCJDaGVjayBzaG93X21zZyI8PHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dDw8bWVtYmVyX2NoZWNrOjpoYXNfc2hvd19tc2c8VGVzdD46OnZhbHVlPDxzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQ8PG1lbWJlcl9jaGVjazo6aGFzX3Nob3dfbXNnPFRlc3QyPjo6dmFsdWU8PHN0ZDo6ZW5kbDsKCiAgICBzdGQ6OmNvdXQ8PCJDaGVjayBwcmludCBtc2ciPDxzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQ8PG1lbWJlcl9jaGVjazo6aGFzX3ByaW50PFRlc3Q+Ojp2YWx1ZTw8c3RkOjplbmRsOwogICAgc3RkOjpjb3V0PDxtZW1iZXJfY2hlY2s6Omhhc19wcmludDxUZXN0Mj46OnZhbHVlPDxzdGQ6OmVuZGw7CgogICAgcmV0dXJuIDA7Cn0=