From cfca06d7963fa0909f90483b42a6d7d194d01e08 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 26 Jul 2020 19:36:28 +0000 Subject: Vendor import of llvm-project master 2e10b7a39b9, the last commit before the llvmorg-12-init tag, from which release/11.x was branched. --- libcxx/CREDITS.TXT | 5 + libcxx/include/__bit_reference | 15 + libcxx/include/__config | 122 +++-- libcxx/include/__functional_base | 4 +- libcxx/include/__libcpp_version | 2 +- libcxx/include/__locale | 6 + libcxx/include/__string | 117 +++++ libcxx/include/__threading_support | 113 ++++- libcxx/include/array | 245 +++++----- libcxx/include/atomic | 760 +++++++++++++++++++++++--------- libcxx/include/barrier | 322 ++++++++++++++ libcxx/include/bit | 9 +- libcxx/include/charconv | 13 +- libcxx/include/chrono | 2 +- libcxx/include/cmath | 4 + libcxx/include/codecvt | 72 +-- libcxx/include/compare | 84 ++++ libcxx/include/complex | 13 +- libcxx/include/concepts | 166 +++++++ libcxx/include/cstddef | 64 ++- libcxx/include/cstdio | 4 + libcxx/include/deque | 24 +- libcxx/include/exception | 2 + libcxx/include/filesystem | 1 + libcxx/include/forward_list | 18 +- libcxx/include/functional | 137 ++++-- libcxx/include/future | 1 + libcxx/include/ios | 51 +-- libcxx/include/iterator | 21 +- libcxx/include/latch | 104 +++++ libcxx/include/list | 20 +- libcxx/include/map | 25 +- libcxx/include/math.h | 61 +-- libcxx/include/memory | 672 ++++++++++++---------------- libcxx/include/module.modulemap | 23 + libcxx/include/numbers | 141 ++++++ libcxx/include/ostream | 6 +- libcxx/include/random | 5 + libcxx/include/regex | 68 ++- libcxx/include/semaphore | 235 ++++++++++ libcxx/include/set | 18 +- libcxx/include/span | 170 +++---- libcxx/include/stddef.h | 8 +- libcxx/include/stdexcept | 7 + libcxx/include/stdlib.h | 64 ++- libcxx/include/string | 498 +++++++++++++-------- libcxx/include/system_error | 1 + libcxx/include/thread | 30 +- libcxx/include/type_traits | 447 ++++++++++++++++--- libcxx/include/typeinfo | 13 +- libcxx/include/unordered_map | 26 +- libcxx/include/unordered_set | 26 +- libcxx/include/variant | 22 +- libcxx/include/vector | 43 +- libcxx/include/version | 21 +- libcxx/include/wchar.h | 1 + libcxx/src/algorithm.cpp | 48 -- libcxx/src/atomic.cpp | 189 ++++++++ libcxx/src/barrier.cpp | 103 +++++ libcxx/src/charconv.cpp | 18 +- libcxx/src/chrono.cpp | 120 ++--- libcxx/src/filesystem/operations.cpp | 12 +- libcxx/src/include/apple_availability.h | 16 +- libcxx/src/locale.cpp | 4 +- libcxx/src/random_shuffle.cpp | 61 +++ libcxx/src/string.cpp | 9 +- libcxx/src/thread.cpp | 6 +- 67 files changed, 4170 insertions(+), 1568 deletions(-) create mode 100644 libcxx/include/barrier create mode 100644 libcxx/include/concepts create mode 100644 libcxx/include/latch create mode 100644 libcxx/include/numbers create mode 100644 libcxx/include/semaphore create mode 100644 libcxx/src/atomic.cpp create mode 100644 libcxx/src/barrier.cpp create mode 100644 libcxx/src/random_shuffle.cpp (limited to 'libcxx') diff --git a/libcxx/CREDITS.TXT b/libcxx/CREDITS.TXT index f97b9d822772..49f095d29645 100644 --- a/libcxx/CREDITS.TXT +++ b/libcxx/CREDITS.TXT @@ -41,6 +41,11 @@ N: Jonathan B Coe E: jbcoe@me.com D: Implementation of propagate_const. +N: Christopher Di Bella +E: cjdb@google.com +E: cjdb.ns@gmail.com +D: Library concepts. + N: Glen Joseph Fernandes E: glenjofe@gmail.com D: Implementation of to_address. diff --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference index 3d4da1cbb68a..4a2b82064b3c 100644 --- a/libcxx/include/__bit_reference +++ b/libcxx/include/__bit_reference @@ -1122,6 +1122,21 @@ public: __bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + // The non-const __bit_iterator has historically had a non-trivial + // copy constructor (as a quirk of its construction). We need to maintain + // this for ABI purposes. + using __type_for_abi_non_trivial_copy_ctor = + _If; + + _LIBCPP_INLINE_VISIBILITY + __bit_iterator(__type_for_abi_non_trivial_copy_ctor const& __it) _NOEXCEPT + : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + + // Always declare the copy assignment operator since the implicit declaration + // is deprecated. + _LIBCPP_INLINE_VISIBILITY + __bit_iterator& operator=(__bit_iterator const&) = default; + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT {return reference(__seg_, __storage_type(1) << __ctz_);} diff --git a/libcxx/include/__config b/libcxx/include/__config index ac4549802ef2..575147cead42 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -32,7 +32,7 @@ # define _GNUC_VER_NEW 0 #endif -#define _LIBCPP_VERSION 10000 +#define _LIBCPP_VERSION 11000 #ifndef _LIBCPP_ABI_VERSION # define _LIBCPP_ABI_VERSION 1 @@ -102,6 +102,9 @@ # define _LIBCPP_ABI_OPTIMIZED_FUNCTION // All the regex constants must be distinct and nonzero. # define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO +// Re-worked external template instantiations for std::string with a focus on +// performance and fast-path inlining. +# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support @@ -342,6 +345,10 @@ # define _LIBCPP_HAS_ALIGNED_ALLOC # define _LIBCPP_HAS_QUICK_EXIT # define _LIBCPP_HAS_C11_FEATURES +# if __FreeBSD_version >= 1300064 || \ + (__FreeBSD_version >= 1201504 && __FreeBSD_version < 1300000) +# define _LIBCPP_HAS_TIMESPEC_GET +# endif # elif defined(__BIONIC__) # define _LIBCPP_HAS_C11_FEATURES # if __ANDROID_API__ >= 21 @@ -391,12 +398,12 @@ #if defined(_LIBCPP_COMPILER_CLANG) -// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for -// _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT left here for backward compatibility. -#if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ - (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)) || \ - defined(_LIBCPP_ALTERNATE_STRING_LAYOUT) -#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +#if defined(_LIBCPP_ALTERNATE_STRING_LAYOUT) +# error _LIBCPP_ALTERNATE_STRING_LAYOUT is deprecated, please use _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT instead +#endif +#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ + (!defined(__arm__) || __ARM_ARCH_7K__ >= 2) +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT #endif #if __has_feature(cxx_alignas) @@ -412,12 +419,8 @@ typedef __char16_t char16_t; typedef __char32_t char32_t; #endif -#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS) -#define _LIBCPP_NO_EXCEPTIONS -#endif - -#if !(__has_feature(cxx_rtti)) && !defined(_LIBCPP_NO_RTTI) -#define _LIBCPP_NO_RTTI +#if !__has_feature(cxx_exceptions) +# define _LIBCPP_NO_EXCEPTIONS #endif #if !(__has_feature(cxx_strong_enums)) @@ -463,6 +466,14 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_OBJC_ARC_WEAK #endif +#if __has_extension(blocks) +# define _LIBCPP_HAS_EXTENSION_BLOCKS +#endif + +#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__) +# define _LIBCPP_HAS_BLOCKS_RUNTIME +#endif + #if !(__has_feature(cxx_relaxed_constexpr)) #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR #endif @@ -488,6 +499,10 @@ typedef __char32_t char32_t; #define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER #endif +#if __has_builtin(__builtin_constant_p) +#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P +#endif + #if !__is_identifier(__has_unique_object_representations) #define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS #endif @@ -509,8 +524,8 @@ typedef __char32_t char32_t; #define _LIBCPP_NORETURN __attribute__((noreturn)) -#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS) -#define _LIBCPP_NO_EXCEPTIONS +#if !__EXCEPTIONS +# define _LIBCPP_NO_EXCEPTIONS #endif // Determine if GCC supports relaxed constexpr @@ -529,9 +544,7 @@ typedef __char32_t char32_t; #if _GNUC_VER >= 700 #define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER -#endif - -#if _GNUC_VER >= 700 +#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P #define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS #endif @@ -741,14 +754,14 @@ typedef __char32_t char32_t; # endif #endif -#ifndef _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT -# ifdef _LIBCPP_OBJECT_FORMAT_COFF // Windows binaries can't merge typeinfos. -# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 0 -#else -// TODO: This isn't strictly correct on ELF platforms due to llvm.org/PR37398 -// And we should consider defaulting to OFF. -# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 1 -#endif +#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION +# ifdef _LIBCPP_OBJECT_FORMAT_COFF // Windows binaries can't merge typeinfos. +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2 +# else + // TODO: This isn't strictly correct on ELF platforms due to llvm.org/PR37398 + // And we should consider defaulting to OFF. +# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 +# endif #endif #ifndef _LIBCPP_HIDE_FROM_ABI @@ -897,6 +910,10 @@ typedef unsigned int char32_t; #define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__; #endif +#ifndef _LIBCPP_EXTERN_TEMPLATE_DEFINE +#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; +#endif + #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \ defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__) #define _LIBCPP_LOCALE__L_EXTENSIONS 1 @@ -1088,17 +1105,12 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #endif // Try to find out if RTTI is disabled. -// g++ and cl.exe have RTTI on by default and define a macro when it is. -// g++ only defines the macro in 4.3.2 and onwards. -#if !defined(_LIBCPP_NO_RTTI) -# if defined(__GNUC__) && \ - ((__GNUC__ >= 5) || \ - (__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && \ - !defined(__GXX_RTTI) -# define _LIBCPP_NO_RTTI -# elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI) -# define _LIBCPP_NO_RTTI -# endif +#if defined(_LIBCPP_COMPILER_CLANG) && !__has_feature(cxx_rtti) +# define _LIBCPP_NO_RTTI +#elif defined(__GNUC__) && !defined(__GXX_RTTI) +# define _LIBCPP_NO_RTTI +#elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI) +# define _LIBCPP_NO_RTTI #endif #ifndef _LIBCPP_WEAK @@ -1121,7 +1133,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( (defined(__MINGW32__) && __has_include()) # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) -# define _LIBCPP_HAS_THREAD_API_C11 + // TODO(44575): Switch to C11 thread API when possible. +# define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(_LIBCPP_WIN32API) # define _LIBCPP_HAS_THREAD_API_WIN32 # else @@ -1350,13 +1363,13 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_HAS_NO_COROUTINES #endif -// FIXME: Correct this macro when either (A) a feature test macro for the -// spaceship operator is provided, or (B) a compiler provides a complete -// implementation. +#if !defined(__cpp_impl_three_way_comparison) || __cpp_impl_three_way_comparison < 201907L #define _LIBCPP_HAS_NO_SPACESHIP_OPERATOR +#endif // Decide whether to use availability macros. #if !defined(_LIBCPP_BUILDING_LIBRARY) && \ + !defined(_LIBCXXABI_BUILDING_LIBRARY) && \ !defined(_LIBCPP_DISABLE_AVAILABILITY) && \ __has_feature(attribute_availability_with_strict) && \ __has_feature(attribute_availability_in_templates) && \ @@ -1374,10 +1387,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( __attribute__((availability(tvos,strict,introduced=10.0))) \ __attribute__((availability(watchos,strict,introduced=3.0))) # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ - __attribute__((availability(macosx,strict,introduced=10.14))) \ - __attribute__((availability(ios,strict,introduced=12.0))) \ - __attribute__((availability(tvos,strict,introduced=12.0))) \ - __attribute__((availability(watchos,strict,introduced=5.0))) + __attribute__((availability(macosx,strict,introduced=10.13))) \ + __attribute__((availability(ios,strict,introduced=11.0))) \ + __attribute__((availability(tvos,strict,introduced=11.0))) \ + __attribute__((availability(watchos,strict,introduced=4.0))) # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ @@ -1418,6 +1431,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( _Pragma("clang attribute pop") \ _Pragma("clang attribute pop") \ _Pragma("clang attribute pop") +# define _LIBCPP_AVAILABILITY_TO_CHARS \ + _LIBCPP_AVAILABILITY_FILESYSTEM +# define _LIBCPP_AVAILABILITY_SYNC \ + __attribute__((unavailable)) #else # define _LIBCPP_AVAILABILITY_SHARED_MUTEX # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS @@ -1432,6 +1449,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_AVAILABILITY_FILESYSTEM # define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH # define _LIBCPP_AVAILABILITY_FILESYSTEM_POP +# define _LIBCPP_AVAILABILITY_TO_CHARS +# define _LIBCPP_AVAILABILITY_SYNC #endif // Define availability that depends on _LIBCPP_NO_EXCEPTIONS. @@ -1515,6 +1534,19 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_FOPEN_CLOEXEC_MODE #endif +#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P +#define _LIBCPP_BUILTIN_CONSTANT_P(x) __builtin_constant_p(x) +#else +#define _LIBCPP_BUILTIN_CONSTANT_P(x) false +#endif + +// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set +// of functions used in cstdio may not be available for low API levels when +// using 64-bit file offsets on LP32. +#if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24 +#define _LIBCPP_HAS_NO_FGETPOS_FSETPOS +#endif + #endif // __cplusplus #endif // _LIBCPP_CONFIG diff --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base index ca761c409b62..f591bf5a9dce 100644 --- a/libcxx/include/__functional_base +++ b/libcxx/include/__functional_base @@ -522,7 +522,7 @@ inline _LIBCPP_INLINE_VISIBILITY reference_wrapper<_Tp> ref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return ref(__t.get()); + return _VSTD::ref(__t.get()); } template @@ -538,7 +538,7 @@ inline _LIBCPP_INLINE_VISIBILITY reference_wrapper cref(reference_wrapper<_Tp> __t) _NOEXCEPT { - return cref(__t.get()); + return _VSTD::cref(__t.get()); } #ifndef _LIBCPP_CXX03_LANG diff --git a/libcxx/include/__libcpp_version b/libcxx/include/__libcpp_version index 5caff40c4a0c..82b3803a20e9 100644 --- a/libcxx/include/__libcpp_version +++ b/libcxx/include/__libcpp_version @@ -1 +1 @@ -10000 +11000 diff --git a/libcxx/include/__locale b/libcxx/include/__locale index 2b6982fc6810..6d10fa4d3d64 100644 --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -496,7 +496,13 @@ public: static const mask punct = 1<<7; static const mask xdigit = 1<<8; static const mask blank = 1<<9; +#if defined(__BIONIC__) + // Historically this was a part of regex_traits rather than ctype_base. The + // historical value of the constant is preserved for ABI compatibility. + static const mask __regex_word = 0x8000; +#else static const mask __regex_word = 1<<10; +#endif // defined(__BIONIC__) #endif static const mask alnum = alpha | digit; static const mask graph = alnum | punct; diff --git a/libcxx/include/__string b/libcxx/include/__string index 056b9b80ea50..9060bf98ad89 100644 --- a/libcxx/include/__string +++ b/libcxx/include/__string @@ -70,6 +70,123 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD +// The the extern template ABI lists are kept outside of to improve the +// readability of that header. + +// The extern template ABI lists are kept outside of to improve the +// readability of that header. We maintain 2 ABI lists: +// - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST +// - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST +// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI. +// +// For unstable, we may explicitly remove function that are external in V1, +// and add (new) external functions to better control inlining and compiler +// optimization opportunities. +// +// For stable, the ABI list should rarely change, except for adding new +// functions supporting new c++ version / API changes. Typically entries +// must never be removed from the stable list. +#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, std::allocator<_CharType> const&)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, std::allocator<_CharType> const&)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \ + _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) + +#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, std::allocator<_CharType> const&)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias(value_type const*, size_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \ + _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \ + _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \ + _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) + + // char_traits template diff --git a/libcxx/include/__threading_support b/libcxx/include/__threading_support index 026429f6a8ec..072c4c7bcc89 100644 --- a/libcxx/include/__threading_support +++ b/libcxx/include/__threading_support @@ -26,6 +26,12 @@ #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) # include # include +# ifdef __APPLE__ +# define _LIBCPP_NO_NATIVE_SEMAPHORES +# endif +# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES +# include +# endif #elif defined(_LIBCPP_HAS_THREAD_API_C11) # include #endif @@ -65,6 +71,12 @@ typedef pthread_mutex_t __libcpp_recursive_mutex_t; typedef pthread_cond_t __libcpp_condvar_t; #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER +#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES +// Semaphore +typedef sem_t __libcpp_semaphore_t; +# define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX +#endif + // Execute once typedef pthread_once_t __libcpp_exec_once_flag; #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT @@ -127,6 +139,9 @@ typedef void* __libcpp_recursive_mutex_t[5]; typedef void* __libcpp_condvar_t; #define _LIBCPP_CONDVAR_INITIALIZER 0 +// Semaphore +typedef void* __libcpp_semaphore_t; + // Execute Once typedef void* __libcpp_exec_once_flag; #define _LIBCPP_EXEC_ONCE_INITIALIZER 0 @@ -191,6 +206,26 @@ int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); +#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES + +// Semaphore +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init); + +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem); + +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem); + +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem); + +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns); + +#endif // _LIBCPP_NO_NATIVE_SEMAPHORES + // Execute once _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_execute_once(__libcpp_exec_once_flag *flag, @@ -242,9 +277,52 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +struct __libcpp_timed_backoff_policy { + _LIBCPP_THREAD_ABI_VISIBILITY + bool operator()(chrono::nanoseconds __elapsed) const; +}; + +inline _LIBCPP_INLINE_VISIBILITY +bool __libcpp_timed_backoff_policy::operator()(chrono::nanoseconds __elapsed) const +{ + if(__elapsed > chrono::milliseconds(128)) + __libcpp_thread_sleep_for(chrono::milliseconds(8)); + else if(__elapsed > chrono::microseconds(64)) + __libcpp_thread_sleep_for(__elapsed / 2); + else if(__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else + ; // poll + return false; +} + +static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64; + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +bool __libcpp_thread_poll_with_backoff( + _Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero()) +{ + auto const __start = chrono::high_resolution_clock::now(); + for(int __count = 0;;) { + if(__f()) + return true; // _Fn completion means success + if(__count < __libcpp_polling_count) { + __count += 1; + continue; + } + chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start; + if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed) + return false; // timeout failure + if(__bf(__elapsed)) + return false; // _BFn completion means failure + } +} + #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) + namespace __thread_detail { inline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) @@ -364,6 +442,38 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) return pthread_cond_destroy(__cv); } +#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES + +// Semaphore +bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init) +{ + return sem_init(__sem, 0, __init) == 0; +} + +bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem) +{ + return sem_destroy(__sem) == 0; +} + +bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem) +{ + return sem_post(__sem) == 0; +} + +bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem) +{ + return sem_wait(__sem) == 0; +} + +bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns) +{ + auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns; + __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time); + return sem_timedwait(__sem, &__ts) == 0; +} + +#endif //_LIBCPP_NO_NATIVE_SEMAPHORES + // Execute once int __libcpp_execute_once(__libcpp_exec_once_flag *flag, void (*init_routine)()) { @@ -445,7 +555,7 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) { - return mtx_init(__m, mtx_recursive) == thrd_success ? 0 : EINVAL; + return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL; } int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) @@ -600,6 +710,7 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) #endif + #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL class _LIBCPP_TYPE_VIS thread; diff --git a/libcxx/include/array b/libcxx/include/array index 88e9d57ff783..e73bbe7fea5f 100644 --- a/libcxx/include/array +++ b/libcxx/include/array @@ -32,24 +32,24 @@ struct array typedef std::reverse_iterator const_reverse_iterator; // No explicit construct/copy/destroy for aggregate type - void fill(const T& u); - void swap(array& a) noexcept(is_nothrow_swappable_v); + void fill(const T& u); // constexpr in C++20 + void swap(array& a) noexcept(is_nothrow_swappable_v); // constexpr in C++20 // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + iterator begin() noexcept; // constexpr in C++17 + const_iterator begin() const noexcept; // constexpr in C++17 + iterator end() noexcept; // constexpr in C++17 + const_iterator end() const noexcept; // constexpr in C++17 - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + reverse_iterator rbegin() noexcept; // constexpr in C++17 + const_reverse_iterator rbegin() const noexcept; // constexpr in C++17 + reverse_iterator rend() noexcept; // constexpr in C++17 + const_reverse_iterator rend() const noexcept; // constexpr in C++17 - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + const_iterator cbegin() const noexcept; // constexpr in C++17 + const_iterator cend() const noexcept; // constexpr in C++17 + const_reverse_iterator crbegin() const noexcept; // constexpr in C++17 + const_reverse_iterator crend() const noexcept; // constexpr in C++17 // capacity: constexpr size_type size() const noexcept; @@ -57,46 +57,51 @@ struct array constexpr bool empty() const noexcept; // element access: - reference operator[](size_type n); - const_reference operator[](size_type n) const; // constexpr in C++14 - const_reference at(size_type n) const; // constexpr in C++14 - reference at(size_type n); - - reference front(); - const_reference front() const; // constexpr in C++14 - reference back(); - const_reference back() const; // constexpr in C++14 - - T* data() noexcept; - const T* data() const noexcept; + reference operator[](size_type n); // constexpr in C++17 + const_reference operator[](size_type n) const; // constexpr in C++14 + reference at(size_type n); // constexpr in C++17 + const_reference at(size_type n) const; // constexpr in C++14 + + reference front(); // constexpr in C++17 + const_reference front() const; // constexpr in C++14 + reference back(); // constexpr in C++17 + const_reference back() const; // constexpr in C++14 + + T* data() noexcept; // constexpr in C++17 + const T* data() const noexcept; // constexpr in C++17 }; - template - array(T, U...) -> array; +template + array(T, U...) -> array; // C++17 template - bool operator==(const array& x, const array& y); + bool operator==(const array& x, const array& y); // constexpr in C++20 template - bool operator!=(const array& x, const array& y); + bool operator!=(const array& x, const array& y); // constexpr in C++20 template - bool operator<(const array& x, const array& y); + bool operator<(const array& x, const array& y); // constexpr in C++20 template - bool operator>(const array& x, const array& y); + bool operator>(const array& x, const array& y); // constexpr in C++20 template - bool operator<=(const array& x, const array& y); + bool operator<=(const array& x, const array& y); // constexpr in C++20 template - bool operator>=(const array& x, const array& y); + bool operator>=(const array& x, const array& y); // constexpr in C++20 template - void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); // C++17 + void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20 + +template + constexpr array, N> to_array(T (&a)[N]); // C++20 +template + constexpr array, N> to_array(T (&&a)[N]); // C++20 template struct tuple_size; template struct tuple_element; template struct tuple_size>; template struct tuple_element>; -template T& get(array&) noexcept; // constexpr in C++14 -template const T& get(const array&) noexcept; // constexpr in C++14 -template T&& get(array&&) noexcept; // constexpr in C++14 +template T& get(array&) noexcept; // constexpr in C++14 +template const T& get(const array&) noexcept; // constexpr in C++14 +template T&& get(array&&) noexcept; // constexpr in C++14 template const T&& get(const array&&) noexcept; // constexpr in C++14 } // std @@ -143,13 +148,14 @@ struct _LIBCPP_TEMPLATE_VIS array _Tp __elems_[_Size]; // No explicit construct/copy/destroy for aggregate type - _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) { - _VSTD::fill_n(__elems_, _Size, __u); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void fill(const value_type& __u) { + _VSTD::fill_n(data(), _Size, __u); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { - std::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_); + std::swap_ranges(data(), data() + _Size, __a.data()); } // iterators: @@ -186,21 +192,38 @@ struct _LIBCPP_TEMPLATE_VIS array _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;} _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return false; } + _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;} // element access: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator[](size_type __n) _NOEXCEPT {return __elems_[__n];} + reference operator[](size_type __n) _NOEXCEPT { + _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array"); + return __elems_[__n]; + } _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - const_reference operator[](size_type __n) const _NOEXCEPT {return __elems_[__n];} + const_reference operator[](size_type __n) const _NOEXCEPT { + _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array"); + return __elems_[__n]; + } - _LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type __n); - _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const; + _LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type __n) + { + if (__n >= _Size) + __throw_out_of_range("array::at"); + return __elems_[__n]; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() _NOEXCEPT {return __elems_[0];} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT {return __elems_[0];} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() _NOEXCEPT {return __elems_[_Size - 1];} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const _NOEXCEPT {return __elems_[_Size - 1];} + _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const + { + if (__n >= _Size) + __throw_out_of_range("array::at"); + return __elems_[__n]; + } + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() _NOEXCEPT {return (*this)[0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT {return (*this)[0];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() _NOEXCEPT {return (*this)[_Size - 1];} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const _NOEXCEPT {return (*this)[_Size - 1];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 value_type* data() _NOEXCEPT {return __elems_;} @@ -208,28 +231,6 @@ struct _LIBCPP_TEMPLATE_VIS array const value_type* data() const _NOEXCEPT {return __elems_;} }; - -template -_LIBCPP_CONSTEXPR_AFTER_CXX14 -typename array<_Tp, _Size>::reference -array<_Tp, _Size>::at(size_type __n) -{ - if (__n >= _Size) - __throw_out_of_range("array::at"); - - return __elems_[__n]; -} - -template -_LIBCPP_CONSTEXPR_AFTER_CXX11 -typename array<_Tp, _Size>::const_reference -array<_Tp, _Size>::at(size_type __n) const -{ - if (__n >= _Size) - __throw_out_of_range("array::at"); - return __elems_[__n]; -} - template struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> { @@ -253,44 +254,50 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> struct _ArrayInStructT { _Tp __data_[1]; }; _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)]; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + value_type* data() _NOEXCEPT {return nullptr;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + const value_type* data() const _NOEXCEPT {return nullptr;} + // No explicit construct/copy/destroy for aggregate type - _LIBCPP_INLINE_VISIBILITY void fill(const value_type&) { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void fill(const value_type&) { static_assert(!is_const<_Tp>::value, "cannot fill zero-sized array of type 'const T'"); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(array&) _NOEXCEPT { static_assert(!is_const<_Tp>::value, "cannot swap zero-sized array of type 'const T'"); } // iterators: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 iterator begin() _NOEXCEPT {return iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator begin() const _NOEXCEPT {return const_iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 iterator end() _NOEXCEPT {return iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator end() const _NOEXCEPT {return const_iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator crend() const _NOEXCEPT {return rend();} // capacity: @@ -302,7 +309,7 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;} // element access: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator[](size_type) _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::operator[] on a zero-sized array"); _LIBCPP_UNREACHABLE(); @@ -314,52 +321,47 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type) { __throw_out_of_range("array::at"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type) const { __throw_out_of_range("array::at"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::front() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::front() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::back() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::back() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - - _LIBCPP_INLINE_VISIBILITY - value_type* data() _NOEXCEPT {return reinterpret_cast(__elems_);} - _LIBCPP_INLINE_VISIBILITY - const value_type* data() const _NOEXCEPT {return reinterpret_cast(__elems_);} }; #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template && ...), void>::type + class = _EnableIf<__all<_IsSame<_Tp, _Args>::value...>::value> > array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>; @@ -415,7 +417,7 @@ operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < _Size == 0 || @@ -479,6 +481,47 @@ get(const array<_Tp, _Size>&& __a) _NOEXCEPT #endif // !_LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 + +template +_LIBCPP_INLINE_VISIBILITY constexpr array, _Size> +__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) { + return {{__arr[_Index]...}}; +} + +template +_LIBCPP_INLINE_VISIBILITY constexpr array, _Size> +__to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) { + return {{_VSTD::move(__arr[_Index])...}}; +} + +template +_LIBCPP_INLINE_VISIBILITY constexpr array, _Size> +to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { + static_assert( + !is_array_v<_Tp>, + "[array.creation]/1: to_array does not accept multidimensional arrays."); + static_assert( + is_constructible_v<_Tp, _Tp&>, + "[array.creation]/1: to_array requires copy constructible elements."); + return __to_array_lvalue_impl(__arr, make_index_sequence<_Size>()); +} + +template +_LIBCPP_INLINE_VISIBILITY constexpr array, _Size> +to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) { + static_assert( + !is_array_v<_Tp>, + "[array.creation]/4: to_array does not accept multidimensional arrays."); + static_assert( + is_move_constructible_v<_Tp>, + "[array.creation]/4: to_array requires move constructible elements."); + return __to_array_rvalue_impl(_VSTD::move(__arr), + make_index_sequence<_Size>()); +} + +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_ARRAY diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 6904dd400032..9c2898653788 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -54,60 +54,30 @@ template T kill_dependency(T y) noexcept; #define ATOMIC_LLONG_LOCK_FREE unspecified #define ATOMIC_POINTER_LOCK_FREE unspecified -// flag type and operations - -typedef struct atomic_flag -{ - bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; - bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; - void clear(memory_order m = memory_order_seq_cst) volatile noexcept; - void clear(memory_order m = memory_order_seq_cst) noexcept; - atomic_flag() noexcept = default; - atomic_flag(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) volatile = delete; -} atomic_flag; - -bool - atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; - -bool - atomic_flag_test_and_set(atomic_flag* obj) noexcept; - -bool - atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, - memory_order m) noexcept; - -bool - atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; - -void - atomic_flag_clear(volatile atomic_flag* obj) noexcept; - -void - atomic_flag_clear(atomic_flag* obj) noexcept; - -void - atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; - -void - atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; - -#define ATOMIC_FLAG_INIT see below -#define ATOMIC_VAR_INIT(value) see below - template struct atomic { + using value_type = T; + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; - void store(T desr, memory_order m = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(T desr) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + T load(memory_order m = memory_order_seq_cst) const volatile noexcept; T load(memory_order m = memory_order_seq_cst) const noexcept; operator T() const volatile noexcept; operator T() const noexcept; + void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; + void store(T desr, memory_order m = memory_order_seq_cst) noexcept; + T operator=(T) volatile noexcept; + T operator=(T) noexcept; + T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; bool compare_exchange_weak(T& expc, T desr, @@ -126,27 +96,38 @@ struct atomic bool compare_exchange_strong(T& expc, T desr, memory_order m = memory_order_seq_cst) noexcept; - atomic() noexcept = default; - constexpr atomic(T desr) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - T operator=(T) volatile noexcept; - T operator=(T) noexcept; + void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept; + void wait(T, memory_order = memory_order::seq_cst) const noexcept; + void notify_one() volatile noexcept; + void notify_one() noexcept; + void notify_all() volatile noexcept; + void notify_all() noexcept; }; template <> struct atomic { + using value_type = integral; + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; - void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(integral desr) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; integral load(memory_order m = memory_order_seq_cst) const noexcept; operator integral() const volatile noexcept; operator integral() const noexcept; + void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; + void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; + integral operator=(integral desr) volatile noexcept; + integral operator=(integral desr) noexcept; + integral exchange(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; @@ -167,30 +148,17 @@ struct atomic bool compare_exchange_strong(integral& expc, integral desr, memory_order m = memory_order_seq_cst) noexcept; - integral - fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; - integral - fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; - integral - fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; - integral - fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; - integral - fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; + integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; - atomic() noexcept = default; - constexpr atomic(integral desr) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - integral operator=(integral desr) volatile noexcept; - integral operator=(integral desr) noexcept; - integral operator++(int) volatile noexcept; integral operator++(int) noexcept; integral operator--(int) volatile noexcept; @@ -209,20 +177,39 @@ struct atomic integral operator|=(integral op) noexcept; integral operator^=(integral op) volatile noexcept; integral operator^=(integral op) noexcept; + + void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept; + void wait(integral, memory_order = memory_order::seq_cst) const noexcept; + void notify_one() volatile noexcept; + void notify_one() noexcept; + void notify_all() volatile noexcept; + void notify_all() noexcept; }; template struct atomic { + using value_type = T*; + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; - void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; - void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; + + atomic() noexcept = default; + constexpr atomic(T* desr) noexcept; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; T* load(memory_order m = memory_order_seq_cst) const noexcept; operator T*() const volatile noexcept; operator T*() const noexcept; + void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; + void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; + T* operator=(T*) volatile noexcept; + T* operator=(T*) noexcept; + T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; bool compare_exchange_weak(T*& expc, T* desr, @@ -246,14 +233,6 @@ struct atomic T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; - atomic() noexcept = default; - constexpr atomic(T* desr) noexcept; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - - T* operator=(T*) volatile noexcept; - T* operator=(T*) noexcept; T* operator++(int) volatile noexcept; T* operator++(int) noexcept; T* operator--(int) volatile noexcept; @@ -266,224 +245,206 @@ struct atomic T* operator+=(ptrdiff_t op) noexcept; T* operator-=(ptrdiff_t op) volatile noexcept; T* operator-=(ptrdiff_t op) noexcept; + + void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept; + void wait(T*, memory_order = memory_order::seq_cst) const noexcept; + void notify_one() volatile noexcept; + void notify_one() noexcept; + void notify_all() volatile noexcept; + void notify_all() noexcept; }; template - bool - atomic_is_lock_free(const volatile atomic* obj) noexcept; + bool atomic_is_lock_free(const volatile atomic* obj) noexcept; + +template + bool atomic_is_lock_free(const atomic* obj) noexcept; + +template + void atomic_store(volatile atomic* obj, T desr) noexcept; + +template + void atomic_store(atomic* obj, T desr) noexcept; + +template + void atomic_store_explicit(volatile atomic* obj, T desr, memory_order m) noexcept; + +template + void atomic_store_explicit(atomic* obj, T desr, memory_order m) noexcept; + +template + T atomic_load(const volatile atomic* obj) noexcept; template - bool - atomic_is_lock_free(const atomic* obj) noexcept; + T atomic_load(const atomic* obj) noexcept; template - void - atomic_init(volatile atomic* obj, T desr) noexcept; + T atomic_load_explicit(const volatile atomic* obj, memory_order m) noexcept; template - void - atomic_init(atomic* obj, T desr) noexcept; + T atomic_load_explicit(const atomic* obj, memory_order m) noexcept; template - void - atomic_store(volatile atomic* obj, T desr) noexcept; + T atomic_exchange(volatile atomic* obj, T desr) noexcept; template - void - atomic_store(atomic* obj, T desr) noexcept; + T atomic_exchange(atomic* obj, T desr) noexcept; template - void - atomic_store_explicit(volatile atomic* obj, T desr, memory_order m) noexcept; + T atomic_exchange_explicit(volatile atomic* obj, T desr, memory_order m) noexcept; template - void - atomic_store_explicit(atomic* obj, T desr, memory_order m) noexcept; + T atomic_exchange_explicit(atomic* obj, T desr, memory_order m) noexcept; template - T - atomic_load(const volatile atomic* obj) noexcept; + bool atomic_compare_exchange_weak(volatile atomic* obj, T* expc, T desr) noexcept; template - T - atomic_load(const atomic* obj) noexcept; + bool atomic_compare_exchange_weak(atomic* obj, T* expc, T desr) noexcept; template - T - atomic_load_explicit(const volatile atomic* obj, memory_order m) noexcept; + bool atomic_compare_exchange_strong(volatile atomic* obj, T* expc, T desr) noexcept; template - T - atomic_load_explicit(const atomic* obj, memory_order m) noexcept; + bool atomic_compare_exchange_strong(atomic* obj, T* expc, T desr) noexcept; template - T - atomic_exchange(volatile atomic* obj, T desr) noexcept; + bool atomic_compare_exchange_weak_explicit(volatile atomic* obj, T* expc, + T desr, + memory_order s, memory_order f) noexcept; template - T - atomic_exchange(atomic* obj, T desr) noexcept; + bool atomic_compare_exchange_weak_explicit(atomic* obj, T* expc, T desr, + memory_order s, memory_order f) noexcept; template - T - atomic_exchange_explicit(volatile atomic* obj, T desr, memory_order m) noexcept; + bool atomic_compare_exchange_strong_explicit(volatile atomic* obj, + T* expc, T desr, + memory_order s, memory_order f) noexcept; template - T - atomic_exchange_explicit(atomic* obj, T desr, memory_order m) noexcept; + bool atomic_compare_exchange_strong_explicit(atomic* obj, T* expc, + T desr, + memory_order s, memory_order f) noexcept; template - bool - atomic_compare_exchange_weak(volatile atomic* obj, T* expc, T desr) noexcept; + void atomic_wait(const volatile atomic* obj, T old) noexcept; template - bool - atomic_compare_exchange_weak(atomic* obj, T* expc, T desr) noexcept; + void atomic_wait(const atomic* obj, T old) noexcept; template - bool - atomic_compare_exchange_strong(volatile atomic* obj, T* expc, T desr) noexcept; + void atomic_wait_explicit(const volatile atomic* obj, T old, memory_order m) noexcept; template - bool - atomic_compare_exchange_strong(atomic* obj, T* expc, T desr) noexcept; + void atomic_wait_explicit(const atomic* obj, T old, memory_order m) noexcept; template - bool - atomic_compare_exchange_weak_explicit(volatile atomic* obj, T* expc, - T desr, - memory_order s, memory_order f) noexcept; + void atomic_one(volatile atomic* obj) noexcept; template - bool - atomic_compare_exchange_weak_explicit(atomic* obj, T* expc, T desr, - memory_order s, memory_order f) noexcept; + void atomic_one(atomic* obj) noexcept; template - bool - atomic_compare_exchange_strong_explicit(volatile atomic* obj, - T* expc, T desr, - memory_order s, memory_order f) noexcept; + void atomic_all(volatile atomic* obj) noexcept; template - bool - atomic_compare_exchange_strong_explicit(atomic* obj, T* expc, - T desr, - memory_order s, memory_order f) noexcept; + void atomic_all(atomic* obj) noexcept; template - Integral - atomic_fetch_add(volatile atomic* obj, Integral op) noexcept; + Integral atomic_fetch_add(volatile atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_add(atomic* obj, Integral op) noexcept; + Integral atomic_fetch_add(atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_add_explicit(volatile atomic* obj, Integral op, + Integral atomic_fetch_add_explicit(volatile atomic* obj, Integral op, memory_order m) noexcept; template - Integral - atomic_fetch_add_explicit(atomic* obj, Integral op, + Integral atomic_fetch_add_explicit(atomic* obj, Integral op, memory_order m) noexcept; template - Integral - atomic_fetch_sub(volatile atomic* obj, Integral op) noexcept; + Integral atomic_fetch_sub(volatile atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_sub(atomic* obj, Integral op) noexcept; + Integral atomic_fetch_sub(atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_sub_explicit(volatile atomic* obj, Integral op, - memory_order m) noexcept; + Integral atomic_fetch_sub_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; + template - Integral - atomic_fetch_sub_explicit(atomic* obj, Integral op, - memory_order m) noexcept; + Integral atomic_fetch_sub_explicit(atomic* obj, Integral op, + memory_order m) noexcept; + template - Integral - atomic_fetch_and(volatile atomic* obj, Integral op) noexcept; + Integral atomic_fetch_and(volatile atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_and(atomic* obj, Integral op) noexcept; + Integral atomic_fetch_and(atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_and_explicit(volatile atomic* obj, Integral op, - memory_order m) noexcept; + Integral atomic_fetch_and_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; + template - Integral - atomic_fetch_and_explicit(atomic* obj, Integral op, - memory_order m) noexcept; + Integral atomic_fetch_and_explicit(atomic* obj, Integral op, + memory_order m) noexcept; + template - Integral - atomic_fetch_or(volatile atomic* obj, Integral op) noexcept; + Integral atomic_fetch_or(volatile atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_or(atomic* obj, Integral op) noexcept; + Integral atomic_fetch_or(atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_or_explicit(volatile atomic* obj, Integral op, + Integral atomic_fetch_or_explicit(volatile atomic* obj, Integral op, memory_order m) noexcept; + template - Integral - atomic_fetch_or_explicit(atomic* obj, Integral op, + Integral atomic_fetch_or_explicit(atomic* obj, Integral op, memory_order m) noexcept; + template - Integral - atomic_fetch_xor(volatile atomic* obj, Integral op) noexcept; + Integral atomic_fetch_xor(volatile atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_xor(atomic* obj, Integral op) noexcept; + Integral atomic_fetch_xor(atomic* obj, Integral op) noexcept; template - Integral - atomic_fetch_xor_explicit(volatile atomic* obj, Integral op, - memory_order m) noexcept; + Integral atomic_fetch_xor_explicit(volatile atomic* obj, Integral op, + memory_order m) noexcept; + template - Integral - atomic_fetch_xor_explicit(atomic* obj, Integral op, - memory_order m) noexcept; + Integral atomic_fetch_xor_explicit(atomic* obj, Integral op, + memory_order m) noexcept; template - T* - atomic_fetch_add(volatile atomic* obj, ptrdiff_t op) noexcept; + T* atomic_fetch_add(volatile atomic* obj, ptrdiff_t op) noexcept; template - T* - atomic_fetch_add(atomic* obj, ptrdiff_t op) noexcept; + T* atomic_fetch_add(atomic* obj, ptrdiff_t op) noexcept; template - T* - atomic_fetch_add_explicit(volatile atomic* obj, ptrdiff_t op, - memory_order m) noexcept; + T* atomic_fetch_add_explicit(volatile atomic* obj, ptrdiff_t op, + memory_order m) noexcept; + template - T* - atomic_fetch_add_explicit(atomic* obj, ptrdiff_t op, memory_order m) noexcept; + T* atomic_fetch_add_explicit(atomic* obj, ptrdiff_t op, memory_order m) noexcept; template - T* - atomic_fetch_sub(volatile atomic* obj, ptrdiff_t op) noexcept; + T* atomic_fetch_sub(volatile atomic* obj, ptrdiff_t op) noexcept; template - T* - atomic_fetch_sub(atomic* obj, ptrdiff_t op) noexcept; + T* atomic_fetch_sub(atomic* obj, ptrdiff_t op) noexcept; template - T* - atomic_fetch_sub_explicit(volatile atomic* obj, ptrdiff_t op, - memory_order m) noexcept; + T* atomic_fetch_sub_explicit(volatile atomic* obj, ptrdiff_t op, + memory_order m) noexcept; + template - T* - atomic_fetch_sub_explicit(atomic* obj, ptrdiff_t op, memory_order m) noexcept; + T* atomic_fetch_sub_explicit(atomic* obj, ptrdiff_t op, memory_order m) noexcept; // Atomics for standard typedef types @@ -516,7 +477,7 @@ typedef atomic atomic_int_fast8_t; typedef atomic atomic_uint_fast8_t; typedef atomic atomic_int_fast16_t; typedef atomic atomic_uint_fast16_t; -typedef atomic atomic_int_fast32_t; +typedef atomic atomic_int_fast32_t; typedef atomic atomic_uint_fast32_t; typedef atomic atomic_int_fast64_t; typedef atomic atomic_uint_fast64_t; @@ -537,18 +498,80 @@ typedef atomic atomic_ptrdiff_t; typedef atomic atomic_intmax_t; typedef atomic atomic_uintmax_t; +// flag type and operations + +typedef struct atomic_flag +{ + atomic_flag() noexcept = default; + atomic_flag(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) volatile = delete; + + bool test(memory_order m = memory_order_seq_cst) volatile noexcept; + bool test(memory_order m = memory_order_seq_cst) noexcept; + bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; + bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; + void clear(memory_order m = memory_order_seq_cst) volatile noexcept; + void clear(memory_order m = memory_order_seq_cst) noexcept; + + void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; + void wait(bool, memory_order = memory_order::seq_cst) const noexcept; + void notify_one() volatile noexcept; + void notify_one() noexcept; + void notify_all() volatile noexcept; + void notify_all() noexcept; +} atomic_flag; + +bool atomic_flag_test(volatile atomic_flag* obj) noexcept; +bool atomic_flag_test(atomic_flag* obj) noexcept; +bool atomic_flag_test_explicit(volatile atomic_flag* obj, + memory_order m) noexcept; +bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept; +bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; +bool atomic_flag_test_and_set(atomic_flag* obj) noexcept; +bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, + memory_order m) noexcept; +bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; +void atomic_flag_clear(volatile atomic_flag* obj) noexcept; +void atomic_flag_clear(atomic_flag* obj) noexcept; +void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; +void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; + +void atomic_wait(const volatile atomic_flag* obj, T old) noexcept; +void atomic_wait(const atomic_flag* obj, T old) noexcept; +void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept; +void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept; +void atomic_one(volatile atomic_flag* obj) noexcept; +void atomic_one(atomic_flag* obj) noexcept; +void atomic_all(volatile atomic_flag* obj) noexcept; +void atomic_all(atomic_flag* obj) noexcept; + // fences void atomic_thread_fence(memory_order m) noexcept; void atomic_signal_fence(memory_order m) noexcept; +// deprecated + +template + void atomic_init(volatile atomic* obj, typename atomic::value_type desr) noexcept; + +template + void atomic_init(atomic* obj, typename atomic::value_type desr) noexcept; + +#define ATOMIC_VAR_INIT(value) see below + +#define ATOMIC_FLAG_INIT see below + } // std */ #include <__config> +#include <__threading_support> #include #include +#include #include #include @@ -629,6 +652,11 @@ typedef enum memory_order { #endif // _LIBCPP_STD_VER > 17 +template _LIBCPP_INLINE_VISIBILITY +bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { + return memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0; +} + static_assert((is_same::type, __memory_order_underlying_t>::value), "unexpected underlying type for std::memory_order"); @@ -1218,9 +1246,9 @@ _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order, memory_order) { __a->__lock(); - _Tp temp; - __cxx_atomic_assign_volatile(temp, __a->__a_value); - bool __ret = temp == *__expected; + _Tp __temp; + __cxx_atomic_assign_volatile(__temp, __a->__a_value); + bool __ret = __temp == *__expected; if(__ret) __cxx_atomic_assign_volatile(__a->__a_value, __value); else @@ -1247,9 +1275,9 @@ _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order, memory_order) { __a->__lock(); - _Tp temp; - __cxx_atomic_assign_volatile(temp, __a->__a_value); - bool __ret = temp == *__expected; + _Tp __temp; + __cxx_atomic_assign_volatile(__temp, __a->__a_value); + bool __ret = __temp == *__expected; if(__ret) __cxx_atomic_assign_volatile(__a->__a_value, __value); else @@ -1452,6 +1480,93 @@ struct __cxx_atomic_impl : public _Base { : _Base(value) {} }; +#ifdef __linux__ + using __cxx_contention_t = int32_t; +#else + using __cxx_contention_t = int64_t; +#endif //__linux__ + +#if _LIBCPP_STD_VER >= 11 + +using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; + +#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); + +template +struct __libcpp_atomic_wait_backoff_impl { + _Atp* __a; + _Fn __test_fn; + _LIBCPP_AVAILABILITY_SYNC + _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const + { + if(__elapsed > chrono::microseconds(64)) + { + auto const __monitor = __libcpp_atomic_monitor(__a); + if(__test_fn()) + return true; + __libcpp_atomic_wait(__a, __monitor); + } + else if(__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else + ; // poll + return false; + } +}; + +template +_LIBCPP_AVAILABILITY_SYNC +_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) +{ + __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn}; + return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); +} + +#else // _LIBCPP_HAS_NO_PLATFORM_WAIT + +template +_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } +template +_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } +template +_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) +{ + return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy()); +} + +#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT + +template +struct __cxx_atomic_wait_test_fn_impl { + _Atp* __a; + _Tp __val; + memory_order __order; + _LIBCPP_INLINE_VISIBILITY bool operator()() const + { + return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val); + } +}; + +template +_LIBCPP_AVAILABILITY_SYNC +_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) +{ + __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; + return __cxx_atomic_wait(__a, __test_fn); +} + +#endif //_LIBCPP_STD_VER >= 11 + // general atomic template ::value && !is_same<_Tp, bool>::value> @@ -1532,6 +1647,19 @@ struct __atomic_base // false memory_order __m = memory_order_seq_cst) _NOEXCEPT {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + {__cxx_atomic_wait(&__a_, __v, __m);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT + {__cxx_atomic_wait(&__a_, __v, __m);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT + {__cxx_atomic_notify_one(&__a_);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT + {__cxx_atomic_notify_one(&__a_);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT + {__cxx_atomic_notify_all(&__a_);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT + {__cxx_atomic_notify_all(&__a_);} + _LIBCPP_INLINE_VISIBILITY __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT @@ -1544,8 +1672,11 @@ struct __atomic_base // false __atomic_base& operator=(const __atomic_base&) volatile = delete; #else private: + _LIBCPP_INLINE_VISIBILITY __atomic_base(const __atomic_base&); + _LIBCPP_INLINE_VISIBILITY __atomic_base& operator=(const __atomic_base&); + _LIBCPP_INLINE_VISIBILITY __atomic_base& operator=(const __atomic_base&) volatile; #endif }; @@ -1643,6 +1774,7 @@ struct atomic : public __atomic_base<_Tp> { typedef __atomic_base<_Tp> __base; + typedef _Tp value_type; _LIBCPP_INLINE_VISIBILITY atomic() _NOEXCEPT _LIBCPP_DEFAULT _LIBCPP_INLINE_VISIBILITY @@ -1663,6 +1795,7 @@ struct atomic<_Tp*> : public __atomic_base<_Tp*> { typedef __atomic_base<_Tp*> __base; + typedef _Tp* value_type; _LIBCPP_INLINE_VISIBILITY atomic() _NOEXCEPT _LIBCPP_DEFAULT _LIBCPP_INLINE_VISIBILITY @@ -1947,6 +2080,76 @@ atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, return __o->compare_exchange_strong(*__e, __d, __s, __f); } +// atomic_wait + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_wait(const volatile atomic<_Tp>* __o, + typename atomic<_Tp>::value_type __v) _NOEXCEPT +{ + return __o->wait(__v); +} + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_wait(const atomic<_Tp>* __o, + typename atomic<_Tp>::value_type __v) _NOEXCEPT +{ + return __o->wait(__v); +} + +// atomic_wait_explicit + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_wait_explicit(const volatile atomic<_Tp>* __o, + typename atomic<_Tp>::value_type __v, + memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) +{ + return __o->wait(__v, __m); +} + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_wait_explicit(const atomic<_Tp>* __o, + typename atomic<_Tp>::value_type __v, + memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) +{ + return __o->wait(__v, __m); +} + +// atomic_notify_one + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT +{ + __o->notify_one(); +} +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT +{ + __o->notify_one(); +} + +// atomic_notify_one + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT +{ + __o->notify_all(); +} +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT +{ + __o->notify_all(); +} + // atomic_fetch_add template @@ -2279,6 +2482,13 @@ typedef struct atomic_flag { __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; + _LIBCPP_INLINE_VISIBILITY + bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} + _LIBCPP_INLINE_VISIBILITY + bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT + {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} + _LIBCPP_INLINE_VISIBILITY bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} @@ -2292,6 +2502,25 @@ typedef struct atomic_flag void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT + {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void notify_one() volatile _NOEXCEPT + {__cxx_atomic_notify_one(&__a_);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void notify_one() _NOEXCEPT + {__cxx_atomic_notify_one(&__a_);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void notify_all() volatile _NOEXCEPT + {__cxx_atomic_notify_all(&__a_);} + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void notify_all() _NOEXCEPT + {__cxx_atomic_notify_all(&__a_);} + _LIBCPP_INLINE_VISIBILITY atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT @@ -2304,12 +2533,44 @@ typedef struct atomic_flag atomic_flag& operator=(const atomic_flag&) volatile = delete; #else private: + _LIBCPP_INLINE_VISIBILITY atomic_flag(const atomic_flag&); + _LIBCPP_INLINE_VISIBILITY atomic_flag& operator=(const atomic_flag&); + _LIBCPP_INLINE_VISIBILITY atomic_flag& operator=(const atomic_flag&) volatile; #endif } atomic_flag; + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT +{ + return __o->test(); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test(const atomic_flag* __o) _NOEXCEPT +{ + return __o->test(); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT +{ + return __o->test(__m); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool +atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT +{ + return __o->test(__m); +} + inline _LIBCPP_INLINE_VISIBILITY bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT @@ -2366,6 +2627,64 @@ atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT __o->clear(__m); } +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT +{ + __o->wait(__v); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT +{ + __o->wait(__v); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_wait_explicit(const volatile atomic_flag* __o, + bool __v, memory_order __m) _NOEXCEPT +{ + __o->wait(__v, __m); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_wait_explicit(const atomic_flag* __o, + bool __v, memory_order __m) _NOEXCEPT +{ + __o->wait(__v, __m); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT +{ + __o->notify_one(); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT +{ + __o->notify_one(); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT +{ + __o->notify_all(); +} + +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC +void +atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT +{ + __o->notify_all(); +} + // fences inline _LIBCPP_INLINE_VISIBILITY @@ -2434,6 +2753,33 @@ typedef atomic atomic_ptrdiff_t; typedef atomic atomic_intmax_t; typedef atomic atomic_uintmax_t; +// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type + +#ifdef __cpp_lib_atomic_is_always_lock_free +# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0) +#else +# define _LIBCPP_CONTENTION_LOCK_FREE false +#endif + +#if ATOMIC_LLONG_LOCK_FREE == 2 +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free; +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free; +#elif ATOMIC_INT_LOCK_FREE == 2 +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free; +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free; +#elif ATOMIC_SHORT_LOCK_FREE == 2 +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free; +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free; +#elif ATOMIC_CHAR_LOCK_FREE == 2 +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free; +typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free; +#else + // No signed/unsigned lock-free types +#endif + +typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free; +typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free; + #define ATOMIC_FLAG_INIT {false} #define ATOMIC_VAR_INIT(__v) {__v} diff --git a/libcxx/include/barrier b/libcxx/include/barrier new file mode 100644 index 000000000000..58e3eef9cfe5 --- /dev/null +++ b/libcxx/include/barrier @@ -0,0 +1,322 @@ +// -*- C++ -*- +//===--------------------------- barrier ----------------------------------===// +// +// 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_BARRIER +#define _LIBCPP_BARRIER + +/* + barrier synopsis + +namespace std +{ + + template + class barrier + { + public: + using arrival_token = see below; + + constexpr explicit barrier(ptrdiff_t phase_count, + CompletionFunction f = CompletionFunction()); + ~barrier(); + + barrier(const barrier&) = delete; + barrier& operator=(const barrier&) = delete; + + [[nodiscard]] arrival_token arrive(ptrdiff_t update = 1); + void wait(arrival_token&& arrival) const; + + void arrive_and_wait(); + void arrive_and_drop(); + + private: + CompletionFunction completion; // exposition only + }; + +} + +*/ + +#include <__config> +#include +#ifndef _LIBCPP_HAS_NO_TREE_BARRIER +# include +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +# error is not supported on this single threaded system +#endif + +#if _LIBCPP_STD_VER >= 14 + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct __empty_completion +{ + inline _LIBCPP_INLINE_VISIBILITY + void operator()() noexcept + { + } +}; + +#ifndef _LIBCPP_HAS_NO_TREE_BARRIER + +/* + +The default implementation of __barrier_base is a classic tree barrier. + +It looks different from literature pseudocode for two main reasons: + 1. Threads that call into std::barrier functions do not provide indices, + so a numbering step is added before the actual barrier algorithm, + appearing as an N+1 round to the N rounds of the tree barrier. + 2. A great deal of attention has been paid to avoid cache line thrashing + by flattening the tree structure into cache-line sized arrays, that + are indexed in an efficient way. + +*/ + +using __barrier_phase_t = uint8_t; + +class __barrier_algorithm_base; + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI +__barrier_algorithm_base* __construct_barrier_algorithm_base(ptrdiff_t& __expected); + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI +bool __arrive_barrier_algorithm_base(__barrier_algorithm_base* __barrier, + __barrier_phase_t __old_phase); + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI +void __destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier); + +template +class __barrier_base { + + ptrdiff_t __expected; + unique_ptr<__barrier_algorithm_base, + void (*)(__barrier_algorithm_base*)> __base; + __atomic_base __expected_adjustment; + _CompletionF __completion; + __atomic_base<__barrier_phase_t> __phase; + +public: + using arrival_token = __barrier_phase_t; + + static constexpr ptrdiff_t max() noexcept { + return numeric_limits::max(); + } + + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + __barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF()) + : __expected(__expected), __base(__construct_barrier_algorithm_base(this->__expected), + &__destroy_barrier_algorithm_base), + __expected_adjustment(0), __completion(move(__completion)), __phase(0) + { + } + [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + arrival_token arrive(ptrdiff_t update) + { + auto const __old_phase = __phase.load(memory_order_relaxed); + for(; update; --update) + if(__arrive_barrier_algorithm_base(__base.get(), __old_phase)) { + __completion(); + __expected += __expected_adjustment.load(memory_order_relaxed); + __expected_adjustment.store(0, memory_order_relaxed); + __phase.store(__old_phase + 2, memory_order_release); + __phase.notify_all(); + } + return __old_phase; + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait(arrival_token&& __old_phase) const + { + auto const __test_fn = [=]() -> bool { + return __phase.load(memory_order_acquire) != __old_phase; + }; + __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy()); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void arrive_and_drop() + { + __expected_adjustment.fetch_sub(1, memory_order_relaxed); + (void)arrive(1); + } +}; + +#else + +/* + +The alternative implementation of __barrier_base is a central barrier. + +Two versions of this algorithm are provided: + 1. A fairly straightforward implementation of the litterature for the + general case where the completion function is not empty. + 2. An optimized implementation that exploits 2's complement arithmetic + and well-defined overflow in atomic arithmetic, to handle the phase + roll-over for free. + +*/ + +template +class __barrier_base { + + __atomic_base __expected; + __atomic_base __arrived; + _CompletionF __completion; + __atomic_base __phase; +public: + using arrival_token = bool; + + static constexpr ptrdiff_t max() noexcept { + return numeric_limits::max(); + } + + _LIBCPP_INLINE_VISIBILITY + __barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF()) + : __expected(__expected), __arrived(__expected), __completion(move(__completion)), __phase(false) + { + } + [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + arrival_token arrive(ptrdiff_t update) + { + auto const __old_phase = __phase.load(memory_order_relaxed); + auto const __result = __arrived.fetch_sub(update, memory_order_acq_rel) - update; + auto const new_expected = __expected.load(memory_order_relaxed); + if(0 == __result) { + __completion(); + __arrived.store(new_expected, memory_order_relaxed); + __phase.store(!__old_phase, memory_order_release); + __phase.notify_all(); + } + return __old_phase; + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait(arrival_token&& __old_phase) const + { + __phase.wait(__old_phase, memory_order_acquire); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void arrive_and_drop() + { + __expected.fetch_sub(1, memory_order_relaxed); + (void)arrive(1); + } +}; + +template<> +class __barrier_base<__empty_completion> { + + static constexpr uint64_t __expected_unit = 1ull; + static constexpr uint64_t __arrived_unit = 1ull << 32; + static constexpr uint64_t __expected_mask = __arrived_unit - 1; + static constexpr uint64_t __phase_bit = 1ull << 63; + static constexpr uint64_t __arrived_mask = (__phase_bit - 1) & ~__expected_mask; + + __atomic_base __phase_arrived_expected; + + static _LIBCPP_INLINE_VISIBILITY + constexpr uint64_t __init(ptrdiff_t __count) _NOEXCEPT + { + return ((uint64_t(1u << 31) - __count) << 32) + | (uint64_t(1u << 31) - __count); + } + +public: + using arrival_token = uint64_t; + + static constexpr ptrdiff_t max() noexcept { + return ptrdiff_t(1u << 31) - 1; + } + + _LIBCPP_INLINE_VISIBILITY + explicit inline __barrier_base(ptrdiff_t __count, __empty_completion = __empty_completion()) + : __phase_arrived_expected(__init(__count)) + { + } + [[nodiscard]] inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + arrival_token arrive(ptrdiff_t update) + { + auto const __inc = __arrived_unit * update; + auto const __old = __phase_arrived_expected.fetch_add(__inc, memory_order_acq_rel); + if((__old ^ (__old + __inc)) & __phase_bit) { + __phase_arrived_expected.fetch_add((__old & __expected_mask) << 32, memory_order_relaxed); + __phase_arrived_expected.notify_all(); + } + return __old & __phase_bit; + } + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait(arrival_token&& __phase) const + { + auto const __test_fn = [=]() -> bool { + uint64_t const __current = __phase_arrived_expected.load(memory_order_acquire); + return ((__current & __phase_bit) != __phase); + }; + __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy()); + } + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void arrive_and_drop() + { + __phase_arrived_expected.fetch_add(__expected_unit, memory_order_relaxed); + (void)arrive(1); + } +}; + +#endif //_LIBCPP_HAS_NO_TREE_BARRIER + +template +class barrier { + + __barrier_base<_CompletionF> __b; +public: + using arrival_token = typename __barrier_base<_CompletionF>::arrival_token; + + static constexpr ptrdiff_t max() noexcept { + return __barrier_base<_CompletionF>::max(); + } + + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF()) + : __b(__count, std::move(__completion)) { + } + + barrier(barrier const&) = delete; + barrier& operator=(barrier const&) = delete; + + [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + arrival_token arrive(ptrdiff_t update = 1) + { + return __b.arrive(update); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait(arrival_token&& __phase) const + { + __b.wait(std::move(__phase)); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void arrive_and_wait() + { + wait(arrive()); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void arrive_and_drop() + { + __b.arrive_and_drop(); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 14 + +#endif //_LIBCPP_BARRIER diff --git a/libcxx/include/bit b/libcxx/include/bit index 6dc85b5d01fb..ae4605b19166 100644 --- a/libcxx/include/bit +++ b/libcxx/include/bit @@ -15,6 +15,7 @@ namespace std { + // [bit.pow.two], integral powers of 2 template constexpr bool ispow2(T x) noexcept; // C++20 template @@ -24,13 +25,13 @@ namespace std { template constexpr T log2p1(T x) noexcept; // C++20 - // 23.20.2, rotating + // [bit.rotate], rotating template constexpr T rotl(T x, unsigned int s) noexcept; // C++20 template constexpr T rotr(T x, unsigned int s) noexcept; // C++20 - // 23.20.3, counting + // [bit.count], counting template constexpr int countl_zero(T x) noexcept; // C++20 template @@ -42,7 +43,7 @@ namespace std { template constexpr int popcount(T x) noexcept; // C++20 - // 20.15.9, endian + // [bit.endian], endian enum class endian { little = see below, // C++20 big = see below, // C++20 @@ -350,7 +351,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool __ispow2(_Tp __t) _NOEXCEPT { static_assert(__bitop_unsigned_integer<_Tp>::value, "__ispow2 requires unsigned"); - return __t != 0 && (((__t & (__t - 1)) == 0)); + return __t != 0 && (((__t & (__t - 1)) == 0)); } diff --git a/libcxx/include/charconv b/libcxx/include/charconv index a644fe094846..b64000242a7e 100644 --- a/libcxx/include/charconv +++ b/libcxx/include/charconv @@ -73,6 +73,7 @@ namespace std { */ +#include <__config> #include <__errc> #include #include @@ -92,8 +93,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD namespace __itoa { -_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); -_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); +_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer) _NOEXCEPT; +_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer) _NOEXCEPT; } #ifndef _LIBCPP_CXX03_LANG @@ -167,6 +168,7 @@ struct _LIBCPP_HIDDEN __traits_base } #endif + _LIBCPP_AVAILABILITY_TO_CHARS static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) { return __u64toa(__v, __p); @@ -189,6 +191,7 @@ struct _LIBCPP_HIDDEN } #endif + _LIBCPP_AVAILABILITY_TO_CHARS static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p) { return __u32toa(__v, __p); @@ -292,6 +295,7 @@ __to_unsigned(_Tp __x) } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) { @@ -306,6 +310,7 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) { @@ -337,6 +342,7 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) @@ -352,6 +358,7 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, } template +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) @@ -380,6 +387,7 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, } template ::value, int>::type = 0> +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result to_chars(char* __first, char* __last, _Tp __value) { @@ -387,6 +395,7 @@ to_chars(char* __first, char* __last, _Tp __value) } template ::value, int>::type = 0> +_LIBCPP_AVAILABILITY_TO_CHARS inline _LIBCPP_INLINE_VISIBILITY to_chars_result to_chars(char* __first, char* __last, _Tp __value, int __base) { diff --git a/libcxx/include/chrono b/libcxx/include/chrono index 6e5de398b72f..117aab31907f 100644 --- a/libcxx/include/chrono +++ b/libcxx/include/chrono @@ -2454,7 +2454,7 @@ chrono::day year_month_day_last::day() const noexcept chrono::day(31), chrono::day(31), chrono::day(30), chrono::day(31), chrono::day(30), chrono::day(31) }; - return month() != February || !__y.is_leap() ? + return (month() != February || !__y.is_leap()) && month().ok() ? __d[static_cast(month()) - 1] : chrono::day{29}; } diff --git a/libcxx/include/cmath b/libcxx/include/cmath index 0f06486fb34f..0901a23a2498 100644 --- a/libcxx/include/cmath +++ b/libcxx/include/cmath @@ -296,6 +296,10 @@ floating_point trunc (arithmetic x); float truncf(float x); long double truncl(long double x); +constexpr float lerp(float a, float b, float t) noexcept; // C++20 +constexpr double lerp(double a, double b, double t) noexcept; // C++20 +constexpr long double lerp(long double a, long double b, long double t) noexcept; // C++20 + } // std */ diff --git a/libcxx/include/codecvt b/libcxx/include/codecvt index 5ea411ea781b..05fa765c3180 100644 --- a/libcxx/include/codecvt +++ b/libcxx/include/codecvt @@ -102,11 +102,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -137,11 +137,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -172,11 +172,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template @@ -260,11 +260,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -295,11 +295,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -330,11 +330,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -365,11 +365,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -400,11 +400,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template @@ -488,11 +488,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template <> @@ -523,11 +523,11 @@ protected: virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; - virtual int do_encoding() const throw(); - virtual bool do_always_noconv() const throw(); + virtual int do_encoding() const _NOEXCEPT; + virtual bool do_always_noconv() const _NOEXCEPT; virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; - virtual int do_max_length() const throw(); + virtual int do_max_length() const _NOEXCEPT; }; template constexpr partial_ordering partial_order(const T& a, const T& b); template constexpr strong_equality strong_equal(const T& a, const T& b); template constexpr weak_equality weak_equal(const T& a, const T& b); + + // [cmp.partialord], Class partial_ordering + class partial_ordering { + public: + // valid values + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; + + // comparisons + friend constexpr bool operator==(partial_ordering v, unspecified) noexcept; + friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default; + friend constexpr bool operator< (partial_ordering v, unspecified) noexcept; + friend constexpr bool operator> (partial_ordering v, unspecified) noexcept; + friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept; + friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept; + friend constexpr bool operator< (unspecified, partial_ordering v) noexcept; + friend constexpr bool operator> (unspecified, partial_ordering v) noexcept; + friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept; + friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept; + friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept; + friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept; + }; + + // [cmp.weakord], Class weak_ordering + class weak_ordering { + public: + // valid values + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + // conversions + constexpr operator partial_ordering() const noexcept; + + // comparisons + friend constexpr bool operator==(weak_ordering v, unspecified) noexcept; + friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default; + friend constexpr bool operator< (weak_ordering v, unspecified) noexcept; + friend constexpr bool operator> (weak_ordering v, unspecified) noexcept; + friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept; + friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept; + friend constexpr bool operator< (unspecified, weak_ordering v) noexcept; + friend constexpr bool operator> (unspecified, weak_ordering v) noexcept; + friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept; + friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept; + friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept; + friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept; + }; + + // [cmp.strongord], Class strong_ordering + class strong_ordering { + public: + // valid values + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; + + // conversions + constexpr operator partial_ordering() const noexcept; + constexpr operator weak_ordering() const noexcept; + + // comparisons + friend constexpr bool operator==(strong_ordering v, unspecified) noexcept; + friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default; + friend constexpr bool operator< (strong_ordering v, unspecified) noexcept; + friend constexpr bool operator> (strong_ordering v, unspecified) noexcept; + friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept; + friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept; + friend constexpr bool operator< (unspecified, strong_ordering v) noexcept; + friend constexpr bool operator> (unspecified, strong_ordering v) noexcept; + friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept; + friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept; + friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept; + friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept; + }; } */ @@ -248,6 +326,8 @@ public: _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept; #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept; _LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept; #endif @@ -364,6 +444,8 @@ public: _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept; #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept; _LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept; #endif @@ -490,6 +572,8 @@ public: _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept; #ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + _LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept; _LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept; #endif diff --git a/libcxx/include/complex b/libcxx/include/complex index c168406befbd..36c66db50e68 100644 --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -243,6 +243,7 @@ template #include #include #include +#include #include #include @@ -1406,10 +1407,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) __x = complex<_Tp>(__r, __i); } else - __is.setstate(ios_base::failbit); + __is.setstate(__is.failbit); } else - __is.setstate(ios_base::failbit); + __is.setstate(__is.failbit); } else if (__c == _CharT(')')) { @@ -1417,10 +1418,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) __x = complex<_Tp>(__r, _Tp(0)); } else - __is.setstate(ios_base::failbit); + __is.setstate(__is.failbit); } else - __is.setstate(ios_base::failbit); + __is.setstate(__is.failbit); } else { @@ -1429,11 +1430,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) if (!__is.fail()) __x = complex<_Tp>(__r, _Tp(0)); else - __is.setstate(ios_base::failbit); + __is.setstate(__is.failbit); } } else - __is.setstate(ios_base::failbit); + __is.setstate(__is.failbit); return __is; } diff --git a/libcxx/include/concepts b/libcxx/include/concepts new file mode 100644 index 000000000000..047e2c290f4e --- /dev/null +++ b/libcxx/include/concepts @@ -0,0 +1,166 @@ +// -*- C++ -*- +//===-------------------------- concepts ----------------------------------===// +// +// 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_CONCEPTS +#define _LIBCPP_CONCEPTS + +/* + concepts synopsis +namespace std { + // [concepts.lang], language-related concepts + // [concept.same], concept same_as + template + concept same_as = see below; + + // [concept.derived], concept derived_from + template + concept derived_from = see below; + + // [concept.convertible], concept convertible_to + template + concept convertible_to = see below; + + // [concept.commonref], concept common_reference_with + template + concept common_reference_with = see below; + + // [concept.common], concept common_with + template + concept common_with = see below; + + // [concepts.arithmetic], arithmetic concepts + template + concept integral = see below; + template + concept signed_integral = see below; + template + concept unsigned_integral = see below; + template + concept floating_point = see below; + + // [concept.assignable], concept assignable_from + template + concept assignable_from = see below; + + // [concept.swappable], concept swappable + namespace ranges { + inline namespace unspecified { + inline constexpr unspecified swap = unspecified; + } + } + template + concept swappable = see below; + template + concept swappable_with = see below; + + // [concept.destructible], concept destructible + template + concept destructible = see below; + + // [concept.constructible], concept constructible_from + template + concept constructible_from = see below; + + // [concept.defaultconstructible], concept default_constructible + template + concept default_constructible = see below; + + // [concept.moveconstructible], concept move_constructible + template + concept move_constructible = see below; + + // [concept.copyconstructible], concept copy_constructible + template + concept copy_constructible = see below; + + // [concepts.compare], comparison concepts + // [concept.boolean], concept boolean + template + concept boolean = see below; + + // [concept.equalitycomparable], concept equality_comparable + template + concept equality_comparable = see below; + template + concept equality_comparable_with = see below; + + // [concept.totallyordered], concept totally_ordered + template + concept totally_ordered = see below; + template + concept totally_ordered_with = see below; + + // [concepts.object], object concepts + template + concept movable = see below; + template + concept copyable = see below; + template + concept semiregular = see below; + template + concept regular = see below; + + // [concepts.callable], callable concepts + // [concept.invocable], concept invocable + template + concept invocable = see below; + + // [concept.regularinvocable], concept regular_invocable + template + concept regular_invocable = see below; + + // [concept.predicate], concept predicate + template + concept predicate = see below; + + // [concept.relation], concept relation + template + concept relation = see below; + + // [concept.equiv], concept equivalence_relation + template + concept equivalence_relation = see below; + + // [concept.strictweakorder], concept strict_weak_order + template + concept strict_weak_order = see below; +} + +*/ + +#include <__config> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L + +// [concept.same] + +template +concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value; + +template +concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; + +#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_CONCEPTS diff --git a/libcxx/include/cstddef b/libcxx/include/cstddef index bd62d6db39e8..2a0bfeb6e15f 100644 --- a/libcxx/include/cstddef +++ b/libcxx/include/cstddef @@ -25,7 +25,7 @@ Types: ptrdiff_t size_t - max_align_t + max_align_t // C++11 nullptr_t byte // C++17 @@ -49,12 +49,34 @@ _LIBCPP_BEGIN_NAMESPACE_STD using ::ptrdiff_t; using ::size_t; -#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \ - defined(__DEFINED_max_align_t) || defined(__NetBSD__) -// Re-use the compiler's max_align_t where possible. +#if !defined(_LIBCPP_CXX03_LANG) using ::max_align_t; -#else -typedef long double max_align_t; +#endif + +template struct __libcpp_is_integral { enum { value = 0 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#endif +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +template <> struct __libcpp_is_integral { enum { value = 1 }; }; +#ifndef _LIBCPP_HAS_NO_INT128 +template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; }; +template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; }; #endif _LIBCPP_END_NAMESPACE_STD @@ -64,6 +86,11 @@ namespace std // purposefully not versioned { enum class byte : unsigned char {}; + +template struct __enable_if_integral_imp {}; +template <> struct __enable_if_integral_imp { using type = byte; }; +template using _EnableByteOverload = typename __enable_if_integral_imp<__libcpp_is_integral<_Tp>::value>::type; + constexpr byte operator| (byte __lhs, byte __rhs) noexcept { return static_cast( @@ -104,10 +131,31 @@ constexpr byte operator~ (byte __b) noexcept ~static_cast(__b) )); } - +template + constexpr _EnableByteOverload<_Integer> & + operator<<=(byte& __lhs, _Integer __shift) noexcept + { return __lhs = __lhs << __shift; } + +template + constexpr _EnableByteOverload<_Integer> + operator<< (byte __lhs, _Integer __shift) noexcept + { return static_cast(static_cast(static_cast(__lhs) << __shift)); } + +template + constexpr _EnableByteOverload<_Integer> & + operator>>=(byte& __lhs, _Integer __shift) noexcept + { return __lhs = __lhs >> __shift; } + +template + constexpr _EnableByteOverload<_Integer> + operator>> (byte __lhs, _Integer __shift) noexcept + { return static_cast(static_cast(static_cast(__lhs) >> __shift)); } + +template > + constexpr _Integer + to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); } } -#include // rest of byte #endif #endif // _LIBCPP_CSTDDEF diff --git a/libcxx/include/cstdio b/libcxx/include/cstdio index 0f3f42dac2da..d0492a083505 100644 --- a/libcxx/include/cstdio +++ b/libcxx/include/cstdio @@ -131,9 +131,13 @@ using ::putc; using ::ungetc; using ::fread; using ::fwrite; +#ifndef _LIBCPP_HAS_NO_FGETPOS_FSETPOS using ::fgetpos; +#endif using ::fseek; +#ifndef _LIBCPP_HAS_NO_FGETPOS_FSETPOS using ::fsetpos; +#endif using ::ftell; using ::rewind; using ::clearerr; diff --git a/libcxx/include/deque b/libcxx/include/deque index 115b1b642701..c2ea5f2dbe6d 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -150,9 +150,11 @@ template noexcept(noexcept(x.swap(y))); template - void erase(deque& c, const U& value); // C++20 + typename deque::size_type + erase(deque& c, const U& value); // C++20 template - void erase_if(deque& c, Predicate pred); // C++20 + typename deque::size_type + erase_if(deque& c, Predicate pred); // C++20 } // std @@ -3021,14 +3023,20 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) #if _LIBCPP_STD_VER > 17 template -inline _LIBCPP_INLINE_VISIBILITY -void erase(deque<_Tp, _Allocator>& __c, const _Up& __v) -{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); } +inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type +erase(deque<_Tp, _Allocator>& __c, const _Up& __v) { + auto __old_size = __c.size(); + __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); + return __old_size - __c.size(); +} template -inline _LIBCPP_INLINE_VISIBILITY -void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) -{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); } +inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type +erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) { + auto __old_size = __c.size(); + __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); + return __old_size - __c.size(); +} #endif diff --git a/libcxx/include/exception b/libcxx/include/exception index c7dcac2b2b33..8e32979f5749 100644 --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -98,6 +98,8 @@ class _LIBCPP_EXCEPTION_ABI exception { public: _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default; + virtual ~exception() _NOEXCEPT; virtual const char* what() const _NOEXCEPT; }; diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem index 0f7a4d556988..1363b630271a 100644 --- a/libcxx/include/filesystem +++ b/libcxx/include/filesystem @@ -1346,6 +1346,7 @@ public: _LIBCPP_INLINE_VISIBILITY const path& path2() const noexcept { return __storage_->__p2_; } + filesystem_error(const filesystem_error&) = default; ~filesystem_error() override; // key function _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list index 3905745931fd..3bd8db8b7d4d 100644 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -169,9 +169,11 @@ template noexcept(noexcept(x.swap(y))); template - void erase(forward_list& c, const U& value); // C++20 + typename forward_list::size_type + erase(forward_list& c, const U& value); // C++20 template - void erase_if(forward_list& c, Predicate pred); // C++20 + typename forward_list::size_type + erase_if(forward_list& c, Predicate pred); // C++20 } // std @@ -1765,13 +1767,17 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) #if _LIBCPP_STD_VER > 17 template inline _LIBCPP_INLINE_VISIBILITY -void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) -{ __c.remove_if(__pred); } + typename forward_list<_Tp, _Allocator>::size_type + erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) { + return __c.remove_if(__pred); +} template inline _LIBCPP_INLINE_VISIBILITY -void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) -{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } + typename forward_list<_Tp, _Allocator>::size_type + erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) { + return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); +} #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/functional b/libcxx/include/functional index 865a28123b97..3e9425320fc3 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -508,6 +508,10 @@ POLICY: For non-variadic implementations, the number of arguments is limited #include <__functional_base> +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) +#include +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -1434,7 +1438,14 @@ void __throw_bad_function_call() #endif } -template class _LIBCPP_TEMPLATE_VIS function; // undefined +#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated) +# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \ + __attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type"))) +#else +# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */ +#endif + +template class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined namespace __function { @@ -1477,6 +1488,12 @@ template _LIBCPP_INLINE_VISIBILITY bool __not_null(function<_Fp> const& __f) { return !!__f; } +#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Rp (^__p)(_Args...)) { return __p; } +#endif + } // namespace __function #ifndef _LIBCPP_CXX03_LANG @@ -1611,7 +1628,7 @@ public: // __base provides an abstract interface for copyable functors. -template class __base; +template class _LIBCPP_TEMPLATE_VIS __base; template class __base<_Rp(_ArgTypes...)> @@ -2238,6 +2255,72 @@ template class __policy_func<_Rp(_ArgTypes...)> #endif // _LIBCPP_NO_RTTI }; +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) + +template +class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> +{ + typedef _Rp1(^__block_type)(_ArgTypes1...); + __block_type __f_; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type const& __f) + : __f_(__f ? Block_copy(__f) : (__block_type)0) + { } + + // [TODO] add && to save on a retain + + _LIBCPP_INLINE_VISIBILITY + explicit __func(__block_type __f, const _Alloc& /* unused */) + : __f_(__f ? Block_copy(__f) : (__block_type)0) + { } + + virtual __base<_Rp(_ArgTypes...)>* __clone() const { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + return nullptr; + } + + virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new (__p) __func(__f_); + } + + virtual void destroy() _NOEXCEPT { + if (__f_) + Block_release(__f_); + __f_ = 0; + } + + virtual void destroy_deallocate() _NOEXCEPT { + _LIBCPP_ASSERT(false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + } + + virtual _Rp operator()(_ArgTypes&& ... __arg) { + return __invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + } + +#ifndef _LIBCPP_NO_RTTI + virtual const void* target(type_info const& __ti) const _NOEXCEPT { + if (__ti == typeid(__func::__block_type)) + return &__f_; + return (const void*)nullptr; + } + + virtual const std::type_info& target_type() const _NOEXCEPT { + return typeid(__func::__block_type); + } +#endif // _LIBCPP_NO_RTTI +}; + +#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC + } // __function template @@ -2255,14 +2338,14 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> template , function>, - __invokable<_Fp&, _ArgTypes...> + __invokable<_Fp, _ArgTypes...> >::value> struct __callable; template struct __callable<_Fp, true> { static const bool value = is_same::value || - is_convertible::type, + is_convertible::type, _Rp>::value; }; template @@ -2272,7 +2355,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> }; template - using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type; + using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; public: typedef _Rp result_type; @@ -2283,7 +2366,7 @@ public: function(nullptr_t) _NOEXCEPT {} function(const function&); function(function&&) _NOEXCEPT; - template> + template> function(_Fp); #if _LIBCPP_STD_VER <= 14 @@ -2297,14 +2380,14 @@ public: function(allocator_arg_t, const _Alloc&, const function&); template function(allocator_arg_t, const _Alloc&, function&&); - template> + template> function(allocator_arg_t, const _Alloc& __a, _Fp __f); #endif function& operator=(const function&); function& operator=(function&&) _NOEXCEPT; function& operator=(nullptr_t) _NOEXCEPT; - template> + template::type>> function& operator=(_Fp&&); ~function(); @@ -2967,14 +3050,14 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2) - return make_pair(__first1, __first1); // Everything matches an empty sequence + return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks while (true) { if (__first1 == __last1) // return __last1 if no element matches *__first2 - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -2985,9 +3068,9 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, while (true) { if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return make_pair(__first1, __m1); + return _VSTD::make_pair(__first1, __m1); if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 { ++__first1; @@ -3009,10 +3092,10 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern const _D2 __len2 = __last2 - __first2; if (__len2 == 0) - return make_pair(__first1, __first1); + return _VSTD::make_pair(__first1, __first1); const _D1 __len1 = __last1 - __first1; if (__len1 < __len2) - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here while (true) @@ -3020,7 +3103,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (__first1 == __s) - return make_pair(__last1, __last1); + return _VSTD::make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -3031,7 +3114,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (++__m2 == __last2) - return make_pair(__first1, __first1 + __len2); + return _VSTD::make_pair(__first1, __first1 + __len2); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source if (!__pred(*__m1, *__m2)) { @@ -3080,15 +3163,19 @@ using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; #endif // > C++17 template -inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred) -{ - for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;) - { - if (__pred(*__iter)) - __iter = __c.erase(__iter); - else - ++__iter; - } +inline typename _Container::size_type +__libcpp_erase_if_container(_Container& __c, _Predicate __pred) { + typename _Container::size_type __old_size = __c.size(); + + const typename _Container::iterator __last = __c.end(); + for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) { + if (__pred(*__iter)) + __iter = __c.erase(__iter); + else + ++__iter; + } + + return __old_size - __c.size(); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/future b/libcxx/include/future index 751d122a6000..bdf74e3055c0 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -506,6 +506,7 @@ public: _LIBCPP_INLINE_VISIBILITY const error_code& code() const _NOEXCEPT {return __ec_;} + future_error(const future_error&) _NOEXCEPT = default; virtual ~future_error() _NOEXCEPT; }; diff --git a/libcxx/include/ios b/libcxx/include/ios index 88efefb46ff2..7f0e2d65e640 100644 --- a/libcxx/include/ios +++ b/libcxx/include/ios @@ -431,7 +431,8 @@ class _LIBCPP_EXCEPTION_ABI ios_base::failure public: explicit failure(const string& __msg, const error_code& __ec = io_errc::stream); explicit failure(const char* __msg, const error_code& __ec = io_errc::stream); - virtual ~failure() throw(); + failure(const failure&) _NOEXCEPT = default; + virtual ~failure() _NOEXCEPT; }; _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY @@ -842,7 +843,7 @@ basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf* _ ios_base::set_rdbuf(__sb); } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& boolalpha(ios_base& __str) { @@ -850,7 +851,7 @@ boolalpha(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& noboolalpha(ios_base& __str) { @@ -858,7 +859,7 @@ noboolalpha(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& showbase(ios_base& __str) { @@ -866,7 +867,7 @@ showbase(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& noshowbase(ios_base& __str) { @@ -874,7 +875,7 @@ noshowbase(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& showpoint(ios_base& __str) { @@ -882,7 +883,7 @@ showpoint(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& noshowpoint(ios_base& __str) { @@ -890,7 +891,7 @@ noshowpoint(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& showpos(ios_base& __str) { @@ -898,7 +899,7 @@ showpos(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& noshowpos(ios_base& __str) { @@ -906,7 +907,7 @@ noshowpos(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& skipws(ios_base& __str) { @@ -914,7 +915,7 @@ skipws(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& noskipws(ios_base& __str) { @@ -922,7 +923,7 @@ noskipws(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& uppercase(ios_base& __str) { @@ -930,7 +931,7 @@ uppercase(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& nouppercase(ios_base& __str) { @@ -938,7 +939,7 @@ nouppercase(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& unitbuf(ios_base& __str) { @@ -946,7 +947,7 @@ unitbuf(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& nounitbuf(ios_base& __str) { @@ -954,7 +955,7 @@ nounitbuf(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& internal(ios_base& __str) { @@ -962,7 +963,7 @@ internal(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& left(ios_base& __str) { @@ -970,7 +971,7 @@ left(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& right(ios_base& __str) { @@ -978,7 +979,7 @@ right(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& dec(ios_base& __str) { @@ -986,7 +987,7 @@ dec(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& hex(ios_base& __str) { @@ -994,7 +995,7 @@ hex(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& oct(ios_base& __str) { @@ -1002,7 +1003,7 @@ oct(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& fixed(ios_base& __str) { @@ -1010,7 +1011,7 @@ fixed(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& scientific(ios_base& __str) { @@ -1018,7 +1019,7 @@ scientific(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& hexfloat(ios_base& __str) { @@ -1026,7 +1027,7 @@ hexfloat(ios_base& __str) return __str; } -inline _LIBCPP_INLINE_VISIBILITY +inline ios_base& defaultfloat(ios_base& __str) { diff --git a/libcxx/include/iterator b/libcxx/include/iterator index 57dd055b4ac9..a13214fca5e4 100644 --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -54,10 +54,8 @@ struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; // 27.4.3, iterator operations -// extension: second argument not conforming to C++03 -template // constexpr in C++17 - constexpr void advance(InputIterator& i, - typename iterator_traits::difference_type n); +template // constexpr in C++17 + constexpr void advance(InputIterator& i, Distance n); template // constexpr in C++17 constexpr typename iterator_traits::difference_type @@ -663,13 +661,14 @@ void __advance(_RandIter& __i, __i += __n; } -template +template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -void advance(_InputIter& __i, - typename iterator_traits<_InputIter>::difference_type __n) +void advance(_InputIter& __i, _Distance __orig_n) { - _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, - "Attempt to advance(it, -n) on a non-bidi iterator"); + _LIBCPP_ASSERT(__orig_n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, + "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); + typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; __advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); } @@ -711,7 +710,7 @@ next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, - "Attempt to next(it, -n) on a non-bidi iterator"); + "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); _VSTD::advance(__x, __n); return __x; @@ -728,7 +727,7 @@ prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, - "Attempt to prev(it, +n) on a non-bidi iterator"); + "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); _VSTD::advance(__x, -__n); return __x; } diff --git a/libcxx/include/latch b/libcxx/include/latch new file mode 100644 index 000000000000..f669f5860d34 --- /dev/null +++ b/libcxx/include/latch @@ -0,0 +1,104 @@ +// -*- C++ -*- +//===--------------------------- latch -----------------------------------===// +// +// 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_LATCH +#define _LIBCPP_LATCH + +/* + latch synopsis + +namespace std +{ + + class latch + { + public: + constexpr explicit latch(ptrdiff_t __expected); + ~latch(); + + latch(const latch&) = delete; + latch& operator=(const latch&) = delete; + + void count_down(ptrdiff_t __update = 1); + bool try_wait() const noexcept; + void wait() const; + void arrive_and_wait(ptrdiff_t __update = 1); + + private: + ptrdiff_t __counter; // exposition only + }; + +} + +*/ + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +# error is not supported on this single threaded system +#endif + +#if _LIBCPP_STD_VER >= 14 + +_LIBCPP_BEGIN_NAMESPACE_STD + +class latch +{ + __atomic_base __a; + +public: + static constexpr ptrdiff_t max() noexcept { + return numeric_limits::max(); + } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr explicit latch(ptrdiff_t __expected) : __a(__expected) { } + + ~latch() = default; + latch(const latch&) = delete; + latch& operator=(const latch&) = delete; + + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void count_down(ptrdiff_t __update = 1) + { + auto const __old = __a.fetch_sub(__update, memory_order_release); + if(__old == __update) + __a.notify_all(); + } + inline _LIBCPP_INLINE_VISIBILITY + bool try_wait() const noexcept + { + return 0 == __a.load(memory_order_acquire); + } + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void wait() const + { + auto const __test_fn = [=]() -> bool { + return try_wait(); + }; + __cxx_atomic_wait(&__a.__a_, __test_fn); + } + inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY + void arrive_and_wait(ptrdiff_t __update = 1) + { + count_down(__update); + wait(); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 14 + +#endif //_LIBCPP_LATCH diff --git a/libcxx/include/list b/libcxx/include/list index ae318ead31da..55b45f1a67d4 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -170,9 +170,11 @@ template noexcept(noexcept(x.swap(y))); template - void erase(list& c, const U& value); // C++20 + typename list::size_type + erase(list& c, const U& value); // C++20 template - void erase_if(list& c, Predicate pred); // C++20 + typename list::size_type + erase_if(list& c, Predicate pred); // C++20 } // std @@ -2471,14 +2473,16 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) #if _LIBCPP_STD_VER > 17 template -inline _LIBCPP_INLINE_VISIBILITY -void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) -{ __c.remove_if(__pred); } +inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type +erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) { + return __c.remove_if(__pred); +} template -inline _LIBCPP_INLINE_VISIBILITY -void erase(list<_Tp, _Allocator>& __c, const _Up& __v) -{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } +inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type +erase(list<_Tp, _Allocator>& __c, const _Up& __v) { + return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); +} #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/map b/libcxx/include/map index b6f89bf5ee54..d2b82591368b 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -254,7 +254,8 @@ swap(map& x, map& y) noexcept(noexcept(x.swap(y))); template - void erase_if(map& c, Predicate pred); // C++20 +typename map::size_type +erase_if(map& c, Predicate pred); // C++20 template , @@ -469,7 +470,8 @@ swap(multimap& x, noexcept(noexcept(x.swap(y))); template - void erase_if(multimap& c, Predicate pred); // C++20 +typename multimap::size_type +erase_if(multimap& c, Predicate pred); // C++20 } // std @@ -1653,10 +1655,13 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x, } #if _LIBCPP_STD_VER > 17 -template +template inline _LIBCPP_INLINE_VISIBILITY -void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } + typename map<_Key, _Tp, _Compare, _Allocator>::size_type + erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) { + return __libcpp_erase_if_container(__c, __pred); +} #endif @@ -2235,10 +2240,14 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, } #if _LIBCPP_STD_VER > 17 -template +template inline _LIBCPP_INLINE_VISIBILITY -void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } + typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type + erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, + _Predicate __pred) { + return __libcpp_erase_if_container(__c, __pred); +} #endif _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/math.h b/libcxx/include/math.h index c9b4733e9c44..1603d5748e2d 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -297,9 +297,6 @@ long double truncl(long double x); #pragma GCC system_header #endif -#define _LIBCPP_STDLIB_INCLUDE_NEXT -#include - #include_next #ifdef __cplusplus @@ -308,6 +305,7 @@ long double truncl(long double x); // back to C++ linkage before including these C++ headers. extern "C++" { +#include #include #include @@ -760,61 +758,12 @@ isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #endif // isunordered // abs - -#undef abs -#undef labs -#ifndef _LIBCPP_HAS_NO_LONG_LONG -#undef llabs -#endif - -// MSVCRT already has the correct prototype in if __cplusplus is defined -#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX) -inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT { - return ::labs(__x); -} -#ifndef _LIBCPP_HAS_NO_LONG_LONG -inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT { - return ::llabs(__x); -} -#endif // _LIBCPP_HAS_NO_LONG_LONG -#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX) - - -#if !(defined(_AIX) || defined(__sun__)) -inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT { - return ::fabsf(__lcpp_x); -} - -inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT { - return ::fabs(__lcpp_x); -} - -inline _LIBCPP_INLINE_VISIBILITY long double -abs(long double __lcpp_x) _NOEXCEPT { - return ::fabsl(__lcpp_x); -} -#endif // !(defined(_AIX) || defined(__sun__)) +// +// handled in stdlib.h // div - -#undef div -#undef ldiv -#ifndef _LIBCPP_HAS_NO_LONG_LONG -#undef lldiv -#endif - -// MSVCRT already has the correct prototype in if __cplusplus is defined -#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX) -inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT { - return ::ldiv(__x, __y); -} -#ifndef _LIBCPP_HAS_NO_LONG_LONG -inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, - long long __y) _NOEXCEPT { - return ::lldiv(__x, __y); -} -#endif // _LIBCPP_HAS_NO_LONG_LONG -#endif // _LIBCPP_MSVCRT / __sun__ / _AIX +// +// handled in stdlib.h // acos diff --git a/libcxx/include/memory b/libcxx/include/memory index 34c3e0c0d8d1..1f9f36c5bbbb 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -80,7 +80,7 @@ struct allocator_traits typedef Alloc::is_always_equal | is_empty is_always_equal; - template using rebind_alloc = Alloc::rebind::other | Alloc; + template using rebind_alloc = Alloc::rebind::other | Alloc; template using rebind_traits = allocator_traits>; static pointer allocate(allocator_type& a, size_type n); // [[nodiscard]] in C++20 @@ -101,7 +101,7 @@ struct allocator_traits }; template <> -class allocator +class allocator // deprecated in C++17, removed in C++20 { public: typedef void* pointer; @@ -115,30 +115,37 @@ template class allocator { public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef typename add_lvalue_reference::type reference; - typedef typename add_lvalue_reference::type const_reference; - typedef T value_type; + typedef size_t size_type; // deprecated in C++17, removed in C++20 + typedef ptrdiff_t difference_type; // deprecated in C++17, removed in C++20 + typedef T* pointer; // deprecated in C++17, removed in C++20 + typedef const T* const_pointer; // deprecated in C++17, removed in C++20 + typedef typename add_lvalue_reference::type + reference; // deprecated in C++17, removed in C++20 + typedef typename add_lvalue_reference::type + const_reference; // deprecated in C++17, removed in C++20 - template struct rebind {typedef allocator other;}; + typedef T value_type; + + template struct rebind {typedef allocator other;}; // deprecated in C++17, removed in C++20 + + typedef true_type propagate_on_container_move_assignment; + typedef true_type is_always_equal; constexpr allocator() noexcept; // constexpr in C++20 constexpr allocator(const allocator&) noexcept; // constexpr in C++20 template constexpr allocator(const allocator&) noexcept; // constexpr in C++20 ~allocator(); - pointer address(reference x) const noexcept; - const_pointer address(const_reference x) const noexcept; - pointer allocate(size_type, allocator::const_pointer hint = 0); - void deallocate(pointer p, size_type n) noexcept; - size_type max_size() const noexcept; + pointer address(reference x) const noexcept; // deprecated in C++17, removed in C++20 + const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20 + T* allocate(size_t n, const void* hint); // deprecated in C++17, removed in C++20 + T* allocate(size_t n); + void deallocate(T* p, size_t n) noexcept; + size_type max_size() const noexcept; // deprecated in C++17, removed in C++20 template - void construct(U* p, Args&&... args); + void construct(U* p, Args&&... args); // deprecated in C++17, removed in C++20 template - void destroy(U* p); + void destroy(U* p); // deprecated in C++17, removed in C++20 }; template @@ -443,6 +450,11 @@ public: template bool owner_before(weak_ptr const& b) const noexcept; }; +template +shared_ptr(weak_ptr) -> shared_ptr; +template +shared_ptr(unique_ptr) -> shared_ptr; + // shared_ptr comparisons: template bool operator==(shared_ptr const& a, shared_ptr const& b) noexcept; @@ -541,6 +553,9 @@ public: template bool owner_before(weak_ptr const& b) const noexcept; }; +template +weak_ptr(shared_ptr) -> weak_ptr; + // weak_ptr specialized algorithms: template void swap(weak_ptr& a, weak_ptr& b) noexcept; @@ -705,8 +720,9 @@ _ValueType __libcpp_acquire_load(_ValueType const* __value) { template class allocator; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) template <> -class _LIBCPP_TEMPLATE_VIS allocator +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator { public: typedef void* pointer; @@ -717,7 +733,7 @@ public: }; template <> -class _LIBCPP_TEMPLATE_VIS allocator +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator { public: typedef const void* pointer; @@ -726,6 +742,7 @@ public: template struct rebind {typedef allocator<_Up> other;}; }; +#endif // pointer_traits @@ -838,7 +855,9 @@ struct __has_rebind private: struct __two {char __lx; char __lxx;}; template static __two __test(...); + _LIBCPP_SUPPRESS_DEPRECATED_PUSH template static char __test(typename _Xp::template rebind<_Up>* = 0); + _LIBCPP_SUPPRESS_DEPRECATED_POP public: static const bool value = sizeof(__test<_Tp>(0)) == 1; }; @@ -1266,7 +1285,9 @@ struct __has_rebind_other private: struct __two {char __lx; char __lxx;}; template static __two __test(...); + _LIBCPP_SUPPRESS_DEPRECATED_PUSH template static char __test(typename _Xp::template rebind<_Up>::other* = 0); + _LIBCPP_SUPPRESS_DEPRECATED_POP public: static const bool value = sizeof(__test<_Tp>(0)) == 1; }; @@ -1280,15 +1301,17 @@ struct __has_rebind_other<_Tp, _Up, false> template ::value> struct __allocator_traits_rebind { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type; + _LIBCPP_SUPPRESS_DEPRECATED_POP }; -#ifndef _LIBCPP_HAS_NO_VARIADICS - template