summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2013-07-01 00:01:51 +0000
committerHoward Hinnant <hhinnant@apple.com>2013-07-01 00:01:51 +0000
commit9dbbf8dece177a54760b7ce6f4b3efc3e4380483 (patch)
tree5e5258ce46fa93a77af17f47cfe9d1233dea50be
parent6862dcc6da98729e1f6463b3223e5120928f4681 (diff)
downloadbcm5719-llvm-9dbbf8dece177a54760b7ce6f4b3efc3e4380483.tar.gz
bcm5719-llvm-9dbbf8dece177a54760b7ce6f4b3efc3e4380483.zip
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
llvm-svn: 185297
-rw-r--r--libcxx/include/functional31
-rw-r--r--libcxx/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp35
2 files changed, 59 insertions, 7 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional
index d9e6ee94bc9..d1a6301fb87 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -1139,8 +1139,11 @@ public:
function(const function&);
function(function&&) _NOEXCEPT;
template<class _Fp>
- 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<class _Alloc>
_LIBCPP_INLINE_VISIBILITY
@@ -1162,7 +1165,8 @@ public:
template<class _Fp>
typename enable_if
<
- __callable<typename decay<_Fp>::type>::value,
+ __callable<typename decay<_Fp>::type>::value &&
+ !is_same<typename remove_reference<_Fp>::type, function>::value,
function&
>::type
operator=(_Fp&&);
@@ -1266,7 +1270,11 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&,
template<class _Rp, class ..._ArgTypes>
template <class _Fp>
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<class _Rp, class ..._ArgTypes>
template <class _Fp>
typename enable_if
<
- function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value,
+ function<_Rp(_ArgTypes...)>::template __callable<typename decay<_Fp>::type>::value &&
+ !is_same<typename remove_reference<_Fp>::type, function<_Rp(_ArgTypes...)>>::value,
function<_Rp(_ArgTypes...)>&
>::type
function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f)
@@ -1749,7 +1758,9 @@ public:
template <class _Gp, class ..._BA,
class = typename enable_if
<
- is_constructible<_Fd, _Gp>::value
+ is_constructible<_Fd, _Gp>::value &&
+ !is_same<typename remove_reference<_Gp>::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 <class _Gp, class ..._BA>
+ template <class _Gp, class ..._BA,
+ class = typename enable_if
+ <
+ is_constructible<_Fd, _Gp>::value &&
+ !is_same<typename remove_reference<_Gp>::type,
+ __bind_r>::value
+ >::type>
_LIBCPP_INLINE_VISIBILITY
explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args)
: base(_VSTD::forward<_Gp>(__f),
diff --git a/libcxx/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp b/libcxx/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp
new file mode 100644
index 00000000000..6315598125c
--- /dev/null
+++ b/libcxx/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.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// template<CopyConstructible Fn, CopyConstructible... Types>
+// unspecified bind(Fn, Types...);
+// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>
+// unspecified bind(Fn, Types...);
+
+// http://llvm.org/bugs/show_bug.cgi?id=16385
+
+#include <functional>
+#include <cmath>
+#include <cassert>
+
+float _pow(float a, float b)
+{
+ return std::pow(a, b);
+}
+
+int main()
+{
+ std::function<float(float, float)> fnc = _pow;
+ auto task = std::bind(fnc, 2.f, 4.f);
+ auto task2(task);
+ assert(task() == 16);
+ assert(task2() == 16);
+}
OpenPOWER on IntegriCloud