From 3c56630b5400c43d1a4393d685a407e68a69ce9e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 20 Aug 2016 01:28:49 +0300 Subject: [PATCH] SFINAE out the converting constructor of arg to avoid hard errors with is_convertible on g++ 4.8/4.9 --- include/boost/bind/arg.hpp | 13 +++++++-- test/Jamfile.v2 | 3 ++ test/arg_copy_fail.cpp | 19 ++++++++++++ test/arg_copy_test.cpp | 34 ++++++++++++++++++++++ test/placeholder_std_bind_test.cpp | 46 ++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 test/arg_copy_fail.cpp create mode 100644 test/arg_copy_test.cpp create mode 100644 test/placeholder_std_bind_test.cpp diff --git a/include/boost/bind/arg.hpp b/include/boost/bind/arg.hpp index a74b829..71e008d 100644 --- a/include/boost/bind/arg.hpp +++ b/include/boost/bind/arg.hpp @@ -21,20 +21,27 @@ #include #include -#include namespace boost { +template< int I, int J > struct _arg_eq +{ +}; + +template< int I > struct _arg_eq< I, I> +{ + typedef void type; +}; + template< int I > struct arg { BOOST_CONSTEXPR arg() { } - template< class T > BOOST_CONSTEXPR arg( T const & /* t */ ) + template< class T > BOOST_CONSTEXPR arg( T const & /* t */, typename _arg_eq< I, is_placeholder::value >::type * = 0 ) { - BOOST_STATIC_ASSERT( I == is_placeholder::value ); } }; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 179d1d1..3c0d84b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -56,4 +56,7 @@ test-suite "bind" [ run bind_type_test.cpp ] [ run bind_unique_ptr_test.cpp ] [ run bind_nested_rv_test.cpp ] + [ compile arg_copy_test.cpp ] + [ compile-fail arg_copy_fail.cpp ] + [ run placeholder_std_bind_test.cpp ] ; diff --git a/test/arg_copy_fail.cpp b/test/arg_copy_fail.cpp new file mode 100644 index 0000000..35e9e3d --- /dev/null +++ b/test/arg_copy_fail.cpp @@ -0,0 +1,19 @@ +// +// arg_copy_fail.cpp - arg<1> to arg<2> +// +// Copyright 2016 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 + +// + +int main() +{ + boost::arg<1> a1(( boost::arg<2>() )); + (void)a1; +} diff --git a/test/arg_copy_test.cpp b/test/arg_copy_test.cpp new file mode 100644 index 0000000..b727ce6 --- /dev/null +++ b/test/arg_copy_test.cpp @@ -0,0 +1,34 @@ +// +// arg_copy_test.cpp - copying a custom placeholder _1 to arg<1> +// +// Copyright 2016 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 + +// + +template struct ph +{ +}; + +namespace boost +{ + +template struct is_placeholder< ::ph > +{ + enum _vt { value = I }; +}; + +} // namespace boost + +int main() +{ + boost::arg<1> a1 = ph<1>(); + (void)a1; +} diff --git a/test/placeholder_std_bind_test.cpp b/test/placeholder_std_bind_test.cpp new file mode 100644 index 0000000..3034b8e --- /dev/null +++ b/test/placeholder_std_bind_test.cpp @@ -0,0 +1,46 @@ +// +// placeholder_std_bind_test.cpp - std::bind with Boost's _1 +// +// Copyright 2016 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_NO_CXX11_HDR_FUNCTIONAL ) + +int main() +{ +} + +#else + +#include +#include +#include + +namespace std +{ + +template struct is_placeholder< boost::arg >: public integral_constant {}; + +} // namespace std + +int foo( int i ) +{ + return i; +} + +int main() +{ + BOOST_TEST_EQ( std::bind( foo, _1 )( 1 ), 1 ); + BOOST_TEST_EQ( std::bind( foo, _2 )( 1, 2 ), 2 ); + BOOST_TEST_EQ( std::bind( foo, _3 )( 1, 2, 3 ), 3 ); + + return boost::report_errors(); +} + +#endif