Boost logo

Boost Users :

From: Sniv Le Flomp (essinivleevlelomp_at_[hidden])
Date: 2005-11-21 20:52:58


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;
}



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net