Brought thread variadic constructor up to current spec, which allows move-only functors and move-only arguments, but disallows functors with non-const lvalue reference parameters.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@131413 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/thread b/include/thread
index 8b3edb7..ca16d21 100644
--- a/include/thread
+++ b/include/thread
@@ -95,6 +95,9 @@
 #include <system_error>
 #include <chrono>
 #include <__mutex_base>
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+#include <tuple>
+#endif
 #include <pthread.h>
 
 #pragma GCC system_header
@@ -315,6 +318,44 @@
 
 __thread_specific_ptr<__thread_struct>& __thread_local_data();
 
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _F, class ..._Args, size_t ..._Indices>
+inline _LIBCPP_INLINE_VISIBILITY
+void
+__threaad_execute(tuple<_F, _Args...>& __t, __tuple_indices<_Indices...>)
+{
+    _STD::move(_STD::get<0>(__t))(_STD::move(_STD::get<_Indices>(__t))...);
+}
+
+template <class _F>
+void*
+__thread_proxy(void* __vp)
+{
+    __thread_local_data().reset(new __thread_struct);
+    std::unique_ptr<_F> __p(static_cast<_F*>(__vp));
+    typedef typename __make_tuple_indices<tuple_size<_F>::value, 1>::type _Index;
+    __threaad_execute(*__p, _Index());
+    return nullptr;
+}
+
+template <class _F, class ..._Args,
+          class
+         >
+thread::thread(_F&& __f, _Args&&... __args)
+{
+    typedef tuple<typename decay<_F>::type, typename decay<_Args>::type...> _G;
+    _STD::unique_ptr<_G> __p(new _G(__decay_copy(_STD::forward<_F>(__f)),
+                                __decay_copy(_STD::forward<_Args>(__args))...));
+    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_G>, __p.get());
+    if (__ec == 0)
+        __p.release();
+    else
+        __throw_system_error(__ec, "thread constructor failed");
+}
+
+#else  // _LIBCPP_HAS_NO_VARIADICS
+
 template <class _F>
 void*
 __thread_proxy(void* __vp)
@@ -325,25 +366,6 @@
     return nullptr;
 }
 
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-
-template <class _F, class ..._Args,
-          class
-         >
-thread::thread(_F&& __f, _Args&&... __args)
-{
-    typedef decltype(bind(std::forward<_F>(__f), std::forward<_Args>(__args)...)) _G;
-    std::unique_ptr<_G> __p(new _G(bind(std::forward<_F>(__f),
-                              std::forward<_Args>(__args)...)));
-    int __ec = pthread_create(&__t_, 0, &__thread_proxy<_G>, __p.get());
-    if (__ec == 0)
-        __p.release();
-    else
-        __throw_system_error(__ec, "thread constructor failed");
-}
-
-#else  // _LIBCPP_HAS_NO_VARIADICS
-
 template <class _F>
 thread::thread(_F __f)
 {