#include <boost/mpl/bool.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
template<
typename T,
typename Signature
>
struct callable {
typedef char no;
struct yes { char c[2]; };
template <typename R>
struct make_signature
{
typedef typename ft::result_type<Signature>::type result_type;
typedef typename ft::parameter_types<Signature>::type parameter_types;
typedef typename mpl::push_front<parameter_types, R*>::type params_plus_class;
typedef typename mpl::push_front<params_plus_class, result_type>::type components_type;
typedef typename ft::member_function_pointer<components_type>::type type;
};
template<typename S, typename make_signature<S>::type>
struct dummy
{ };
template<typename S>
static yes
check(dummy<S, &S::operator()> *);
template<typename S>
static no check(...);
typedef boost::mpl::bool_<sizeof(check<T>(0))
== sizeof(yes)>
type;
};
struct test {
void operator()(int) { };
void operator()(std::string) { };
void operator()(bool, bool, bool) { };
};
#include <iostream>
#include <ostream>
void test2(int) { }
void test2(std::string) { }
int main()
{
std::cout << callable<test, void(int)>::type::value << '\n';
std::cout << callable<test, void(float)>::type::value << '\n';
std::cout << callable<test, void(std::string)>::type::value << '\n';
std::cout << callable<test, void(bool, bool, float)>::type::value << '\n';
std::cout << callable<test, void(bool, bool, bool)>::type::value << '\n';
}