diff --git a/include/turtle/detail/expectation_template.hpp b/include/turtle/detail/expectation_template.hpp index 1cdc763..ca9f644 100644 --- a/include/turtle/detail/expectation_template.hpp +++ b/include/turtle/detail/expectation_template.hpp @@ -133,9 +133,9 @@ namespace detail > > () ) , file_( "unknown location" ) - , line_( 0 ) + , line_( 0 ) #if defined(MOCK_THREAD_SAFE) - , blocked(ATOMIC_VAR_INIT(false)) + , blocked(false) #endif { } expectation( const char* file, int line ) @@ -149,10 +149,20 @@ namespace detail , file_( file ) , line_( line ) #if defined(MOCK_THREAD_SAFE) - , blocked(ATOMIC_VAR_INIT(false)) + , blocked(false) #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() { for( sequences_cit it = sequences_.begin(); @@ -197,7 +207,7 @@ namespace detail expectation &async(const duration timeout) { timeout_ = timeout; - blocked = false; + blocked.store(false,std::memory_order_release); return *this; } #endif @@ -220,7 +230,7 @@ namespace detail { 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; } } @@ -232,7 +242,7 @@ namespace detail BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const { #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) ); #else return !invocation_->exhausted() @@ -294,7 +304,7 @@ namespace detail int line_; #if defined(MOCK_THREAD_SAFE) boost::optional timeout_; - mutable std::atomic_bool blocked; + mutable std::atomic blocked; #endif }; } diff --git a/include/turtle/detail/function.hpp b/include/turtle/detail/function.hpp index 4a48220..f29aa65 100644 --- a/include/turtle/detail/function.hpp +++ b/include/turtle/detail/function.hpp @@ -49,6 +49,10 @@ namespace detail : e_( &e ) {} + wrapper_base( wrapper_base && w ) + : e_( w.e_ ) + {} + template< typename T > void returns( T t ) { @@ -64,6 +68,11 @@ namespace detail : e_( &e ) {} + wrapper_base( wrapper_base && w ) + : e_( w.e_ ) + {} + + E* e_; }; template< typename R, typename E > @@ -73,6 +82,10 @@ namespace detail : e_( &e ) {} + wrapper_base( wrapper_base && w ) + : e_( w.e_ ) + {} + void returns( R* r ) { e_->returns( r ); diff --git a/include/turtle/detail/function_impl_template.hpp b/include/turtle/detail/function_impl_template.hpp index 0da6e80..1f731e3 100644 --- a/include/turtle/detail/function_impl_template.hpp +++ b/include/turtle/detail/function_impl_template.hpp @@ -91,7 +91,7 @@ namespace detail } return valid_; } - + virtual void reset() { lock _( mutex_ ); @@ -112,9 +112,16 @@ namespace detail : wrapper_base< R, expectation_type >( e ) , lock_( m ) {} - + wrapper(const wrapper &) = delete; + wrapper( wrapper && w) + : wrapper_base< R, expectation_type > (*w.e_) + , lock_( std::move(w.lock_) ) + { + + } + wrapper &once() { this->e_->invoke( boost::make_shared< detail::once >() ); diff --git a/include/turtle/detail/mutex.hpp b/include/turtle/detail/mutex.hpp index 6180b6b..29b5fe8 100644 --- a/include/turtle/detail/mutex.hpp +++ b/include/turtle/detail/mutex.hpp @@ -41,13 +41,19 @@ namespace detail typedef MOCK_THREAD_NAMESPACE::condition_variable_any condition_variable; typedef MOCK_THREAD_NAMESPACE::chrono::nanoseconds nanoseconds; typedef MOCK_THREAD_NAMESPACE::unique_lock lock_base; - - struct lock : public lock_base + + struct lock : public lock_base { lock(const boost::shared_ptr< detail::mutex > &m) : lock_base (*m) , m_(m) {} + + lock(lock && l) + : lock_base(*l.m_) + , m_(l.m_) + { + } ~lock() { unlock(); diff --git a/test/test_async.cpp b/test/test_async.cpp index f7853c3..57f9b65 100644 --- a/test/test_async.cpp +++ b/test/test_async.cpp @@ -29,11 +29,11 @@ namespace BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fixture ) { #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_THREAD_NAMESPACE::thread context([&](){ + MOCK_THREAD_NAMESPACE::thread context([&](){ 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(); 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 ) { #if defined(MOCK_THREAD_SAFE) - const mock_class m; + const mock_class m{}; bool unexpected_call_received = false; 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)); try{ m.my_method("some parameter"); @@ -64,4 +64,4 @@ BOOST_AUTO_TEST_CASE( mock_object_asynchonous_call_expectation_fails ) context.join(); BOOST_CHECK(unexpected_call_received == true); #endif -} \ No newline at end of file +} diff --git a/test/test_integration.cpp b/test/test_integration.cpp index 71ed0c6..8562da3 100644 --- a/test/test_integration.cpp +++ b/test/test_integration.cpp @@ -128,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE( mock_object_method_const_disambiguation, mock_error_fix my_const_ambiguited_mock mock; MOCK_EXPECT( mock.tag1 ); 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()" ); }