LWG2442: call_once() shouldn't DECAY_COPY(). Patch from K-Ballo.
This patch fixes LWG issue 2422 by removing the DECAY_COPY from call once. The review can be found here: http://reviews.llvm.org/D10191 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@239654 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eeeada1c77
commit
bc1e44d14e
@ -442,7 +442,11 @@ void call_once(once_flag&, _Callable&&, _Args&&...);
|
|||||||
|
|
||||||
template<class _Callable>
|
template<class _Callable>
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void call_once(once_flag&, _Callable);
|
void call_once(once_flag&, _Callable&);
|
||||||
|
|
||||||
|
template<class _Callable>
|
||||||
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
|
void call_once(once_flag&, const _Callable&);
|
||||||
|
|
||||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||||
|
|
||||||
@ -465,7 +469,11 @@ private:
|
|||||||
#else // _LIBCPP_HAS_NO_VARIADICS
|
#else // _LIBCPP_HAS_NO_VARIADICS
|
||||||
template<class _Callable>
|
template<class _Callable>
|
||||||
friend
|
friend
|
||||||
void call_once(once_flag&, _Callable);
|
void call_once(once_flag&, _Callable&);
|
||||||
|
|
||||||
|
template<class _Callable>
|
||||||
|
friend
|
||||||
|
void call_once(once_flag&, const _Callable&);
|
||||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -474,15 +482,10 @@ private:
|
|||||||
template <class _Fp>
|
template <class _Fp>
|
||||||
class __call_once_param
|
class __call_once_param
|
||||||
{
|
{
|
||||||
_Fp __f_;
|
_Fp& __f_;
|
||||||
public:
|
public:
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
|
explicit __call_once_param(_Fp& __f) : __f_(__f) {}
|
||||||
#else
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
|
||||||
explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void operator()()
|
void operator()()
|
||||||
@ -496,7 +499,7 @@ private:
|
|||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void __execute(__tuple_indices<_Indices...>)
|
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_))...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -505,15 +508,10 @@ private:
|
|||||||
template <class _Fp>
|
template <class _Fp>
|
||||||
class __call_once_param
|
class __call_once_param
|
||||||
{
|
{
|
||||||
_Fp __f_;
|
_Fp& __f_;
|
||||||
public:
|
public:
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {}
|
explicit __call_once_param(_Fp& __f) : __f_(__f) {}
|
||||||
#else
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
|
||||||
explicit __call_once_param(const _Fp& __f) : __f_(__f) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void operator()()
|
void operator()()
|
||||||
@ -543,9 +541,9 @@ call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
|
|||||||
{
|
{
|
||||||
if (__flag.__state_ != ~0ul)
|
if (__flag.__state_ != ~0ul)
|
||||||
{
|
{
|
||||||
typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp;
|
typedef tuple<_Callable&&, _Args&&...> _Gp;
|
||||||
__call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)),
|
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
|
||||||
__decay_copy(_VSTD::forward<_Args>(__args))...));
|
__call_once_param<_Gp> __p(__f);
|
||||||
__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
|
__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -555,7 +553,7 @@ call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
|
|||||||
template<class _Callable>
|
template<class _Callable>
|
||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
void
|
void
|
||||||
call_once(once_flag& __flag, _Callable __func)
|
call_once(once_flag& __flag, _Callable& __func)
|
||||||
{
|
{
|
||||||
if (__flag.__state_ != ~0ul)
|
if (__flag.__state_ != ~0ul)
|
||||||
{
|
{
|
||||||
@ -564,6 +562,18 @@ call_once(once_flag& __flag, _Callable __func)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class _Callable>
|
||||||
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
|
void
|
||||||
|
call_once(once_flag& __flag, const _Callable& __func)
|
||||||
|
{
|
||||||
|
if (__flag.__state_ != ~0ul)
|
||||||
|
{
|
||||||
|
__call_once_param<const _Callable> __p(__func);
|
||||||
|
__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||||
|
|
||||||
_LIBCPP_END_NAMESPACE_STD
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
// struct once_flag;
|
// struct once_flag;
|
||||||
|
|
||||||
// template<class Callable, class ...Args>
|
// 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 <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -153,6 +153,35 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
// reference qualifiers on functions are a C++11 extension
|
||||||
|
struct RefQual
|
||||||
|
{
|
||||||
|
int lv_called, rv_called;
|
||||||
|
|
||||||
|
RefQual() : lv_called(0), rv_called(0) {}
|
||||||
|
|
||||||
|
void operator()() & { ++lv_called; }
|
||||||
|
void operator()() && { ++rv_called; }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@ -204,5 +233,22 @@ int main()
|
|||||||
std::once_flag f;
|
std::once_flag f;
|
||||||
std::call_once(f, MoveOnly(), MoveOnly());
|
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);
|
||||||
|
}
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
// reference qualifiers on functions are a C++11 extension
|
||||||
|
{
|
||||||
|
std::once_flag f1, f2;
|
||||||
|
RefQual rq;
|
||||||
|
std::call_once(f1, rq);
|
||||||
|
assert(rq.lv_called == 1);
|
||||||
|
std::call_once(f2, std::move(rq));
|
||||||
|
assert(rq.rv_called == 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||||
}
|
}
|
||||||
|
@ -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#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#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#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#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#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>
|
<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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user