diff --git a/src/libraries/turtle/is_functor.hpp b/src/libraries/turtle/is_functor.hpp index 85f3117..a0cf055 100644 --- a/src/libraries/turtle/is_functor.hpp +++ b/src/libraries/turtle/is_functor.hpp @@ -10,35 +10,63 @@ #define MOCK_IS_FUNCTOR_HPP_INCLUDED #include +#include +#include namespace mock { namespace detail { - typedef char true_type[2]; - typedef char false_type[1]; + typedef char true_type; + struct false_type + { + char padding[8]; + }; template< typename T > - true_type& has_result_type_helper( T*, BOOST_DEDUCED_TYPENAME T::result_type* = 0 ); + true_type& has_result_type_tester( T*, BOOST_DEDUCED_TYPENAME T::result_type* = 0 ); template< typename T > - false_type& has_result_type_helper( T, ... ); + false_type& has_result_type_tester( T, ... ); template< typename T > - struct has_result_type + struct has_result_type_impl { - static T* t(); - enum { value = sizeof( has_result_type_helper( t() ) ) == sizeof( true_type ) }; + static T* t; + enum { value = sizeof( has_result_type_tester( t ) ) == sizeof( true_type ) }; }; - template< typename T, bool B = has_result_type< T >::value > + template< typename T > + struct has_result_type : public boost::integral_constant< bool, has_result_type_impl< T >::value > + { + }; + + template< typename T > + true_type& has_sig_tester( T*, BOOST_DEDUCED_TYPENAME T::template sig< void >* = 0 ); + template< typename T > + false_type& has_sig_tester( T, ... ); + + template< typename T > + struct has_sig_impl + { + static T* t; + enum { value = sizeof( has_sig_tester( t ) ) == sizeof( true_type ) }; + }; + + template< typename T > + struct has_sig : public boost::integral_constant< bool, has_sig_impl< T >::value > + { + }; + + template< typename T > struct is_functor { - typedef BOOST_DEDUCED_TYPENAME boost::function_types::is_callable_builtin< T >::type type; - }; - template< typename T > - struct is_functor< T, true > - { - typedef boost::true_type type; + typedef BOOST_DEDUCED_TYPENAME boost::mpl::or_< + BOOST_DEDUCED_TYPENAME boost::mpl::or_< + BOOST_DEDUCED_TYPENAME boost::function_types::is_callable_builtin< T >::type, + BOOST_DEDUCED_TYPENAME has_result_type< T >::type + >::type, + BOOST_DEDUCED_TYPENAME has_sig< T >::type + >::type type; }; } } diff --git a/src/tests/turtle_test/is_functor_test.cpp b/src/tests/turtle_test/is_functor_test.cpp index 0a3e491..a13faa7 100644 --- a/src/tests/turtle_test/is_functor_test.cpp +++ b/src/tests/turtle_test/is_functor_test.cpp @@ -9,6 +9,13 @@ #include #include #include +#ifdef _MSC_VER +#pragma warning( push, 0 ) +#endif +#include +#ifdef _MSC_VER +#pragma warning( pop ) +#endif #include #define BOOST_LIB_NAME boost_unit_test_framework @@ -25,18 +32,6 @@ namespace void f0 () {} bool f1( int ) { return false; } bool f2( std::string, int ) { return false; } - - struct unary_functor0 : public std::unary_function< void, void > - { - }; - struct unary_functor1 : public std::unary_function< int, void > - { - }; - - struct s - { - typedef void result_type; - }; } BOOST_AUTO_TEST_CASE( function_is_functor ) @@ -64,6 +59,15 @@ BOOST_AUTO_TEST_CASE( std_bind_first_is_functor ) check( std::bind1st( std::ptr_fun( &f2 ), "" ) ); } +namespace +{ + struct unary_functor0 : public std::unary_function< void, void > + { + }; + struct unary_functor1 : public std::unary_function< int, void > + { + }; +} BOOST_AUTO_TEST_CASE( std_unary_functor_is_functor ) { check( unary_functor0() ); @@ -77,12 +81,40 @@ BOOST_AUTO_TEST_CASE( boost_bind_is_functor ) check( boost::bind( &f2, "", _1 ) ); } +BOOST_AUTO_TEST_CASE( boost_lambda_is_functor ) +{ + check( boost::lambda::_1 < 42 ); +} + BOOST_AUTO_TEST_CASE( boost_function_is_functor ) { check( boost::function< void() >() ); } +namespace +{ + struct result_type_functor + { + typedef void result_type; + }; +} BOOST_AUTO_TEST_CASE( class_with_result_type_is_functor ) { - check( s() ); + check( result_type_functor() ); +} + +namespace +{ + struct sig_functor + { + template< typename Args > + struct sig + { + typedef void type; + }; + }; +} +BOOST_AUTO_TEST_CASE( class_with_sig_is_functor ) +{ + check( sig_functor() ); }