From ea8c0ef25e34d33e13a4bbba0ce4495e318ad2bb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 26 Jan 2004 19:13:17 +0000 Subject: [PATCH] bind and mem_fn now support operator== and operator!= [SVN r21978] --- include/boost/bind.hpp | 100 ++++++ include/boost/bind/arg.hpp | 5 + include/boost/bind/bind_template.hpp | 5 + include/boost/bind/mem_fn_template.hpp | 180 +++++++++++ include/boost/mem_fn.hpp | 10 + test/Jamfile | 4 +- test/Jamfile.v2 | 4 +- test/bind_eq_test.cpp | 414 +++++++++++++++++++++++++ test/mem_fn_eq_test.cpp | 301 ++++++++++++++++++ 9 files changed, 1021 insertions(+), 2 deletions(-) create mode 100644 test/bind_eq_test.cpp create mode 100644 test/mem_fn_eq_test.cpp diff --git a/include/boost/bind.hpp b/include/boost/bind.hpp index 0613a89..73fabcf 100644 --- a/include/boost/bind.hpp +++ b/include/boost/bind.hpp @@ -69,6 +69,18 @@ template struct result_traits< unspecified, reference_wrapper > #endif +// ref_compare + +template bool ref_compare(T const & a, T const & b, long) +{ + return a == b; +} + +template bool ref_compare(reference_wrapper const & a, reference_wrapper const & b, int) +{ + return a.get_pointer() == b.get_pointer(); +} + // bind_t forward declaration for listN template class bind_t; @@ -84,6 +96,11 @@ public: T & get() { return t_; } T const & get() const { return t_; } + bool operator==(value const & rhs) const + { + return t_ == rhs.t_; + } + private: T t_; @@ -157,6 +174,11 @@ public: { } + bool operator==(list0 const &) const + { + return true; + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -203,6 +225,11 @@ public: BOOST_BIND_VISIT_EACH(v, a1_, 0); } + bool operator==(list1 const & rhs) const + { + return ref_compare(a1_, rhs.a1_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -257,6 +284,11 @@ public: BOOST_BIND_VISIT_EACH(v, a2_, 0); } + bool operator==(list2 const & rhs) const + { + return ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -315,6 +347,11 @@ public: BOOST_BIND_VISIT_EACH(v, a3_, 0); } + bool operator==(list3 const & rhs) const + { + return ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -377,6 +414,13 @@ public: BOOST_BIND_VISIT_EACH(v, a4_, 0); } + bool operator==(list4 const & rhs) const + { + return + ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0) && + ref_compare(a4_, rhs.a4_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -443,6 +487,13 @@ public: BOOST_BIND_VISIT_EACH(v, a5_, 0); } + bool operator==(list5 const & rhs) const + { + return + ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0) && + ref_compare(a4_, rhs.a4_, 0) && ref_compare(a5_, rhs.a5_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -513,6 +564,13 @@ public: BOOST_BIND_VISIT_EACH(v, a6_, 0); } + bool operator==(list6 const & rhs) const + { + return + ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0) && + ref_compare(a4_, rhs.a4_, 0) && ref_compare(a5_, rhs.a5_, 0) && ref_compare(a6_, rhs.a6_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -587,6 +645,14 @@ public: BOOST_BIND_VISIT_EACH(v, a7_, 0); } + bool operator==(list7 const & rhs) const + { + return + ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0) && + ref_compare(a4_, rhs.a4_, 0) && ref_compare(a5_, rhs.a5_, 0) && ref_compare(a6_, rhs.a6_, 0) && + ref_compare(a7_, rhs.a7_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -665,6 +731,14 @@ public: BOOST_BIND_VISIT_EACH(v, a8_, 0); } + bool operator==(list8 const & rhs) const + { + return + ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0) && + ref_compare(a4_, rhs.a4_, 0) && ref_compare(a5_, rhs.a5_, 0) && ref_compare(a6_, rhs.a6_, 0) && + ref_compare(a7_, rhs.a7_, 0) && ref_compare(a8_, rhs.a8_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -747,6 +821,14 @@ public: BOOST_BIND_VISIT_EACH(v, a9_, 0); } + bool operator==(list9 const & rhs) const + { + return + ref_compare(a1_, rhs.a1_, 0) && ref_compare(a2_, rhs.a2_, 0) && ref_compare(a3_, rhs.a3_, 0) && + ref_compare(a4_, rhs.a4_, 0) && ref_compare(a5_, rhs.a5_, 0) && ref_compare(a6_, rhs.a6_, 0) && + ref_compare(a7_, rhs.a7_, 0) && ref_compare(a8_, rhs.a8_, 0) && ref_compare(a9_, rhs.a9_, 0); + } + #ifdef BOOST_NO_VOID_RETURNS template struct evaluator @@ -963,6 +1045,8 @@ template class bind_t { public: + typedef bind_t this_type; + bind_t(F f, L const & l): f_(f), l_(l) {} #define BOOST_BIND_EVALUATE return l_(type(), f_, a) @@ -980,6 +1064,8 @@ template class implementation { public: + typedef implementation this_type; + implementation(F f, L const & l): f_(f), l_(l) {} #define BOOST_BIND_EVALUATE return L::BOOST_NESTED_TEMPLATE evaluator::type::eval(l_, f_, a); @@ -1001,6 +1087,8 @@ private: public: + typedef implementation this_type; + implementation(F f, L const & l): f_(f), l_(l) {} #define BOOST_BIND_EVALUATE L::BOOST_NESTED_TEMPLATE evaluator::type::eval(l_, f_, a); @@ -1021,6 +1109,18 @@ public: #endif +// bind_t::operator== + +template bool operator==(bind_t const & a, bind_t const & b) +{ + return a.compare(b); +} + +template bool operator!=(bind_t const & a, bind_t const & b) +{ + return !a.compare(b); +} + // add_value #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || (__SUNPRO_CC >= 0x530) diff --git a/include/boost/bind/arg.hpp b/include/boost/bind/arg.hpp index a31615d..5deeb7e 100644 --- a/include/boost/bind/arg.hpp +++ b/include/boost/bind/arg.hpp @@ -27,6 +27,11 @@ template class arg { }; +template bool operator==(arg const &, arg const &) +{ + return true; +} + } // namespace boost #endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED diff --git a/include/boost/bind/bind_template.hpp b/include/boost/bind/bind_template.hpp index d6e5a3b..9ab88c9 100644 --- a/include/boost/bind/bind_template.hpp +++ b/include/boost/bind/bind_template.hpp @@ -151,6 +151,11 @@ l_.accept(v); } + bool compare(this_type const & rhs) const + { + return ref_compare(f_, rhs.f_, 0) && l_ == rhs.l_; + } + private: F f_; diff --git a/include/boost/bind/mem_fn_template.hpp b/include/boost/bind/mem_fn_template.hpp index ac260b8..68e2ee4 100644 --- a/include/boost/bind/mem_fn_template.hpp +++ b/include/boost/bind/mem_fn_template.hpp @@ -55,6 +55,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(); } + + bool operator==(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf0 @@ -94,6 +104,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(); } + + bool operator==(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf1 @@ -139,6 +159,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1); } + + bool operator==(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf1 @@ -179,6 +209,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1); } + + bool operator==(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf2 @@ -222,6 +262,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); } + + bool operator==(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf2 @@ -260,6 +310,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); } + + bool operator==(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf3 @@ -303,6 +363,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); } + + bool operator==(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf3 @@ -341,6 +411,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); } + + bool operator==(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf4 @@ -384,6 +464,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); } + + bool operator==(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf4 @@ -422,6 +512,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); } + + bool operator==(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf5 @@ -465,6 +565,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); } + + bool operator==(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf5 @@ -503,6 +613,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); } + + bool operator==(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf6 @@ -546,6 +666,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); } + + bool operator==(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf6 @@ -584,6 +714,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); } + + bool operator==(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf7 @@ -627,6 +767,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); } + + bool operator==(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf7 @@ -665,6 +815,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); } + + bool operator==(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ != rhs.f_; + } }; // mf8 @@ -708,6 +868,16 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); } + + bool operator==(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ != rhs.f_; + } }; // cmf8 @@ -751,5 +921,15 @@ public: { BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); } + + bool operator==(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ != rhs.f_; + } }; diff --git a/include/boost/mem_fn.hpp b/include/boost/mem_fn.hpp index 1e5f606..777a87b 100644 --- a/include/boost/mem_fn.hpp +++ b/include/boost/mem_fn.hpp @@ -308,6 +308,16 @@ public: { return (t.*f_); } + + bool operator==(dm const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(dm const & rhs) const + { + return f_ != rhs.f_; + } }; } // namespace _mfi diff --git a/test/Jamfile b/test/Jamfile index 96cbc1d..31b8b25 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -1,6 +1,6 @@ # Boost.Bind Library test Jamfile # -# Copyright (c) 2003 Peter Dimov +# Copyright (c) 2003, 2004 Peter Dimov # # Permission to copy, use, modify, sell and distribute this software # is granted provided this copyright notice appears in all copies. @@ -18,8 +18,10 @@ DEPENDS all : bind ; { test-suite "bind" : [ run bind_test.cpp ] + [ run bind_eq_test.cpp ] [ run mem_fn_test.cpp ] [ run mem_fn_void_test.cpp ] [ run mem_fn_derived_test.cpp ] + [ run mem_fn_eq_test.cpp ] ; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 388a84c..650abcc 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost.Bind Library test Jamfile # -# Copyright (c) 2003 Peter Dimov +# Copyright (c) 2003, 2004 Peter Dimov # # Permission to copy, use, modify, sell and distribute this software # is granted provided this copyright notice appears in all copies. @@ -12,8 +12,10 @@ import testing ; test-suite "bind" : [ run bind_test.cpp ] + [ run bind_eq_test.cpp ] [ run mem_fn_test.cpp ] [ run mem_fn_void_test.cpp ] [ run mem_fn_derived_test.cpp ] + [ run mem_fn_eq_test.cpp ] ; diff --git a/test/bind_eq_test.cpp b/test/bind_eq_test.cpp new file mode 100644 index 0000000..513cff1 --- /dev/null +++ b/test/bind_eq_test.cpp @@ -0,0 +1,414 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// +// bind_eq_test.cpp - boost::bind equality operator +// +// Copyright (c) 2004 Peter Dimov +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(push, 3) +#endif + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(pop) +#endif + +#include + +struct X +{ + int i_; + + explicit X(int i): i_(i) + { + } + + bool operator==(X const & rhs) const + { + return i_ == rhs.i_; + } +}; + +// f_* + +int f_0() +{ + return 0; +} + +int f_1(X) +{ + return 0; +} + +int f_2(X, X) +{ + return 0; +} + +int f_3(X, X, X) +{ + return 0; +} + +int f_4(X, X, X, X) +{ + return 0; +} + +int f_5(X, X, X, X, X) +{ + return 0; +} + +int f_6(X, X, X, X, X, X) +{ + return 0; +} + +int f_7(X, X, X, X, X, X, X) +{ + return 0; +} + +int f_8(X, X, X, X, X, X, X, X) +{ + return 0; +} + +int f_9(X, X, X, X, X, X, X, X, X) +{ + return 0; +} + +// fv_* + +void fv_0() +{ +} + +void fv_1(X) +{ +} + +void fv_2(X, X) +{ +} + +void fv_3(X, X, X) +{ +} + +void fv_4(X, X, X, X) +{ +} + +void fv_5(X, X, X, X, X) +{ +} + +void fv_6(X, X, X, X, X, X) +{ +} + +void fv_7(X, X, X, X, X, X, X) +{ +} + +void fv_8(X, X, X, X, X, X, X, X) +{ +} + +void fv_9(X, X, X, X, X, X, X, X, X) +{ +} + +template void test_eq(F f1, F f2) +{ + BOOST_TEST(f1 == f2); + BOOST_TEST(!(f1 != f2)); +} + +template void test_ne(F f1, F f2) +{ + BOOST_TEST(f1 != f2); + BOOST_TEST(!(f1 == f2)); +} + +// 0 + +template void test_0(F f) +{ + test_eq( boost::bind(f), boost::bind(f) ); +} + +// 1 + +template void test_1_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1), boost::bind(f, v1) ); + test_ne( boost::bind(f, v1), boost::bind(f, v2) ); +} + +template void test_1(F f) +{ + test_eq( boost::bind(f, _1), boost::bind(f, _1) ); + + test_1_( f, X(1), X(2) ); + + X a(0), b(0); + test_1_( f, boost::ref(a), boost::ref(b) ); +} + +// 2 + +template void test_2_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1), boost::bind(f, v1, v1) ); + test_ne( boost::bind(f, v1, v1), boost::bind(f, v1, v2) ); + test_ne( boost::bind(f, v1, v1), boost::bind(f, v2, v1) ); +} + +template void test_2(F f) +{ + test_eq( boost::bind(f, _1, _2), boost::bind(f, _1, _2) ); + + test_2_( f, X(1), X(2) ); + + X a(0), b(0); + test_2_( f, boost::ref(a), boost::ref(b) ); +} + +// 3 + +template void test_3_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1), boost::bind(f, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1), boost::bind(f, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1), boost::bind(f, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1), boost::bind(f, v2, v1, v1) ); +} + +template void test_3(F f) +{ + test_eq( boost::bind(f, _1, _2, _3), boost::bind(f, _1, _2, _3) ); + + test_3_( f, X(1), X(2) ); + + X a(0), b(0); + test_3_( f, boost::ref(a), boost::ref(b) ); +} + +// 4 + +template void test_4_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1, v1), boost::bind(f, v1, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1), boost::bind(f, v1, v2, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1), boost::bind(f, v2, v1, v1, v1) ); +} + +template void test_4(F f) +{ + test_eq( boost::bind(f, _1, _2, _3, _4), boost::bind(f, _1, _2, _3, _4) ); + + test_4_( f, X(1), X(2) ); + + X a(0), b(0); + test_4_( f, boost::ref(a), boost::ref(b) ); +} + +// 5 + +template void test_5_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v2, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1), boost::bind(f, v1, v2, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1), boost::bind(f, v2, v1, v1, v1, v1) ); +} + +template void test_5(F f) +{ + test_eq( boost::bind(f, _1, _2, _3, _4, _5), boost::bind(f, _1, _2, _3, _4, _5) ); + + test_5_( f, X(1), X(2) ); + + X a(0), b(0); + test_5_( f, boost::ref(a), boost::ref(b) ); +} + +// 6 + +template void test_6_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v2, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v2, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v2, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1), boost::bind(f, v2, v1, v1, v1, v1, v1) ); +} + +template void test_6(F f) +{ + test_eq( boost::bind(f, _1, _2, _3, _4, _5, _6), boost::bind(f, _1, _2, _3, _4, _5, _6) ); + + test_6_( f, X(1), X(2) ); + + X a(0), b(0); + test_6_( f, boost::ref(a), boost::ref(b) ); +} + +// 7 + +template void test_7_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v2, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v2, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v2, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v2, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v2, v1, v1, v1, v1, v1, v1) ); +} + +template void test_7(F f) +{ + test_eq( boost::bind(f, _1, _2, _3, _4, _5, _6, _7), boost::bind(f, _1, _2, _3, _4, _5, _6, _7) ); + + test_7_( f, X(1), X(2) ); + + X a(0), b(0); + test_7_( f, boost::ref(a), boost::ref(b) ); +} + +// 8 + +template void test_8_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v2, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v2, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v2, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v2, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v2, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v2, v1, v1, v1, v1, v1, v1, v1) ); +} + +template void test_8(F f) +{ + test_eq( boost::bind(f, _1, _2, _3, _4, _5, _6, _7, _8), boost::bind(f, _1, _2, _3, _4, _5, _6, _7, _8) ); + + test_8_( f, X(1), X(2) ); + + X a(0), b(0); + test_8_( f, boost::ref(a), boost::ref(b) ); +} + +// 9 + +template void test_9_(F f, V v1, V v2) +{ + test_eq( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v2) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v2, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v1, v2, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v1, v2, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v1, v2, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v1, v2, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v1, v2, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v1, v2, v1, v1, v1, v1, v1, v1, v1) ); + test_ne( boost::bind(f, v1, v1, v1, v1, v1, v1, v1, v1, v1), boost::bind(f, v2, v1, v1, v1, v1, v1, v1, v1, v1) ); +} + +template void test_9(F f) +{ + test_eq( boost::bind(f, _1, _2, _3, _4, _5, _6, _7, _8, _9), boost::bind(f, _1, _2, _3, _4, _5, _6, _7, _8, _9) ); + + test_9_( f, X(1), X(2) ); + + X a(0), b(0); + test_9_( f, boost::ref(a), boost::ref(b) ); +} + +int main() +{ + // 0 + + test_0( f_0 ); + test_0( fv_0 ); + + // 1 + + test_1( f_1 ); + test_1( fv_1 ); + + // 2 + + test_2( f_2 ); + test_2( fv_2 ); + + // 3 + + test_3( f_3 ); + test_3( fv_3 ); + + // 4 + + test_4( f_4 ); + test_4( fv_4 ); + + // 5 + + test_5( f_5 ); + test_5( fv_5 ); + + // 6 + + test_6( f_6 ); + test_6( fv_6 ); + + // 7 + + test_7( f_7 ); + test_7( fv_7 ); + + // 8 + + test_8( f_8 ); + test_8( fv_8 ); + + // 9 + + test_9( f_9 ); + test_9( fv_9 ); + + return boost::report_errors(); +} diff --git a/test/mem_fn_eq_test.cpp b/test/mem_fn_eq_test.cpp new file mode 100644 index 0000000..9244c0c --- /dev/null +++ b/test/mem_fn_eq_test.cpp @@ -0,0 +1,301 @@ +#include + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined +#pragma warning(disable: 4711) // function selected for automatic inline expansion +#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// +// mem_fn_eq_test.cpp - boost::mem_fn equality operator +// +// Copyright (c) 2004 Peter Dimov +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(push, 3) +#endif + +#include + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(pop) +#endif + +#include + +struct X +{ + int dm_1; + int dm_2; + + // 0 + + int mf0_1() { return 0; } + int mf0_2() { return 0; } + + int cmf0_1() const { return 0; } + int cmf0_2() const { return 0; } + + void mf0v_1() {} + void mf0v_2() {} + + void cmf0v_1() const {} + void cmf0v_2() const {} + + // 1 + + int mf1_1(int) { return 0; } + int mf1_2(int) { return 0; } + + int cmf1_1(int) const { return 0; } + int cmf1_2(int) const { return 0; } + + void mf1v_1(int) {} + void mf1v_2(int) {} + + void cmf1v_1(int) const {} + void cmf1v_2(int) const {} + + // 2 + + int mf2_1(int, int) { return 0; } + int mf2_2(int, int) { return 0; } + + int cmf2_1(int, int) const { return 0; } + int cmf2_2(int, int) const { return 0; } + + void mf2v_1(int, int) {} + void mf2v_2(int, int) {} + + void cmf2v_1(int, int) const {} + void cmf2v_2(int, int) const {} + + // 3 + + int mf3_1(int, int, int) { return 0; } + int mf3_2(int, int, int) { return 0; } + + int cmf3_1(int, int, int) const { return 0; } + int cmf3_2(int, int, int) const { return 0; } + + void mf3v_1(int, int, int) {} + void mf3v_2(int, int, int) {} + + void cmf3v_1(int, int, int) const {} + void cmf3v_2(int, int, int) const {} + + // 4 + + int mf4_1(int, int, int, int) { return 0; } + int mf4_2(int, int, int, int) { return 0; } + + int cmf4_1(int, int, int, int) const { return 0; } + int cmf4_2(int, int, int, int) const { return 0; } + + void mf4v_1(int, int, int, int) {} + void mf4v_2(int, int, int, int) {} + + void cmf4v_1(int, int, int, int) const {} + void cmf4v_2(int, int, int, int) const {} + + // 5 + + int mf5_1(int, int, int, int, int) { return 0; } + int mf5_2(int, int, int, int, int) { return 0; } + + int cmf5_1(int, int, int, int, int) const { return 0; } + int cmf5_2(int, int, int, int, int) const { return 0; } + + void mf5v_1(int, int, int, int, int) {} + void mf5v_2(int, int, int, int, int) {} + + void cmf5v_1(int, int, int, int, int) const {} + void cmf5v_2(int, int, int, int, int) const {} + + // 6 + + int mf6_1(int, int, int, int, int, int) { return 0; } + int mf6_2(int, int, int, int, int, int) { return 0; } + + int cmf6_1(int, int, int, int, int, int) const { return 0; } + int cmf6_2(int, int, int, int, int, int) const { return 0; } + + void mf6v_1(int, int, int, int, int, int) {} + void mf6v_2(int, int, int, int, int, int) {} + + void cmf6v_1(int, int, int, int, int, int) const {} + void cmf6v_2(int, int, int, int, int, int) const {} + + // 7 + + int mf7_1(int, int, int, int, int, int, int) { return 0; } + int mf7_2(int, int, int, int, int, int, int) { return 0; } + + int cmf7_1(int, int, int, int, int, int, int) const { return 0; } + int cmf7_2(int, int, int, int, int, int, int) const { return 0; } + + void mf7v_1(int, int, int, int, int, int, int) {} + void mf7v_2(int, int, int, int, int, int, int) {} + + void cmf7v_1(int, int, int, int, int, int, int) const {} + void cmf7v_2(int, int, int, int, int, int, int) const {} + + // 8 + + int mf8_1(int, int, int, int, int, int, int, int) { return 0; } + int mf8_2(int, int, int, int, int, int, int, int) { return 0; } + + int cmf8_1(int, int, int, int, int, int, int, int) const { return 0; } + int cmf8_2(int, int, int, int, int, int, int, int) const { return 0; } + + void mf8v_1(int, int, int, int, int, int, int, int) {} + void mf8v_2(int, int, int, int, int, int, int, int) {} + + void cmf8v_1(int, int, int, int, int, int, int, int) const {} + void cmf8v_2(int, int, int, int, int, int, int, int) const {} + +}; + +int main() +{ + BOOST_TEST( boost::mem_fn(&X::dm_1) == boost::mem_fn(&X::dm_1) ); + BOOST_TEST( boost::mem_fn(&X::dm_1) != boost::mem_fn(&X::dm_2) ); + + // 0 + + BOOST_TEST( boost::mem_fn(&X::mf0_1) == boost::mem_fn(&X::mf0_1) ); + BOOST_TEST( boost::mem_fn(&X::mf0_1) != boost::mem_fn(&X::mf0_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf0_1) == boost::mem_fn(&X::cmf0_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf0_1) != boost::mem_fn(&X::cmf0_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf0v_1) == boost::mem_fn(&X::mf0v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf0v_1) != boost::mem_fn(&X::mf0v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf0v_1) == boost::mem_fn(&X::cmf0v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf0v_1) != boost::mem_fn(&X::cmf0v_2) ); + + // 1 + + BOOST_TEST( boost::mem_fn(&X::mf1_1) == boost::mem_fn(&X::mf1_1) ); + BOOST_TEST( boost::mem_fn(&X::mf1_1) != boost::mem_fn(&X::mf1_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf1_1) == boost::mem_fn(&X::cmf1_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf1_1) != boost::mem_fn(&X::cmf1_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf1v_1) == boost::mem_fn(&X::mf1v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf1v_1) != boost::mem_fn(&X::mf1v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf1v_1) == boost::mem_fn(&X::cmf1v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf1v_1) != boost::mem_fn(&X::cmf1v_2) ); + + // 2 + + BOOST_TEST( boost::mem_fn(&X::mf2_1) == boost::mem_fn(&X::mf2_1) ); + BOOST_TEST( boost::mem_fn(&X::mf2_1) != boost::mem_fn(&X::mf2_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf2_1) == boost::mem_fn(&X::cmf2_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf2_1) != boost::mem_fn(&X::cmf2_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf2v_1) == boost::mem_fn(&X::mf2v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf2v_1) != boost::mem_fn(&X::mf2v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf2v_1) == boost::mem_fn(&X::cmf2v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf2v_1) != boost::mem_fn(&X::cmf2v_2) ); + + // 3 + + BOOST_TEST( boost::mem_fn(&X::mf3_1) == boost::mem_fn(&X::mf3_1) ); + BOOST_TEST( boost::mem_fn(&X::mf3_1) != boost::mem_fn(&X::mf3_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf3_1) == boost::mem_fn(&X::cmf3_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf3_1) != boost::mem_fn(&X::cmf3_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf3v_1) == boost::mem_fn(&X::mf3v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf3v_1) != boost::mem_fn(&X::mf3v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf3v_1) == boost::mem_fn(&X::cmf3v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf3v_1) != boost::mem_fn(&X::cmf3v_2) ); + + // 4 + + BOOST_TEST( boost::mem_fn(&X::mf4_1) == boost::mem_fn(&X::mf4_1) ); + BOOST_TEST( boost::mem_fn(&X::mf4_1) != boost::mem_fn(&X::mf4_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf4_1) == boost::mem_fn(&X::cmf4_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf4_1) != boost::mem_fn(&X::cmf4_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf4v_1) == boost::mem_fn(&X::mf4v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf4v_1) != boost::mem_fn(&X::mf4v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf4v_1) == boost::mem_fn(&X::cmf4v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf4v_1) != boost::mem_fn(&X::cmf4v_2) ); + + // 5 + + BOOST_TEST( boost::mem_fn(&X::mf5_1) == boost::mem_fn(&X::mf5_1) ); + BOOST_TEST( boost::mem_fn(&X::mf5_1) != boost::mem_fn(&X::mf5_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf5_1) == boost::mem_fn(&X::cmf5_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf5_1) != boost::mem_fn(&X::cmf5_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf5v_1) == boost::mem_fn(&X::mf5v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf5v_1) != boost::mem_fn(&X::mf5v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf5v_1) == boost::mem_fn(&X::cmf5v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf5v_1) != boost::mem_fn(&X::cmf5v_2) ); + + // 6 + + BOOST_TEST( boost::mem_fn(&X::mf6_1) == boost::mem_fn(&X::mf6_1) ); + BOOST_TEST( boost::mem_fn(&X::mf6_1) != boost::mem_fn(&X::mf6_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf6_1) == boost::mem_fn(&X::cmf6_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf6_1) != boost::mem_fn(&X::cmf6_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf6v_1) == boost::mem_fn(&X::mf6v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf6v_1) != boost::mem_fn(&X::mf6v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf6v_1) == boost::mem_fn(&X::cmf6v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf6v_1) != boost::mem_fn(&X::cmf6v_2) ); + + // 7 + + BOOST_TEST( boost::mem_fn(&X::mf7_1) == boost::mem_fn(&X::mf7_1) ); + BOOST_TEST( boost::mem_fn(&X::mf7_1) != boost::mem_fn(&X::mf7_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf7_1) == boost::mem_fn(&X::cmf7_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf7_1) != boost::mem_fn(&X::cmf7_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf7v_1) == boost::mem_fn(&X::mf7v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf7v_1) != boost::mem_fn(&X::mf7v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf7v_1) == boost::mem_fn(&X::cmf7v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf7v_1) != boost::mem_fn(&X::cmf7v_2) ); + + // 8 + + BOOST_TEST( boost::mem_fn(&X::mf8_1) == boost::mem_fn(&X::mf8_1) ); + BOOST_TEST( boost::mem_fn(&X::mf8_1) != boost::mem_fn(&X::mf8_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf8_1) == boost::mem_fn(&X::cmf8_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf8_1) != boost::mem_fn(&X::cmf8_2) ); + + BOOST_TEST( boost::mem_fn(&X::mf8v_1) == boost::mem_fn(&X::mf8v_1) ); + BOOST_TEST( boost::mem_fn(&X::mf8v_1) != boost::mem_fn(&X::mf8v_2) ); + + BOOST_TEST( boost::mem_fn(&X::cmf8v_1) == boost::mem_fn(&X::cmf8v_1) ); + BOOST_TEST( boost::mem_fn(&X::cmf8v_1) != boost::mem_fn(&X::cmf8v_2) ); + + + return boost::report_errors(); +}