diff --git a/src/libraries/turtle/constraints.hpp b/src/libraries/turtle/constraints.hpp index 69d753e..08cb375 100644 --- a/src/libraries/turtle/constraints.hpp +++ b/src/libraries/turtle/constraints.hpp @@ -13,6 +13,7 @@ #include "log.hpp" #include #include +#include #include #include @@ -91,12 +92,12 @@ namespace detail struct same { explicit same( const Expected& expected ) - : expected_( &boost::unwrap_ref( expected ) ) + : expected_( boost::addressof( boost::unwrap_ref( expected ) ) ) {} template< typename Actual > bool operator()( const Actual& actual ) const { - return &actual == expected_; + return boost::addressof( actual ) == expected_; } friend std::ostream& operator<<( std::ostream& os, const same& s ) { @@ -106,6 +107,45 @@ namespace detail boost::unwrap_reference< Expected >::type* expected_; }; + template< typename Expected > + struct retrieve + { + explicit retrieve( Expected& expected ) + : expected_( boost::addressof( boost::unwrap_ref( expected ) ) ) + {} + template< typename Actual > + bool operator()( const Actual& actual, + BOOST_DEDUCED_TYPENAME boost::disable_if< + boost::is_convertible< + const Actual*, + BOOST_DEDUCED_TYPENAME + boost::unwrap_reference< Expected >::type + > + >::type* = 0 ) const + { + *expected_ = actual; + return true; + } + template< typename Actual > + bool operator()( Actual& actual, + BOOST_DEDUCED_TYPENAME boost::enable_if< + boost::is_convertible< Actual*, + BOOST_DEDUCED_TYPENAME + boost::unwrap_reference< Expected >::type + > + >::type* = 0 ) const + { + *expected_ = boost::addressof( actual ); + return true; + } + friend std::ostream& operator<<( std::ostream& s, const retrieve& r ) + { + return s << "retrieve( " << mock::format( *r.expected_ ) << " )"; + } + BOOST_DEDUCED_TYPENAME + boost::unwrap_reference< Expected >::type* expected_; + }; + template< typename Expected > struct assign { @@ -138,45 +178,6 @@ namespace detail Expected expected_; }; - template< typename Expected > - struct retrieve - { - explicit retrieve( Expected& expected ) - : expected_( &boost::unwrap_ref( expected ) ) - {} - template< typename Actual > - bool operator()( const Actual& actual, - BOOST_DEDUCED_TYPENAME boost::disable_if< - boost::is_convertible< - const Actual*, - BOOST_DEDUCED_TYPENAME - boost::unwrap_reference< Expected >::type - > - >::type* = 0 ) const - { - *expected_ = actual; - return true; - } - template< typename Actual > - bool operator()( Actual& actual, - BOOST_DEDUCED_TYPENAME boost::enable_if< - boost::is_convertible< Actual*, - BOOST_DEDUCED_TYPENAME - boost::unwrap_reference< Expected >::type - > - >::type* = 0 ) const - { - *expected_ = &actual; - return true; - } - friend std::ostream& operator<<( std::ostream& s, const retrieve& r ) - { - return s << "retrieve( " << mock::format( *r.expected_ ) << " )"; - } - BOOST_DEDUCED_TYPENAME - boost::unwrap_reference< Expected >::type* expected_; - }; - template< typename Expected > struct contain { diff --git a/src/tests/turtle_test/constraints_test.cpp b/src/tests/turtle_test/constraints_test.cpp index cc550e1..6139e2b 100644 --- a/src/tests/turtle_test/constraints_test.cpp +++ b/src/tests/turtle_test/constraints_test.cpp @@ -312,3 +312,21 @@ BOOST_AUTO_TEST_CASE( contain_with_strings ) BOOST_CHECK( ! c.f_( std::string( "this is a string" ) ) ); } } + +namespace +{ + struct type_with_overloaded_address_operator + { + void operator&() {} + void operator&() const {} + }; +} + +BOOST_AUTO_TEST_CASE( type_with_overloaded_address_operator_can_be_used_in_constraints ) +{ + type_with_overloaded_address_operator t; + mock::same( t ).f_( t ); + mock::retrieve( t ).f_( t ); + type_with_overloaded_address_operator* pt; + mock::retrieve( pt ).f_( t ); +}