From c37537401cd450f09a7440c842c62eabc4bddff8 Mon Sep 17 00:00:00 2001 From: mat007 Date: Sun, 1 Mar 2015 11:28:47 +0000 Subject: [PATCH] Fixed action for pointer to const data as return type git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@770 860be788-9bd5-4423-9f1e-828f051e677b --- test/detail/test_function.cpp | 41 ++++++++++--- turtle/detail/action.hpp | 109 ++++++++++++++-------------------- 2 files changed, 78 insertions(+), 72 deletions(-) diff --git a/test/detail/test_function.cpp b/test/detail/test_function.cpp index a180288..3210dbe 100644 --- a/test/detail/test_function.cpp +++ b/test/detail/test_function.cpp @@ -437,6 +437,15 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_value, mock_e BOOST_CHECK( ! f() ); CHECK_CALLS( 1 ); } +#ifdef BOOST_MSVC // this produces a warning with gcc + { + mock::detail::function< int* const() > f; + int i = 0; + f.expect().returns( &i ); + BOOST_CHECK_EQUAL( &i, f() ); + CHECK_CALLS( 1 ); + } +#endif { mock::detail::function< int() > f; f.expect().returns( 0 ); @@ -570,20 +579,36 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_moves_the_set_unique_ptr_lval BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_moves_the_set_unique_ptr_rvalue, mock_error_fixture ) { - mock::detail::function< std::unique_ptr< int >() > f; - f.expect().moves( std::unique_ptr< int >( new int ) ); - BOOST_CHECK_NO_THROW( f() ); - CHECK_CALLS( 1 ); + { + mock::detail::function< std::unique_ptr< int >() > f; + f.expect().moves( std::unique_ptr< int >( new int ) ); + BOOST_CHECK_NO_THROW( f() ); + CHECK_CALLS( 1 ); + } } #endif // MOCK_SMART_PTR BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_shared_ptr_value, mock_error_fixture ) { - mock::detail::function< boost::shared_ptr< base >() > f; - f.expect().returns( new derived ); - BOOST_CHECK_NO_THROW( f() ); - CHECK_CALLS( 1 ); + { + mock::detail::function< boost::shared_ptr< base >() > f; + f.expect().returns( new derived ); + BOOST_CHECK_NO_THROW( f() ); + CHECK_CALLS( 1 ); + } + { + mock::detail::function< const boost::shared_ptr< base >&() > f; + f.expect().returns( new derived ); + BOOST_CHECK_NO_THROW( f() ); + CHECK_CALLS( 1 ); + } + { + mock::detail::function< boost::shared_ptr< base >&() > f; + f.expect().returns( new derived ); + BOOST_CHECK_NO_THROW( f() ); + CHECK_CALLS( 1 ); + } } BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_by_reference, mock_error_fixture ) diff --git a/turtle/detail/action.hpp b/turtle/detail/action.hpp index 2acfd49..02c5e4c 100644 --- a/turtle/detail/action.hpp +++ b/turtle/detail/action.hpp @@ -91,16 +91,7 @@ namespace detail template< typename Value > void returns( const Value& v ) { - returns( boost::ref( v_.store( v ) ) ); - } - template< typename Value > - void returns( Value* v ) - { - typedef typename - boost::remove_reference< - typename boost::remove_const< Result >::type - >::type result_type; - returns( result_type( v ) ); + this->set( boost::ref( store( v ) ) ); } template< typename Y > void returns( const boost::reference_wrapper< Y >& r ) @@ -114,68 +105,58 @@ namespace detail this->set( boost::bind( &boost::move< BOOST_RV_REF( Value ) >, - boost::ref( v_.store( boost::move( v ) ) ) ) ); + boost::ref( store( boost::move( v ) ) ) ) ); } private: - struct value + struct value : boost::noncopyable { - struct holder : boost::noncopyable - { - virtual ~holder() - {} - }; - template< typename T > - struct holder_imp : holder - { - holder_imp( BOOST_RV_REF( T ) t ) - : t_( boost::move( t ) ) - {} - holder_imp( const T& t ) - : t_( t ) - {} - T t_; - }; + virtual ~value() + {} + }; + template< typename T > + struct value_imp : value + { + typedef + typename boost::remove_const< + typename boost::remove_reference< + T + >::type + >::type value_type; - template< typename T > - T& store( BOOST_RV_REF( T ) t ) - { - h_.reset( new holder_imp< T >( boost::move( t ) ) ); - return static_cast< holder_imp< T >& >( *h_ ).t_; - } - template< typename T > - T& store( const T& t ) - { - h_.reset( new holder_imp< T >( t ) ); - return static_cast< holder_imp< T >& >( *h_ ).t_; - } - boost::shared_ptr< holder > h_; + value_imp( BOOST_RV_REF( value_type ) t ) + : t_( boost::move( t ) ) + {} + value_imp( const T& t ) + : t_( t ) + {} + template< typename Y > + value_imp( Y* y ) + : t_( y ) + {} + value_type t_; }; - value v_; - }; - - template< typename Result, typename Signature > - class action< Result*, Signature > - : public action_base< Result*, Signature > - { - public: - void returns( Result* r ) - { - this->set( boost::bind( &do_val< Result* >, r ) ); - } - template< typename Y > - void returns( const boost::reference_wrapper< Y >& r ) - { - this->set( r ); - } - - private: template< typename T > - static T do_val( T t ) + T& store( BOOST_RV_REF( T ) t ) { - return t; + v_.reset( new value_imp< T >( boost::move( t ) ) ); + return static_cast< value_imp< T >& >( *v_ ).t_; } + template< typename T > + T& store( const T& t ) + { + v_.reset( new value_imp< T >( t ) ); + return static_cast< value_imp< T >& >( *v_ ).t_; + } + template< typename T > + Result& store( T* t ) + { + v_.reset( new value_imp< Result >( t ) ); + return static_cast< value_imp< Result >& >( *v_ ).t_; + } + + boost::shared_ptr< value > v_; }; template< typename Signature > @@ -210,13 +191,13 @@ namespace detail void returns( Y* r ) { v_.reset( r ); - returns( boost::ref( v_ ) ); + this->set( boost::ref( v_ ) ); } template< typename Y > void returns( std::auto_ptr< Y > r ) { v_ = r; - returns( boost::ref( v_ ) ); + this->set( boost::ref( v_ ) ); } template< typename Y > void returns( const boost::reference_wrapper< Y >& r )