File indexing completed on 2026-05-03 08:13:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___MUTEX_ONCE_FLAG_H
0010 #define _LIBCPP___MUTEX_ONCE_FLAG_H
0011
0012 #include <__config>
0013 #include <__functional/invoke.h>
0014 #include <__memory/shared_count.h> // __libcpp_acquire_load
0015 #include <__tuple/tuple_indices.h>
0016 #include <__tuple/tuple_size.h>
0017 #include <__utility/forward.h>
0018 #include <__utility/move.h>
0019 #include <cstdint>
0020 #ifndef _LIBCPP_CXX03_LANG
0021 # include <tuple>
0022 #endif
0023
0024 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0025 # pragma GCC system_header
0026 #endif
0027
0028 _LIBCPP_PUSH_MACROS
0029 #include <__undef_macros>
0030
0031 _LIBCPP_BEGIN_NAMESPACE_STD
0032
0033 struct _LIBCPP_TEMPLATE_VIS once_flag;
0034
0035 #ifndef _LIBCPP_CXX03_LANG
0036
0037 template <class _Callable, class... _Args>
0038 _LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&&, _Args&&...);
0039
0040 #else
0041
0042 template <class _Callable>
0043 _LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&);
0044
0045 template <class _Callable>
0046 _LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&);
0047
0048 #endif
0049
0050 struct _LIBCPP_TEMPLATE_VIS once_flag {
0051 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(_Unset) {}
0052 once_flag(const once_flag&) = delete;
0053 once_flag& operator=(const once_flag&) = delete;
0054
0055 #if defined(_LIBCPP_ABI_MICROSOFT)
0056 typedef uintptr_t _State_type;
0057 #else
0058 typedef unsigned long _State_type;
0059 #endif
0060
0061 static const _State_type _Unset = 0;
0062 static const _State_type _Pending = 1;
0063 static const _State_type _Complete = ~_State_type(0);
0064
0065 private:
0066 _State_type __state_;
0067
0068 #ifndef _LIBCPP_CXX03_LANG
0069 template <class _Callable, class... _Args>
0070 friend void call_once(once_flag&, _Callable&&, _Args&&...);
0071 #else
0072 template <class _Callable>
0073 friend void call_once(once_flag&, _Callable&);
0074
0075 template <class _Callable>
0076 friend void call_once(once_flag&, const _Callable&);
0077 #endif
0078 };
0079
0080 #ifndef _LIBCPP_CXX03_LANG
0081
0082 template <class _Fp>
0083 class __call_once_param {
0084 _Fp& __f_;
0085
0086 public:
0087 _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}
0088
0089 _LIBCPP_HIDE_FROM_ABI void operator()() {
0090 typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index;
0091 __execute(_Index());
0092 }
0093
0094 private:
0095 template <size_t... _Indices>
0096 _LIBCPP_HIDE_FROM_ABI void __execute(__tuple_indices<_Indices...>) {
0097 std::__invoke(std::get<0>(std::move(__f_)), std::get<_Indices>(std::move(__f_))...);
0098 }
0099 };
0100
0101 #else
0102
0103 template <class _Fp>
0104 class __call_once_param {
0105 _Fp& __f_;
0106
0107 public:
0108 _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}
0109
0110 _LIBCPP_HIDE_FROM_ABI void operator()() { __f_(); }
0111 };
0112
0113 #endif
0114
0115 template <class _Fp>
0116 void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) {
0117 __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);
0118 (*__p)();
0119 }
0120
0121 _LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));
0122
0123 #ifndef _LIBCPP_CXX03_LANG
0124
0125 template <class _Callable, class... _Args>
0126 inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) {
0127 if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
0128 typedef tuple<_Callable&&, _Args&&...> _Gp;
0129 _Gp __f(std::forward<_Callable>(__func), std::forward<_Args>(__args)...);
0130 __call_once_param<_Gp> __p(__f);
0131 std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>);
0132 }
0133 }
0134
0135 #else
0136
0137 template <class _Callable>
0138 inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) {
0139 if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
0140 __call_once_param<_Callable> __p(__func);
0141 std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
0142 }
0143 }
0144
0145 template <class _Callable>
0146 inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) {
0147 if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
0148 __call_once_param<const _Callable> __p(__func);
0149 std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
0150 }
0151 }
0152
0153 #endif
0154
0155 _LIBCPP_END_NAMESPACE_STD
0156
0157 _LIBCPP_POP_MACROS
0158
0159 #endif