#include <iostream>
#include <type_traits>
#include <utility>
#include <functional>
#include <iostream>
#include <string>
#include <typeinfo>
template< class... > using void_t = void;
namespace impl
{
template <typename...>
struct callable_args
{
};
template <class F, class Args, class = void>
struct callable : std::false_type
{
};
template <class F, class... Args>
struct callable<F, callable_args<Args...>, void_t<std::result_of_t<F(Args...)>>> : std::true_type
{
};
}
template <class F, class... Args>
struct callable : impl::callable<F, impl::callable_args<Args...>>
{
};
template <class F, class... Args>
constexpr auto callable_v = callable<F, Args...>::value;
int main()
{
{
using Func = std::function<void()>;
auto result = callable_v<Func>;
std::cout << "test 1 (should be 1) = " << result << std::endl;
}
{
using Func = std::function<void(int)>;
auto result = callable_v<Func, int>;
std::cout << "test 2 (should be 1) = " << result << std::endl;
}
{
using Func = std::function<int(int)>;
auto result = callable_v<Func, int>;
std::cout << "test 3 (should be 1) = " << result << std::endl;
}
{
using Func = std::function<int(double)>;
auto result = callable_v<Func, std::string>;
std::cout << "test 4 (should be 0) = " << result << std::endl;
}
{
using Func = std::function<int(double, int)>;
auto result = callable_v<Func, double>;
std::cout << "test 5 (should be 0) = " << result << std::endl;
}
std::getchar();
return EXIT_SUCCESS;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dHlwZWluZm8+Cgp0ZW1wbGF0ZTwgY2xhc3MuLi4gPiB1c2luZyB2b2lkX3QgPSB2b2lkOwoKbmFtZXNwYWNlIGltcGwKewoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+CiAgc3RydWN0IGNhbGxhYmxlX2FyZ3MKICB7CiAgfTsKCiAgdGVtcGxhdGUgPGNsYXNzIEYsIGNsYXNzIEFyZ3MsIGNsYXNzID0gdm9pZD4KICBzdHJ1Y3QgY2FsbGFibGUgOiBzdGQ6OmZhbHNlX3R5cGUKICB7CiAgfTsKCiAgdGVtcGxhdGUgPGNsYXNzIEYsIGNsYXNzLi4uIEFyZ3M+CiAgc3RydWN0IGNhbGxhYmxlPEYsIGNhbGxhYmxlX2FyZ3M8QXJncy4uLj4sIHZvaWRfdDxzdGQ6OnJlc3VsdF9vZl90PEYoQXJncy4uLik+Pj4gOiBzdGQ6OnRydWVfdHlwZQogIHsKICB9OwoKfQoKdGVtcGxhdGUgPGNsYXNzIEYsIGNsYXNzLi4uIEFyZ3M+CnN0cnVjdCBjYWxsYWJsZSA6IGltcGw6OmNhbGxhYmxlPEYsIGltcGw6OmNhbGxhYmxlX2FyZ3M8QXJncy4uLj4+CnsKfTsKCnRlbXBsYXRlIDxjbGFzcyBGLCBjbGFzcy4uLiBBcmdzPgpjb25zdGV4cHIgYXV0byBjYWxsYWJsZV92ID0gY2FsbGFibGU8RiwgQXJncy4uLj46OnZhbHVlOwoKCmludCBtYWluKCkKewogIHsKICAgIHVzaW5nIEZ1bmMgPSBzdGQ6OmZ1bmN0aW9uPHZvaWQoKT47CiAgICBhdXRvIHJlc3VsdCA9IGNhbGxhYmxlX3Y8RnVuYz47CiAgICBzdGQ6OmNvdXQgPDwgInRlc3QgMSAoc2hvdWxkIGJlIDEpID0gIiA8PCByZXN1bHQgPDwgc3RkOjplbmRsOwogIH0KCiAgewogICAgdXNpbmcgRnVuYyA9IHN0ZDo6ZnVuY3Rpb248dm9pZChpbnQpPjsKICAgIGF1dG8gcmVzdWx0ID0gY2FsbGFibGVfdjxGdW5jLCBpbnQ+OwogICAgc3RkOjpjb3V0IDw8ICJ0ZXN0IDIgKHNob3VsZCBiZSAxKSA9ICIgPDwgcmVzdWx0IDw8IHN0ZDo6ZW5kbDsKICB9CgogIHsKICAgIHVzaW5nIEZ1bmMgPSBzdGQ6OmZ1bmN0aW9uPGludChpbnQpPjsKICAgIGF1dG8gcmVzdWx0ID0gY2FsbGFibGVfdjxGdW5jLCBpbnQ+OwogICAgc3RkOjpjb3V0IDw8ICJ0ZXN0IDMgKHNob3VsZCBiZSAxKSA9ICIgPDwgcmVzdWx0IDw8IHN0ZDo6ZW5kbDsKICB9CgogIHsKICAgIHVzaW5nIEZ1bmMgPSBzdGQ6OmZ1bmN0aW9uPGludChkb3VibGUpPjsKICAgIGF1dG8gcmVzdWx0ID0gY2FsbGFibGVfdjxGdW5jLCBzdGQ6OnN0cmluZz47CiAgICBzdGQ6OmNvdXQgPDwgInRlc3QgNCAoc2hvdWxkIGJlIDApID0gIiA8PCByZXN1bHQgPDwgc3RkOjplbmRsOwogIH0KCiAgewogICAgdXNpbmcgRnVuYyA9IHN0ZDo6ZnVuY3Rpb248aW50KGRvdWJsZSwgaW50KT47CiAgICBhdXRvIHJlc3VsdCA9IGNhbGxhYmxlX3Y8RnVuYywgZG91YmxlPjsKICAgIHN0ZDo6Y291dCA8PCAidGVzdCA1IChzaG91bGQgYmUgMCkgPSAiIDw8IHJlc3VsdCA8PCBzdGQ6OmVuZGw7CiAgfQoKICBzdGQ6OmdldGNoYXIoKTsKCiAgcmV0dXJuIEVYSVRfU1VDQ0VTUzsKfQ==