mirror of
https://github.com/darlinghq/darling-libcxx.git
synced 2024-11-23 20:09:41 +00:00
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.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@131414 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
656bdc3667
commit
ad935d583d
@ -175,6 +175,9 @@ template<class Callable, class ...Args>
|
||||
#include <__config>
|
||||
#include <__mutex_base>
|
||||
#include <functional>
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
@ -455,6 +458,39 @@ private:
|
||||
#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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class _F>
|
||||
void
|
||||
__call_once_proxy(void* __vp)
|
||||
@ -494,10 +532,9 @@ call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args)
|
||||
{
|
||||
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>);
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +129,22 @@ void f42()
|
||||
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 @@ int main()
|
||||
t1.join();
|
||||
assert(init2::called == 5);
|
||||
}
|
||||
{
|
||||
std::once_flag f;
|
||||
std::call_once(f, MoveOnly(), MoveOnly());
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user