Hi mclow.lists, EricWF,
Implement LWG2442, use references to `call_once` arguments instead of
decay-copying them.
http://reviews.llvm.org/D10191
Files:
include/mutex
test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
www/cxx1z_status.html
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/mutex
===================================================================
--- include/mutex
+++ include/mutex
@@ -442,7 +442,7 @@
template<class _Callable>
_LIBCPP_INLINE_VISIBILITY
-void call_once(once_flag&, _Callable);
+void call_once(once_flag&, const _Callable&);
#endif // _LIBCPP_HAS_NO_VARIADICS
@@ -465,24 +465,19 @@
#else // _LIBCPP_HAS_NO_VARIADICS
template<class _Callable>
friend
- void call_once(once_flag&, _Callable);
+ void call_once(once_flag&, const _Callable&);
#endif // _LIBCPP_HAS_NO_VARIADICS
};
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Fp>
class __call_once_param
{
- _Fp __f_;
+ _Fp& __f_;
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
-#else
- _LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
-#endif
+ explicit __call_once_param(_Fp& __f) : __f_(__f) {}
_LIBCPP_INLINE_VISIBILITY
void operator()()
@@ -496,24 +491,19 @@
_LIBCPP_INLINE_VISIBILITY
void __execute(__tuple_indices<_Indices...>)
{
- __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...);
+ __invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...);
}
};
#else
template <class _Fp>
class __call_once_param
{
- _Fp __f_;
+ const _Fp& __f_;
public:
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- _LIBCPP_INLINE_VISIBILITY
- explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
-#else
_LIBCPP_INLINE_VISIBILITY
explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
-#endif
_LIBCPP_INLINE_VISIBILITY
void operator()()
@@ -543,9 +533,9 @@
{
if (__flag.__state_ != ~0ul)
{
- typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp;
- __call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)),
- __decay_copy(_VSTD::forward<_Args>(__args))...));
+ typedef tuple<_Callable&&, _Args&&...> _Gp;
+ _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
+ __call_once_param<_Gp> __p(__f);
__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
}
}
@@ -555,7 +545,7 @@
template<class _Callable>
inline _LIBCPP_INLINE_VISIBILITY
void
-call_once(once_flag& __flag, _Callable __func)
+call_once(once_flag& __flag, const _Callable& __func)
{
if (__flag.__state_ != ~0ul)
{
Index: test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
===================================================================
--- test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
+++ test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
@@ -14,7 +14,7 @@
// struct once_flag;
// template<class Callable, class ...Args>
-// void call_once(once_flag& flag, Callable func, Args&&... args);
+// void call_once(once_flag& flag, Callable&& func, Args&&... args);
#include <mutex>
#include <thread>
@@ -153,6 +153,23 @@
}
};
+class NonCopyable
+{
+#if !defined(__clang__)
+ // GCC 4.8 complains about the following being private
+public:
+ NonCopyable(const NonCopyable&)
+ {
+ }
+#else
+ NonCopyable(const NonCopyable&);
+#endif
+public:
+ NonCopyable() {}
+
+ void operator()(int&) {}
+};
+
#endif
int main()
@@ -204,5 +221,11 @@
std::once_flag f;
std::call_once(f, MoveOnly(), MoveOnly());
}
+ // check LWG2442: call_once() shouldn't DECAY_COPY()
+ {
+ std::once_flag f;
+ int i = 0;
+ std::call_once(f, NonCopyable(), i);
+ }
#endif // _LIBCPP_HAS_NO_VARIADICS
}
Index: www/cxx1z_status.html
===================================================================
--- www/cxx1z_status.html
+++ www/cxx1z_status.html
@@ -127,7 +127,7 @@
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2438">2438</td><td>std::iterator inheritance shouldn't be mandated</td><td>Lenexa</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2439">2439</td><td>unique_copy() sometimes can't fall back to reading its output</td><td>Lenexa</td><td></td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2440">2440</td><td>seed_seq::size() should be noexcept</td><td>Lenexa</td><td>Complete</td></tr>
- <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2442">2442</td><td>call_once() shouldn't DECAY_COPY()</td><td>Lenexa</td><td></td></tr>
+ <tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2442">2442</td><td>call_once() shouldn't DECAY_COPY()</td><td>Lenexa</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2448">2448</td><td>Non-normative Container destructor specification</td><td>Lenexa</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2454">2454</td><td>Add raw_storage_iterator::base() member</td><td>Lenexa</td><td>Complete</td></tr>
<tr><td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2455">2455</td><td>Allocator default construction should be allowed to throw</td><td>Lenexa</td><td>Complete</td></tr>
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits