brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 529aa77 Raw
103 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___CXX03___MUTEX_ONCE_FLAG_H10#define _LIBCPP___CXX03___MUTEX_ONCE_FLAG_H11 12#include <__cxx03/__config>13#include <__cxx03/__memory/addressof.h>14#include <__cxx03/__memory/shared_ptr.h> // __libcpp_acquire_load15#include <__cxx03/__tuple/tuple_indices.h>16#include <__cxx03/__tuple/tuple_size.h>17#include <__cxx03/__type_traits/invoke.h>18#include <__cxx03/__utility/forward.h>19#include <__cxx03/__utility/move.h>20#include <__cxx03/cstdint>21 22#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)23#  pragma GCC system_header24#endif25 26_LIBCPP_PUSH_MACROS27#include <__cxx03/__undef_macros>28 29_LIBCPP_BEGIN_NAMESPACE_STD30 31struct _LIBCPP_TEMPLATE_VIS once_flag;32 33template <class _Callable>34_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&);35 36template <class _Callable>37_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&);38 39struct _LIBCPP_TEMPLATE_VIS once_flag {40  _LIBCPP_HIDE_FROM_ABI once_flag() _NOEXCEPT : __state_(_Unset) {}41  once_flag(const once_flag&)            = delete;42  once_flag& operator=(const once_flag&) = delete;43 44#if defined(_LIBCPP_ABI_MICROSOFT)45  typedef uintptr_t _State_type;46#else47  typedef unsigned long _State_type;48#endif49 50  static const _State_type _Unset    = 0;51  static const _State_type _Pending  = 1;52  static const _State_type _Complete = ~_State_type(0);53 54private:55  _State_type __state_;56 57  template <class _Callable>58  friend void call_once(once_flag&, _Callable&);59 60  template <class _Callable>61  friend void call_once(once_flag&, const _Callable&);62};63 64template <class _Fp>65class __call_once_param {66  _Fp& __f_;67 68public:69  _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {}70 71  _LIBCPP_HIDE_FROM_ABI void operator()() { __f_(); }72};73 74template <class _Fp>75void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) {76  __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp);77  (*__p)();78}79 80_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*));81 82template <class _Callable>83inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) {84  if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {85    __call_once_param<_Callable> __p(__func);86    std::__call_once(__flag.__state_, std::addressof(__p), std::addressof(__call_once_proxy<_Callable>));87  }88}89 90template <class _Callable>91inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) {92  if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {93    __call_once_param<const _Callable> __p(__func);94    std::__call_once(__flag.__state_, std::addressof(__p), std::addressof(__call_once_proxy<const _Callable>));95  }96}97 98_LIBCPP_END_NAMESPACE_STD99 100_LIBCPP_POP_MACROS101 102#endif // _LIBCPP___CXX03___MUTEX_ONCE_FLAG_H103