#include <iostream>
#include <type_traits>
#include <string>
#include <utility>
#define create_trait(trait_name, ...)\
std::true_type trait_name##_sfinae(std::decay_t<decltype(__VA_ARGS__)> *);\
template <typename...> std::false_type trait_name##_sfinae(...);\
template <typename... Ts> struct trait_name : decltype(trait_name##_sfinae<Ts...>(nullptr)) {};
template <typename T>
create_trait(has_member_type, std::declval<typename T::type>());
template <typename... Ts>
create_trait(have_common_type, std::declval<std::common_type_t<Ts...>>());
template <typename T1, typename T2>
create_trait(less_than_comparable, std::declval<T1>() < std::declval<T2>());
struct test { using type = void; };
int main()
{
std::cout << has_member_type<int>::value << std::endl;
std::cout << has_member_type<test>::value << std::endl;
std::cout << have_common_type<int, char, bool>::value << std::endl;
std::cout << have_common_type<int, char, std::string>::value << std::endl;
std::cout << less_than_comparable<int, char>::value << std::endl;
std::cout << less_than_comparable<int, std::string>::value << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx1dGlsaXR5PgoKCiNkZWZpbmUgY3JlYXRlX3RyYWl0KHRyYWl0X25hbWUsIC4uLilcCnN0ZDo6dHJ1ZV90eXBlIHRyYWl0X25hbWUjI19zZmluYWUoc3RkOjpkZWNheV90PGRlY2x0eXBlKF9fVkFfQVJHU19fKT4gKik7XAp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IHN0ZDo6ZmFsc2VfdHlwZSB0cmFpdF9uYW1lIyNfc2ZpbmFlKC4uLik7XAp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gVHM+IHN0cnVjdCB0cmFpdF9uYW1lIDogZGVjbHR5cGUodHJhaXRfbmFtZSMjX3NmaW5hZTxUcy4uLj4obnVsbHB0cikpIHt9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CmNyZWF0ZV90cmFpdChoYXNfbWVtYmVyX3R5cGUsIHN0ZDo6ZGVjbHZhbDx0eXBlbmFtZSBUOjp0eXBlPigpKTsKCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUcz4KY3JlYXRlX3RyYWl0KGhhdmVfY29tbW9uX3R5cGUsIHN0ZDo6ZGVjbHZhbDxzdGQ6OmNvbW1vbl90eXBlX3Q8VHMuLi4+PigpKTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+CmNyZWF0ZV90cmFpdChsZXNzX3RoYW5fY29tcGFyYWJsZSwgc3RkOjpkZWNsdmFsPFQxPigpIDwgc3RkOjpkZWNsdmFsPFQyPigpKTsKCnN0cnVjdCB0ZXN0IHsgdXNpbmcgdHlwZSA9IHZvaWQ7IH07CgppbnQgbWFpbigpIAp7CglzdGQ6OmNvdXQgPDwgaGFzX21lbWJlcl90eXBlPGludD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCBoYXNfbWVtYmVyX3R5cGU8dGVzdD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCBoYXZlX2NvbW1vbl90eXBlPGludCwgY2hhciwgYm9vbD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCBoYXZlX2NvbW1vbl90eXBlPGludCwgY2hhciwgc3RkOjpzdHJpbmc+Ojp2YWx1ZSA8PCBzdGQ6OmVuZGw7CglzdGQ6OmNvdXQgPDwgbGVzc190aGFuX2NvbXBhcmFibGU8aW50LCBjaGFyPjo6dmFsdWUgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8IGxlc3NfdGhhbl9jb21wYXJhYmxlPGludCwgc3RkOjpzdHJpbmc+Ojp2YWx1ZSA8PCBzdGQ6OmVuZGw7CglyZXR1cm4gMDsKfQ==