Hi,
I only needed to check for member functions.
I don't know how to put in all the crazy boost compiler workarounds.
I'd like to hear of any ideas for ways to make it better.
- Sniv
#include <boost/preprocessor/cat.hpp>
// ----------------------------------------------------------------------------
typedef char (&false_tag)[1];
typedef char (&true_tag)[2];
template <bool> struct bool_tag;
template <> struct bool_tag<false> { typedef false_tag type; };
template <> struct bool_tag<true> { typedef true_tag type; };
template <size_t> struct size_bool;
template <> struct size_bool<sizeof(bool_tag<true>::type)> { static const bool value = true; };
template <> struct size_bool<sizeof(bool_tag<false>::type)> { static const bool value = false; };
// ----------------------------------------------------------------------------
template <typename T> struct get_class;
template <class C, typename R> struct get_class<R (C::*)()> { typedef C type; };
template <class C, typename R, typename T1> struct get_class<R (C::*)(T1)> { typedef C type; };
template <class C, typename R, typename T1, typename T2> struct get_class<R (C::*)(T1, T2)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3> struct get_class<R (C::*)(T1, T2, T3)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4> struct get_class<R (C::*)(T1, T2, T3, T4)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4, typename T5> struct get_class<R (C::*)(T1, T2, T3, T4, T5)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> struct get_class<R (C::*)(T1, T2, T3, T4, T5, T6)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> struct get_class<R (C::*)(T1, T2, T3, T4, T5, T6, T7)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> struct get_class<R (C::*)(T1, T2, T3, T4, T5, T6, T7, T8)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> struct get_class<R (C::*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)> { typedef C type; };
template <class C, typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10> struct get_class<R (C::*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> { typedef C type; };
// ----------------------------------------------------------------------------
#define HAS_XXX_MEMBER_FUNCTION_NAMED_DEF(MEMBER) \
HAS_XXX_MEMBER_FUNCTION_DEF(BOOST_PP_CAT(has_, MEMBER), MEMBER) \
#define HAS_XXX_MEMBER_FUNCTION_DEF(NAME, MEMBER) \
template <typename _Sig> \
struct NAME \
{ \
template <_Sig> struct pmf_helper {}; \
template <class T> static bool_tag<false>::type test(...); \
template <class T> static bool_tag<true>::type test(pmf_helper<&T::MEMBER>*); \
static const bool value = size_bool<sizeof(test<typename get_class<_Sig>::type>(0))>::value; \
}; \
// ----------------------------------------------------------------------------
struct Test1 { void f(); };
struct Test2 { int f(bool); };
struct Test3 {};
HAS_XXX_MEMBER_FUNCTION_NAMED_DEF(f)
int main()
{
cout << has_f<void (Test1::*)()>::value << endl;
cout << has_f<int (Test2::*)(bool)>::value << endl;
cout << has_f<int (Test3::*)(bool)>::value << endl;
}