[cfe-commits] [libcxx] r131414 - in /libcxx/trunk: include/mutex test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp

Howard Hinnant hhinnant at apple.com
Mon May 16 12:05:11 PDT 2011


Author: hhinnant
Date: Mon May 16 14:05:11 2011
New Revision: 131414

URL: http://llvm.org/viewvc/llvm-project?rev=131414&view=rev
Log:
Brought call_once variadic call 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/mutex
    libcxx/trunk/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp

Modified: libcxx/trunk/include/mutex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/mutex?rev=131414&r1=131413&r2=131414&view=diff
==============================================================================
--- libcxx/trunk/include/mutex (original)
+++ libcxx/trunk/include/mutex Mon May 16 14:05:11 2011
@@ -175,6 +175,9 @@
 #include <__config>
 #include <__mutex_base>
 #include <functional>
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+#include <tuple>
+#endif
 
 #pragma GCC system_header
 
@@ -455,6 +458,39 @@
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 };
 
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+template <class _F>
+class __call_once_param
+{
+    _F __f_;
+public:
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __call_once_param(_F&& __f) : __f_(_STD::move(__f)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit __call_once_param(const _F& __f) : __f_(__f) {}
+#endif
+
+    _LIBCPP_INLINE_VISIBILITY
+    void operator()()
+    {
+        typedef typename __make_tuple_indices<tuple_size<_F>::value, 1>::type _Index;
+        __execute(_Index());
+    }
+
+private:
+    template <size_t ..._Indices>
+    _LIBCPP_INLINE_VISIBILITY
+    void __execute(__tuple_indices<_Indices...>)
+    {
+        _STD::move(_STD::get<0>(__f_))(_STD::move(_STD::get<_Indices>(__f_))...);
+    }
+};
+
+#else
+
 template <class _F>
 class __call_once_param
 {
@@ -475,6 +511,8 @@
     }
 };
 
+#endif
+
 template <class _F>
 void
 __call_once_proxy(void* __vp)
@@ -494,10 +532,9 @@
 {
     if (__builtin_expect(__flag.__state_ , ~0ul) != ~0ul)
     {
-        typedef decltype(std::bind(std::forward<_Callable>(__func),
-                         std::forward<_Args>(__args)...)) _G;
-        __call_once_param<_G> __p(std::bind(std::forward<_Callable>(__func),
-                                 std::forward<_Args>(__args)...));
+        typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _G;
+        __call_once_param<_G> __p(_G(__decay_copy(_STD::forward<_Callable>(__func)),
+                                __decay_copy(_STD::forward<_Args>(__args))...));
         __call_once(__flag.__state_, &__p, &__call_once_proxy<_G>);
     }
 }

Modified: libcxx/trunk/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp?rev=131414&r1=131413&r2=131414&view=diff
==============================================================================
--- libcxx/trunk/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp (original)
+++ libcxx/trunk/test/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp Mon May 16 14:05:11 2011
@@ -129,6 +129,22 @@
     std::call_once(flg41, init41);
 }
 
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+class MoveOnly
+{
+    MoveOnly(const MoveOnly&);
+public:
+    MoveOnly() {}
+    MoveOnly(MoveOnly&&) {}
+
+    void operator()(MoveOnly&&)
+    {
+    }
+};
+
+#endif
+
 int main()
 {
     // check basic functionality
@@ -174,5 +190,9 @@
         t1.join();
         assert(init2::called == 5);
     }
+    {
+        std::once_flag f;
+        std::call_once(f, MoveOnly(), MoveOnly());
+    }
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 }





More information about the cfe-commits mailing list