Path: blob/main/contrib/llvm-project/libcxx/include/__mutex/once_flag.h
35262 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef _LIBCPP___MUTEX_ONCE_FLAG_H9#define _LIBCPP___MUTEX_ONCE_FLAG_H1011#include <__config>12#include <__functional/invoke.h>13#include <__memory/shared_ptr.h> // __libcpp_acquire_load14#include <__tuple/tuple_indices.h>15#include <__tuple/tuple_size.h>16#include <__utility/forward.h>17#include <__utility/move.h>18#include <cstdint>19#ifndef _LIBCPP_CXX03_LANG20# include <tuple>21#endif2223#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)24# pragma GCC system_header25#endif2627_LIBCPP_PUSH_MACROS28#include <__undef_macros>2930_LIBCPP_BEGIN_NAMESPACE_STD3132struct _LIBCPP_TEMPLATE_VIS once_flag;3334#ifndef _LIBCPP_CXX03_LANG3536template <class _Callable, class... _Args>37_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&&, _Args&&...);3839#else // _LIBCPP_CXX03_LANG4041template <class _Callable>42_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&);4344template <class _Callable>45_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&);4647#endif // _LIBCPP_CXX03_LANG4849struct _LIBCPP_TEMPLATE_VIS once_flag {50_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(_Unset) {}51once_flag(const once_flag&) = delete;52once_flag& operator=(const once_flag&) = delete;5354#if defined(_LIBCPP_ABI_MICROSOFT)55typedef uintptr_t _State_type;56#else57typedef unsigned long _State_type;58#endif5960static const _State_type _Unset = 0;61static const _State_type _Pending = 1;62static const _State_type _Complete = ~_State_type(0);6364private:65_State_type __state_;6667#ifndef _LIBCPP_CXX03_LANG68template <class _Callable, class... _Args>69friend void call_once(once_flag&, _Callable&&, _Args&&...);70#else // _LIBCPP_CXX03_LANG71template <class _Callable>72friend void call_once(once_flag&, _Callable&);7374template <class _Callable>75friend void call_once(once_flag&, const _Callable&);76#endif // _LIBCPP_CXX03_LANG77};7879#ifndef _LIBCPP_CXX03_LANG8081template <class _Fp>82class __call_once_param {83_Fp& __f_;8485public:86_LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}8788_LIBCPP_HIDE_FROM_ABI void operator()() {89typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;90__execute(_Index());91}9293private:94template <size_t... _Indices>95_LIBCPP_HIDE_FROM_ABI void __execute(__tuple_indices<_Indices...>) {96std::__invoke(std::get<0>(std::move(__f_)), std::get<_Indices>(std::move(__f_))...);97}98};99100#else101102template <class _Fp>103class __call_once_param {104_Fp& __f_;105106public:107_LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}108109_LIBCPP_HIDE_FROM_ABI void operator()() { __f_(); }110};111112#endif113114template <class _Fp>115void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) {116__call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);117(*__p)();118}119120_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));121122#ifndef _LIBCPP_CXX03_LANG123124template <class _Callable, class... _Args>125inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) {126if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {127typedef tuple<_Callable&&, _Args&&...> _Gp;128_Gp __f(std::forward<_Callable>(__func), std::forward<_Args>(__args)...);129__call_once_param<_Gp> __p(__f);130std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);131}132}133134#else // _LIBCPP_CXX03_LANG135136template <class _Callable>137inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) {138if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {139__call_once_param<_Callable> __p(__func);140std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);141}142}143144template <class _Callable>145inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) {146if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {147__call_once_param<const _Callable> __p(__func);148std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);149}150}151152#endif // _LIBCPP_CXX03_LANG153154_LIBCPP_END_NAMESPACE_STD155156_LIBCPP_POP_MACROS157158#endif // _LIBCPP___MUTEX_ONCE_FLAG_H159160161