mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Added support for C++11 lambdas as constraints
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@620 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
c5861a744d
commit
4afe1d32d4
6 changed files with 77 additions and 10 deletions
|
|
@ -261,4 +261,10 @@ This is actually a bug in the compiler, for more information see [@http://connec
|
|||
|
||||
[endsect]
|
||||
|
||||
[section Using C++11 lambda as constraints requires decltype compiler support]
|
||||
|
||||
The technique used in order to detect whether a constraint is a C++11 lambda or not is based on decltype, which means the library can fail to detect a lambda in case the compiler does not support it.
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
|
|
|||
|
|
@ -590,6 +590,14 @@ Example using [@http://www.boost.org/libs/phoenix Boost.Phoenix] :
|
|||
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::_1 == 42 );
|
||||
}
|
||||
|
||||
Example using C++11 lambdas :
|
||||
|
||||
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_constraint_with_cxx11_lambda )
|
||||
{
|
||||
mock_class c;
|
||||
MOCK_EXPECT( c.method ).with( []( int actual ) { return 42 == actual; } );
|
||||
}
|
||||
|
||||
Example using &&, || and ! :
|
||||
|
||||
BOOST_AUTO_TEST_CASE( demonstrates_combining_constraints )
|
||||
|
|
|
|||
|
|
@ -22,19 +22,29 @@
|
|||
namespace
|
||||
{
|
||||
struct declared_but_not_defined;
|
||||
BOOST_MPL_ASSERT_NOT(( mock::detail::is_functor< declared_but_not_defined > ));
|
||||
BOOST_MPL_ASSERT_NOT(( mock::detail::is_functor< declared_but_not_defined, int > ));
|
||||
|
||||
template< typename T >
|
||||
void is_functor( T )
|
||||
{
|
||||
BOOST_MPL_ASSERT(( mock::detail::is_functor< T > ));
|
||||
BOOST_MPL_ASSERT(( mock::detail::is_functor< T, int > ));
|
||||
}
|
||||
template< typename T >
|
||||
void is_not_functor( T )
|
||||
{
|
||||
BOOST_MPL_ASSERT_NOT(( mock::detail::is_functor< T, int > ));
|
||||
}
|
||||
|
||||
void f0 () {}
|
||||
void f0() {}
|
||||
bool f1( int ) { return false; }
|
||||
bool f2( std::string, int ) { return false; }
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( data_is_not_functor )
|
||||
{
|
||||
is_not_functor( 42 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( function_is_functor )
|
||||
{
|
||||
is_functor( f0 );
|
||||
|
|
@ -63,12 +73,11 @@ BOOST_AUTO_TEST_CASE( std_bind_first_is_functor )
|
|||
namespace
|
||||
{
|
||||
struct unary_functor0 : public std::unary_function< void, void >
|
||||
{
|
||||
};
|
||||
{};
|
||||
struct unary_functor1 : public std::unary_function< int, void >
|
||||
{
|
||||
};
|
||||
{};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( std_unary_functor_is_functor )
|
||||
{
|
||||
is_functor( unary_functor0() );
|
||||
|
|
@ -105,6 +114,7 @@ namespace
|
|||
typedef void result_type;
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( class_with_result_type_is_functor )
|
||||
{
|
||||
is_functor( result_type_functor() );
|
||||
|
|
@ -121,7 +131,20 @@ namespace
|
|||
};
|
||||
};
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( class_with_sig_is_functor )
|
||||
{
|
||||
is_functor( sig_functor() );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( cxx11_lambda_is_functor )
|
||||
{
|
||||
is_not_functor( []() {} );
|
||||
is_functor( []( int ) {} );
|
||||
is_not_functor( []( const std::string&, int ) {} );
|
||||
is_not_functor( []( int, const std::string& ) {} );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef MOCK_CONFIG_HPP_INCLUDED
|
||||
#define MOCK_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/comparison/less.hpp>
|
||||
|
||||
|
|
@ -48,4 +49,8 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE)
|
||||
# define MOCK_DECLTYPE
|
||||
#endif
|
||||
|
||||
#endif // MOCK_CONFIG_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@
|
|||
#ifndef MOCK_IS_FUNCTOR_HPP_INCLUDED
|
||||
#define MOCK_IS_FUNCTOR_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include <boost/function_types/is_callable_builtin.hpp>
|
||||
#include <boost/type_traits/detail/yes_no_type.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
|
||||
namespace mock
|
||||
|
|
@ -22,10 +24,33 @@ namespace detail
|
|||
BOOST_MPL_HAS_XXX_TEMPLATE_DEF( sig )
|
||||
BOOST_MPL_HAS_XXX_TEMPLATE_DEF( result )
|
||||
|
||||
template< typename T >
|
||||
#ifdef MOCK_DECLTYPE
|
||||
|
||||
template< typename T, typename P >
|
||||
struct is_callable
|
||||
{
|
||||
typedef boost::type_traits::yes_type yes_type;
|
||||
typedef boost::type_traits::no_type no_type;
|
||||
|
||||
template< typename T >
|
||||
static yes_type check(
|
||||
decltype( boost::declval< T >()( boost::declval< P >() ) )* );
|
||||
template< typename T >
|
||||
static no_type check( ... );
|
||||
|
||||
typedef boost::mpl::bool_<
|
||||
sizeof( check< T >( 0 ) ) == sizeof( yes_type ) > type;
|
||||
};
|
||||
|
||||
#endif // MOCK_DECLTYPE
|
||||
|
||||
template< typename T, typename P >
|
||||
struct is_functor
|
||||
: boost::mpl::or_<
|
||||
boost::function_types::is_callable_builtin< T >,
|
||||
#ifdef MOCK_DECLTYPE
|
||||
is_callable< T, P >,
|
||||
#endif
|
||||
has_result_type< T >,
|
||||
has_result< T >,
|
||||
has_sig< T >
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace mock
|
|||
template< typename Actual, typename Functor >
|
||||
class matcher< Actual, Functor,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if<
|
||||
detail::is_functor< Functor >
|
||||
detail::is_functor< Functor, Actual >
|
||||
>::type
|
||||
> : public detail::matcher_base< Actual >
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue