#include <utility>
#include <type_traits>
template<typename T>
using NoRef = typename std::remove_reference<T>::type;
template<typename T>
using EnableIf = typename std::enable_if<T::value, void>::type;
template<typename T, typename = void>
struct is_callable_impl : std::is_function<T> {};
template<typename T>
struct is_callable_impl<T, EnableIf<std::is_class<NoRef<T>>>> {
using yes = char;
using no = struct { char s[2]; };
struct F { void operator()(); };
struct Derived : T, F { };
template<typename U, U> struct Check;
template<typename V>
static no test(Check<void (F::*)(), &V::operator()>*);
template<typename>
static yes test(...);
static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
};
template<typename T>
struct Callable : std::integral_constant<bool, is_callable_impl<T>::value> {};
struct A {};
struct B {
void operator()();
};
struct C {
char operator()(int, int);
};
struct D {
template<typename T, typename U>
void operator()(T, U);
float operator()(int, char, double);
};
struct E {
template<typename T>
char operator()(T, double);
};
int main() {
static_assert(!Callable<int>::value, "...");
static_assert(Callable<void()>::value, "...");
auto l = [] () { };
static_assert(Callable<decltype(l)>::value, "...");
static_assert(!Callable<A>::value, "...");
static_assert(Callable<B>::value, "...");
static_assert(Callable<C>::value, "...");
static_assert(Callable<D>::value, "...");
static_assert(Callable<E>::value, "...");
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp1c2luZyBOb1JlZiA9IHR5cGVuYW1lIHN0ZDo6cmVtb3ZlX3JlZmVyZW5jZTxUPjo6dHlwZTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnVzaW5nIEVuYWJsZUlmID0gdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8VDo6dmFsdWUsIHZvaWQ+Ojp0eXBlOwoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWUgPSB2b2lkPgpzdHJ1Y3QgaXNfY2FsbGFibGVfaW1wbCA6IHN0ZDo6aXNfZnVuY3Rpb248VD4ge307Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgaXNfY2FsbGFibGVfaW1wbDxULCBFbmFibGVJZjxzdGQ6OmlzX2NsYXNzPE5vUmVmPFQ+Pj4+IHsKICAgIHVzaW5nIHllcyA9IGNoYXI7CiAgICB1c2luZyBubyA9IHN0cnVjdCB7IGNoYXIgc1syXTsgfTsKCiAgICBzdHJ1Y3QgRiB7IHZvaWQgb3BlcmF0b3IoKSgpOyB9OwogICAgc3RydWN0IERlcml2ZWQgOiBULCBGIHsgfTsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFUsIFU+IHN0cnVjdCBDaGVjazsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBWPgogICAgc3RhdGljIG5vIHRlc3QoQ2hlY2s8dm9pZCAoRjo6KikoKSwgJlY6Om9wZXJhdG9yKCk+Kik7CgogICAgdGVtcGxhdGU8dHlwZW5hbWU+CiAgICBzdGF0aWMgeWVzIHRlc3QoLi4uKTsKCiAgICBzdGF0aWMgY29uc3QgYm9vbCB2YWx1ZSA9IHNpemVvZih0ZXN0PERlcml2ZWQ+KDApKSA9PSBzaXplb2YoeWVzKTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBDYWxsYWJsZSA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwgaXNfY2FsbGFibGVfaW1wbDxUPjo6dmFsdWU+IHt9OwoKc3RydWN0IEEge307CnN0cnVjdCBCIHsgCiAgICB2b2lkIG9wZXJhdG9yKCkoKTsgCn07CgpzdHJ1Y3QgQyB7IAogICAgY2hhciBvcGVyYXRvcigpKGludCwgaW50KTsgCn07CnN0cnVjdCBEIHsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+CiAgICB2b2lkIG9wZXJhdG9yKCkoVCwgVSk7CiAgICBmbG9hdCBvcGVyYXRvcigpKGludCwgY2hhciwgZG91YmxlKTsKfTsKCnN0cnVjdCBFIHsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICBjaGFyIG9wZXJhdG9yKCkoVCwgZG91YmxlKTsKfTsKCmludCBtYWluKCkgewogICAgc3RhdGljX2Fzc2VydCghQ2FsbGFibGU8aW50Pjo6dmFsdWUsICIuLi4iKTsKICAgIHN0YXRpY19hc3NlcnQoQ2FsbGFibGU8dm9pZCgpPjo6dmFsdWUsICIuLi4iKTsKICAgIGF1dG8gbCA9IFtdICgpIHsgfTsKICAgIHN0YXRpY19hc3NlcnQoQ2FsbGFibGU8ZGVjbHR5cGUobCk+Ojp2YWx1ZSwgIi4uLiIpOwogICAgc3RhdGljX2Fzc2VydCghQ2FsbGFibGU8QT46OnZhbHVlLCAiLi4uIik7CiAgICBzdGF0aWNfYXNzZXJ0KENhbGxhYmxlPEI+Ojp2YWx1ZSwgIi4uLiIpOwogICAgc3RhdGljX2Fzc2VydChDYWxsYWJsZTxDPjo6dmFsdWUsICIuLi4iKTsKICAgIHN0YXRpY19hc3NlcnQoQ2FsbGFibGU8RD46OnZhbHVlLCAiLi4uIik7CiAgICBzdGF0aWNfYXNzZXJ0KENhbGxhYmxlPEU+Ojp2YWx1ZSwgIi4uLiIpOwp9