#include <type_traits>
#include <iostream>
// Our test candidates:
struct i_have_foo { void foo() const {} };
struct i_dont { void bazinga() const {} };
int bar(std::ostream) {}
// First checker:
struct _test_has_foo {
template<class T>
static auto test(T* p) -> decltype(p->foo(), std::true_type());
template<class>
static auto test(...) -> std::false_type;
};
template<class T>
struct has_foo : decltype(_test_has_foo::test<T>(0))
{};
// Second checker:
struct _test_is_supported_by_bar {
template<class T>
static auto test(T* p) -> decltype(bar(*p), std::true_type());
template<class>
static auto test(...) -> std::false_type;
};
template<class T>
struct is_supported_by_bar : decltype(_test_is_supported_by_bar::test<T>(0))
{};
// Test:
int main()
{
std::cout << has_foo<i_have_foo>::value << std::endl;
std::cout << has_foo<i_dont>::value << std::endl;
std::cout << std::endl;
std::cout << is_supported_by_bar<std::ostream>::value << std::endl;
std::cout << is_supported_by_bar<std::istream>::value << std::endl;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8aW9zdHJlYW0+CgoKLy8gT3VyIHRlc3QgY2FuZGlkYXRlczoKc3RydWN0IGlfaGF2ZV9mb28geyB2b2lkIGZvbygpIGNvbnN0IHt9IH07CnN0cnVjdCBpX2RvbnQgICAgIHsgdm9pZCBiYXppbmdhKCkgY29uc3Qge30gfTsKaW50IGJhcihzdGQ6Om9zdHJlYW0pIHt9CgoKLy8gRmlyc3QgY2hlY2tlcjoKc3RydWN0IF90ZXN0X2hhc19mb28gewogICAgdGVtcGxhdGU8Y2xhc3MgVD4KICAgIHN0YXRpYyBhdXRvIHRlc3QoVCogcCkgLT4gZGVjbHR5cGUocC0+Zm9vKCksIHN0ZDo6dHJ1ZV90eXBlKCkpOwoKICAgIHRlbXBsYXRlPGNsYXNzPgogICAgc3RhdGljIGF1dG8gdGVzdCguLi4pIC0+IHN0ZDo6ZmFsc2VfdHlwZTsKfTsKdGVtcGxhdGU8Y2xhc3MgVD4Kc3RydWN0IGhhc19mb28gOiBkZWNsdHlwZShfdGVzdF9oYXNfZm9vOjp0ZXN0PFQ+KDApKQp7fTsKCgovLyBTZWNvbmQgY2hlY2tlcjoKc3RydWN0IF90ZXN0X2lzX3N1cHBvcnRlZF9ieV9iYXIgewogICAgdGVtcGxhdGU8Y2xhc3MgVD4KICAgIHN0YXRpYyBhdXRvIHRlc3QoVCogcCkgLT4gZGVjbHR5cGUoYmFyKCpwKSwgc3RkOjp0cnVlX3R5cGUoKSk7CgogICAgdGVtcGxhdGU8Y2xhc3M+CiAgICBzdGF0aWMgYXV0byB0ZXN0KC4uLikgLT4gc3RkOjpmYWxzZV90eXBlOwp9Owp0ZW1wbGF0ZTxjbGFzcyBUPgpzdHJ1Y3QgaXNfc3VwcG9ydGVkX2J5X2JhciA6IGRlY2x0eXBlKF90ZXN0X2lzX3N1cHBvcnRlZF9ieV9iYXI6OnRlc3Q8VD4oMCkpCnt9OwoKCi8vIFRlc3Q6CmludCBtYWluKCkKewogICAgc3RkOjpjb3V0IDw8IGhhc19mb288aV9oYXZlX2Zvbz46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCBoYXNfZm9vPGlfZG9udD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgIAogICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKICAgIAogICAgc3RkOjpjb3V0IDw8IGlzX3N1cHBvcnRlZF9ieV9iYXI8c3RkOjpvc3RyZWFtPjo6dmFsdWUgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IGlzX3N1cHBvcnRlZF9ieV9iYXI8c3RkOjppc3RyZWFtPjo6dmFsdWUgPDwgc3RkOjplbmRsOwp9