Wrapped constraints parameters with boost::addressof where needed in order to support types with overloaded operator&

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@385 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2011-10-02 14:57:25 +00:00
parent 7fc80c1035
commit db36244dfc
2 changed files with 60 additions and 41 deletions

View file

@ -13,6 +13,7 @@
#include "log.hpp" #include "log.hpp"
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/stringize.hpp>
@ -91,12 +92,12 @@ namespace detail
struct same struct same
{ {
explicit same( const Expected& expected ) explicit same( const Expected& expected )
: expected_( &boost::unwrap_ref( expected ) ) : expected_( boost::addressof( boost::unwrap_ref( expected ) ) )
{} {}
template< typename Actual > template< typename Actual >
bool operator()( const Actual& actual ) const bool operator()( const Actual& actual ) const
{ {
return &actual == expected_; return boost::addressof( actual ) == expected_;
} }
friend std::ostream& operator<<( std::ostream& os, const same& s ) friend std::ostream& operator<<( std::ostream& os, const same& s )
{ {
@ -106,6 +107,45 @@ namespace detail
boost::unwrap_reference< Expected >::type* expected_; 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 > template< typename Expected >
struct assign struct assign
{ {
@ -138,45 +178,6 @@ namespace detail
Expected expected_; 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 > template< typename Expected >
struct contain struct contain
{ {

View file

@ -312,3 +312,21 @@ BOOST_AUTO_TEST_CASE( contain_with_strings )
BOOST_CHECK( ! c.f_( std::string( "this is a string" ) ) ); 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 );
}