#include <type_traits>
#include <utility>
namespace util
{
template <typename T>
struct always_void
{
typedef void type;
};
}
namespace detail
{
template <typename T, typename Args, typename Enable = void>
struct is_callable_impl
: std::false_type
{};
template <typename T, typename... A>
struct is_callable_impl<T, void(A...)
, typename util::always_void<
decltype(std::declval<T>()(std::declval<A>()...))
>::type
> : std::true_type
{};
template <typename T, typename C>
struct is_callable_impl<T, void(C)
, typename util::always_void<
decltype(
(std::declval<typename std::remove_pointer<C>::type>()
.*std::declval<T>()))
>::type
> : std::true_type
{};
template <typename T, typename C, typename... A>
struct is_callable_impl<T, void(C, A...)
, typename util::always_void<
decltype(
(std::declval<typename std::remove_pointer<C>::type>()
.*std::declval<T>())(std::declval<A>()...))
>::type
> : std::true_type
{};
}
template <typename T, typename... A>
struct is_callable
: detail::is_callable_impl<T, void(A...)>
{};
struct X {};
int main()
{
static_assert(is_callable<void (X::*)(int) const, X&, int>::value, "increment::call");
auto lambda = [](){};
static_assert(is_callable<decltype(lambda)>::value, "");
static_assert(is_callable<void()>::value, "");
static_assert(is_callable<int (X::*)(double), X*, float>::value, "");
static_assert(!is_callable<int (X::*)(double), X const*, float>::value, "");
static_assert(is_callable<int (X::*)(double), X&, float>::value, "");
static_assert(!is_callable<int (X::*)(double), X const&, float>::value, "");
static_assert(is_callable<int (X::*)(double) const, X*, float>::value, "");
static_assert(is_callable<int (X::*)(double) const, X const*, float>::value, "");
static_assert(is_callable<int (X::*)(double) const, X&, float>::value, "");
static_assert(is_callable<int (X::*)(double) const, X const&, float>::value, "");
static_assert(is_callable<int (X::*), X*>::value, "");
static_assert(is_callable<int (X::*), X const*>::value, "");
static_assert(is_callable<int (X::*), X&>::value, "");
static_assert(is_callable<int (X::*), X const&>::value, "");
static_assert(is_callable<int (X::*), X&&>::value, "");
static_assert(is_callable<int (X::*), X const&&>::value, "");
static_assert(!is_callable<void(int&), int>::value, "");
static_assert(is_callable<void(int&), int&>::value, "");
static_assert(!is_callable<void(int&), int const&>::value, "");
static_assert(!is_callable<void(int&), int&&>::value, "");
static_assert(!is_callable<void(int&), int const&&>::value, "");
static_assert(is_callable<void(int const&), int>::value, "");
static_assert(is_callable<void(int const&), int&>::value, "");
static_assert(is_callable<void(int const&), int const&>::value, "");
static_assert(is_callable<void(int const&), int&&>::value, "");
static_assert(is_callable<void(int const&), int const&&>::value, "");
static_assert(is_callable<void(int&&), int>::value, "");
static_assert(!is_callable<void(int&&), int&>::value, "");
static_assert(!is_callable<void(int&&), int const&>::value, "");
static_assert(is_callable<void(int&&), int&&>::value, "");
static_assert(!is_callable<void(int&&), int const&&>::value, "");
static_assert(is_callable<void(int const&&), int>::value, "");
static_assert(!is_callable<void(int const&&), int&>::value, "");
static_assert(!is_callable<void(int const&&), int const&>::value, "");
static_assert(is_callable<void(int const&&), int&&>::value, "");
static_assert(is_callable<void(int const&&), int const&&>::value, "");
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KCiAgICBuYW1lc3BhY2UgdXRpbAogICAgewogICAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogICAgICAgIHN0cnVjdCBhbHdheXNfdm9pZAogICAgICAgIHsKICAgICAgICAgICAgdHlwZWRlZiB2b2lkIHR5cGU7CiAgICAgICAgfTsKICAgIH0KCiAgICBuYW1lc3BhY2UgZGV0YWlsCiAgICB7CiAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEFyZ3MsIHR5cGVuYW1lIEVuYWJsZSA9IHZvaWQ+CiAgICAgICAgc3RydWN0IGlzX2NhbGxhYmxlX2ltcGwKICAgICAgICAgIDogc3RkOjpmYWxzZV90eXBlCiAgICAgICAge307CgogICAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBPgogICAgICAgIHN0cnVjdCBpc19jYWxsYWJsZV9pbXBsPFQsIHZvaWQoQS4uLikKICAgICAgICAgICwgdHlwZW5hbWUgdXRpbDo6YWx3YXlzX3ZvaWQ8CiAgICAgICAgICAgICAgICBkZWNsdHlwZShzdGQ6OmRlY2x2YWw8VD4oKShzdGQ6OmRlY2x2YWw8QT4oKS4uLikpCiAgICAgICAgICAgID46OnR5cGUKICAgICAgICA+IDogc3RkOjp0cnVlX3R5cGUKICAgICAgICB7fTsKCiAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEM+CiAgICAgICAgc3RydWN0IGlzX2NhbGxhYmxlX2ltcGw8VCwgdm9pZChDKQogICAgICAgICAgICAsIHR5cGVuYW1lIHV0aWw6OmFsd2F5c192b2lkPAogICAgICAgICAgICAgICAgICBkZWNsdHlwZSgKICAgICAgICAgICAgICAgICAgICAgIChzdGQ6OmRlY2x2YWw8dHlwZW5hbWUgc3RkOjpyZW1vdmVfcG9pbnRlcjxDPjo6dHlwZT4oKQogICAgICAgICAgICAgICAgICAgICAgICAgIC4qc3RkOjpkZWNsdmFsPFQ+KCkpKQogICAgICAgICAgICAgID46OnR5cGUKICAgICAgICA+IDogc3RkOjp0cnVlX3R5cGUKICAgICAgICB7fTsKCiAgICAgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIEMsIHR5cGVuYW1lLi4uIEE+CiAgICAgICAgc3RydWN0IGlzX2NhbGxhYmxlX2ltcGw8VCwgdm9pZChDLCBBLi4uKQogICAgICAgICAgICAsIHR5cGVuYW1lIHV0aWw6OmFsd2F5c192b2lkPAogICAgICAgICAgICAgICAgICBkZWNsdHlwZSgKICAgICAgICAgICAgICAgICAgICAgIChzdGQ6OmRlY2x2YWw8dHlwZW5hbWUgc3RkOjpyZW1vdmVfcG9pbnRlcjxDPjo6dHlwZT4oKQogICAgICAgICAgICAgICAgICAgICAgICAgIC4qc3RkOjpkZWNsdmFsPFQ+KCkpKHN0ZDo6ZGVjbHZhbDxBPigpLi4uKSkKICAgICAgICAgICAgICA+Ojp0eXBlCiAgICAgICAgPiA6IHN0ZDo6dHJ1ZV90eXBlCiAgICAgICAge307CiAgICB9CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEE+CiAgICBzdHJ1Y3QgaXNfY2FsbGFibGUKICAgICAgOiBkZXRhaWw6OmlzX2NhbGxhYmxlX2ltcGw8VCwgdm9pZChBLi4uKT4KICAgIHt9OwoKc3RydWN0IFgge307CgppbnQgbWFpbigpCnsKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8dm9pZCAoWDo6KikoaW50KSBjb25zdCwgWCYsIGludD46OnZhbHVlLCAiaW5jcmVtZW50OjpjYWxsIik7CgogICAgYXV0byBsYW1iZGEgPSBbXSgpe307CiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPGRlY2x0eXBlKGxhbWJkYSk+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTx2b2lkKCk+Ojp2YWx1ZSwgIiIpOwoKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8aW50IChYOjoqKShkb3VibGUpLCBYKiwgZmxvYXQ+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8aW50IChYOjoqKShkb3VibGUpLCBYIGNvbnN0KiwgZmxvYXQ+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTxpbnQgKFg6OiopKGRvdWJsZSksIFgmLCBmbG9hdD46OnZhbHVlLCAiIik7CiAgICBzdGF0aWNfYXNzZXJ0KCFpc19jYWxsYWJsZTxpbnQgKFg6OiopKGRvdWJsZSksIFggY29uc3QmLCBmbG9hdD46OnZhbHVlLCAiIik7CiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPGludCAoWDo6KikoZG91YmxlKSBjb25zdCwgWCosIGZsb2F0Pjo6dmFsdWUsICIiKTsKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8aW50IChYOjoqKShkb3VibGUpIGNvbnN0LCBYIGNvbnN0KiwgZmxvYXQ+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTxpbnQgKFg6OiopKGRvdWJsZSkgY29uc3QsIFgmLCBmbG9hdD46OnZhbHVlLCAiIik7CiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPGludCAoWDo6KikoZG91YmxlKSBjb25zdCwgWCBjb25zdCYsIGZsb2F0Pjo6dmFsdWUsICIiKTsKCiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPGludCAoWDo6KiksIFgqPjo6dmFsdWUsICIiKTsKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8aW50IChYOjoqKSwgWCBjb25zdCo+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTxpbnQgKFg6OiopLCBYJj46OnZhbHVlLCAiIik7CiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPGludCAoWDo6KiksIFggY29uc3QmPjo6dmFsdWUsICIiKTsKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8aW50IChYOjoqKSwgWCYmPjo6dmFsdWUsICIiKTsKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8aW50IChYOjoqKSwgWCBjb25zdCYmPjo6dmFsdWUsICIiKTsKCiAgICBzdGF0aWNfYXNzZXJ0KCFpc19jYWxsYWJsZTx2b2lkKGludCYpLCBpbnQ+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTx2b2lkKGludCYpLCBpbnQmPjo6dmFsdWUsICIiKTsKICAgIHN0YXRpY19hc3NlcnQoIWlzX2NhbGxhYmxlPHZvaWQoaW50JiksIGludCBjb25zdCY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQmKSwgaW50JiY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQmKSwgaW50IGNvbnN0JiY+Ojp2YWx1ZSwgIiIpOwoKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8dm9pZChpbnQgY29uc3QmKSwgaW50Pjo6dmFsdWUsICIiKTsKICAgIHN0YXRpY19hc3NlcnQoaXNfY2FsbGFibGU8dm9pZChpbnQgY29uc3QmKSwgaW50Jj46OnZhbHVlLCAiIik7CiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPHZvaWQoaW50IGNvbnN0JiksIGludCBjb25zdCY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTx2b2lkKGludCBjb25zdCYpLCBpbnQmJj46OnZhbHVlLCAiIik7CiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPHZvaWQoaW50IGNvbnN0JiksIGludCBjb25zdCYmPjo6dmFsdWUsICIiKTsKCiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPHZvaWQoaW50JiYpLCBpbnQ+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQmJiksIGludCY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQmJiksIGludCBjb25zdCY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTx2b2lkKGludCYmKSwgaW50JiY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQmJiksIGludCBjb25zdCYmPjo6dmFsdWUsICIiKTsKCiAgICBzdGF0aWNfYXNzZXJ0KGlzX2NhbGxhYmxlPHZvaWQoaW50IGNvbnN0JiYpLCBpbnQ+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQgY29uc3QmJiksIGludCY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydCghaXNfY2FsbGFibGU8dm9pZChpbnQgY29uc3QmJiksIGludCBjb25zdCY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTx2b2lkKGludCBjb25zdCYmKSwgaW50JiY+Ojp2YWx1ZSwgIiIpOwogICAgc3RhdGljX2Fzc2VydChpc19jYWxsYWJsZTx2b2lkKGludCBjb25zdCYmKSwgaW50IGNvbnN0JiY+Ojp2YWx1ZSwgIiIpOwoKICAgIHJldHVybiAwOwp9Cg==