From d3a5d3010c0181eb8deacdc7aedf2cb250e391b2 Mon Sep 17 00:00:00 2001 From: Mathieu Champlon Date: Mon, 15 Jan 2018 06:23:25 +0100 Subject: [PATCH] Fixed move-only type argument in actions Because boost::function does not move the parameters it receives we need to use std::function instead. --- doc/changelog.qbk | 1 + include/turtle/detail/action.hpp | 4 ++-- include/turtle/detail/expectation_template.hpp | 12 ++++++++---- include/turtle/detail/function.hpp | 1 + .../turtle/detail/function_impl_template.hpp | 2 +- include/turtle/detail/function_template.hpp | 17 +++++------------ include/turtle/detail/matcher_base_template.hpp | 9 ++++++--- test/test_integration.cpp | 16 ++++++++++++++++ 8 files changed, 40 insertions(+), 22 deletions(-) diff --git a/doc/changelog.qbk b/doc/changelog.qbk index 64aba81..e76e4ab 100644 --- a/doc/changelog.qbk +++ b/doc/changelog.qbk @@ -13,6 +13,7 @@ Not yet released * Fixed mocking of a function returning a reference for gcc 4.1 * Added MOCK_NO_AUTO_PTR to deactivate std::auto_ptr support * Added [@https://github.com/philsquared/Catch Catch] integration +* Fixed move-only type argument in actions [endsect] diff --git a/include/turtle/detail/action.hpp b/include/turtle/detail/action.hpp index f261d57..7e1fdb2 100644 --- a/include/turtle/detail/action.hpp +++ b/include/turtle/detail/action.hpp @@ -27,8 +27,8 @@ namespace detail class action_base { private: - typedef boost::function< Signature > functor_type; - typedef boost::function< Result() > action_type; + typedef std::function< Signature > functor_type; + typedef std::function< Result() > action_type; public: const functor_type& functor() const diff --git a/include/turtle/detail/expectation_template.hpp b/include/turtle/detail/expectation_template.hpp index 0c2ac58..4dd0c7c 100644 --- a/include/turtle/detail/expectation_template.hpp +++ b/include/turtle/detail/expectation_template.hpp @@ -23,6 +23,9 @@ #define MOCK_EXPECTATION_SERIALIZE_ANY(z, n, d) \ BOOST_PP_IF(n, << ", " <<,) "any" +#define MOCK_CALL_PARAM_TYPE(z, n, d) \ + typename boost::call_traits< T##n >::param_type + namespace mock { namespace detail @@ -36,7 +39,7 @@ namespace detail { private: virtual bool operator()( - BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM_TYPE, _) ) { return true; } @@ -70,7 +73,7 @@ namespace detail private: virtual bool operator()( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) { return BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_IS_VALID, _); @@ -100,7 +103,7 @@ namespace detail private: virtual bool operator()( - BOOST_PP_ENUM_BINARY_PARAMS( MOCK_NUM_ARGS, T, a ) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) { return f_( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); } @@ -198,7 +201,7 @@ namespace detail } bool is_valid( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) const { return !invocation_->exhausted() && (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); @@ -256,6 +259,7 @@ namespace detail } } // mock +#undef MOCK_CALL_PARAM_TYPE #undef MOCK_EXPECTATION_INITIALIZE #undef MOCK_EXPECTATION_MEMBER #undef MOCK_EXPECTATION_IS_VALID diff --git a/include/turtle/detail/function.hpp b/include/turtle/detail/function.hpp index 4a48220..837b169 100644 --- a/include/turtle/detail/function.hpp +++ b/include/turtle/detail/function.hpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/include/turtle/detail/function_impl_template.hpp b/include/turtle/detail/function_impl_template.hpp index 19cd6ff..c60ce6f 100644 --- a/include/turtle/detail/function_impl_template.hpp +++ b/include/turtle/detail/function_impl_template.hpp @@ -235,7 +235,7 @@ namespace detail MOCK_FUNCTION_CONTEXT, it->file(), it->line() ); if( it->functor() ) return it->functor()( - BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ); + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ); return it->trigger(); } error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT ); diff --git a/include/turtle/detail/function_template.hpp b/include/turtle/detail/function_template.hpp index f356eca..04a0ad2 100644 --- a/include/turtle/detail/function_template.hpp +++ b/include/turtle/detail/function_template.hpp @@ -8,12 +8,8 @@ #include "function_impl_template.hpp" -#define MOCK_FUNCTION_CALL(z, n, d ) \ - BOOST_PP_COMMA_IF(n) typename \ - boost::call_traits< T##n >::param_type - -#define MOCK_FUNCTION_PARAM(z, n, d) \ - MOCK_FUNCTION_CALL(z, n, d) t##n +#define MOCK_FORWARD(z, n, d) \ + boost::forward< T##n >( t##n ) namespace mock { @@ -36,7 +32,7 @@ namespace detail private: typedef function_impl< - R ( BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_CALL, _) ) + R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > impl_type; typedef typename impl_type::wrapper_type expectation_type; typedef typename impl_type::error_type error_type; @@ -76,9 +72,9 @@ namespace detail } R operator()( - BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_PARAM, _) ) const + BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const { - return (*impl_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ); + return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ); } friend std::ostream& operator<<( std::ostream& s, const function& f ) @@ -106,6 +102,3 @@ namespace detail }; } } // mock - -#undef MOCK_FUNCTION_CALL -#undef MOCK_FUNCTION_PARAM diff --git a/include/turtle/detail/matcher_base_template.hpp b/include/turtle/detail/matcher_base_template.hpp index d3d0993..79bc17b 100644 --- a/include/turtle/detail/matcher_base_template.hpp +++ b/include/turtle/detail/matcher_base_template.hpp @@ -6,6 +6,9 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#define MOCK_CALL_PARAM(z, n, d) \ + typename boost::call_traits< T##n >::param_type a##n + namespace mock { namespace detail @@ -13,15 +16,15 @@ namespace detail template< typename Signature > class matcher_base; template< - BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Actual_) > - class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Actual_) ) > + BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) > + class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) > : boost::noncopyable { public: virtual ~matcher_base() {} virtual bool operator()( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Actual_, actual_) ) = 0; + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) = 0; friend std::ostream& operator<<( std::ostream& s, const matcher_base& m ) diff --git a/test/test_integration.cpp b/test/test_integration.cpp index 71ed0c6..a93d979 100644 --- a/test/test_integration.cpp +++ b/test/test_integration.cpp @@ -690,3 +690,19 @@ BOOST_FIXTURE_TEST_CASE( mock_method_accepts_polymorphic_multi_constraint, mock_ m.m2( 1, 2 ); CHECK_CALLS( 1 ); } + +#ifdef MOCK_SMART_PTR + +BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_action, mock_error_fixture ) +{ + MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) ); + std::unique_ptr< int > p; + MOCK_EXPECT( f ).once().calls( + []( std::unique_ptr< int > ) + { + } ); + f( std::unique_ptr< int >( new int( 7 ) ) ); + CHECK_CALLS( 1 ); +} + +#endif