diff options
author | Howard Hinnant <hhinnant@apple.com> | 2013-07-01 00:01:51 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2013-07-01 00:01:51 +0000 |
commit | 9dbbf8dece177a54760b7ce6f4b3efc3e4380483 (patch) | |
tree | 5e5258ce46fa93a77af17f47cfe9d1233dea50be | |
parent | 6862dcc6da98729e1f6463b3223e5120928f4681 (diff) | |
download | bcm5719-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/functional | 31 | ||||
-rw-r--r-- | libcxx/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp | 35 |
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); +} |