Fix semantics for comparison against reference_wrappers

[SVN r21901]
This commit is contained in:
Douglas Gregor
2004-01-24 23:31:40 +00:00
parent c31ad8700e
commit 746676d274
3 changed files with 145 additions and 8 deletions

View File

@ -318,17 +318,19 @@ namespace boost {
// for compilers that don't support SFINAE. // for compilers that don't support SFINAE.
template<typename Function, typename Functor> template<typename Function, typename Functor>
bool bool
compare_equal(const Function& f, const Functor&, mpl::bool_<true>) compare_equal(const Function& f, const Functor&, int, mpl::bool_<true>)
{ return f.empty(); } { return f.empty(); }
template<typename Function, typename Functor> template<typename Function, typename Functor>
bool bool
compare_not_equal(const Function& f, const Functor&, mpl::bool_<true>) compare_not_equal(const Function& f, const Functor&, int,
mpl::bool_<true>)
{ return !f.empty(); } { return !f.empty(); }
template<typename Function, typename Functor> template<typename Function, typename Functor>
bool bool
compare_equal(const Function& f, const Functor& g, mpl::bool_<false>) compare_equal(const Function& f, const Functor& g, long,
mpl::bool_<false>)
{ {
if (const Functor* fp = f.template target<Functor>()) if (const Functor* fp = f.template target<Functor>())
return *fp == g; return *fp == g;
@ -337,13 +339,34 @@ namespace boost {
template<typename Function, typename Functor> template<typename Function, typename Functor>
bool bool
compare_not_equal(const Function& f, const Functor& g, compare_equal(const Function& f, const reference_wrapper<Functor>& g,
int, mpl::bool_<false>)
{
if (const Functor* fp = f.template target<Functor>())
return fp == g.get_pointer();
else return false;
}
template<typename Function, typename Functor>
bool
compare_not_equal(const Function& f, const Functor& g, long,
mpl::bool_<false>) mpl::bool_<false>)
{ {
if (const Functor* fp = f.template target<Functor>()) if (const Functor* fp = f.template target<Functor>())
return *fp != g; return *fp != g;
else return true; else return true;
} }
template<typename Function, typename Functor>
bool
compare_not_equal(const Function& f,
const reference_wrapper<Functor>& g, int,
mpl::bool_<false>)
{
if (const Functor* fp = f.template target<Functor>())
return fp != g.get_pointer();
else return true;
}
#endif // BOOST_NO_SFINAE #endif // BOOST_NO_SFINAE
} // end namespace function } // end namespace function
} // end namespace detail } // end namespace detail

View File

@ -590,7 +590,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Functor g) Functor g)
{ {
typedef mpl::bool_<(is_integral<Functor>::value)> integral; typedef mpl::bool_<(is_integral<Functor>::value)> integral;
return detail::function::compare_equal(f, g, integral()); return detail::function::compare_equal(f, g, 0, integral());
} }
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS , template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
@ -603,7 +603,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Allocator>& f) Allocator>& f)
{ {
typedef mpl::bool_<(is_integral<Functor>::value)> integral; typedef mpl::bool_<(is_integral<Functor>::value)> integral;
return detail::function::compare_equal(f, g, integral()); return detail::function::compare_equal(f, g, 0, integral());
} }
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS , template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
@ -616,7 +616,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Functor g) Functor g)
{ {
typedef mpl::bool_<(is_integral<Functor>::value)> integral; typedef mpl::bool_<(is_integral<Functor>::value)> integral;
return detail::function::compare_not_equal(f, g, integral()); return detail::function::compare_not_equal(f, g, 0, integral());
} }
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS , template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
@ -629,7 +629,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Allocator>& f) Allocator>& f)
{ {
typedef mpl::bool_<(is_integral<Functor>::value)> integral; typedef mpl::bool_<(is_integral<Functor>::value)> integral;
return detail::function::compare_not_equal(f, g, integral()); return detail::function::compare_not_equal(f, g, 0, integral());
} }
#else #else
@ -690,6 +690,62 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
if (const Functor* fp = f.template target<Functor>()) return g != *fp; if (const Functor* fp = f.template target<Functor>()) return g != *fp;
else return true; else return true;
} }
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator, typename Functor>
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<Functor> g)
{
if (const Functor* fp = f.template target<Functor>())
return fp == g.get_pointer();
else return false;
}
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator, typename Functor>
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
operator==(reference_wrapper<Functor> g,
const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>& f)
{
if (const Functor* fp = f.template target<Functor>())
return g.get_pointer() == fp;
else return false;
}
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator, typename Functor>
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<Functor> g)
{
if (const Functor* fp = f.template target<Functor>())
return fp != g.get_pointer();
else return true;
}
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator, typename Functor>
BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
operator!=(reference_wrapper<Functor> g,
const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>& f)
{
if (const Functor* fp = f.template target<Functor>())
return g.get_pointer() != fp;
else return true;
}
#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL #undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
#endif // Compiler supporting SFINAE #endif // Compiler supporting SFINAE

View File

@ -87,10 +87,68 @@ static void equal_test()
#endif #endif
} }
static void ref_equal_test()
{
{
ReturnInt ri(17);
boost::function0<int> 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<int(void)> 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*[]) int test_main(int, char*[])
{ {
target_test(); target_test();
equal_test(); equal_test();
ref_equal_test();
return 0; return 0;
} }