From e5d99ce0855d1b238280fa6225b309c4b1bb15a3 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 1 Dec 2009 02:24:53 +0000 Subject: [PATCH] Make mem_fn work with overloaded unary operator&. Refs #3003. Sorry it took so long. [SVN r58073] --- include/boost/bind/mem_fn_template.hpp | 54 +++++----- test/Jamfile.v2 | 1 + test/mem_fn_unary_addr_test.cpp | 141 +++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 27 deletions(-) create mode 100644 test/mem_fn_unary_addr_test.cpp diff --git a/include/boost/bind/mem_fn_template.hpp b/include/boost/bind/mem_fn_template.hpp index 1db0713..7f01c24 100644 --- a/include/boost/bind/mem_fn_template.hpp +++ b/include/boost/bind/mem_fn_template.hpp @@ -51,14 +51,14 @@ public: template R operator()(U & u) const { - BOOST_MEM_FN_RETURN call(u, &u); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 )); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u) const { - BOOST_MEM_FN_RETURN call(u, &u); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 )); } #endif @@ -109,7 +109,7 @@ public: template R operator()(U const & u) const { - BOOST_MEM_FN_RETURN call(u, &u); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 )); } R operator()(T const & t) const @@ -164,14 +164,14 @@ public: template R operator()(U & u, A1 a1) const { - BOOST_MEM_FN_RETURN call(u, &u, a1); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1) const { - BOOST_MEM_FN_RETURN call(u, &u, a1); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1); } #endif @@ -223,7 +223,7 @@ public: template R operator()(U const & u, A1 a1) const { - BOOST_MEM_FN_RETURN call(u, &u, a1); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1); } R operator()(T const & t, A1 a1) const @@ -276,14 +276,14 @@ public: template R operator()(U & u, A1 a1, A2 a2) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2); } #endif @@ -333,7 +333,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2); } R operator()(T const & t, A1 a1, A2 a2) const @@ -386,14 +386,14 @@ public: template R operator()(U & u, A1 a1, A2 a2, A3 a3) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3); } #endif @@ -443,7 +443,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3); } R operator()(T const & t, A1 a1, A2 a2, A3 a3) const @@ -496,14 +496,14 @@ public: template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4); } #endif @@ -553,7 +553,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4); } R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4) const @@ -606,14 +606,14 @@ public: template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5); } #endif @@ -663,7 +663,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5); } R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const @@ -716,14 +716,14 @@ public: template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6); } #endif @@ -773,7 +773,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6); } R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const @@ -826,14 +826,14 @@ public: template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6, a7); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6, a7); } #endif @@ -883,7 +883,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6, a7); } R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const @@ -936,14 +936,14 @@ public: template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6, a7, a8); } #ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6, a7, a8); } #endif @@ -998,7 +998,7 @@ public: template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const { - BOOST_MEM_FN_RETURN call(u, &u, a1, a2, a3, a4, a5, a6, a7, a8); + BOOST_MEM_FN_RETURN call(u, static_cast< U const * >( 0 ), a1, a2, a3, a4, a5, a6, a7, a8); } R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index cecc7f7..68dc83d 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -43,4 +43,5 @@ test-suite "bind" [ run bind_ref_test.cpp ] [ run bind_eq3_test.cpp ] [ run protect_test.cpp ] + [ run mem_fn_unary_addr_test.cpp ] ; diff --git a/test/mem_fn_unary_addr_test.cpp b/test/mem_fn_unary_addr_test.cpp new file mode 100644 index 0000000..cb5da8b --- /dev/null +++ b/test/mem_fn_unary_addr_test.cpp @@ -0,0 +1,141 @@ +#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_unary_addr_test.cpp - poisoned operator& test +// +// Copyright (c) 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#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 + +unsigned int hash = 0; + +struct X +{ + int f0() { f1(17); return 0; } + int g0() const { g1(17); return 0; } + + int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; } + int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; } + + int f2(int a1, int a2) { f1(a1); f1(a2); return 0; } + int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; } + + int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; } + int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; } + + int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; } + int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; } + + int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; } + int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; } + + int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; } + int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; } + + int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; } + int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; } + + int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; } + int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; } +}; + +template class Y +{ +private: + + T * pt_; + + void operator& (); + void operator& () const; + +public: + + explicit Y( T * pt ): pt_( pt ) + { + } + + T * get() const + { + return pt_; + } +}; + +template T * get_pointer( Y< T > const & y ) +{ + return y.get(); +} + +int detect_errors(bool x) +{ + if( x ) + { + std::cerr << "no errors detected.\n"; + return 0; + } + else + { + std::cerr << "test failed.\n"; + return 1; + } +} + +int main() +{ + using boost::mem_fn; + + X x; + + Y px( &x ); + Y pcx( &x ); + + mem_fn(&X::f0)( px ); + mem_fn(&X::g0)( pcx ); + + mem_fn(&X::f1)( px, 1 ); + mem_fn(&X::g1)( pcx, 1 ); + + mem_fn(&X::f2)( px, 1, 2 ); + mem_fn(&X::g2)( pcx, 1, 2 ); + + mem_fn(&X::f3)( px, 1, 2, 3 ); + mem_fn(&X::g3)( pcx, 1, 2, 3 ); + + mem_fn(&X::f4)( px, 1, 2, 3, 4 ); + mem_fn(&X::g4)( pcx, 1, 2, 3, 4 ); + + mem_fn(&X::f5)( px, 1, 2, 3, 4, 5 ); + mem_fn(&X::g5)( pcx, 1, 2, 3, 4, 5 ); + + mem_fn(&X::f6)( px, 1, 2, 3, 4, 5, 6 ); + mem_fn(&X::g6)( pcx, 1, 2, 3, 4, 5, 6 ); + + mem_fn(&X::f7)( px, 1, 2, 3, 4, 5, 6, 7 ); + mem_fn(&X::g7)( pcx, 1, 2, 3, 4, 5, 6, 7 ); + + mem_fn(&X::f8)( px, 1, 2, 3, 4, 5, 6, 7, 8 ); + mem_fn(&X::g8)( pcx, 1, 2, 3, 4, 5, 6, 7, 8 ); + + return detect_errors( hash == 2155 ); +}