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.
template<typename Function, typename Functor>
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(); }
template<typename Function, typename Functor>
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(); }
template<typename Function, typename Functor>
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>())
return *fp == g;
@ -337,13 +339,34 @@ namespace boost {
template<typename Function, typename Functor>
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>)
{
if (const Functor* fp = f.template target<Functor>())
return *fp != g;
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
} // end namespace function
} // end namespace detail

View File

@ -590,7 +590,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Functor g)
{
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 ,
@ -603,7 +603,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Allocator>& f)
{
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 ,
@ -616,7 +616,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Functor g)
{
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 ,
@ -629,7 +629,7 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
Allocator>& f)
{
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
@ -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;
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
#endif // Compiler supporting SFINAE

View File

@ -87,10 +87,68 @@ static void equal_test()
#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*[])
{
target_test();
equal_test();
ref_equal_test();
return 0;
}