From db56733e4ed2125944b89e01cf36a9e451dd36f5 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 27 May 2015 01:29:50 +0300 Subject: [PATCH 01/11] Move placeholders to namespace boost::placeholders. --- include/boost/bind.hpp | 4 +- include/boost/bind/arg.hpp | 6 +-- include/boost/bind/placeholders.hpp | 65 +++++++++++++---------------- test/protect_test.cpp | 2 +- 4 files changed, 36 insertions(+), 41 deletions(-) diff --git a/include/boost/bind.hpp b/include/boost/bind.hpp index fd3421e..336f17c 100644 --- a/include/boost/bind.hpp +++ b/include/boost/bind.hpp @@ -10,7 +10,7 @@ // // bind.hpp - binds function objects to arguments // -// Copyright (c) 2009 Peter Dimov +// Copyright (c) 2009, 2015 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at @@ -21,4 +21,6 @@ #include +using namespace boost::placeholders; + #endif // #ifndef BOOST_BIND_HPP_INCLUDED diff --git a/include/boost/bind/arg.hpp b/include/boost/bind/arg.hpp index c879bb4..a74b829 100644 --- a/include/boost/bind/arg.hpp +++ b/include/boost/bind/arg.hpp @@ -28,17 +28,17 @@ namespace boost template< int I > struct arg { - arg() + BOOST_CONSTEXPR arg() { } - template< class T > arg( T const & /* t */ ) + template< class T > BOOST_CONSTEXPR arg( T const & /* t */ ) { BOOST_STATIC_ASSERT( I == is_placeholder::value ); } }; -template< int I > bool operator==( arg const &, arg const & ) +template< int I > BOOST_CONSTEXPR bool operator==( arg const &, arg const & ) { return true; } diff --git a/include/boost/bind/placeholders.hpp b/include/boost/bind/placeholders.hpp index 3b098b1..cf8c375 100644 --- a/include/boost/bind/placeholders.hpp +++ b/include/boost/bind/placeholders.hpp @@ -11,10 +11,11 @@ // bind/placeholders.hpp - _N definitions // // Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright 2015 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) +// 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 // // See http://www.boost.org/libs/bind/bind.html for documentation. // @@ -22,48 +23,40 @@ #include #include -namespace +namespace boost { -#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ < 4) +namespace placeholders +{ -static inline boost::arg<1> _1() { return boost::arg<1>(); } -static inline boost::arg<2> _2() { return boost::arg<2>(); } -static inline boost::arg<3> _3() { return boost::arg<3>(); } -static inline boost::arg<4> _4() { return boost::arg<4>(); } -static inline boost::arg<5> _5() { return boost::arg<5>(); } -static inline boost::arg<6> _6() { return boost::arg<6>(); } -static inline boost::arg<7> _7() { return boost::arg<7>(); } -static inline boost::arg<8> _8() { return boost::arg<8>(); } -static inline boost::arg<9> _9() { return boost::arg<9>(); } +#if defined(BOOST_NO_CXX11_CONSTEXPR) -#elif defined(BOOST_MSVC) || (defined(__DECCXX_VER) && __DECCXX_VER <= 60590031) || defined(__MWERKS__) || \ - defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ < 2) - -static boost::arg<1> _1; -static boost::arg<2> _2; -static boost::arg<3> _3; -static boost::arg<4> _4; -static boost::arg<5> _5; -static boost::arg<6> _6; -static boost::arg<7> _7; -static boost::arg<8> _8; -static boost::arg<9> _9; +inline boost::arg<1> _1() { return boost::arg<1>(); } +inline boost::arg<2> _2() { return boost::arg<2>(); } +inline boost::arg<3> _3() { return boost::arg<3>(); } +inline boost::arg<4> _4() { return boost::arg<4>(); } +inline boost::arg<5> _5() { return boost::arg<5>(); } +inline boost::arg<6> _6() { return boost::arg<6>(); } +inline boost::arg<7> _7() { return boost::arg<7>(); } +inline boost::arg<8> _8() { return boost::arg<8>(); } +inline boost::arg<9> _9() { return boost::arg<9>(); } #else -boost::arg<1> _1; -boost::arg<2> _2; -boost::arg<3> _3; -boost::arg<4> _4; -boost::arg<5> _5; -boost::arg<6> _6; -boost::arg<7> _7; -boost::arg<8> _8; -boost::arg<9> _9; +static constexpr boost::arg<1> _1; +static constexpr boost::arg<2> _2; +static constexpr boost::arg<3> _3; +static constexpr boost::arg<4> _4; +static constexpr boost::arg<5> _5; +static constexpr boost::arg<6> _6; +static constexpr boost::arg<7> _7; +static constexpr boost::arg<8> _8; +static constexpr boost::arg<9> _9; #endif -} // unnamed namespace +} // namespace placeholders + +} // namespace boost #endif // #ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED diff --git a/test/protect_test.cpp b/test/protect_test.cpp index 7ca46ea..0da7d51 100644 --- a/test/protect_test.cpp +++ b/test/protect_test.cpp @@ -8,7 +8,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include -#include +#include #include From 377014f1a49eb17d329396c2f74f0148ee74931c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Hunold?= Date: Wed, 27 May 2015 15:39:52 +0200 Subject: [PATCH 02/11] Suppress clang warning about 'using namespace boost::placeholders' warning: using namespace directive in global context in header [-Wheader-hygiene] The warning is unhelpfull as this a backwards-compatibility fix. --- include/boost/bind.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/boost/bind.hpp b/include/boost/bind.hpp index 336f17c..0e03b60 100644 --- a/include/boost/bind.hpp +++ b/include/boost/bind.hpp @@ -21,6 +21,17 @@ #include +#if defined(BOOST_CLANG) +# pragma clang diagnostic push +# if __has_warning("-Wheader-hygiene") +# pragma clang diagnostic ignored "-Wheader-hygiene" +# endif +#endif + using namespace boost::placeholders; +#if defined(BOOST_CLANG) +# pragma clang diagnostic pop +#endif + #endif // #ifndef BOOST_BIND_HPP_INCLUDED From 12b976939c050a23e8d79d28f55df9bc65019b28 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 27 May 2015 17:28:56 +0300 Subject: [PATCH 03/11] Cosmetic indentation fix --- include/boost/bind.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/bind.hpp b/include/boost/bind.hpp index 0e03b60..e8accaa 100644 --- a/include/boost/bind.hpp +++ b/include/boost/bind.hpp @@ -23,8 +23,8 @@ #if defined(BOOST_CLANG) # pragma clang diagnostic push -# if __has_warning("-Wheader-hygiene") -# pragma clang diagnostic ignored "-Wheader-hygiene" +# if __has_warning("-Wheader-hygiene") +# pragma clang diagnostic ignored "-Wheader-hygiene" # endif #endif From cf266d22e4dac67b04fb7402a19accc584665520 Mon Sep 17 00:00:00 2001 From: Marcel Raad Date: Fri, 29 May 2015 11:26:59 +0200 Subject: [PATCH 04/11] Fix compilation with BOOST_BIND_NO_PLACEHOLDERS If BOOST_BIND_NO_PLACEHOLDERS is defined, there is no namespace boost::placeholders. --- include/boost/bind.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/bind.hpp b/include/boost/bind.hpp index e8accaa..450120c 100644 --- a/include/boost/bind.hpp +++ b/include/boost/bind.hpp @@ -21,6 +21,8 @@ #include +#ifndef BOOST_BIND_NO_PLACEHOLDERS + #if defined(BOOST_CLANG) # pragma clang diagnostic push # if __has_warning("-Wheader-hygiene") @@ -34,4 +36,6 @@ using namespace boost::placeholders; # pragma clang diagnostic pop #endif +#endif // #ifndef BOOST_BIND_NO_PLACEHOLDERS + #endif // #ifndef BOOST_BIND_HPP_INCLUDED From 6bee84b2850f53a96128fea358afdb939c03f556 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 29 May 2015 23:50:19 +0300 Subject: [PATCH 05/11] Add test for BOOST_BIND_NO_PLACEHOLDERS --- test/Jamfile.v2 | 1 + test/bind_no_placeholders_test.cpp | 98 ++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 test/bind_no_placeholders_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 52e57cd..238ce37 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -50,4 +50,5 @@ test-suite "bind" [ run bind_function2_test.cpp ] [ run bind_fwd_test.cpp ] [ run bind_fwd2_test.cpp ] + [ run bind_no_placeholders_test.cpp ] ; diff --git a/test/bind_no_placeholders_test.cpp b/test/bind_no_placeholders_test.cpp new file mode 100644 index 0000000..3dfc0c4 --- /dev/null +++ b/test/bind_no_placeholders_test.cpp @@ -0,0 +1,98 @@ +// +// bind_no_placeholders_test.cpp - test for BOOST_BIND_NO_PLACEHOLDERS +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2001 David Abrahams +// +// 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 +// + +#define BOOST_BIND_NO_PLACEHOLDERS +#include +#include + +// + +long f_0() +{ + return 17041L; +} + +long f_1(long a) +{ + return a; +} + +long f_2(long a, long b) +{ + return a + 10 * b; +} + +long f_3(long a, long b, long c) +{ + return a + 10 * b + 100 * c; +} + +long f_4(long a, long b, long c, long d) +{ + return a + 10 * b + 100 * c + 1000 * d; +} + +long f_5(long a, long b, long c, long d, long e) +{ + return a + 10 * b + 100 * c + 1000 * d + 10000 * e; +} + +long f_6(long a, long b, long c, long d, long e, long f) +{ + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f; +} + +long f_7(long a, long b, long c, long d, long e, long f, long g) +{ + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g; +} + +long f_8(long a, long b, long c, long d, long e, long f, long g, long h) +{ + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h; +} + +long f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i) +{ + return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i; +} + +void function_test() +{ + using namespace boost; + + arg<1> _1; + arg<2> _2; + arg<3> _3; + arg<4> _4; + arg<5> _5; + arg<6> _6; + arg<7> _7; + arg<8> _8; + arg<9> _9; + + BOOST_TEST( bind(f_0)() == 17041L ); + BOOST_TEST( bind(f_1, _1)(1) == 1L ); + BOOST_TEST( bind(f_2, _1, _2)(1, 2) == 21L ); + BOOST_TEST( bind(f_3, _1, _2, _3)(1, 2, 3) == 321L ); + BOOST_TEST( bind(f_4, _1, _2, _3, _4)(1, 2, 3, 4) == 4321L ); + BOOST_TEST( bind(f_5, _1, _2, _3, _4, _5)(1, 2, 3, 4, 5) == 54321L ); + BOOST_TEST( bind(f_6, _1, _2, _3, _4, _5, _6)(1, 2, 3, 4, 5, 6) == 654321L ); + BOOST_TEST( bind(f_7, _1, _2, _3, _4, _5, _6, _7)(1, 2, 3, 4, 5, 6, 7) == 7654321L ); + BOOST_TEST( bind(f_8, _1, _2, _3, _4, _5, _6, _7, _8)(1, 2, 3, 4, 5, 6, 7, 8) == 87654321L ); + BOOST_TEST( bind(f_9, _1, _2, _3, _4, _5, _6, _7, _8, _9)(1, 2, 3, 4, 5, 6, 7, 8, 9) == 987654321L ); +} + +int main() +{ + function_test(); + return boost::report_errors(); +} From 37a5201a552c3de442befc47b180dc6386228ed6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 30 May 2015 01:00:37 +0300 Subject: [PATCH 06/11] Update copyright. --- test/bind_no_placeholders_test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/bind_no_placeholders_test.cpp b/test/bind_no_placeholders_test.cpp index 3dfc0c4..840823d 100644 --- a/test/bind_no_placeholders_test.cpp +++ b/test/bind_no_placeholders_test.cpp @@ -3,6 +3,7 @@ // // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. // Copyright (c) 2001 David Abrahams +// Copyright (c) 2015 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at From 92549594f0e38a15e189b2e0bf831f8534aa1fcd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 30 May 2015 01:11:30 +0300 Subject: [PATCH 07/11] Add test for taking placeholders by const& (phoenix::bind takes its arguments by const&) --- test/Jamfile.v2 | 1 + test/placeholder_const_ref_test.cpp | 37 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 test/placeholder_const_ref_test.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 238ce37..f1f2ab3 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -51,4 +51,5 @@ test-suite "bind" [ run bind_fwd_test.cpp ] [ run bind_fwd2_test.cpp ] [ run bind_no_placeholders_test.cpp ] + [ run placeholder_const_ref_test.cpp ] ; diff --git a/test/placeholder_const_ref_test.cpp b/test/placeholder_const_ref_test.cpp new file mode 100644 index 0000000..f0835b0 --- /dev/null +++ b/test/placeholder_const_ref_test.cpp @@ -0,0 +1,37 @@ +// +// placeholder_const_ref_test.cpp - forming a const& to _1 +// +// Copyright 2015 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 +#include +#include + +// + +template void test( T const &, int i ) +{ + BOOST_TEST_EQ( boost::is_placeholder::value, i ); +} + +int main() +{ + using namespace boost::placeholders; + + test( _1, 1 ); + test( _2, 2 ); + test( _3, 3 ); + test( _4, 4 ); + test( _5, 5 ); + test( _6, 6 ); + test( _7, 7 ); + test( _8, 8 ); + test( _9, 9 ); + + return boost::report_errors(); +} From 2ee272fa8d5a969d5c7516e98077026640d12fa2 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 30 May 2015 01:17:50 +0300 Subject: [PATCH 08/11] Revert to old scheme of only using inline functions as placeholders on Borland and g++ 3. --- include/boost/bind/placeholders.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/boost/bind/placeholders.hpp b/include/boost/bind/placeholders.hpp index cf8c375..b819ef4 100644 --- a/include/boost/bind/placeholders.hpp +++ b/include/boost/bind/placeholders.hpp @@ -29,7 +29,7 @@ namespace boost namespace placeholders { -#if defined(BOOST_NO_CXX11_CONSTEXPR) +#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ < 4) inline boost::arg<1> _1() { return boost::arg<1>(); } inline boost::arg<2> _2() { return boost::arg<2>(); } @@ -43,15 +43,15 @@ inline boost::arg<9> _9() { return boost::arg<9>(); } #else -static constexpr boost::arg<1> _1; -static constexpr boost::arg<2> _2; -static constexpr boost::arg<3> _3; -static constexpr boost::arg<4> _4; -static constexpr boost::arg<5> _5; -static constexpr boost::arg<6> _6; -static constexpr boost::arg<7> _7; -static constexpr boost::arg<8> _8; -static constexpr boost::arg<9> _9; +BOOST_STATIC_CONSTEXPR boost::arg<1> _1; +BOOST_STATIC_CONSTEXPR boost::arg<2> _2; +BOOST_STATIC_CONSTEXPR boost::arg<3> _3; +BOOST_STATIC_CONSTEXPR boost::arg<4> _4; +BOOST_STATIC_CONSTEXPR boost::arg<5> _5; +BOOST_STATIC_CONSTEXPR boost::arg<6> _6; +BOOST_STATIC_CONSTEXPR boost::arg<7> _7; +BOOST_STATIC_CONSTEXPR boost::arg<8> _8; +BOOST_STATIC_CONSTEXPR boost::arg<9> _9; #endif From da16abf365861f2727d30a619aec67421243a014 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 4 Jun 2015 19:54:24 +0100 Subject: [PATCH 09/11] Fix links to headers in release. Because the 'include' directory is deleted from the final release, all the header links break. Can currently see the broken links in the inspect report. --- doc/bind/implementation.qbk | 18 +++++++++--------- doc/bind/purpose.qbk | 4 ++-- doc/bind/troubleshooting.qbk | 4 ++-- doc/mem_fn/implementation.qbk | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/bind/implementation.qbk b/doc/bind/implementation.qbk index 40d339a..f19023c 100644 --- a/doc/bind/implementation.qbk +++ b/doc/bind/implementation.qbk @@ -11,15 +11,15 @@ [section Files] -* [@../../include/boost/bind.hpp boost/bind.hpp] (main header) -* [@../../include/boost/bind/bind_cc.hpp boost/bind/bind_cc.hpp] (used by `bind.hpp`, do not include directly) -* [@../../include/boost/bind/bind_mf_cc.hpp boost/bind/bind_mf_cc.hpp] (used by `bind.hpp`, do not include directly) -* [@../../include/boost/bind/bind_template.hpp boost/bind/bind_template.hpp] (used by `bind.hpp`, do not include directly) -* [@../../include/boost/bind/arg.hpp boost/bind/arg.hpp] (defines the type of the placeholder arguments) -* [@../../include/boost/bind/placeholders.hpp boost/bind/placeholders.hpp] (defines the `_1`, `_2`, ... `_9` placeholders) -* [@../../include/boost/bind/apply.hpp boost/bind/apply.hpp] (`apply` helper function object) -* [@../../include/boost/bind/protect.hpp boost/bind/protect.hpp] (`protect` helper function) -* [@../../include/boost/bind/make_adaptable.hpp boost/bind/make_adaptable.hpp] (`make_adaptable` helper function) +* [@../../../../boost/bind.hpp boost/bind.hpp] (main header) +* [@../../../../boost/bind/bind_cc.hpp boost/bind/bind_cc.hpp] (used by `bind.hpp`, do not include directly) +* [@../../../../boost/bind/bind_mf_cc.hpp boost/bind/bind_mf_cc.hpp] (used by `bind.hpp`, do not include directly) +* [@../../../../boost/bind/bind_template.hpp boost/bind/bind_template.hpp] (used by `bind.hpp`, do not include directly) +* [@../../../../boost/bind/arg.hpp boost/bind/arg.hpp] (defines the type of the placeholder arguments) +* [@../../../../boost/bind/placeholders.hpp boost/bind/placeholders.hpp] (defines the `_1`, `_2`, ... `_9` placeholders) +* [@../../../../boost/bind/apply.hpp boost/bind/apply.hpp] (`apply` helper function object) +* [@../../../../boost/bind/protect.hpp boost/bind/protect.hpp] (`protect` helper function) +* [@../../../../boost/bind/make_adaptable.hpp boost/bind/make_adaptable.hpp] (`make_adaptable` helper function) * [@../../test/bind_test.cpp libs/bind/test/bind_test.cpp] (test) * [@../../bind_as_compose.cpp libs/bind/bind_as_compose.cpp] (function composition example) * [@../../bind_visitor.cpp libs/bind/bind_visitor.cpp] (visitor example) diff --git a/doc/bind/purpose.qbk b/doc/bind/purpose.qbk index 8ec1e79..146d8db 100644 --- a/doc/bind/purpose.qbk +++ b/doc/bind/purpose.qbk @@ -215,7 +215,7 @@ argument, so the example below does not work as expected: The desired effect can be achieved via a helper function object `apply` that applies its first argument, as a function object, to the rest of its argument list. For convenience, an implementation of `apply` is provided in the -[@../../include/boost/bind/apply.hpp apply.hpp] header file. Here is how the +[@../../../../boost/bind/apply.hpp apply.hpp] header file. Here is how the modified version of the previous example looks like: typedef void (*pf)(int); @@ -230,7 +230,7 @@ with the help of another function object, `protect`, that masks the type so that `bind` does not recognize and evaluate it. When called, protect simply forwards the argument list to the other function object unmodified. -The header [@../../include/boost/bind/protect.hpp protect.hpp] contains an +The header [@../../../../boost/bind/protect.hpp protect.hpp] contains an implementation of `protect`. To `protect` a bind function object from evaluation, use `protect(bind(f, ...))`. diff --git a/doc/bind/troubleshooting.qbk b/doc/bind/troubleshooting.qbk index 2897a3d..21a7b37 100644 --- a/doc/bind/troubleshooting.qbk +++ b/doc/bind/troubleshooting.qbk @@ -179,9 +179,9 @@ these concepts. This allows unary and binary function objects resulting from [@http://en.cppreference.com/w/cpp/utility/functional/unary_negate `std::unary_negate`] and [@http://en.cppreference.com/w/cpp/utility/functional/binary_negate `std::binary_negate`]. -The `make_adaptable` function is defined in [@../../include/boost/bind/make_adaptable.hpp +The `make_adaptable` function is defined in [@../../../../boost/bind/make_adaptable.hpp ``], which must be included explicitly in -addition to [@../../include/boost/bind.hpp ``]: +addition to [@../../../../boost/bind.hpp ``]: #include diff --git a/doc/mem_fn/implementation.qbk b/doc/mem_fn/implementation.qbk index f7314ad..b648c13 100644 --- a/doc/mem_fn/implementation.qbk +++ b/doc/mem_fn/implementation.qbk @@ -11,10 +11,10 @@ [section Files] -* [@../../include/boost/mem_fn.hpp boost/mem_fn.hpp] (main header) -* [@../../include/boost/bind/mem_fn_cc.hpp boost/bind/mem_fn_cc.hpp] (used by `mem_fn.hpp`, do not include directly) -* [@../../include/boost/bind/mem_fn_vw.hpp boost/bind/mem_fn_vw.hpp] (used by `mem_fn.hpp`, do not include directly) -* [@../../include/boost/bind/mem_fn_template.hpp boost/bind/mem_fn_template.hpp] (used by `mem_fn.hpp`, do not include directly) +* [@../../../../boost/mem_fn.hpp boost/mem_fn.hpp] (main header) +* [@../../../../boost/bind/mem_fn_cc.hpp boost/bind/mem_fn_cc.hpp] (used by `mem_fn.hpp`, do not include directly) +* [@../../../../boost/bind/mem_fn_vw.hpp boost/bind/mem_fn_vw.hpp] (used by `mem_fn.hpp`, do not include directly) +* [@../../../../boost/bind/mem_fn_template.hpp boost/bind/mem_fn_template.hpp] (used by `mem_fn.hpp`, do not include directly) * [@../../test/mem_fn_test.cpp libs/bind/test/mem_fn_test.cpp] (test) * [@../../test/mem_fn_derived_test.cpp libs/bind/test/mem_fn_derived_test.cpp] (test with derived objects) * [@../../test/mem_fn_fastcall_test.cpp libs/bind/test/mem_fn_fastcall_test.cpp] (test for `__fastcall`) From 8647ccca80e1547952e121cc0ddf38fd974df814 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2015 19:08:59 +0300 Subject: [PATCH 10/11] Do not generate documentation manifest files. --- doc/Jamfile.v2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index c481aa6..d2347df 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -27,6 +27,8 @@ boostbook standalone_bind toc.max.depth=2 # How far down we go with TOC's generate.section.toc.level=0 + + generate.manifest=0 ; xml mem_fn_ : mem_fn.qbk ; @@ -47,4 +49,6 @@ boostbook standalone_mem_fn toc.max.depth=2 # How far down we go with TOC's generate.section.toc.level=0 + + generate.manifest=0 ; From 20a07a05f79a91e9e20e1a0cd99f25ee0818eb58 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 6 Jun 2015 19:10:20 +0300 Subject: [PATCH 11/11] Add generated HTML documentation. --- doc/.gitignore | 1 - doc/html/bind.html | 1552 ++++++++++++++++++++++++++++++++++++++++++ doc/html/mem_fn.html | 552 +++++++++++++++ 3 files changed, 2104 insertions(+), 1 deletion(-) delete mode 100644 doc/.gitignore create mode 100644 doc/html/bind.html create mode 100644 doc/html/mem_fn.html diff --git a/doc/.gitignore b/doc/.gitignore deleted file mode 100644 index ac7af2e..0000000 --- a/doc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/html/ diff --git a/doc/html/bind.html b/doc/html/bind.html new file mode 100644 index 0000000..9a2b0a9 --- /dev/null +++ b/doc/html/bind.html @@ -0,0 +1,1552 @@ + + + +Chapter 1. Boost.Bind + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+
+
+

+Chapter 1. Boost.Bind

+
+
+
+

+ Distributed under the Boost + Software License, Version 1.0. +

+
+
+
+

Table of Contents

+
+
Purpose
+
+
Using + bind with functions and function pointers
+
Using bind with function + objects
+
Using + bind with pointers to members
+
Using + nested binds for function composition
+
Overloaded + operators (new in Boost 1.33)
+
+
Examples
+
+
Using + bind with standard algorithms
+
Using bind + with Boost.Function
+
+
Limitations
+
Frequently Asked Questions
+
+
Why doesn't this compile?
+
Why does this + compile? It should not.
+
What is the difference between bind(f, ...) and + bind<R>(f, ...)?
+
Does bind + work with Windows API functions?
+
Does bind work + with COM methods?
+
Does bind + work with Mac toolbox functions?
+
Does bind + work with extern "C" functions?
+
Why doesn't + bind automatically recognize nonstandard functions?
+
+
Troubleshooting
+
+
Incorrect + number of arguments
+
The + function object cannot be called with the specified arguments
+
Accessing + an argument that does not exist
+
Inappropriate + use of bind(f, ...)
+
Inappropriate + use of bind<R>(f, ...)
+
Binding + a nonstandard function
+
Binding + an overloaded function
+
Modeling + STL function object concepts
+
const in signatures
+
MSVC + specific: using boost::bind;
+
MSVC + specific: class templates shadow function templates
+
MSVC + specific: ... in signatures treated + as type
+
+
Interface
+
+
Synopsis
+
Common requirements
+
Common definitions
+
bind
+
Additional overloads
+
+
Implementation
+
+
Files
+
Dependencies
+
Number of Arguments
+
__stdcall, + __cdecl, __fastcall, + and pascal Support
+
visit_each support
+
+
Acknowledgements
+
+
+
+ +

+ boost::bind is a generalization of the standard + functions std::bind1st and std::bind2nd. + It supports arbitrary function objects, functions, function pointers, and member + function pointers, and is able to bind any argument to a specific value or + route input arguments into arbitrary positions. bind + does not place any requirements on the function object; in particular, it does + not need the result_type, + first_argument_type and second_argument_type standard typedefs. +

+
+ +

+ Given these definitions: +

+
int f(int a, int b)
+{
+    return a + b;
+}
+
+int g(int a, int b, int c)
+{
+    return a + b + c;
+}
+
+

+ bind(f, 1, 2) + will produce a "nullary" function object that takes no arguments + and returns f(1, 2). Similarly, bind(g, + 1, 2, 3)() is equivalent to + g(1, 2, 3). +

+

+ It is possible to selectively bind only some of the arguments. bind(f, _1, + 5)(x) is equivalent + to f(x, 5); here _1 + is a placeholder argument that means "substitute + with the first input argument." +

+

+ For comparison, here is the same operation expressed with the standard library + primitives: +

+
std::bind2nd(std::ptr_fun(f), 5)(x);
+
+

+ bind covers the functionality + of std::bind1st as well: +

+
std::bind1st(std::ptr_fun(f), 5)(x);   // f(5, x)
+bind(f, 5, _1)(x);                     // f(5, x)
+
+

+ bind can handle functions + with more than two arguments, and its argument substitution mechanism is + more general: +

+
bind(f, _2, _1)(x, y);                 // f(y, x)
+bind(g, _1, 9, _1)(x);                 // g(x, 9, x)
+bind(g, _3, _3, _3)(x, y, z);          // g(z, z, z)
+bind(g, _1, _1, _1)(x, y, z);          // g(x, x, x)
+
+

+ Note that, in the last example, the function object produced by bind(g, _1, + _1, _1) does + not contain references to any arguments beyond the first, but it can still + be used with more than one argument. Any extra arguments are silently ignored, + just like the first and the second argument are ignored in the third example. +

+

+ The arguments that bind takes + are copied and held internally by the returned function object. For example, + in the following code: +

+
int i = 5;
+bind(f, i, _1);
+
+

+ a copy of the value of i + is stored into the function object. boost::ref and boost::cref can be used to make the function + object store a reference to an object, rather than a copy: +

+
int i = 5;
+bind(f, ref(i), _1);
+bind(f, cref(i), _1);
+
+
+
+ +

+ bind is not limited to functions; + it accepts arbitrary function objects. In the general case, the return type + of the generated function object's operator() has to be specified explicitly (without + a typeof operator the return + type cannot be inferred): +

+
struct F
+{
+    int operator()(int a, int b) { return a - b; }
+    bool operator()(long a, long b) { return a == b; }
+};
+
+F f;
+int x = 104;
+bind<int>(f, _1, _1)(x);		// f(x, x), i.e. zero
+
+

+ Some compilers have trouble with the bind<R>(f, ...) + syntax. For portability reasons, an alternative way to express the above + is supported: +

+
boost::bind(boost::type<int>(), f, _1, _1)(x);
+
+

+ Note, however, that the alternative syntax is provided only as a workaround. + It is not part of the interface. +

+

+ When the function object exposes a nested type named result_type, + the explicit return type can be omitted: +

+
int x = 8;
+bind(std::less<int>(), _1, 9)(x);	// x < 9
+
+

+ [Note: the ability to omit the return type is not available + on all compilers.] +

+

+ By default, bind makes a + copy of the provided function object. boost::ref and + boost::cref can be used to make it store a reference + to the function object, rather than a copy. This can be useful when the function + object is non-copyable, expensive to copy, or contains state; of course, + in this case the programmer is expected to ensure that the function object + is not destroyed while it's still being used. +

+
struct F2
+{
+    int s;
+
+    typedef void result_type;
+    void operator()(int x) { s += x; }
+};
+
+F2 f2 = { 0 };
+int a[] = { 1, 2, 3 };
+
+std::for_each(a, a+3, bind(ref(f2), _1));
+
+assert(f2.s == 6);
+
+
+
+ +

+ Pointers to member functions and pointers to data members are not function + objects, because they do not support operator(). For convenience, bind + accepts member pointers as its first argument, and the behavior is as if + boost::mem_fn + has been used to convert the member pointer into a function object. In other + words, the expression +

+
bind(&X::f, args)
+
+

+ is equivalent to +

+
bind<R>(mem_fn(&X::f), args)
+
+

+ where R is the return type + of X::f (for member functions) or the type of + the member (for data members.) +

+

+ [Note: mem_fn + creates function objects that are able to accept a pointer, a reference, + or a smart pointer to an object as its first argument; for additional information, + see the mem_fn documentation.] +

+

+ Example: +

+
struct X
+{
+    bool f(int a);
+};
+
+X x;
+shared_ptr<X> p(new X);
+int i = 5;
+
+bind(&X::f, ref(x), _1)(i);		// x.f(i)
+bind(&X::f, &x, _1)(i);			// (&x)->f(i)
+bind(&X::f, x, _1)(i);			// (internal copy of x).f(i)
+bind(&X::f, p, _1)(i);			// (internal copy of p)->f(i)
+
+

+ The last two examples are interesting in that they produce "self-contained" + function objects. bind(&X::f, x, + _1) + stores a copy of x. bind(&X::f, p, + _1) + stores a copy of p, and since + p is a boost::shared_ptr, the function object + retains a reference to its instance of X + and will remain valid even when p + goes out of scope or is reset(). +

+
+
+ +

+ Some of the arguments passed to bind + may be nested bind expressions themselves: +

+
bind(f, bind(g, _1))(x);               // f(g(x))
+
+

+ The inner bind expressions are evaluated, in unspecified + order, before the outer bind + when the function object is called; the results of the evaluation are then + substituted in their place when the outer bind + is evaluated. In the example above, when the function object is called with + the argument list (x), bind(g, + _1)(x) is evaluated + first, yielding g(x), and + then bind(f, g(x))(x) is evaluated, + yielding the final result f(g(x)). +

+

+ This feature of bind can + be used to perform function composition. See bind_as_compose.cpp + for an example that demonstrates how to use bind + to achieve similar functionality to Boost.Compose. +

+

+ Note that the first argument - the bound function object - is not evaluated, + even when it's a function object that is produced by bind + or a placeholder argument, so the example below does + not work as expected: +

+
typedef void (*pf)(int);
+
+std::vector<pf> v;
+std::for_each(v.begin(), v.end(), bind(_1, 5));
+
+

+ The desired effect can be achieved via a helper function object apply that applies its first argument, + as a function object, to the rest of its argument list. For convenience, + an implementation of apply + is provided in the apply.hpp + header file. Here is how the modified version of the previous example looks + like: +

+
typedef void (*pf)(int);
+
+std::vector<pf> v;
+std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
+
+

+ Although the first argument is, by default, not evaluated, all other arguments + are. Sometimes it is necessary not to evaluate arguments subsequent to the + first, even when they are nested bind subexpressions. + This can be achieved with the help of another function object, protect, that masks the type so that bind does not recognize and evaluate it. + When called, protect simply forwards the argument list to the other function + object unmodified. +

+

+ The header protect.hpp + contains an implementation of protect. + To protect a bind function + object from evaluation, use protect(bind(f, ...)). +

+
+
+ +

+ For convenience, the function objects produced by bind + overload the logical not operator ! + and the relational and logical operators ==, + !=, <, + <=, >, + >=, &&, + ||. +

+

+ !bind(f, + ...) is equivalent to bind(logical_not(), bind(f, + ...)), where logical_not + is a function object that takes one argument x + and returns !x. +

+

+ bind(f, ...) + op x, + where op is a relational or logical + operator, is equivalent to bind(relation(), bind(f, + ...), x), where relation + is a function object that takes two arguments a + and b and returns a op b. +

+

+ What this means in practice is that you can conveniently negate the result + of bind: +

+
std::remove_if(first, last, !bind(&X::visible, _1)); // remove invisible objects
+
+

+ and compare the result of bind + against a value: +

+
std::find_if(first, last, bind(&X::name, _1) == "Peter");
+std::find_if(first, last, bind(&X::name, _1) == "Peter" || bind(&X::name, _1) == "Paul");
+
+

+ against a placeholder: +

+
bind(&X::name, _1) == _2
+
+

+ or against another bind expression: +

+
std::sort(first, last, bind(&X::name, _1) < bind(&X::name, _2)); // sort by name
+
+
+
+
+ +
+ +
class image;
+
+class animation
+{
+public:
+    void advance(int ms);
+    bool inactive() const;
+    void render(image & target) const;
+};
+
+std::vector<animation> anims;
+
+template<class C, class P> void erase_if(C & c, P pred)
+{
+    c.erase(std::remove_if(c.begin(), c.end(), pred), c.end());
+}
+
+void update(int ms)
+{
+    std::for_each(anims.begin(), anims.end(), boost::bind(&animation::advance, _1, ms));
+    erase_if(anims, boost::mem_fn(&animation::inactive));
+}
+
+void render(image & target)
+{
+    std::for_each(anims.begin(), anims.end(), boost::bind(&animation::render, _1, boost::ref(target)));
+}
+
+
+
+ +
class button
+{
+public:
+    boost::function<void()> onClick;
+};
+
+class player
+{
+public:
+    void play();
+    void stop();
+};
+
+button playButton, stopButton;
+player thePlayer;
+
+void connect()
+{
+    playButton.onClick = boost::bind(&player::play, &thePlayer);
+    stopButton.onClick = boost::bind(&player::stop, &thePlayer);
+}
+
+
+
+
+ +

+ As a general rule, the function objects generated by bind + take their arguments by reference and cannot, therefore, accept non-const temporaries + or literal constants. This is an inherent limitation of the C++ language in + its current (2003) incarnation, known as the forwarding + problem. (It will be fixed in the next standard, usually called C++0x.) +

+

+ The library uses signatures of the form +

+
template<class T> void f(T & t);
+
+

+ to accept arguments of arbitrary types and pass them on unmodified. As noted, + this does not work with non-const r-values. +

+

+ On compilers that support partial ordering of function templates, a possible + solution is to add an overload: +

+
template<class T> void f(T & t);
+template<class T> void f(T const & t);
+
+

+ Unfortunately, this requires providing 512 overloads for nine arguments, which + is impractical. The library chooses a small subset: for up to two arguments, + it provides the const overloads in full, for arities of three and more it provides + a single additional overload with all of the arguments taken by const reference. + This covers a reasonable portion of the use cases. +

+
+
+ +
+ +

+ See the dedicated Troubleshooting section. +

+
+
+ +

+ Probably because you used the general bind<R>(f, ...) + syntax, thereby instructing bind + to not "inspect" f to detect arity and return type errors. +

+
+
+ +

+ The first form instructs bind + to inspect the type of f + in order to determine its arity (number of arguments) and return type. Arity + errors will be detected at "bind time". This syntax, of course, + places some requirements on f. + It must be a function, function pointer, member function pointer, or a function + object that defines a nested type named result_type; + in short, it must be something that bind + can recognize. +

+

+ The second form instructs bind + to not attempt to recognize the type of f. + It is generally used with function objects that do not, or cannot, expose + result_type, but it can also + be used with nonstandard functions. For example, the current implementation + does not automatically recognize variable-argument functions like printf, so you will have to use bind<int>(printf, ...). Note + that an alternative bind(type<R>(), f, ...) + syntax is supported for portability reasons. +

+

+ Another important factor to consider is that compilers without partial template + specialization or function template partial ordering support cannot handle + the first form when f is + a function object, and in most cases will not handle the second form when + f is a function (pointer) + or a member function pointer. +

+
+
+ +

+ Yes, if you #define + BOOST_BIND_ENABLE_STDCALL. + An alternative is to treat the function as a generic + function object and use the bind<R>(f, ...) + syntax. +

+
+ +
+ +

+ Yes, if you #define + BOOST_BIND_ENABLE_PASCAL. + An alternative is to treat the function as a generic + function object and use the bind<R>(f, ...) + syntax. +

+
+
+ +

+ Sometimes. On some platforms, pointers to extern "C" functions + are equivalent to "ordinary" function pointers, so they work fine. + Other platforms treat them as different types. A platform-specific implementation + of bind is expected to handle + the problem transparently; this implementation does not. As usual, the workaround + is to treat the function as a generic + function object and use the bind<R>(f, ...) + syntax. +

+
+
+ +

+ Non-portable extensions, in general, should default to off to prevent vendor + lock-in. Had the appropriate + macros been defined automatically, you could have accidentally taken + advantage of them without realizing that your code is, perhaps, no longer + portable. In addition, some compilers have the option to make __stdcall (__fastcall) + their default calling convention, in which case no separate support would + be necessary. +

+
+
+
+ +
+ +

+ In a bind(f, a1, a2, + ..., aN) expression, the function object f must be able to take exactly N arguments. + This error is normally detected at "bind time"; in other words, + the compilation error is reported on the line where bind() is invoked: +

+
int f(int, int);
+
+int main()
+{
+    boost::bind(f, 1);    // error, f takes two arguments
+    boost::bind(f, 1, 2); // OK
+}
+
+

+ A common variation of this error is to forget that member functions have + an implicit "this" argument: +

+
struct X
+{
+    int f(int);
+}
+
+int main()
+{
+    boost::bind(&X::f, 1);     // error, X::f takes two arguments
+    boost::bind(&X::f, _1, 1); // OK
+}
+
+
+
+ +

+ As in normal function calls, the function object that is bound must be compatible + with the argument list. The incompatibility will usually be detected by the + compiler at "call time" and the result is typically an error in + bind.hpp on a line that looks like: +

+
return f(a[a1_], a[a2_]);
+
+

+ An example of this kind of error: +

+
int f(int);
+
+int main()
+{
+    boost::bind(f, "incompatible");      // OK so far, no call
+    boost::bind(f, "incompatible")();    // error, "incompatible" is not an int
+    boost::bind(f, _1);                  // OK
+    boost::bind(f, _1)("incompatible");  // error, "incompatible" is not an int
+}
+
+
+
+ +

+ The placeholder _N selects + the argument at position N + from the argument list passed at "call time." Naturally, it is + an error to attempt to access beyond the end of this list: +

+
int f(int);
+
+int main()
+{
+    boost::bind(f, _1);                  // OK
+    boost::bind(f, _1)();                // error, there is no argument number 1
+}
+
+

+ The error is usually reported in bind.hpp, at + a line similar to: +

+
return f(a[a1_]);
+
+

+ When emulating std::bind1st(f, a), a common mistake of this category is to + type bind(f, a, _2) + instead of the correct bind(f, + a, _1). +

+
+
+ +

+ The bind(f, a1, a2, + ..., aN) form + causes automatic recognition of the type of f. + It will not work with arbitrary function objects; f + must be a function or a member function pointer. +

+

+ It is possible to use this form with function objects that define result_type, but only on compilers that + support partial specialization and partial ordering. In particular, MSVC + up to version 7.0 does not support this syntax for function objects. +

+
+
+ +

+ The bind<R>(f, a1, a2, + ..., aN) form + supports arbitrary function objects. +

+

+ It is possible (but not recommended) to use this form with functions or member + function pointers, but only on compilers that support partial ordering. In + particular, MSVC up to version 7.0 does not fully support this syntax for + functions and member function pointers. +

+
+
+ +

+ By default, the bind(f, a1, a2, + ..., aN) form + recognizes "ordinary" C++ functions and function pointers. Functions that use a different calling + convention, or variable-argument functions such as std::printf, + do not work. The general bind<R>(f, a1, a2, + ..., aN) form + works with nonstandard functions. +

+

+ On some platforms, extern "C" functions, like std::strcmp, + are not recognized by the short form of bind. +

+

+ See also __stdcall + and pascal Support. +

+
+
+ +

+ An attempt to bind an overloaded function usually results in an error, as + there is no way to tell which overload was meant to be bound. This is a common + problem with member functions with two overloads, const and non-const, as + in this simplified example: +

+
struct X
+{
+    int& get();
+    int const& get() const;
+};
+
+int main()
+{
+    boost::bind(&X::get, _1);
+}
+
+

+ The ambiguity can be resolved manually by casting the (member) function pointer + to the desired type: +

+
int main()
+{
+    boost::bind(static_cast< int const& (X::*) () const >(&X::get), _1);
+}
+
+

+ Another, arguably more readable, alternative is to introduce a temporary + variable: +

+
int main()
+{
+    int const& (X::*get) () const = &X::get;
+    boost::bind(get, _1);
+}
+
+
+
+ +

+ The function objects that are produced by bind + do not model the STL Unary + Function or Binary + Function concepts, even when the function objects are + unary or binary operations, because the function object types are missing + public typedefs result_type + and argument_type or first_argument_type and second_argument_type. + In cases where these typedefs are desirable, however, the utility function + make_adaptable can be used + to adapt unary and binary function objects to these concepts. This allows + unary and binary function objects resulting from bind + to be combined with STL templates such as std::unary_negate + and std::binary_negate. +

+

+ The make_adaptable function + is defined in <boost/bind/make_adaptable.hpp>, + which must be included explicitly in addition to <boost/bind.hpp>: +

+
#include <boost/bind/make_adaptable.hpp>
+
+template <class R, class F> unspecified-type make_adaptable(F f);
+
+template<class R, class A1, class F> unspecified-unary-functional-type make_adaptable(F f);
+
+template<class R, class A1, class A2, class F> unspecified-binary-functional-type make_adaptable(F f);
+
+template<class R, class A1, class A2, class A3, class F> unspecified-ternary-functional-type make_adaptable(F f);
+
+template<class R, class A1, class A2, class A3, class A4, class F> unspecified-4-ary-functional-type make_adaptable(F f);
+
+

+ This example shows how to use make_adaptable + to make a predicate for "is not a space": +

+
typedef char char_t;
+std::locale loc("");
+const std::ctype<char_t>& ct = std::use_facet<std::ctype<char_t> >(loc);
+
+auto isntspace = std::not1(boost::make_adaptable<bool, char_t>(boost::bind(&std::ctype<char_t>::is, &ct, std::ctype_base::space, _1)));
+
+

+ In this example, bind creates + the "is a space" (unary) predicate. It is then passed to make_adaptable so that a function object + modeling the Unary Function concept can be created, + serving as the argument to std::not1. +

+
+
+ +

+ Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with + the top-level const in function + signatures: +

+
int f(int const);
+
+int main()
+{
+    boost::bind(f, 1);     // error
+}
+
+

+ Workaround: remove the const + qualifier from the argument. +

+
+
+ +

+ On MSVC (up to version 7.0), when boostbind + is brought into scope with an using declaration: +

+
using boost::bind;
+
+

+ the syntax bind<R>(f, ...) + does not work. Workaround: either use the qualified name, boost::bind, + or use an using directive instead: +

+
using namespace boost;
+
+
+
+ +

+ On MSVC (up to version 7.0), a nested class template named bind will shadow the function template + boost::bind, breaking the bind<R>(f, ...)syntax. + Unfortunately, some libraries contain nested class templates named bind (ironically, such code is often an + MSVC specific workaround.) +

+

+ The workaround is to use the alternative bind(type<R>(), f, ...) + syntax. +

+
+
+ +

+ MSVC (up to version 7.0) treats the ellipsis in a variable argument function + (such as std::printf) as a type. Therefore, it will accept + the (incorrect in the current implementation) form: +

+
bind(printf, "%s\n", _1);
+
+

+ and will reject the correct version: +

+
bind<int>(printf, "%s\n", _1);
+
+
+
+
+ +
+ +
namespace boost
+{
+// no arguments
+
+template<class R, class F> unspecified-1 bind(F f);
+
+template<class F> unspecified-1-1 bind(F f);
+
+template<class R> unspecified-2 bind(R (*f) ());
+
+// one argument
+
+template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1);
+
+template<class F, class A1> unspecified-3-1 bind(F f, A1 a1);
+
+template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1);
+
+template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1);
+
+template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1);
+
+template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1);
+
+// two arguments
+
+template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2);
+
+template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2);
+
+template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2);
+
+template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2);
+
+template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2);
+
+// implementation defined number of additional overloads for more arguments
+}
+
+namespace
+{
+ unspecified-placeholder-type-1 _1;
+
+ unspecified-placeholder-type-2 _2;
+
+ unspecified-placeholder-type-3 _3;
+
+// implementation defined number of additional placeholder definitions
+}
+
+
+
+ +

+ All unspecified-N types returned by bind + are CopyConstructible. unspecified-N::result_type + is defined as the return type of unspecified-N::operator(). +

+

+ All unspecified-placeholder-N types are CopyConstructible. + Their copy constructors do not throw exceptions. +

+
+
+ +

+ The function μ(x, v1, + v2, ..., vm), where m + is a nonnegative integer, is defined as: +

+
    +
  • + x.get(), + when x is of type boost::reference_wrapper<T> for some type T; +
  • +
  • + vk, when x is (a copy of) the placeholder _k + for some positive integer k; +
  • +
  • + x(v1, v2, ..., vm) when x + is (a copy of) a function object returned by bind; +
  • +
  • + x otherwise. +
  • +
+
+
+

+bind +

+
template<class R, class F> unspecified-1 bind(F f)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(), + implicitly converted to R. +
  • +
  • + Throws: Nothing unless the copy constructor of + F throws an exception. +
  • +
+
template<class F> unspecified-1-1 bind(F f)
+
+
    +
  • + Effects: Equivalent to bind<typename + F::result_type, + F>(f). +
  • +
  • + Notes: Implementations are allowed to infer the + return type of f via + other means as an extension, without relying on the result_type + member. +
  • +
+
template<class R> unspecified-2 bind(R (*f) ())
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(). +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm)), + implicitly converted to R. +
  • +
  • + Throws: Nothing unless the copy constructors of + F or A1 + throw an exception. +
  • +
+
template<class F, class A1> unspecified-3-1 bind(F f, A1 a1)
+
+
    +
  • + Effects: Equivalent to bind<typename + F::result_type, + F, + A1>(f, a1). +
  • +
  • + Notes: Implementations are allowed to infer the + return type of f via + other means as an extension, without relying on the result_type + member. +
  • +
+
template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm)). +
  • +
  • + Throws: Nothing unless the copy constructor of + A1 throws an exception. +
  • +
+
template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1)
+
+
+
template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1)
+
+
+
template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1)
+
+
+
template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)), + implicitly converted to R. +
  • +
  • + Throws: Nothing unless the copy constructors of + F, A1 + or A2 throw an exception. +
  • +
+
template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2)
+
+
    +
  • + Effects: Equivalent to bind<typename + F::result_type, + F, + A1, + A2>(f, a1, a2). +
  • +
  • + Notes: Implementations are allowed to infer the + return type of f via + other means as an extension, without relying on the result_type + member. +
  • +
+
template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)). +
  • +
  • + Throws: Nothing unless the copy constructors of + A1 or A2 + throw an exception. +
  • +
+
template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2)
+
+
+
template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2)
+
+
+
+
+ +

+ Implementations are allowed to provide additional bind + overloads in order to support more arguments or different function pointer + variations. +

+
+
+
+ +
+

+Files +

+
+
+ +
+ +

+ This implementation supports function objects with up to nine arguments. + This is an implementation detail, not an inherent limitation of the design. +

+
+
+ +

+ Some platforms allow several types of (member) functions that differ by their + calling convention (the rules by which the function is invoked: how are arguments + passed, how is the return value handled, and who cleans up the stack - if + any.) +

+

+ For example, Windows API functions and COM interface member functions use + a calling convention known as __stdcall. + Borland VCL components use __fastcall. + Mac toolbox functions use a pascal + calling convention. +

+

+ To use bind with __stdcall functions, #define + the macro BOOST_BIND_ENABLE_STDCALL + before including <boost/bind.hpp>. +

+

+ To use bind with __stdcall member functions, #define the macro BOOST_MEM_FN_ENABLE_STDCALL + before including <boost/bind.hpp>. +

+

+ To use bind with __fastcall functions, #define + the macro BOOST_BIND_ENABLE_FASTCALL + before including <boost/bind.hpp>. +

+

+ To use bind with __fastcall member functions, #define the macro BOOST_MEM_FN_ENABLE_FASTCALL + before including <boost/bind.hpp>. +

+

+ To use bind with pascal functions, #define + the macro BOOST_BIND_ENABLE_PASCAL + before including <boost/bind.hpp>. +

+

+ To use bind with __cdecl member functions, #define the macro BOOST_MEM_FN_ENABLE_CDECL + before including <boost/bind.hpp>. +

+

+ It is best to define these macros in the project options, + via -D + on the command line, or as the first line in the translation unit (.cpp file) + where bind is used. + Not following this rule can lead to obscure errors when a header includes + bind.hpp before the macro has been defined. +

+

+ [Note: this is a non-portable extension. It is not part + of the interface.] +

+

+ [Note: Some compilers provide only minimal support for + the __stdcall keyword.] +

+
+
+ +

+ Function objects returned by bind + support the experimental and undocumented, as of yet, visit_each + enumeration interface. +

+

+ See bind_visitor.cpp for an example. +

+
+
+
+ +

+ Earlier efforts that have influenced the library design: +

+
+

+ Doug Gregor suggested that a visitor mechanism would allow bind + to interoperate with a signal/slot library. +

+

+ John Maddock fixed a MSVC-specific conflict between bind + and the type traits library. +

+

+ Numerous improvements were suggested during the formal review period by Ross + Smith, Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was + Darin Adler. +

+

+ The precise semantics of bind + were refined in discussions with Jaakko Järvi. +

+

+ Dave Abrahams fixed a MSVC-specific conflict between bind + and the iterator adaptors + library. +

+

+ Dave Abrahams modified bind + and mem_fn to support void returns on deficient compilers. +

+

+ Mac Murrett contributed the "pascal" support enabled by BOOST_BIND_ENABLE_PASCAL. +

+

+ The alternative bind(type<R>(), f, ...) + syntax was inspired by a discussion with Dave Abrahams and Joel de Guzman. +

+

+ This documentation was ported to Quickbook by Agustín Bergé. +

+
+
+ + + +

Last revised: June 06, 2015 at 16:07:44 GMT

+
+
+ + diff --git a/doc/html/mem_fn.html b/doc/html/mem_fn.html new file mode 100644 index 0000000..486d55e --- /dev/null +++ b/doc/html/mem_fn.html @@ -0,0 +1,552 @@ + + + +Chapter 1. Boost.Member Function + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+
+
+

+Chapter 1. Boost.Member Function

+
+
+
+

+ Distributed under the Boost + Software License, Version 1.0. +

+
+
+ +
+ +

+ boost::mem_fn is a generalization of the standard + functions std::mem_fun and std::mem_fun_ref. + It supports member function pointers with more than one argument, and the returned + function object can take a pointer, a reference, or a smart pointer to an object + instance as its first argument. mem_fn + also supports pointers to data members by treating them as functions taking + no arguments and returning a (const) reference to the member. +

+

+ The purpose of mem_fn is twofold. + First, it allows users to invoke a member function on a container with the + familiar +

+
std::for_each(v.begin(), v.end(), boost::mem_fn(&Shape::draw));
+
+

+ syntax, even when the container stores smart pointers. +

+

+ Second, it can be used as a building block by library developers that want + to treat a pointer to member function as a function object. A library might + define an enhanced for_each + algorithm with an overload of the form: +

+
template<class It, class R, class T> void for_each(It first, It last, R (T::*pmf) ())
+{
+    std::for_each(first, last, boost::mem_fn(pmf));
+}
+
+

+ that will allow the convenient syntax: +

+
for_each(v.begin(), v.end(), &Shape::draw);
+
+

+ When documenting the feature, the library author will simply state: +

+
template<class It, class R, class T> void for_each(It first, It last, R (T::*pmf) ());
+
+
  • + Effects: Equivalent to std::for_each(first, last, boost::mem_fn(pmf)). +
+

+ where boost::mem_fn can be a link to this page. See the + documentation of bind + for an example. +

+

+ mem_fn takes one argument, + a pointer to a member, and returns a function object suitable for use with + standard or user-defined algorithms: +

+
struct X
+{
+    void f();
+};
+
+void g(std::vector<X> & v)
+{
+    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
+};
+
+void h(std::vector<X *> const & v)
+{
+    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
+};
+
+void k(std::vector<boost::shared_ptr<X> > const & v)
+{
+    std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f));
+};
+
+

+ The returned function object takes the same arguments as the input member function + plus a "flexible" first argument that represents the object instance. +

+

+ When the function object is invoked with a first argument x + that is neither a pointer nor a reference to the appropriate class (X in the example above), it uses get_pointer(x) to obtain + a pointer from x. Library authors + can "register" their smart pointer classes by supplying an appropriate + get_pointer overload, allowing + mem_fn to recognize and support + them. +

+

+ [Note: get_pointer + is not restricted to return a pointer. Any object that can be used in a member + function call expression (x->*pmf)(...) will work.] +

+

+ [Note: the library uses an unqualified call to get_pointer. Therefore, it will find, through + argument-dependent lookup, get_pointer + overloads that are defined in the same namespace as the corresponding smart + pointer class, in addition to any boost::get_pointer + overloads.] +

+

+ All function objects returned by mem_fn + expose a result_type typedef + that represents the return type of the member function. For data members, + result_type is defined as the + type of the member. +

+
+
+ +
+ +

+ Yes. For simple uses, mem_fn + provides additional functionality that the standard adaptors do not. Complicated + expressions that use std::bind1st, + std::bind2nd or Boost.Compose + along with the standard adaptors can be rewritten using boost::bind + that automatically takes advantage of mem_fn. +

+
+
+ +

+ No, unless you have good reasons to do so. mem_fn + is not 100% compatible with the standard adaptors, although it comes pretty + close. In particular, mem_fn + does not return objects of type std::[const_]mem_fun[1][_ref]_t, + as the standard adaptors do, and it is not possible to fully describe the + type of the first argument using the standard argument_type + and first_argument_type nested + typedefs. Libraries that need adaptable function objects in order to function + might not like mem_fn. +

+
+ +
+ +

+ Non-portable extensions, in general, should default to off to prevent vendor + lock-in. Had BOOST_MEM_FN_ENABLE_STDCALL + been defined automatically, you could have accidentally taken advantage of + it without realizing that your code is, perhaps, no longer portable. In addition, + it is possible for the default calling convention to be __stdcall, + in which case enabling __stdcall + support will result in duplicate definitions. +

+
+
+
+ +
+ +
namespace boost
+{
+    template<class T> T * get_pointer(T * p);
+
+    template<class R, class T> unspecified-1 mem_fn(R (T::*pmf) ());
+
+    template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const);
+
+    template<class R, class T> unspecified-2-1 mem_fn(R T::*pm);
+
+    template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1));
+
+    template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const);
+
+    template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2));
+
+    template<class R, class T, class A1, class A2> unspecified-6 mem_fn(R (T::*pmf) (A1, A2) const);
+
+    // implementation defined number of additional overloads for more arguments
+}
+
+
+
+ +

+ All unspecified-N types mentioned in the Synopsis are + CopyConstructible and Assignable. + Their copy constructors and assignment operators do not throw exceptions. + unspecified-N::result_type is defined as the return type + of the member function pointer passed as an argument to mem_fn + (R in the Synopsis.) unspecified-2-1::result_type + is defined as R. +

+
+
+ +
template<class T> T * get_pointer(T * p)
+
+
    +
  • + Returns: p. +
  • +
  • + Throws: Nothing. +
  • +
+
+
+

+mem_fn +

+
template<class R, class T> unspecified-1 mem_fn(R (T::*pmf) ())
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t) is equivalent to (t.*pmf)() + when t is an l-value + of type T or derived, + (get_pointer(t)->*pmf)() otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t) is equivalent to (t.*pmf)() + when t is of type T [const] or derived, + (get_pointer(t)->*pmf)() otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T> unspecified-2-1 mem_fn(R T::*pm)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t) is equivalent to t.*pm + when t is of type T [const] or derived, + get_pointer(t)->*pm otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1))
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t, a1) is equivalent to (t.*pmf)(a1) + when t is an l-value + of type T or derived, + (get_pointer(t)->*pmf)(a1) otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t, a1) is equivalent to (t.*pmf)(a1) + when t is of type T [const] or derived, + (get_pointer(t)->*pmf)(a1) otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2))
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t, a1, a2) is equivalent to (t.*pmf)(a1, a2) + when t is an l-value + of type T or derived, + (get_pointer(t)->*pmf)(a1, a2) otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1, class A2> unspecified-6 mem_fn(R (T::*pmf) (A1, A2) const)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t, a1, a2) is equivalent to (t.*pmf)(a1, a2) + when t is of type T [const] or derived, + (get_pointer(t)->*pmf)(a1, a2) otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
+
+
+ +
+

+Files +

+
+
+ +
+ +

+ This implementation supports member functions with up to eight arguments. + This is not an inherent limitation of the design, but an implementation detail. +

+
+
+ +

+ Some platforms allow several types of member functions that differ by their + calling convention (the rules by which the function is invoked: how are arguments + passed, how is the return value handled, and who cleans up the stack - if + any.) +

+

+ For example, Windows API functions and COM interface member functions use + a calling convention known as __stdcall. + Borland VCL components use __fastcall. + UDK, the component model of OpenOffice.org, uses __cdecl. +

+

+ To use mem_fn with __stdcall member functions, #define the macro BOOST_MEM_FN_ENABLE_STDCALL + before including <boost/mem_fn.hpp>. +

+

+ To use mem_fn with __fastcall member functions, #define the macro BOOST_MEM_FN_ENABLE_FASTCALL + before including <boost/mem_fn.hpp>. +

+

+ To use mem_fn with __cdecl member functions, #define the macro BOOST_MEM_FN_ENABLE_CDECL + before including <boost/mem_fn.hpp>. +

+

+ It is best to define these macros in the project options, + via -D + on the command line, or as the first line in the translation unit (.cpp file) + where mem_fn is used. + Not following this rule can lead to obscure errors when a header includes + mem_fn.hpp before the macro has been defined. +

+

+ [Note: this is a non-portable extension. It is not part + of the interface.] +

+

+ [Note: Some compilers provide only minimal support for + the __stdcall keyword.] +

+
+
+
+ +
    +
  • + Rene Jager's initial suggestion of using traits classes to make mem_fn adapt to user-defined smart pointers + inspired the get_pointer-based + design. +
  • +
  • + Numerous improvements were suggested during the formal review period by + Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was + Darin Adler. +
  • +
  • + Steve Anichini pointed out that COM interfaces use __stdcall. +
  • +
  • + Dave Abrahams modified bind + and mem_fn to support + void returns on deficient + compilers. +
  • +
  • + Daniel Boelzle pointed out that UDK uses __cdecl. +
  • +
+

+ This documentation was ported to Quickbook by Agustín Bergé. +

+
+
+ + + +

Last revised: June 06, 2015 at 16:07:47 GMT

+
+
+ +