[cfe-commits] [libcxx] r131413 - in /libcxx/trunk: include/thread include/type_traits test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp

Howard Hinnant hhinnant at apple.com
Mon May 16 11:40:35 PDT 2011


Author: hhinnant
Date: Mon May 16 13:40:35 2011
New Revision: 131413

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

Modified:
    libcxx/trunk/include/thread
    libcxx/trunk/include/type_traits
    libcxx/trunk/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp

Modified: libcxx/trunk/include/thread
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/thread?rev=131413&r1=131412&r2=131413&view=diff
==============================================================================
--- libcxx/trunk/include/thread (original)
+++ libcxx/trunk/include/thread Mon May 16 13:40:35 2011
@@ -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,26 +318,35 @@
 
 __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));
-    (*__p)();
+    typedef typename __make_tuple_indices<tuple_size<_F>::value, 1>::type _Index;
+    __threaad_execute(*__p, _Index());
     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)...)));
+    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();
@@ -345,6 +357,16 @@
 #else  // _LIBCPP_HAS_NO_VARIADICS
 
 template <class _F>
+void*
+__thread_proxy(void* __vp)
+{
+    __thread_local_data().reset(new __thread_struct);
+    std::unique_ptr<_F> __p(static_cast<_F*>(__vp));
+    (*__p)();
+    return nullptr;
+}
+
+template <class _F>
 thread::thread(_F __f)
 {
     std::unique_ptr<_F> __p(new _F(__f));

Modified: libcxx/trunk/include/type_traits
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/type_traits?rev=131413&r1=131412&r2=131413&view=diff
==============================================================================
--- libcxx/trunk/include/type_traits (original)
+++ libcxx/trunk/include/type_traits Mon May 16 13:40:35 2011
@@ -1419,6 +1419,14 @@
                      >::type type;
 };
 
+template <class _Tp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename decay<_Tp>::type
+__decay_copy(_Tp&& __t)
+{
+    return _STD::forward<_Tp>(__t);
+}
+
 template <class _MP, bool _IsMemberFuctionPtr, bool _IsMemberObjectPtr>
 struct __member_pointer_traits_imp
 {

Modified: libcxx/trunk/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp?rev=131413&r1=131412&r2=131413&view=diff
==============================================================================
--- libcxx/trunk/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp (original)
+++ libcxx/trunk/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp Mon May 16 13:40:35 2011
@@ -71,6 +71,22 @@
 int G::n_alive = 0;
 bool G::op_run = false;
 
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+class MoveOnly
+{
+    MoveOnly(const MoveOnly&);
+public:
+    MoveOnly() {}
+    MoveOnly(MoveOnly&&) {}
+
+    void operator()(MoveOnly&&)
+    {
+    }
+};
+
+#endif
+
 int main()
 {
     {
@@ -126,5 +142,9 @@
         assert(G::n_alive == 0);
         assert(G::op_run);
     }
+    {
+        std::thread t = std::thread(MoveOnly(), MoveOnly());
+        t.join();
+    }
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 }





More information about the cfe-commits mailing list