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:
Eric Fiselier
2015-06-13 02:23:00 +00:00
parent eeeada1c77
commit bc1e44d14e
3 changed files with 79 additions and 23 deletions

View File

@@ -442,7 +442,11 @@ void call_once(once_flag&, _Callable&&, _Args&&...);
template<class _Callable>
_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
@@ -465,7 +469,11 @@ private:
#else // _LIBCPP_HAS_NO_VARIADICS
template<class _Callable>
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
};
@@ -474,15 +482,10 @@ private:
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,7 +499,7 @@ private:
_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_))...);
}
};
@@ -505,15 +508,10 @@ private:
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()()
@@ -543,9 +541,9 @@ call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
{
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 +553,7 @@ call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
template<class _Callable>
inline _LIBCPP_INLINE_VISIBILITY
void
call_once(once_flag& __flag, _Callable __func)
call_once(once_flag& __flag, _Callable& __func)
{
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
_LIBCPP_END_NAMESPACE_STD