From cf330e8c86daa84ffedd2497f68646b11296b639 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Sun, 5 Jul 2020 22:29:14 +0200 Subject: [PATCH] Remove usage of Boost.MPL and reduce Boost.FunctionTypes usage They are known to be slow on compilation and C++11 offer better alternatives --- include/turtle/detail/is_functor.hpp | 18 +------- include/turtle/detail/parameter.hpp | 54 +++++++++++++++++++----- include/turtle/detail/signature.hpp | 62 ++++++++++++++++----------- include/turtle/mock.hpp | 11 ++--- test/detail/test_function.cpp | 1 - test/detail/test_is_functor.cpp | 63 ++++------------------------ 6 files changed, 94 insertions(+), 115 deletions(-) diff --git a/include/turtle/detail/is_functor.hpp b/include/turtle/detail/is_functor.hpp index 817213a..ca804b7 100644 --- a/include/turtle/detail/is_functor.hpp +++ b/include/turtle/detail/is_functor.hpp @@ -10,10 +10,6 @@ #define MOCK_IS_FUNCTOR_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include -#include #include #include @@ -21,10 +17,6 @@ namespace mock { namespace detail { - BOOST_MPL_HAS_XXX_TRAIT_DEF( result_type ) - BOOST_MPL_HAS_XXX_TEMPLATE_DEF( sig ) - BOOST_MPL_HAS_XXX_TEMPLATE_DEF( result ) - template< typename F, typename P, class = void > struct is_callable : std::false_type {}; @@ -33,15 +25,7 @@ namespace detail {}; template< typename T, typename P > - struct is_functor - : boost::mpl::or_< - boost::function_types::is_callable_builtin< T >, - is_callable< T, P >, - has_result_type< T >, - has_result< T >, - has_sig< T > - > - {}; + using is_functor = is_callable< T, P >; } } // mock diff --git a/include/turtle/detail/parameter.hpp b/include/turtle/detail/parameter.hpp index 38925a2..4c25a3b 100644 --- a/include/turtle/detail/parameter.hpp +++ b/include/turtle/detail/parameter.hpp @@ -10,24 +10,56 @@ #define MOCK_PARAMETER_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include namespace mock { namespace detail { - template< typename Signature, int n > - struct parameter + template< class... > + struct tuple; + + template< std::size_t I, class T > + struct tuple_element; + + template< std::size_t I, class H, class... T > + struct tuple_element> : tuple_element> + {}; + + template< class H, class... T > + struct tuple_element<0, tuple> { - typedef typename - boost::mpl::at_c< - typename - boost::function_types::parameter_types< Signature >, - n - >::type type; + using type = H; }; + + template< typename Signature > + struct result_type; + + template< typename R, typename... Args > + struct result_type< R(Args...) > + { + using type = R; + }; + + template< typename Signature > + struct function_arity; + + template< typename R, typename... Args > + struct function_arity< R(Args...) > + { + static constexpr size_t value = sizeof...(Args); + }; + + template< typename Signature > + struct parameter_types; + + template< typename R, typename... Args > + struct parameter_types< R(Args...) > + { + using type = tuple; + }; + + template< typename Signature, int n > + using parameter = tuple_element< n, typename parameter_types::type >; } } // mock diff --git a/include/turtle/detail/signature.hpp b/include/turtle/detail/signature.hpp index 03c016c..9df1ee2 100644 --- a/include/turtle/detail/signature.hpp +++ b/include/turtle/detail/signature.hpp @@ -10,33 +10,47 @@ #define MOCK_SIGNATURE_HPP_INCLUDED #include "../config.hpp" -#include -#include -#include -#include -#include -#include -#define BOOST_TYPEOF_SILENT -#include +#include namespace mock { namespace detail { +#define MOCK_NOARG +#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \ + template< typename R, typename... Args > \ + struct strip_function_qualifiers \ + { using type = R(Args...); }; \ + template< typename R, typename... Args > \ + struct strip_function_qualifiers \ + { using type = R(Args..., ...); }; + +#define MOCK_STRIP_FUNCTION_QUALIFIERS_REF(cv) \ + MOCK_STRIP_FUNCTION_QUALIFIERS(cv,) \ + MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &) \ + MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &&) + + template + struct strip_function_qualifiers; + MOCK_STRIP_FUNCTION_QUALIFIERS_REF(MOCK_NOARG) + MOCK_STRIP_FUNCTION_QUALIFIERS_REF(const) + MOCK_STRIP_FUNCTION_QUALIFIERS_REF(volatile) + MOCK_STRIP_FUNCTION_QUALIFIERS_REF(const volatile) +#undef MOCK_NOARG +#undef MOCK_STRIP_FUNCTION_QUALIFIERS +#undef MOCK_STRIP_FUNCTION_QUALIFIERS_REF + template< typename M > - struct signature : - boost::function_types::function_type< - boost::mpl::joint_view< - boost::mpl::single_view< - typename - boost::function_types::result_type< M >::type - >, - typename boost::mpl::pop_front< - typename - boost::function_types::parameter_types< M > - >::type - > - > + struct signature; + + template< typename R, typename... Args> + struct signature< R(Args...) > + { + using type = R(Args...); + }; + + template< typename Sig, typename C> + struct signature< Sig(C::*) >: signature< typename strip_function_qualifiers::type > {}; template< typename T > @@ -55,9 +69,9 @@ namespace detail #define MOCK_SIGNATURE(M) \ mock::detail::signature< \ - BOOST_TYPEOF( \ - mock::detail::ambiguous_method_requires_to_specify_signature( \ - &base_type::M ) ) \ + std::remove_cv_t< std::remove_reference_t < decltype( \ + mock::detail::ambiguous_method_requires_to_specify_signature( &base_type::M ) \ + ) > > \ >::type #endif // MOCK_SIGNATURE_HPP_INCLUDED diff --git a/include/turtle/mock.hpp b/include/turtle/mock.hpp index af0cc12..49faacb 100644 --- a/include/turtle/mock.hpp +++ b/include/turtle/mock.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #define MOCK_CLASS(T) \ struct T : mock::object @@ -79,7 +78,7 @@ #define MOCK_DECL_PARAMS(n, S, tpn) \ BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn)) #define MOCK_DECL(M, n, S, c, tpn) \ - tpn boost::function_types::result_type< \ + tpn mock::detail::result_type< \ MOCK_FUNCTION_TYPE((S), tpn) >::type M( \ MOCK_DECL_PARAMS(n, S, tpn) ) c @@ -91,9 +90,7 @@ #define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \ MOCK_DECL(M, n, S, c, tpn) \ { \ - BOOST_MPL_ASSERT_RELATION( n, ==, \ - boost::function_types::function_arity< \ - MOCK_FUNCTION_TYPE((S), tpn) >::value ); \ + static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE((S), tpn) >::value, "Arity mismatch" ); \ return MOCK_ANONYMOUS_HELPER(t)( \ MOCK_FORWARD_PARAMS(n, S, tpn) ); \ } @@ -171,9 +168,7 @@ MOCK_FUNCTION_HELPER(S, t, s, tpn) \ s MOCK_DECL(F, n, S,,tpn) \ { \ - BOOST_MPL_ASSERT_RELATION( n, ==, \ - boost::function_types::function_arity< \ - MOCK_FUNCTION_TYPE((S), tpn) >::value ); \ + static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE((S), tpn) >::value, "Arity mismatch" ); \ return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \ } diff --git a/test/detail/test_function.cpp b/test/detail/test_function.cpp index 599d89f..69566da 100644 --- a/test/detail/test_function.cpp +++ b/test/detail/test_function.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/test/detail/test_is_functor.cpp b/test/detail/test_is_functor.cpp index 88adf31..6a659c6 100644 --- a/test/detail/test_is_functor.cpp +++ b/test/detail/test_is_functor.cpp @@ -22,18 +22,17 @@ namespace { struct declared_but_not_defined; - BOOST_MPL_ASSERT_NOT(( - mock::detail::is_functor< declared_but_not_defined, int > )); + static_assert( !mock::detail::is_functor< declared_but_not_defined, int >::value, "Should not be a functor" ); template< typename T > void is_functor( T ) { - BOOST_MPL_ASSERT(( mock::detail::is_functor< T, int > )); + static_assert( mock::detail::is_functor< T, int >::value, "Should be functor"); } template< typename T > void is_not_functor( T ) { - BOOST_MPL_ASSERT_NOT(( mock::detail::is_functor< T, int > )); + static_assert( !mock::detail::is_functor< T, int >::value, "Should not be a functor" ); } void f0() {} @@ -48,22 +47,22 @@ BOOST_AUTO_TEST_CASE( data_is_not_functor ) BOOST_AUTO_TEST_CASE( function_is_functor ) { - is_functor( f0 ); + is_not_functor( f0 ); is_functor( f1 ); - is_functor( f2 ); + is_not_functor( f2 ); } BOOST_AUTO_TEST_CASE( function_pointer_is_functor ) { - is_functor( &f0 ); + is_not_functor( &f0 ); is_functor( &f1 ); - is_functor( &f2 ); + is_not_functor( &f2 ); } BOOST_AUTO_TEST_CASE( std_ptr_fun_is_functor ) { is_functor( std::ptr_fun( &f1 ) ); - is_functor( std::ptr_fun( &f2 ) ); + is_not_functor( std::ptr_fun( &f2 ) ); } BOOST_AUTO_TEST_CASE( std_bind_first_is_functor ) @@ -71,20 +70,6 @@ BOOST_AUTO_TEST_CASE( std_bind_first_is_functor ) is_functor( 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 ) -{ - is_functor( unary_functor0() ); - is_functor( unary_functor1() ); -} - BOOST_AUTO_TEST_CASE( boost_bind_is_functor ) { is_functor( boost::bind( &f0 ) ); @@ -105,37 +90,7 @@ BOOST_AUTO_TEST_CASE( boost_phoenix_is_functor ) BOOST_AUTO_TEST_CASE( boost_function_is_functor ) { - is_functor( boost::function< void() >() ); -} - -namespace -{ - struct result_type_functor - { - typedef void result_type; - }; -} - -BOOST_AUTO_TEST_CASE( class_with_result_type_is_functor ) -{ - is_functor( result_type_functor() ); -} - -namespace -{ - struct sig_functor - { - template< typename Args > - struct sig - { - typedef void type; - }; - }; -} - -BOOST_AUTO_TEST_CASE( class_with_sig_is_functor ) -{ - is_functor( sig_functor() ); + is_functor( boost::function< void(int) >() ); } #ifdef MOCK_LAMBDAS