Removed all copies of the wrapper object

This commit is contained in:
Thomas Bernard 2016-01-16 01:19:43 +01:00
parent 4eadca553b
commit 04497bd5b5
6 changed files with 54 additions and 18 deletions

View file

@ -133,9 +133,9 @@ namespace detail
> >
> () ) > () )
, file_( "unknown location" ) , file_( "unknown location" )
, line_( 0 ) , line_( 0 )
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_THREAD_SAFE)
, blocked(ATOMIC_VAR_INIT(false)) , blocked(false)
#endif #endif
{ } { }
expectation( const char* file, int line ) expectation( const char* file, int line )
@ -149,10 +149,20 @@ namespace detail
, file_( file ) , file_( file )
, line_( line ) , line_( line )
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_THREAD_SAFE)
, blocked(ATOMIC_VAR_INIT(false)) , blocked(false)
#endif #endif
{ } { }
expectation(expectation && e)
: invocation_ ( e.invocation_)
, matcher_(e.matcher_)
, file_(e.file_)
, line_(e.line_)
#if defined(MOCK_THREAD_SAFE)
, blocked(false)
#endif
{}
~expectation() ~expectation()
{ {
for( sequences_cit it = sequences_.begin(); for( sequences_cit it = sequences_.begin();
@ -197,7 +207,7 @@ namespace detail
expectation &async(const duration timeout) expectation &async(const duration timeout)
{ {
timeout_ = timeout; timeout_ = timeout;
blocked = false; blocked.store(false,std::memory_order_release);
return *this; return *this;
} }
#endif #endif
@ -220,7 +230,7 @@ namespace detail
{ {
if (MOCK_THREAD_NAMESPACE::cv_status::timeout == cv->wait_for(lk.get_unique_lock(), *timeout_)) if (MOCK_THREAD_NAMESPACE::cv_status::timeout == cv->wait_for(lk.get_unique_lock(), *timeout_))
{ {
std::atomic_store(&blocked,true); blocked.store(true, std::memory_order_release);
return false; return false;
} }
} }
@ -232,7 +242,7 @@ namespace detail
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_THREAD_SAFE)
return !blocked && !invocation_->exhausted() return !blocked.load(std::memory_order_acquire) && !invocation_->exhausted()
&& (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); && (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) );
#else #else
return !invocation_->exhausted() return !invocation_->exhausted()
@ -294,7 +304,7 @@ namespace detail
int line_; int line_;
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_THREAD_SAFE)
boost::optional<nanoseconds> timeout_; boost::optional<nanoseconds> timeout_;
mutable std::atomic_bool blocked; mutable std::atomic<bool> blocked;
#endif #endif
}; };
} }

View file

@ -49,6 +49,10 @@ namespace detail
: e_( &e ) : e_( &e )
{} {}
wrapper_base( wrapper_base && w )
: e_( w.e_ )
{}
template< typename T > template< typename T >
void returns( T t ) void returns( T t )
{ {
@ -64,6 +68,11 @@ namespace detail
: e_( &e ) : e_( &e )
{} {}
wrapper_base( wrapper_base && w )
: e_( w.e_ )
{}
E* e_; E* e_;
}; };
template< typename R, typename E > template< typename R, typename E >
@ -73,6 +82,10 @@ namespace detail
: e_( &e ) : e_( &e )
{} {}
wrapper_base( wrapper_base && w )
: e_( w.e_ )
{}
void returns( R* r ) void returns( R* r )
{ {
e_->returns( r ); e_->returns( r );

View file

@ -91,7 +91,7 @@ namespace detail
} }
return valid_; return valid_;
} }
virtual void reset() virtual void reset()
{ {
lock _( mutex_ ); lock _( mutex_ );
@ -112,9 +112,16 @@ namespace detail
: wrapper_base< R, expectation_type >( e ) : wrapper_base< R, expectation_type >( e )
, lock_( m ) , lock_( m )
{} {}
wrapper(const wrapper &) = delete; wrapper(const wrapper &) = delete;
wrapper( wrapper && w)
: wrapper_base< R, expectation_type > (*w.e_)
, lock_( std::move(w.lock_) )
{
}
wrapper &once() wrapper &once()
{ {
this->e_->invoke( boost::make_shared< detail::once >() ); this->e_->invoke( boost::make_shared< detail::once >() );

View file

@ -41,13 +41,19 @@ namespace detail
typedef MOCK_THREAD_NAMESPACE::condition_variable_any condition_variable; typedef MOCK_THREAD_NAMESPACE::condition_variable_any condition_variable;
typedef MOCK_THREAD_NAMESPACE::chrono::nanoseconds nanoseconds; typedef MOCK_THREAD_NAMESPACE::chrono::nanoseconds nanoseconds;
typedef MOCK_THREAD_NAMESPACE::unique_lock<mutex> lock_base; typedef MOCK_THREAD_NAMESPACE::unique_lock<mutex> lock_base;
struct lock : public lock_base struct lock : public lock_base
{ {
lock(const boost::shared_ptr< detail::mutex > &m) lock(const boost::shared_ptr< detail::mutex > &m)
: lock_base (*m) : lock_base (*m)
, m_(m) , m_(m)
{} {}
lock(lock && l)
: lock_base(*l.m_)
, m_(l.m_)
{
}
~lock() ~lock()
{ {
unlock(); unlock();

View file

@ -29,11 +29,11 @@ namespace
BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fixture )
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_THREAD_SAFE)
const mock_class m; const mock_class m{};
MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" ); MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" );
MOCK_THREAD_NAMESPACE::thread context([&](){ MOCK_THREAD_NAMESPACE::thread context([&](){
MOCK_THREAD_NAMESPACE::this_thread::sleep_for(MOCK_THREAD_NAMESPACE::chrono::milliseconds(10)); MOCK_THREAD_NAMESPACE::this_thread::sleep_for(MOCK_THREAD_NAMESPACE::chrono::milliseconds(10));
m.my_method("some parameter"); m.my_method("some parameter");
}); });
mock::verify(); mock::verify();
CHECK_CALLS( 1 ); CHECK_CALLS( 1 );
@ -45,10 +45,10 @@ BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fi
BOOST_AUTO_TEST_CASE( mock_object_asynchonous_call_expectation_fails ) BOOST_AUTO_TEST_CASE( mock_object_asynchonous_call_expectation_fails )
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_THREAD_SAFE)
const mock_class m; const mock_class m{};
bool unexpected_call_received = false; bool unexpected_call_received = false;
MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" ); MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" );
MOCK_THREAD_NAMESPACE::thread context([&](){ MOCK_THREAD_NAMESPACE::thread context([&](){
MOCK_THREAD_NAMESPACE::this_thread::sleep_for(MOCK_THREAD_NAMESPACE::chrono::milliseconds(100)); MOCK_THREAD_NAMESPACE::this_thread::sleep_for(MOCK_THREAD_NAMESPACE::chrono::milliseconds(100));
try{ try{
m.my_method("some parameter"); m.my_method("some parameter");
@ -64,4 +64,4 @@ BOOST_AUTO_TEST_CASE( mock_object_asynchonous_call_expectation_fails )
context.join(); context.join();
BOOST_CHECK(unexpected_call_received == true); BOOST_CHECK(unexpected_call_received == true);
#endif #endif
} }

View file

@ -128,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE( mock_object_method_const_disambiguation, mock_error_fix
my_const_ambiguited_mock mock; my_const_ambiguited_mock mock;
MOCK_EXPECT( mock.tag1 ); MOCK_EXPECT( mock.tag1 );
BOOST_CHECK_NO_THROW( mock.my_method() ); BOOST_CHECK_NO_THROW( mock.my_method() );
const my_const_ambiguited_mock const_mock; const my_const_ambiguited_mock const_mock{};
CHECK_ERROR( const_mock.my_method(), "unexpected call", 1, "?.my_const_ambiguited_mock::tag_2()" ); CHECK_ERROR( const_mock.my_method(), "unexpected call", 1, "?.my_const_ambiguited_mock::tag_2()" );
} }