Remove usage of Boost.MPL and reduce Boost.FunctionTypes usage

They are known to be slow on compilation and C++11 offer better alternatives
This commit is contained in:
Alexander Grund 2020-07-05 22:29:14 +02:00
parent df5b77af95
commit cf330e8c86
No known key found for this signature in database
GPG key ID: AA48A0760367A42B
6 changed files with 94 additions and 115 deletions

View file

@ -10,10 +10,6 @@
#define MOCK_IS_FUNCTOR_HPP_INCLUDED #define MOCK_IS_FUNCTOR_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/function_types/is_callable_builtin.hpp>
#include <boost/utility/declval.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/make_void.hpp> #include <boost/type_traits/make_void.hpp>
#include <type_traits> #include <type_traits>
@ -21,10 +17,6 @@ namespace mock
{ {
namespace detail 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 > template< typename F, typename P, class = void >
struct is_callable : std::false_type struct is_callable : std::false_type
{}; {};
@ -33,15 +25,7 @@ namespace detail
{}; {};
template< typename T, typename P > template< typename T, typename P >
struct is_functor using is_functor = is_callable< T, P >;
: boost::mpl::or_<
boost::function_types::is_callable_builtin< T >,
is_callable< T, P >,
has_result_type< T >,
has_result< T >,
has_sig< T >
>
{};
} }
} // mock } // mock

View file

@ -10,24 +10,56 @@
#define MOCK_PARAMETER_HPP_INCLUDED #define MOCK_PARAMETER_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/mpl/at.hpp>
namespace mock namespace mock
{ {
namespace detail namespace detail
{ {
template< typename Signature, int n > template< class... >
struct parameter struct tuple;
template< std::size_t I, class T >
struct tuple_element;
template< std::size_t I, class H, class... T >
struct tuple_element<I, tuple<H, T...>> : tuple_element<I-1, tuple<T...>>
{};
template< class H, class... T >
struct tuple_element<0, tuple<H, T...>>
{ {
typedef typename using type = H;
boost::mpl::at_c<
typename
boost::function_types::parameter_types< Signature >,
n
>::type type;
}; };
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<Args...>;
};
template< typename Signature, int n >
using parameter = tuple_element< n, typename parameter_types<Signature>::type >;
} }
} // mock } // mock

View file

@ -10,33 +10,47 @@
#define MOCK_SIGNATURE_HPP_INCLUDED #define MOCK_SIGNATURE_HPP_INCLUDED
#include "../config.hpp" #include "../config.hpp"
#include <boost/function_types/parameter_types.hpp> #include <type_traits>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/single_view.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/pop_front.hpp>
#define BOOST_TYPEOF_SILENT
#include <boost/typeof/typeof.hpp>
namespace mock namespace mock
{ {
namespace detail namespace detail
{ {
#define MOCK_NOARG
#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \
template< typename R, typename... Args > \
struct strip_function_qualifiers<R(Args...) cv ref > \
{ using type = R(Args...); }; \
template< typename R, typename... Args > \
struct strip_function_qualifiers<R(Args..., ...) cv ref > \
{ 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<typename>
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 > template< typename M >
struct signature : struct signature;
boost::function_types::function_type<
boost::mpl::joint_view< template< typename R, typename... Args>
boost::mpl::single_view< struct signature< R(Args...) >
typename {
boost::function_types::result_type< M >::type using type = R(Args...);
>, };
typename boost::mpl::pop_front<
typename template< typename Sig, typename C>
boost::function_types::parameter_types< M > struct signature< Sig(C::*) >: signature< typename strip_function_qualifiers<Sig>::type >
>::type
>
>
{}; {};
template< typename T > template< typename T >
@ -55,9 +69,9 @@ namespace detail
#define MOCK_SIGNATURE(M) \ #define MOCK_SIGNATURE(M) \
mock::detail::signature< \ mock::detail::signature< \
BOOST_TYPEOF( \ std::remove_cv_t< std::remove_reference_t < decltype( \
mock::detail::ambiguous_method_requires_to_specify_signature( \ mock::detail::ambiguous_method_requires_to_specify_signature( &base_type::M ) \
&base_type::M ) ) \ ) > > \
>::type >::type
#endif // MOCK_SIGNATURE_HPP_INCLUDED #endif // MOCK_SIGNATURE_HPP_INCLUDED

View file

@ -22,7 +22,6 @@
#include <boost/preprocessor/repetition/repeat.hpp> #include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
#include <boost/utility/identity_type.hpp> #include <boost/utility/identity_type.hpp>
#include <boost/mpl/assert.hpp>
#define MOCK_CLASS(T) \ #define MOCK_CLASS(T) \
struct T : mock::object struct T : mock::object
@ -79,7 +78,7 @@
#define MOCK_DECL_PARAMS(n, S, tpn) \ #define MOCK_DECL_PARAMS(n, S, tpn) \
BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn)) BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn))
#define MOCK_DECL(M, n, S, c, 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_FUNCTION_TYPE((S), tpn) >::type M( \
MOCK_DECL_PARAMS(n, S, tpn) ) c MOCK_DECL_PARAMS(n, S, tpn) ) c
@ -91,9 +90,7 @@
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \ #define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
MOCK_DECL(M, n, S, c, tpn) \ MOCK_DECL(M, n, S, c, tpn) \
{ \ { \
BOOST_MPL_ASSERT_RELATION( n, ==, \ static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE((S), tpn) >::value, "Arity mismatch" ); \
boost::function_types::function_arity< \
MOCK_FUNCTION_TYPE((S), tpn) >::value ); \
return MOCK_ANONYMOUS_HELPER(t)( \ return MOCK_ANONYMOUS_HELPER(t)( \
MOCK_FORWARD_PARAMS(n, S, tpn) ); \ MOCK_FORWARD_PARAMS(n, S, tpn) ); \
} }
@ -171,9 +168,7 @@
MOCK_FUNCTION_HELPER(S, t, s, tpn) \ MOCK_FUNCTION_HELPER(S, t, s, tpn) \
s MOCK_DECL(F, n, S,,tpn) \ s MOCK_DECL(F, n, S,,tpn) \
{ \ { \
BOOST_MPL_ASSERT_RELATION( n, ==, \ static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE((S), tpn) >::value, "Arity mismatch" ); \
boost::function_types::function_arity< \
MOCK_FUNCTION_TYPE((S), tpn) >::value ); \
return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \ return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \
} }

View file

@ -12,7 +12,6 @@
#include <turtle/constraints.hpp> #include <turtle/constraints.hpp>
#include <boost/test/auto_unit_test.hpp> #include <boost/test/auto_unit_test.hpp>
#include <boost/utility/result_of.hpp> #include <boost/utility/result_of.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>

View file

@ -22,18 +22,17 @@
namespace namespace
{ {
struct declared_but_not_defined; struct declared_but_not_defined;
BOOST_MPL_ASSERT_NOT(( static_assert( !mock::detail::is_functor< declared_but_not_defined, int >::value, "Should not be a functor" );
mock::detail::is_functor< declared_but_not_defined, int > ));
template< typename T > template< typename T >
void is_functor( 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 > template< typename T >
void is_not_functor( 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() {} void f0() {}
@ -48,22 +47,22 @@ BOOST_AUTO_TEST_CASE( data_is_not_functor )
BOOST_AUTO_TEST_CASE( function_is_functor ) BOOST_AUTO_TEST_CASE( function_is_functor )
{ {
is_functor( f0 ); is_not_functor( f0 );
is_functor( f1 ); is_functor( f1 );
is_functor( f2 ); is_not_functor( f2 );
} }
BOOST_AUTO_TEST_CASE( function_pointer_is_functor ) BOOST_AUTO_TEST_CASE( function_pointer_is_functor )
{ {
is_functor( &f0 ); is_not_functor( &f0 );
is_functor( &f1 ); is_functor( &f1 );
is_functor( &f2 ); is_not_functor( &f2 );
} }
BOOST_AUTO_TEST_CASE( std_ptr_fun_is_functor ) BOOST_AUTO_TEST_CASE( std_ptr_fun_is_functor )
{ {
is_functor( std::ptr_fun( &f1 ) ); 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 ) 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 ), "" ) ); 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 ) BOOST_AUTO_TEST_CASE( boost_bind_is_functor )
{ {
is_functor( boost::bind( &f0 ) ); 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 ) BOOST_AUTO_TEST_CASE( boost_function_is_functor )
{ {
is_functor( boost::function< void() >() ); is_functor( boost::function< void(int) >() );
}
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() );
} }
#ifdef MOCK_LAMBDAS #ifdef MOCK_LAMBDAS