diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -543,6 +543,7 @@ __memory_resource/unsynchronized_pool_resource.h __mutex/lock_guard.h __mutex/mutex.h + __mutex/once_flag.h __mutex/tag_types.h __mutex/unique_lock.h __node_handle diff --git a/libcxx/include/__locale b/libcxx/include/__locale --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -13,12 +13,12 @@ #include <__availability> #include <__config> #include <__memory/shared_ptr.h> // __shared_count +#include <__mutex/once_flag.h> #include <__type_traits/make_unsigned.h> #include #include #include #include -#include #include // Some platforms require more includes than others. Keep the includes on all plaforms for now. diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__mutex/once_flag.h @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MUTEX_ONCE_FLAG_H +#define _LIBCPP___MUTEX_ONCE_FLAG_H + +#include <__config> +#include <__functional/invoke.h> +#include <__memory/shared_ptr.h> // __libcpp_acquire_load +#include <__tuple/tuple_indices.h> +#include <__tuple/tuple_size.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include +#ifndef _LIBCPP_CXX03_LANG +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_TEMPLATE_VIS once_flag; + +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&&, _Args&&...); + +#else // _LIBCPP_CXX03_LANG + +template +_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, _Callable&); + +template +_LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&); + +#endif // _LIBCPP_CXX03_LANG + +struct _LIBCPP_TEMPLATE_VIS once_flag { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(0) {} + once_flag(const once_flag&) = delete; + once_flag& operator=(const once_flag&) = delete; + +#if defined(_LIBCPP_ABI_MICROSOFT) + typedef uintptr_t _State_type; +#else + typedef unsigned long _State_type; +#endif + +private: + _State_type __state_; + +#ifndef _LIBCPP_CXX03_LANG + template + friend void call_once(once_flag&, _Callable&&, _Args&&...); +#else // _LIBCPP_CXX03_LANG + template + friend void call_once(once_flag&, _Callable&); + + template + friend void call_once(once_flag&, const _Callable&); +#endif // _LIBCPP_CXX03_LANG +}; + +#ifndef _LIBCPP_CXX03_LANG + +template +class __call_once_param { + _Fp& __f_; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {} + + _LIBCPP_HIDE_FROM_ABI void operator()() { + typedef typename __make_tuple_indices::value, 1>::type _Index; + __execute(_Index()); + } + +private: + template + _LIBCPP_HIDE_FROM_ABI void __execute(__tuple_indices<_Indices...>) { + _VSTD::__invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...); + } +}; + +#else + +template +class __call_once_param { + _Fp& __f_; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __call_once_param(_Fp& __f) : __f_(__f) {} + + _LIBCPP_HIDE_FROM_ABI void operator()() { __f_(); } +}; + +#endif + +template +void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) { + __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); + (*__p)(); +} + +_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*)); + +#ifndef _LIBCPP_CXX03_LANG + +template +inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) { + if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) { + typedef tuple<_Callable&&, _Args&&...> _Gp; + _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); + __call_once_param<_Gp> __p(__f); + std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); + } +} + +#else // _LIBCPP_CXX03_LANG + +template +inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) { + if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) { + __call_once_param<_Callable> __p(__func); + std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) { + if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) { + __call_once_param __p(__func); + std::__call_once(__flag.__state_, &__p, &__call_once_proxy); + } +} + +#endif // _LIBCPP_CXX03_LANG + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___MUTEX_ONCE_FLAG_H diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt --- a/libcxx/include/codecvt +++ b/libcxx/include/codecvt @@ -562,6 +562,7 @@ # include # include # include +# include # include # include # include diff --git a/libcxx/include/fstream b/libcxx/include/fstream --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -1752,6 +1752,7 @@ # include # include # include +# include # include # include # include diff --git a/libcxx/include/ios b/libcxx/include/ios --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -1055,6 +1055,7 @@ # include # include # include +# include # include # include # include diff --git a/libcxx/include/locale b/libcxx/include/locale --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -4355,6 +4355,7 @@ # include # include # include +# include # include # include # include diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1575,6 +1575,7 @@ module std_private_mutex_lock_guard [system] { header "__mutex/lock_guard.h" } module std_private_mutex_mutex [system] { header "__mutex/mutex.h" } +module std_private_mutex_once_flag [system] { header "__mutex/once_flag.h" } module std_private_mutex_tag_types [system] { header "__mutex/tag_types.h" } module std_private_mutex_unique_lock [system] { header "__mutex/unique_lock.h" } diff --git a/libcxx/include/mutex b/libcxx/include/mutex --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -194,6 +194,7 @@ #include <__memory/shared_ptr.h> #include <__mutex/lock_guard.h> #include <__mutex/mutex.h> +#include <__mutex/once_flag.h> #include <__mutex/tag_types.h> #include <__mutex/unique_lock.h> #include <__thread/id.h> @@ -555,157 +556,6 @@ #endif // _LIBCPP_STD_VER >= 17 #endif // !_LIBCPP_HAS_NO_THREADS -struct _LIBCPP_TEMPLATE_VIS once_flag; - -#ifndef _LIBCPP_CXX03_LANG - -template -_LIBCPP_INLINE_VISIBILITY -void call_once(once_flag&, _Callable&&, _Args&&...); - -#else // _LIBCPP_CXX03_LANG - -template -_LIBCPP_INLINE_VISIBILITY -void call_once(once_flag&, _Callable&); - -template -_LIBCPP_INLINE_VISIBILITY -void call_once(once_flag&, const _Callable&); - -#endif // _LIBCPP_CXX03_LANG - -struct _LIBCPP_TEMPLATE_VIS once_flag -{ - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR - once_flag() _NOEXCEPT : __state_(0) {} - once_flag(const once_flag&) = delete; - once_flag& operator=(const once_flag&) = delete; - -#if defined(_LIBCPP_ABI_MICROSOFT) - typedef uintptr_t _State_type; -#else - typedef unsigned long _State_type; -#endif - -private: - _State_type __state_; - -#ifndef _LIBCPP_CXX03_LANG - template - friend - void call_once(once_flag&, _Callable&&, _Args&&...); -#else // _LIBCPP_CXX03_LANG - template - friend - void call_once(once_flag&, _Callable&); - - template - friend - void call_once(once_flag&, const _Callable&); -#endif // _LIBCPP_CXX03_LANG -}; - -#ifndef _LIBCPP_CXX03_LANG - -template -class __call_once_param -{ - _Fp& __f_; -public: - _LIBCPP_INLINE_VISIBILITY - explicit __call_once_param(_Fp& __f) : __f_(__f) {} - - _LIBCPP_INLINE_VISIBILITY - void operator()() - { - typedef typename __make_tuple_indices::value, 1>::type _Index; - __execute(_Index()); - } - -private: - template - _LIBCPP_INLINE_VISIBILITY - void __execute(__tuple_indices<_Indices...>) - { - _VSTD::__invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...); - } -}; - -#else - -template -class __call_once_param -{ - _Fp& __f_; -public: - _LIBCPP_INLINE_VISIBILITY - explicit __call_once_param(_Fp& __f) : __f_(__f) {} - - _LIBCPP_INLINE_VISIBILITY - void operator()() - { - __f_(); - } -}; - -#endif - -template -void _LIBCPP_INLINE_VISIBILITY -__call_once_proxy(void* __vp) -{ - __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); - (*__p)(); -} - -_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*)); - -#ifndef _LIBCPP_CXX03_LANG - -template -inline _LIBCPP_INLINE_VISIBILITY -void -call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) -{ - if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) - { - typedef tuple<_Callable&&, _Args&&...> _Gp; - _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); - __call_once_param<_Gp> __p(__f); - std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); - } -} - -#else // _LIBCPP_CXX03_LANG - -template -inline _LIBCPP_INLINE_VISIBILITY -void -call_once(once_flag& __flag, _Callable& __func) -{ - if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) - { - __call_once_param<_Callable> __p(__func); - std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); - } -} - -template -inline _LIBCPP_INLINE_VISIBILITY -void -call_once(once_flag& __flag, const _Callable& __func) -{ - if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) - { - __call_once_param __p(__func); - std::__call_once(__flag.__state_, &__p, &__call_once_proxy); - } -} - -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/libcxx/include/regex b/libcxx/include/regex --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -6953,6 +6953,7 @@ # include # include # include +# include # include # include # include diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -404,6 +404,7 @@ iomanip version ios atomic ios cctype +ios cerrno ios clocale ios concepts ios cstddef @@ -802,8 +803,12 @@ stop_token atomic stop_token cstddef stop_token cstdint +stop_token cstring +stop_token ctime stop_token limits +stop_token ratio stop_token thread +stop_token type_traits stop_token version streambuf cstdint streambuf ios diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -146,6 +146,7 @@ codecvt new codecvt stdexcept codecvt string +codecvt tuple codecvt type_traits codecvt typeinfo codecvt version @@ -354,6 +355,7 @@ fstream ostream fstream stdexcept fstream string +fstream tuple fstream type_traits fstream typeinfo fstream version @@ -404,6 +406,7 @@ iomanip version ios atomic ios cctype +ios cerrno ios clocale ios concepts ios cstddef @@ -419,6 +422,7 @@ ios stdexcept ios string ios system_error +ios tuple ios type_traits ios typeinfo ios version @@ -501,6 +505,7 @@ locale stdexcept locale streambuf locale string +locale tuple locale type_traits locale typeinfo locale version @@ -716,6 +721,7 @@ regex new regex stdexcept regex string +regex tuple regex type_traits regex typeinfo regex utility @@ -803,8 +809,12 @@ stop_token atomic stop_token cstddef stop_token cstdint +stop_token cstring +stop_token ctime stop_token limits +stop_token ratio stop_token thread +stop_token type_traits stop_token version streambuf cstdint streambuf ios diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -146,6 +146,7 @@ codecvt new codecvt stdexcept codecvt string +codecvt tuple codecvt type_traits codecvt typeinfo codecvt version @@ -356,6 +357,7 @@ fstream ostream fstream stdexcept fstream string +fstream tuple fstream type_traits fstream typeinfo fstream version @@ -406,6 +408,7 @@ iomanip version ios atomic ios cctype +ios cerrno ios clocale ios concepts ios cstddef @@ -421,6 +424,7 @@ ios stdexcept ios string ios system_error +ios tuple ios type_traits ios typeinfo ios version @@ -503,6 +507,7 @@ locale stdexcept locale streambuf locale string +locale tuple locale type_traits locale typeinfo locale version @@ -718,6 +723,7 @@ regex new regex stdexcept regex string +regex tuple regex type_traits regex typeinfo regex utility @@ -805,8 +811,12 @@ stop_token atomic stop_token cstddef stop_token cstdint +stop_token cstring +stop_token ctime stop_token limits +stop_token ratio stop_token thread +stop_token type_traits stop_token version streambuf cstdint streambuf ios diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -146,6 +146,7 @@ codecvt new codecvt stdexcept codecvt string +codecvt tuple codecvt type_traits codecvt typeinfo codecvt version @@ -356,6 +357,7 @@ fstream ostream fstream stdexcept fstream string +fstream tuple fstream type_traits fstream typeinfo fstream version @@ -406,6 +408,7 @@ iomanip version ios atomic ios cctype +ios cerrno ios clocale ios concepts ios cstddef @@ -421,6 +424,7 @@ ios stdexcept ios string ios system_error +ios tuple ios type_traits ios typeinfo ios version @@ -503,6 +507,7 @@ locale stdexcept locale streambuf locale string +locale tuple locale type_traits locale typeinfo locale version @@ -718,6 +723,7 @@ regex new regex stdexcept regex string +regex tuple regex type_traits regex typeinfo regex utility @@ -805,8 +811,12 @@ stop_token atomic stop_token cstddef stop_token cstdint +stop_token cstring +stop_token ctime stop_token limits +stop_token ratio stop_token thread +stop_token type_traits stop_token version streambuf cstdint streambuf ios diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -153,6 +153,7 @@ codecvt new codecvt stdexcept codecvt string +codecvt tuple codecvt type_traits codecvt typeinfo codecvt version @@ -363,6 +364,7 @@ fstream ostream fstream stdexcept fstream string +fstream tuple fstream type_traits fstream typeinfo fstream version @@ -412,6 +414,7 @@ iomanip version ios atomic ios cctype +ios cerrno ios clocale ios concepts ios cstddef @@ -427,6 +430,7 @@ ios stdexcept ios string ios system_error +ios tuple ios type_traits ios typeinfo ios version @@ -509,6 +513,7 @@ locale stdexcept locale streambuf locale string +locale tuple locale type_traits locale typeinfo locale version @@ -724,6 +729,7 @@ regex new regex stdexcept regex string +regex tuple regex type_traits regex typeinfo regex utility diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -99,10 +99,10 @@ codecvt initializer_list codecvt iosfwd codecvt limits -codecvt mutex codecvt new codecvt stdexcept codecvt string +codecvt tuple codecvt typeinfo codecvt version compare cmath @@ -250,11 +250,11 @@ fstream iosfwd fstream istream fstream limits -fstream mutex fstream new fstream ostream fstream stdexcept fstream string +fstream tuple fstream typeinfo fstream version functional array @@ -292,19 +292,22 @@ iomanip istream iomanip version ios cctype +ios cerrno ios clocale ios cstddef ios cstdint ios cstdlib ios cstring +ios ctime ios cwchar ios initializer_list ios iosfwd ios limits -ios mutex ios new +ios ratio ios stdexcept ios string +ios tuple ios typeinfo ios version iosfwd version @@ -357,11 +360,11 @@ locale ios locale iosfwd locale limits -locale mutex locale new locale stdexcept locale streambuf locale string +locale tuple locale typeinfo locale version map compare @@ -516,10 +519,10 @@ regex initializer_list regex iosfwd regex limits -regex mutex regex new regex stdexcept regex string +regex tuple regex typeinfo regex vector regex version diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -99,10 +99,10 @@ codecvt initializer_list codecvt iosfwd codecvt limits -codecvt mutex codecvt new codecvt stdexcept codecvt string +codecvt tuple codecvt typeinfo codecvt version compare cmath @@ -250,11 +250,11 @@ fstream iosfwd fstream istream fstream limits -fstream mutex fstream new fstream ostream fstream stdexcept fstream string +fstream tuple fstream typeinfo fstream version functional array @@ -292,19 +292,22 @@ iomanip istream iomanip version ios cctype +ios cerrno ios clocale ios cstddef ios cstdint ios cstdlib ios cstring +ios ctime ios cwchar ios initializer_list ios iosfwd ios limits -ios mutex ios new +ios ratio ios stdexcept ios string +ios tuple ios typeinfo ios version iosfwd version @@ -357,11 +360,11 @@ locale ios locale iosfwd locale limits -locale mutex locale new locale stdexcept locale streambuf locale string +locale tuple locale typeinfo locale version map compare @@ -516,10 +519,10 @@ regex initializer_list regex iosfwd regex limits -regex mutex regex new regex stdexcept regex string +regex tuple regex typeinfo regex vector regex version