Barry wrote:
Kai-Uwe Bux wrote:
[many lines]
Good job,
boost.is_function seems to do hard coding to meet possible function
argument list length.
Makes me wonder whether there is a bug in my code. I wouldn't be
surprised.
though is_function checks function not pointer to function.
with a wrapper this should also work with function check.
template <class T>
struct is_function
{
static const bool value = is_function_pointer<T*>::value;
};
SHOW_BOOL( is_function<int(int)>::value );
SHOW_BOOL( is_function<int(int, int)>::value );
SHOW_BOOL( is_function<int(*)(int)>::value );
SHOW_BOOL( is_function<int(*)(int, int)>::value );
I actually think that the code needs some cleanup and that testing for
being
a function is simpler than testing for being a function pointer. So, I
changed it the other way around. Here are the versions I added to my
library:
// is_class_type
// =============
template < typename T >
class is_class_type {
typedef char (&yes) [1];
typedef char (&no) [2];
template < typename S >
static yes check ( int S::* );
template < typename S >
static no check ( ... );
public:
static bool const value = ( sizeof( check<T>( 0 ) ) == sizeof(yes) );
}; // is_class_type
// is_pointer_type:
// ================
struct unused_type {};
template < typename T >
struct is_pointer_type {
static const bool value = false;
typedef unused_type pointee_type;
};
template < typename T >
struct is_pointer_type<T*> {
static const bool value = true;
typedef T pointee_type;
};
// is_function_type
// ================
template < typename T >
class is_function_type {
typedef char (&no) [1];
typedef char (&yes) [2];
template < typename S >
static
yes check ( S * );
template < typename S >
static
no check ( ... );
public:
static bool const value =
( ! is_class_type<T>::value )
&&
( sizeof( check<T>( * (T*)(0) ) )== sizeof( yes ) );
};
// is_function_pointer
// ===================
template < typename T >
struct is_function_pointer {
static bool const value =
( is_pointer_type<T>::value
&&
is_function_type< typename is_pointer_type<T>::pointee_type
::value );
};
Note that the template is_function_type<> does not need the
is_pointer_type<> template. That is why I think that
is_function_type<> is
conceptually simpler than is_function_pointer<> and my reason to prefer
this implementation to the previous one.
Best
Kai-Uwe Bux