From 961c3c5fa99103d80252c0235fe3ff8a262af3fb Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 8 Aug 2009 22:59:06 +0000 Subject: [PATCH] Merge [54385] to release. [SVN r55478] --- include/boost/bind/protect.hpp | 160 +++++++++++++++++++ test/Jamfile.v2 | 1 + test/protect_test.cpp | 281 +++++++++++++++++++++++++++++++++ 3 files changed, 442 insertions(+) create mode 100644 test/protect_test.cpp diff --git a/include/boost/bind/protect.hpp b/include/boost/bind/protect.hpp index b1ff2a2..749e158 100644 --- a/include/boost/bind/protect.hpp +++ b/include/boost/bind/protect.hpp @@ -5,12 +5,16 @@ // protect.hpp // // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2009 Steven Watanabe // // 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 +#include + namespace boost { @@ -47,6 +51,22 @@ public: return f_(a1); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(const A1 & a1) + { + return f_(a1); + } + + template result_type operator()(const A1 & a1) const + { + return f_(a1); + } + +#endif + template result_type operator()(A1 & a1, A2 & a2) { return f_(a1, a2); @@ -57,6 +77,41 @@ public: return f_(a1, a2); } +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 & a2) + { + return f_(a1, a2); + } + + template result_type operator()(A1 const & a1, A2 & a2) const + { + return f_(a1, a2); + } + + template result_type operator()(A1 & a1, A2 const & a2) + { + return f_(a1, a2); + } + + template result_type operator()(A1 & a1, A2 const & a2) const + { + return f_(a1, a2); + } + + template result_type operator()(A1 const & a1, A2 const & a2) + { + return f_(a1, a2); + } + + template result_type operator()(A1 const & a1, A2 const & a2) const + { + return f_(a1, a2); + } + +#endif + template result_type operator()(A1 & a1, A2 & a2, A3 & a3) { return f_(a1, a2, a3); @@ -66,6 +121,21 @@ public: { return f_(a1, a2, a3); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) + { + return f_(a1, a2, a3); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) const + { + return f_(a1, a2, a3); + } + +#endif template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) { @@ -76,6 +146,21 @@ public: { return f_(a1, a2, a3, a4); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) + { + return f_(a1, a2, a3, a4); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) const + { + return f_(a1, a2, a3, a4); + } + +#endif template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) { @@ -86,6 +171,21 @@ public: { return f_(a1, a2, a3, a4, a5); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) + { + return f_(a1, a2, a3, a4, a5); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) const + { + return f_(a1, a2, a3, a4, a5); + } + +#endif template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) { @@ -96,6 +196,21 @@ public: { return f_(a1, a2, a3, a4, a5, a6); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) + { + return f_(a1, a2, a3, a4, a5, a6); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) const + { + return f_(a1, a2, a3, a4, a5, a6); + } + +#endif template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) { @@ -106,6 +221,21 @@ public: { return f_(a1, a2, a3, a4, a5, a6, a7); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) + { + return f_(a1, a2, a3, a4, a5, a6, a7); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) const + { + return f_(a1, a2, a3, a4, a5, a6, a7); + } + +#endif template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) { @@ -116,6 +246,21 @@ public: { return f_(a1, a2, a3, a4, a5, a6, a7, a8); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) const + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8); + } + +#endif template result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) { @@ -126,6 +271,21 @@ public: { return f_(a1, a2, a3, a4, a5, a6, a7, a8, a9); } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } + + template result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) const + { + return f_(a1, a2, a3, a4, a5, a6, a7, a8, a9); + } + +#endif private: diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index ea85a0b..cecc7f7 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -42,4 +42,5 @@ test-suite "bind" [ run mem_fn_ref_test.cpp ] [ run bind_ref_test.cpp ] [ run bind_eq3_test.cpp ] + [ run protect_test.cpp ] ; diff --git a/test/protect_test.cpp b/test/protect_test.cpp new file mode 100644 index 0000000..7ca46ea --- /dev/null +++ b/test/protect_test.cpp @@ -0,0 +1,281 @@ +// protect_test.cpp +// +// Copyright (c) 2009 Steven Watanabe +// +// 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 +#include + +#include + +int f(int x) +{ + return x; +} + +int& g(int& x) +{ + return x; +} + +template +const T& constify(const T& arg) +{ + return arg; +} + +int main() +{ + int i[9] = {0,1,2,3,4,5,6,7,8}; + + // non-const + + // test nullary + BOOST_TEST(boost::protect(boost::bind(f, 1))() == 1); + + // test lvalues + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0]) == &i[0]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1]) == &i[1]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2]) == &i[2]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3]) == &i[3]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4]) == &i[4]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]); + BOOST_TEST(&boost::protect(boost::bind(g, _7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]); + BOOST_TEST(&boost::protect(boost::bind(g, _7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]); + BOOST_TEST(&boost::protect(boost::bind(g, _8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]); + + BOOST_TEST(&boost::protect(boost::bind(g, _1))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]); + BOOST_TEST(&boost::protect(boost::bind(g, _2))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]); + BOOST_TEST(&boost::protect(boost::bind(g, _3))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]); + BOOST_TEST(&boost::protect(boost::bind(g, _4))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]); + BOOST_TEST(&boost::protect(boost::bind(g, _5))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]); + BOOST_TEST(&boost::protect(boost::bind(g, _6))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]); + BOOST_TEST(&boost::protect(boost::bind(g, _7))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]); + BOOST_TEST(&boost::protect(boost::bind(g, _8))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]); + BOOST_TEST(&boost::protect(boost::bind(g, _9))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]); + + // test rvalues + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0) == 0); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1) == 1); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2) == 2); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3) == 3); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4) == 4); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5) == 5); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5, 6) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5, 6) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5, 6) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5, 6) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5, 6) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5, 6) == 5); + BOOST_TEST(boost::protect(boost::bind(f, _7))(0, 1, 2, 3, 4, 5, 6) == 6); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5, 6, 7) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5, 6, 7) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5, 6, 7) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5, 6, 7) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5, 6, 7) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5, 6, 7) == 5); + BOOST_TEST(boost::protect(boost::bind(f, _7))(0, 1, 2, 3, 4, 5, 6, 7) == 6); + BOOST_TEST(boost::protect(boost::bind(f, _8))(0, 1, 2, 3, 4, 5, 6, 7) == 7); + + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _3))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2); + BOOST_TEST(boost::protect(boost::bind(f, _4))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3); + BOOST_TEST(boost::protect(boost::bind(f, _5))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4); + BOOST_TEST(boost::protect(boost::bind(f, _6))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5); + BOOST_TEST(boost::protect(boost::bind(f, _7))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6); + BOOST_TEST(boost::protect(boost::bind(f, _8))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7); + BOOST_TEST(boost::protect(boost::bind(f, _9))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8); + + // test mixed perfect forwarding + BOOST_TEST(boost::protect(boost::bind(f, _1))(i[0], 1) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(i[0], 1) == 1); + BOOST_TEST(boost::protect(boost::bind(f, _1))(0, i[1]) == 0); + BOOST_TEST(boost::protect(boost::bind(f, _2))(0, i[1]) == 1); + + // const + + // test nullary + BOOST_TEST(constify(constify(boost::protect(boost::bind(f, 1))))() == 1); + + // test lvalues + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _1))))(i[0]) == &i[0]); + + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _1))))(i[0], i[1]) == &i[0]); + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _2))))(i[0], i[1]) == &i[1]); + + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _1))))(i[0], i[1], i[2]) == &i[0]); + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _2))))(i[0], i[1], i[2]) == &i[1]); + BOOST_TEST(&constify(constify(boost::protect(boost::bind(g, _3))))(i[0], i[1], i[2]) == &i[2]); + + BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3]) == &i[3]); + + BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4]) == &i[4]); + + BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5]) == &i[5]); + + BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[5]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6]) == &i[6]); + + BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[5]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[6]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]) == &i[7]); + + BOOST_TEST(&constify(boost::protect(boost::bind(g, _1)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[0]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _2)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[1]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _3)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[2]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _4)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[3]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _5)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[4]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _6)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[5]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _7)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[6]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _8)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[7]); + BOOST_TEST(&constify(boost::protect(boost::bind(g, _9)))(i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7], i[8]) == &i[8]); + + // test rvalues + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0) == 0); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1) == 1); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2) == 2); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3) == 3); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4) == 4); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5) == 5); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5, 6) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5, 6) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5, 6) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5, 6) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5, 6) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5, 6) == 5); + BOOST_TEST(constify(boost::protect(boost::bind(f, _7)))(0, 1, 2, 3, 4, 5, 6) == 6); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5, 6, 7) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5, 6, 7) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5, 6, 7) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5, 6, 7) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5, 6, 7) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5, 6, 7) == 5); + BOOST_TEST(constify(boost::protect(boost::bind(f, _7)))(0, 1, 2, 3, 4, 5, 6, 7) == 6); + BOOST_TEST(constify(boost::protect(boost::bind(f, _8)))(0, 1, 2, 3, 4, 5, 6, 7) == 7); + + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _3)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 2); + BOOST_TEST(constify(boost::protect(boost::bind(f, _4)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 3); + BOOST_TEST(constify(boost::protect(boost::bind(f, _5)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 4); + BOOST_TEST(constify(boost::protect(boost::bind(f, _6)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 5); + BOOST_TEST(constify(boost::protect(boost::bind(f, _7)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 6); + BOOST_TEST(constify(boost::protect(boost::bind(f, _8)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 7); + BOOST_TEST(constify(boost::protect(boost::bind(f, _9)))(0, 1, 2, 3, 4, 5, 6, 7, 8) == 8); + + // test mixed perfect forwarding + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(i[0], 1) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(i[0], 1) == 1); + BOOST_TEST(constify(boost::protect(boost::bind(f, _1)))(0, i[1]) == 0); + BOOST_TEST(constify(boost::protect(boost::bind(f, _2)))(0, i[1]) == 1); + + return boost::report_errors(); +}