diff --git a/build/vc100/turtle.vcxproj b/build/vc100/turtle.vcxproj
index 19ce6a4..da3c4dd 100644
--- a/build/vc100/turtle.vcxproj
+++ b/build/vc100/turtle.vcxproj
@@ -148,7 +148,7 @@
-
+
diff --git a/build/vc100/turtle.vcxproj.filters b/build/vc100/turtle.vcxproj.filters
index 1ad3f82..bbfd10d 100644
--- a/build/vc100/turtle.vcxproj.filters
+++ b/build/vc100/turtle.vcxproj.filters
@@ -37,9 +37,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -73,5 +70,8 @@
Source Files
+
+ Source Files
+
\ No newline at end of file
diff --git a/build/vc100/turtle_test.vcxproj b/build/vc100/turtle_test.vcxproj
index e8343dc..ca7de70 100644
--- a/build/vc100/turtle_test.vcxproj
+++ b/build/vc100/turtle_test.vcxproj
@@ -199,6 +199,7 @@
+
diff --git a/build/vc100/turtle_test.vcxproj.filters b/build/vc100/turtle_test.vcxproj.filters
index 7ab6ed9..f489b3d 100644
--- a/build/vc100/turtle_test.vcxproj.filters
+++ b/build/vc100/turtle_test.vcxproj.filters
@@ -40,6 +40,9 @@
Source Files
+
+ Source Files
+
diff --git a/build/vc80/turtle.vcproj b/build/vc80/turtle.vcproj
index 12d874f..5856283 100644
--- a/build/vc80/turtle.vcproj
+++ b/build/vc80/turtle.vcproj
@@ -192,6 +192,10 @@
RelativePath="..\..\src\libraries\turtle\functional.hpp"
>
+
+
diff --git a/build/vc80/turtle_test.vcproj b/build/vc80/turtle_test.vcproj
index 492812c..902d25a 100644
--- a/build/vc80/turtle_test.vcproj
+++ b/build/vc80/turtle_test.vcproj
@@ -206,6 +206,10 @@
RelativePath="..\..\src\tests\turtle_test\function_test.cpp"
>
+
+
diff --git a/src/libraries/turtle/check.hpp b/src/libraries/turtle/check.hpp
index d6fb2ac..15a2a33 100644
--- a/src/libraries/turtle/check.hpp
+++ b/src/libraries/turtle/check.hpp
@@ -11,6 +11,7 @@
#include "placeholder.hpp"
#include "is_functor.hpp"
+#include "has_operator.hpp"
#include "constraints.hpp"
#include "format.hpp"
#include
@@ -67,9 +68,12 @@ namespace detail
template< typename Functor >
explicit check( const Functor& f,
BOOST_DEDUCED_TYPENAME boost::enable_if<
- BOOST_DEDUCED_TYPENAME detail::is_functor< Functor >
+ BOOST_DEDUCED_TYPENAME boost::mpl::or_<
+ BOOST_DEDUCED_TYPENAME detail::is_functor< Functor >,
+ BOOST_DEDUCED_TYPENAME detail::has_operator< Functor, Actual > // $$$$ MAT : add a has_const_operator too ?
+ >
>::type* = 0 )
- : desc_( "?" )
+ : desc_( mock::format( f ) )
{
BOOST_CONCEPT_ASSERT(( FunctorCompatible< Functor, Actual > ));
f_ = f;
@@ -79,7 +83,10 @@ namespace detail
template< typename Expected >
explicit check( const Expected& expected,
BOOST_DEDUCED_TYPENAME boost::disable_if<
- BOOST_DEDUCED_TYPENAME detail::is_functor< Expected >
+ BOOST_DEDUCED_TYPENAME boost::mpl::or_<
+ BOOST_DEDUCED_TYPENAME detail::is_functor< Expected >,
+ BOOST_DEDUCED_TYPENAME detail::has_operator< Expected, Actual >
+ >
>::type* = 0 )
: desc_( mock::format( expected ) )
{
diff --git a/src/libraries/turtle/has_operator.hpp b/src/libraries/turtle/has_operator.hpp
new file mode 100644
index 0000000..11184ee
--- /dev/null
+++ b/src/libraries/turtle/has_operator.hpp
@@ -0,0 +1,34 @@
+//
+// Copyright Mathieu Champlon 2011
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef MOCK_HAS_OPERATOR_HPP_INCLUDED
+#define MOCK_HAS_OPERATOR_HPP_INCLUDED
+
+#include
+#include
+#include
+
+namespace mock
+{
+namespace detail
+{
+ typedef boost::type_traits::yes_type yes_type;
+ typedef boost::type_traits::no_type no_type;
+
+ template< typename T, typename Actual, bool(T::*)( Actual ) const > struct has_operator_helper_class {};
+
+ template< typename T, typename Actual > yes_type& has_operator_helper( has_operator_helper_class< T, Actual, &T::operator() >* );
+ template< typename T, typename Actual > no_type& has_operator_helper( ... );
+
+ template< typename T, typename Actual > struct has_operator
+ : boost::mpl::bool_< sizeof( has_operator_helper< T, Actual >( 0 ) ) == sizeof( yes_type ) >
+ {};
+}
+}
+
+#endif // #ifndef MOCK_HAS_OPERATOR_HPP_INCLUDED
diff --git a/src/tests/turtle_test/has_operator_test.cpp b/src/tests/turtle_test/has_operator_test.cpp
new file mode 100644
index 0000000..0cc6c5b
--- /dev/null
+++ b/src/tests/turtle_test/has_operator_test.cpp
@@ -0,0 +1,35 @@
+//
+// Copyright Mathieu Champlon 2009
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include
+
+#include
+#define BOOST_LIB_NAME boost_unit_test_framework
+#include
+
+namespace
+{
+ struct functor_with_valid_operator
+ {
+ bool operator()( float ) const
+ {
+ return true;
+ }
+ };
+ BOOST_STATIC_ASSERT(( mock::detail::has_operator< functor_with_valid_operator, float >::type::value ));
+
+ struct functor_with_valid_template_operator
+ {
+ template< typename T >
+ bool operator()( T ) const
+ {
+ return true;
+ }
+ };
+ BOOST_STATIC_ASSERT(( mock::detail::has_operator< functor_with_valid_template_operator, float >::type::value ));
+}
diff --git a/src/tests/turtle_test/integration_test.cpp b/src/tests/turtle_test/integration_test.cpp
index 714338b..820f0fe 100644
--- a/src/tests/turtle_test/integration_test.cpp
+++ b/src/tests/turtle_test/integration_test.cpp
@@ -310,3 +310,52 @@ BOOST_AUTO_TEST_CASE( boost_optional_on_base_class_reference_as_return_type )
MOCK_EXPECT( b, method ).once().returns( boost::ref( o ) );
b.method();
}
+
+namespace
+{
+ template< typename Expected >
+ struct near_constraint
+ {
+ near_constraint( Expected expected, Expected threshold )
+ : expected_( expected )
+ , threshold_( threshold )
+ {}
+
+ template< typename Actual >
+ bool operator()( Actual actual ) const
+ {
+ return std::abs( actual - expected_ ) < threshold_;
+ }
+
+ friend std::ostream& operator<<( std::ostream& os, const near_constraint& c )
+ {
+ return os << "std::abs( _ - " << c.expected_ << " ) < " << c.threshold_;
+ }
+
+ //template< typename Actual >
+ //void explain( std::ostream& os, Actual actual ) const
+ //{
+ // os << std::abs( actual - expected_ ) << " >= " << threshold_;
+ //}
+
+ Expected expected_;
+ Expected threshold_;
+ };
+ template< typename Expected >
+ near_constraint< Expected > near( Expected expected, Expected threshold )
+ {
+ return near_constraint< Expected >( expected, threshold );
+ }
+
+ MOCK_CLASS( custom_constraint_mock )
+ {
+ MOCK_METHOD_EXT( method, 1, void( float ), method )
+ };
+}
+
+BOOST_AUTO_TEST_CASE( writing_custom_constraint )
+{
+ custom_constraint_mock m;
+ MOCK_EXPECT( m, method ).with( near( 3.f, 0.01f ) );
+ m.method( 3.f );
+}