Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:57

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 // _LIBCPP_CXX03_LANG
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 // _LIBCPP_CXX03_LANG
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  // _LIBCPP_CXX03_LANG
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 // _LIBCPP_CXX03_LANG
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 // _LIBCPP_CXX03_LANG
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 // _LIBCPP_CXX03_LANG
0154 
0155 _LIBCPP_END_NAMESPACE_STD
0156 
0157 _LIBCPP_POP_MACROS
0158 
0159 #endif // _LIBCPP___MUTEX_ONCE_FLAG_H