diff --git a/include/boost/function/function_base.hpp b/include/boost/function/function_base.hpp index 635dc62..6da90a2 100644 --- a/include/boost/function/function_base.hpp +++ b/include/boost/function/function_base.hpp @@ -318,17 +318,19 @@ namespace boost { // for compilers that don't support SFINAE. template bool - compare_equal(const Function& f, const Functor&, mpl::bool_) + compare_equal(const Function& f, const Functor&, int, mpl::bool_) { return f.empty(); } template bool - compare_not_equal(const Function& f, const Functor&, mpl::bool_) + compare_not_equal(const Function& f, const Functor&, int, + mpl::bool_) { return !f.empty(); } template bool - compare_equal(const Function& f, const Functor& g, mpl::bool_) + compare_equal(const Function& f, const Functor& g, long, + mpl::bool_) { if (const Functor* fp = f.template target()) return *fp == g; @@ -337,13 +339,34 @@ namespace boost { template bool - compare_not_equal(const Function& f, const Functor& g, + compare_equal(const Function& f, const reference_wrapper& g, + int, mpl::bool_) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + + template + bool + compare_not_equal(const Function& f, const Functor& g, long, mpl::bool_) { if (const Functor* fp = f.template target()) return *fp != g; else return true; } + + template + bool + compare_not_equal(const Function& f, + const reference_wrapper& g, int, + mpl::bool_) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } #endif // BOOST_NO_SFINAE } // end namespace function } // end namespace detail diff --git a/include/boost/function/function_template.hpp b/include/boost/function/function_template.hpp index b8b4fc4..96a2d71 100644 --- a/include/boost/function/function_template.hpp +++ b/include/boost/function/function_template.hpp @@ -590,7 +590,7 @@ template::value)> integral; - return detail::function::compare_equal(f, g, integral()); + return detail::function::compare_equal(f, g, 0, integral()); } template& f) { typedef mpl::bool_<(is_integral::value)> integral; - return detail::function::compare_equal(f, g, integral()); + return detail::function::compare_equal(f, g, 0, integral()); } template::value)> integral; - return detail::function::compare_not_equal(f, g, integral()); + return detail::function::compare_not_equal(f, g, 0, integral()); } template& f) { typedef mpl::bool_<(is_integral::value)> integral; - return detail::function::compare_not_equal(f, g, integral()); + return detail::function::compare_not_equal(f, g, 0, integral()); } #else @@ -690,6 +690,62 @@ template()) return g != *fp; else return true; } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>& f, + reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(reference_wrapper g, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() == fp; + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>& f, + reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(reference_wrapper g, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS , + Allocator>& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() != fp; + else return true; + } #undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL #endif // Compiler supporting SFINAE diff --git a/test/contains_test.cpp b/test/contains_test.cpp index 601828c..258e7a9 100644 --- a/test/contains_test.cpp +++ b/test/contains_test.cpp @@ -87,10 +87,68 @@ static void equal_test() #endif } +static void ref_equal_test() +{ + { + ReturnInt ri(17); + boost::function0 f = boost::ref(ri); + + // References and values are equal + 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)); + BOOST_TEST(!(ri != f)); + + // 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(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + { + ReturnInt ri(17); + boost::function f = boost::ref(ri); + + // References and values are equal + 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)); + BOOST_TEST(!(ri != f)); + + // 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)); + } +#endif +} + int test_main(int, char*[]) { target_test(); equal_test(); + ref_equal_test(); return 0; }