diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index 5784bb9..e4d0433 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -63,6 +63,12 @@ namespace boost { namespace python { namespace objects { # define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX #endif +#define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \ + typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \ + (::boost::is_integral::value)>::value), \ + Type>::type + + #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) namespace boost { @@ -432,6 +438,29 @@ public: } } +#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3 + // GCC 3.3 and newer cannot copy with the global operator==, due to + // problems with instantiation of function return types before it + // has been verified that the argument types match up. + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g) const + { + if (const Functor* fp = target()) + return function_equal(*fp, g); + else return false; + } + + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g) const + { + if (const Functor* fp = target()) + return !function_equal(*fp, g); + else return true; + } +#endif + public: // should be protected, but GCC 2.95.3 will fail to allow access detail::function::any_pointer (*manager)( detail::function::any_pointer, @@ -524,12 +553,10 @@ template } #else -#define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \ - typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \ - (::boost::is_integral::value)>::value), \ - Type>::type - -// Comparisons between boost::function objects and arbitrary function objects +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) +// Comparisons between boost::function objects and arbitrary function +// objects. GCC 3.3 and before has an obnoxious bug that prevents this +// from working. template BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) operator==(const function_base& f, Functor g) @@ -565,6 +592,7 @@ template return !function_equal(g, *fp); else return true; } +# endif template BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) @@ -601,7 +629,7 @@ template return g.get_pointer() != fp; else return true; } -#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL + #endif // Compiler supporting SFINAE namespace detail { @@ -626,6 +654,7 @@ namespace detail { } // end namespace detail } // end namespace boost +#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL #undef BOOST_FUNCTION_COMPARE_TYPE_ID #endif // BOOST_FUNCTION_BASE_HEADER diff --git a/test/contains_test.cpp b/test/contains_test.cpp index 02f0ece..0153339 100644 --- a/test/contains_test.cpp +++ b/test/contains_test.cpp @@ -56,18 +56,24 @@ static void equal_test() f = &forty_two; BOOST_TEST(f == &forty_two); - BOOST_TEST(&forty_two == f); BOOST_TEST(f != ReturnInt(17)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(&forty_two == f); BOOST_TEST(ReturnInt(17) != f); +#endif + BOOST_TEST(f.contains(&forty_two)); f = ReturnInt(17); BOOST_TEST(f != &forty_two); - BOOST_TEST(&forty_two != f); BOOST_TEST(f == ReturnInt(17)); - BOOST_TEST(ReturnInt(17) == f); BOOST_TEST(f != ReturnInt(16)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(&forty_two != f); + BOOST_TEST(ReturnInt(17) == f); BOOST_TEST(ReturnInt(16) != f); +#endif + BOOST_TEST(f.contains(ReturnInt(17))); #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) @@ -75,17 +81,21 @@ static void equal_test() g = &forty_two; BOOST_TEST(g == &forty_two); - BOOST_TEST(&forty_two == g); BOOST_TEST(g != ReturnInt(17)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(&forty_two == g); BOOST_TEST(ReturnInt(17) != g); +# endif g = ReturnInt(17); BOOST_TEST(g != &forty_two); - BOOST_TEST(&forty_two != g); BOOST_TEST(g == ReturnInt(17)); - BOOST_TEST(ReturnInt(17) == g); BOOST_TEST(g != ReturnInt(16)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(&forty_two != g); + BOOST_TEST(ReturnInt(17) == g); BOOST_TEST(ReturnInt(16) != g); +# endif #endif } @@ -99,22 +109,26 @@ static void ref_equal_test() BOOST_TEST(f == boost::ref(ri)); BOOST_TEST(f == ri); BOOST_TEST(boost::ref(ri) == f); - BOOST_TEST(ri == f); BOOST_TEST(!(f != boost::ref(ri))); BOOST_TEST(!(f != ri)); BOOST_TEST(!(boost::ref(ri) != f)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(ri == f); BOOST_TEST(!(ri != f)); +#endif // Values equal, references inequal ReturnInt ri2(17); BOOST_TEST(f == ri2); BOOST_TEST(f != boost::ref(ri2)); - BOOST_TEST(ri2 == f); BOOST_TEST(boost::ref(ri2) != f); BOOST_TEST(!(f != ri2)); BOOST_TEST(!(f == boost::ref(ri2))); - BOOST_TEST(!(ri2 != f)); BOOST_TEST(!(boost::ref(ri2) == f)); +#if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(ri2 == f); + BOOST_TEST(!(ri2 != f)); +#endif } #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) @@ -126,22 +140,26 @@ static void ref_equal_test() BOOST_TEST(f == boost::ref(ri)); BOOST_TEST(f == ri); BOOST_TEST(boost::ref(ri) == f); - BOOST_TEST(ri == f); BOOST_TEST(!(f != boost::ref(ri))); BOOST_TEST(!(f != ri)); BOOST_TEST(!(boost::ref(ri) != f)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(ri == f); BOOST_TEST(!(ri != f)); +# endif // Values equal, references inequal ReturnInt ri2(17); BOOST_TEST(f == ri2); BOOST_TEST(f != boost::ref(ri2)); - BOOST_TEST(ri2 == f); BOOST_TEST(boost::ref(ri2) != f); BOOST_TEST(!(f != ri2)); BOOST_TEST(!(f == boost::ref(ri2))); - BOOST_TEST(!(ri2 != f)); BOOST_TEST(!(boost::ref(ri2) == f)); +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + BOOST_TEST(ri2 == f); + BOOST_TEST(!(ri2 != f)); +# endif } #endif }