From 099dec1ba0a48c1b033565be651ca37b24c3ebca Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 1 Jul 2013 00:01:51 +0000 Subject: [PATCH] The bind and function functor constructors and assignment operators were overly general and getting confused with the copy constructor and copy assignment operators. Constrained them. This fixes http://llvm.org/bugs/show_bug.cgi?id=16385 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@185297 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/functional | 31 ++++++++++++---- .../func.bind/func.bind.bind/copy.pass.cpp | 35 +++++++++++++++++++ 2 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp diff --git a/include/functional b/include/functional index d9e6ee94..d1a6301f 100644 --- a/include/functional +++ b/include/functional @@ -1139,8 +1139,11 @@ public: function(const function&); function(function&&) _NOEXCEPT; template - function(_Fp, - typename enable_if<__callable<_Fp>::value>::type* = 0); + function(_Fp, typename enable_if + < + __callable<_Fp>::value && + !is_same<_Fp, function>::value + >::type* = 0); template _LIBCPP_INLINE_VISIBILITY @@ -1162,7 +1165,8 @@ public: template typename enable_if < - __callable::type>::value, + __callable::type>::value && + !is_same::type, function>::value, function& >::type operator=(_Fp&&); @@ -1266,7 +1270,11 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, template template function<_Rp(_ArgTypes...)>::function(_Fp __f, - typename enable_if<__callable<_Fp>::value>::type*) + typename enable_if + < + __callable<_Fp>::value && + !is_same<_Fp, function>::value + >::type*) : __f_(0) { if (__not_null(__f)) @@ -1370,7 +1378,8 @@ template template typename enable_if < - function<_Rp(_ArgTypes...)>::template __callable::type>::value, + function<_Rp(_ArgTypes...)>::template __callable::type>::value && + !is_same::type, function<_Rp(_ArgTypes...)>>::value, function<_Rp(_ArgTypes...)>& >::type function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) @@ -1749,7 +1758,9 @@ public: template ::value + is_constructible<_Fd, _Gp>::value && + !is_same::type, + __bind>::value >::type> _LIBCPP_INLINE_VISIBILITY explicit __bind(_Gp&& __f, _BA&& ...__bound_args) @@ -1814,7 +1825,13 @@ public: #endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS - template + template ::value && + !is_same::type, + __bind_r>::value + >::type> _LIBCPP_INLINE_VISIBILITY explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) : base(_VSTD::forward<_Gp>(__f), diff --git a/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp b/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp new file mode 100644 index 00000000..63155981 --- /dev/null +++ b/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// template +// unspecified bind(Fn, Types...); +// template +// unspecified bind(Fn, Types...); + +// http://llvm.org/bugs/show_bug.cgi?id=16385 + +#include +#include +#include + +float _pow(float a, float b) +{ + return std::pow(a, b); +} + +int main() +{ + std::function fnc = _pow; + auto task = std::bind(fnc, 2.f, 4.f); + auto task2(task); + assert(task() == 16); + assert(task2() == 16); +}