[libcxx] r185297 - 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

Howard Hinnant hhinnant at apple.com
Sun Jun 30 17:01:51 PDT 2013


Author: hhinnant
Date: Sun Jun 30 19:01:51 2013
New Revision: 185297

URL: http://llvm.org/viewvc/llvm-project?rev=185297&view=rev
Log:
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

Added:
    libcxx/trunk/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp
Modified:
    libcxx/trunk/include/functional

Modified: libcxx/trunk/include/functional
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/functional?rev=185297&r1=185296&r2=185297&view=diff
==============================================================================
--- libcxx/trunk/include/functional (original)
+++ libcxx/trunk/include/functional Sun Jun 30 19:01:51 2013
@@ -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(al
 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),

Added: libcxx/trunk/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp?rev=185297&view=auto
==============================================================================
--- libcxx/trunk/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp (added)
+++ libcxx/trunk/test/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp Sun Jun 30 19:01:51 2013
@@ -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);
+}





More information about the cfe-commits mailing list