diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
| commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
| tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /libcxx/include | |
| parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
Notes
Diffstat (limited to 'libcxx/include')
55 files changed, 3748 insertions, 1399 deletions
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<!_IsConst, __bit_iterator, struct __private_nat>; + +    _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(<pthread.h>))  #    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 <class _Tp> @@ -538,7 +538,7 @@ inline _LIBCPP_INLINE_VISIBILITY  reference_wrapper<const _Tp>  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 <string> to improve the +// readability of that header. + +// The extern template ABI lists are kept outside of <string> 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<false>(value_type const*, size_type)) \ +  _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(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 <class _CharT> 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 <pthread.h>  # include <sched.h> +# ifdef __APPLE__ +#  define _LIBCPP_NO_NATIVE_SEMAPHORES +# endif +# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES +# include <semaphore.h> +# endif  #elif defined(_LIBCPP_HAS_THREAD_API_C11)  # include <threads.h>  #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<class _Fn, class _BFn> +_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_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<T>); +    void fill(const T& u);                                      // constexpr in C++20 +    void swap(array& a) noexcept(is_nothrow_swappable_v<T>);    // 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 <class T, class... U> -    array(T, U...) -> array<T, 1 + sizeof...(U)>; +template <class T, class... U> +  array(T, U...) -> array<T, 1 + sizeof...(U)>;                 // C++17  template <class T, size_t N> -  bool operator==(const array<T,N>& x, const array<T,N>& y); +  bool operator==(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20  template <class T, size_t N> -  bool operator!=(const array<T,N>& x, const array<T,N>& y); +  bool operator!=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20  template <class T, size_t N> -  bool operator<(const array<T,N>& x, const array<T,N>& y); +  bool operator<(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20  template <class T, size_t N> -  bool operator>(const array<T,N>& x, const array<T,N>& y); +  bool operator>(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20  template <class T, size_t N> -  bool operator<=(const array<T,N>& x, const array<T,N>& y); +  bool operator<=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20  template <class T, size_t N> -  bool operator>=(const array<T,N>& x, const array<T,N>& y); +  bool operator>=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20  template <class T, size_t N > -  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17 +  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20 + +template <class T, size_t N> +  constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);  // C++20 +template <class T, size_t N> +  constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20  template <class T> struct tuple_size;  template <size_t I, class T> struct tuple_element;  template <class T, size_t N> struct tuple_size<array<T, N>>;  template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>; -template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14 -template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14 -template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14 +template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept;               // constexpr in C++14 +template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept;   // constexpr in C++14 +template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept;             // constexpr in C++14  template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) 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<T, N>"); +        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<T, N>"); +        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 <class _Tp, size_t _Size> -_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 <class _Tp, size_t _Size> -_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 <class _Tp>  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<T, 0>::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<T, 0>::at");        _LIBCPP_UNREACHABLE();      } -    _LIBCPP_INLINE_VISIBILITY +    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11      const_reference at(size_type) const {        __throw_out_of_range("array<T, 0>::at");        _LIBCPP_UNREACHABLE();      } -    _LIBCPP_INLINE_VISIBILITY +    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14      reference front() _NOEXCEPT {        _LIBCPP_ASSERT(false, "cannot call array<T, 0>::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<T, 0>::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<T, 0>::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<T, 0>::back() on a zero-sized array");        _LIBCPP_UNREACHABLE();      } - -    _LIBCPP_INLINE_VISIBILITY -    value_type* data() _NOEXCEPT {return reinterpret_cast<value_type*>(__elems_);} -    _LIBCPP_INLINE_VISIBILITY -    const value_type* data() const _NOEXCEPT {return reinterpret_cast<const value_type*>(__elems_);}  };  #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES  template<class _Tp, class... _Args, -         class = typename enable_if<(is_same_v<_Tp, _Args> && ...), 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 <class _Tp, size_t _Size> -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 <typename _Tp, size_t _Size, size_t... _Index> +_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size> +__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) { +  return {{__arr[_Index]...}}; +} + +template <typename _Tp, size_t _Size, size_t... _Index> +_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size> +__to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) { +  return {{_VSTD::move(__arr[_Index])...}}; +} + +template <typename _Tp, size_t _Size> +_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _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 <typename _Tp, size_t _Size> +_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _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 <class T> 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 <class T>  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<integral>  { +    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<integral>      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>      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 <class T>  struct atomic<T*>  { +    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*>      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*>      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 <class T> -    bool -    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; +  bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; + +template <class T> +  bool atomic_is_lock_free(const atomic<T>* obj) noexcept; + +template <class T> +  void atomic_store(volatile atomic<T>* obj, T desr) noexcept; + +template <class T> +  void atomic_store(atomic<T>* obj, T desr) noexcept; + +template <class T> +  void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; + +template <class T> +  void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; + +template <class T> +  T atomic_load(const volatile atomic<T>* obj) noexcept;  template <class T> -    bool -    atomic_is_lock_free(const atomic<T>* obj) noexcept; +  T atomic_load(const atomic<T>* obj) noexcept;  template <class T> -    void -    atomic_init(volatile atomic<T>* obj, T desr) noexcept; +  T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;  template <class T> -    void -    atomic_init(atomic<T>* obj, T desr) noexcept; +  T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;  template <class T> -    void -    atomic_store(volatile atomic<T>* obj, T desr) noexcept; +  T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;  template <class T> -    void -    atomic_store(atomic<T>* obj, T desr) noexcept; +  T atomic_exchange(atomic<T>* obj, T desr) noexcept;  template <class T> -    void -    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; +  T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;  template <class T> -    void -    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; +  T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;  template <class T> -    T -    atomic_load(const volatile atomic<T>* obj) noexcept; +  bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;  template <class T> -    T -    atomic_load(const atomic<T>* obj) noexcept; +  bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;  template <class T> -    T -    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; +  bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;  template <class T> -    T -    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; +  bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;  template <class T> -    T -    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; +  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, +                                             T desr, +                                             memory_order s, memory_order f) noexcept;  template <class T> -    T -    atomic_exchange(atomic<T>* obj, T desr) noexcept; +  bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, +                                             memory_order s, memory_order f) noexcept;  template <class T> -    T -    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; +  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, +                                               T* expc, T desr, +                                               memory_order s, memory_order f) noexcept;  template <class T> -    T -    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; +  bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, +                                               T desr, +                                               memory_order s, memory_order f) noexcept;  template <class T> -    bool -    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; +  void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;  template <class T> -    bool -    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; +  void atomic_wait(const atomic<T>* obj, T old) noexcept;  template <class T> -    bool -    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; +  void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;  template <class T> -    bool -    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; +  void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;  template <class T> -    bool -    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, -                                          T desr, -                                          memory_order s, memory_order f) noexcept; +  void atomic_one(volatile atomic<T>* obj) noexcept;  template <class T> -    bool -    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, -                                          memory_order s, memory_order f) noexcept; +  void atomic_one(atomic<T>* obj) noexcept;  template <class T> -    bool -    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, -                                            T* expc, T desr, -                                            memory_order s, memory_order f) noexcept; +  void atomic_all(volatile atomic<T>* obj) noexcept;  template <class T> -    bool -    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, -                                            T desr, -                                            memory_order s, memory_order f) noexcept; +  void atomic_all(atomic<T>* obj) noexcept;  template <class Integral> -    Integral -    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, +  Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,                                memory_order m) noexcept;  template <class Integral> -    Integral -    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, +  Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,                                memory_order m) noexcept;  template <class Integral> -    Integral -    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, -                              memory_order m) noexcept; +  Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, +                                     memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, -                              memory_order m) noexcept; +  Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, +                                     memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, -                              memory_order m) noexcept; +  Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, +                                     memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, -                              memory_order m) noexcept; +  Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, +                                     memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, +  Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,                               memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, +  Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,                               memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; +  Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;  template <class Integral> -    Integral -    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, -                              memory_order m) noexcept; +  Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, +                                     memory_order m) noexcept; +  template <class Integral> -    Integral -    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, -                              memory_order m) noexcept; +  Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, +                                     memory_order m) noexcept;  template <class T> -    T* -    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; +  T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;  template <class T> -    T* -    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; +  T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;  template <class T> -    T* -    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, -                              memory_order m) noexcept; +  T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, +                               memory_order m) noexcept; +  template <class T> -    T* -    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; +  T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;  template <class T> -    T* -    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; +  T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;  template <class T> -    T* -    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; +  T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;  template <class T> -    T* -    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, -                              memory_order m) noexcept; +  T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, +                               memory_order m) noexcept; +  template <class T> -    T* -    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; +  T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;  // Atomics for standard typedef types @@ -516,7 +477,7 @@ typedef atomic<int_fast8_t>   atomic_int_fast8_t;  typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;  typedef atomic<int_fast16_t>  atomic_int_fast16_t;  typedef atomic<uint_fast16_t> atomic_uint_fast16_t; -typedef atomic<int_fast32_t>  atomic_int_fast32_t; +typedef atomic<int_fast32_t>  atomic_int_fast32_t;      typedef atomic<uint_fast32_t> atomic_uint_fast32_t;  typedef atomic<int_fast64_t>  atomic_int_fast64_t;  typedef atomic<uint_fast64_t> atomic_uint_fast64_t; @@ -537,18 +498,80 @@ typedef atomic<ptrdiff_t> atomic_ptrdiff_t;  typedef atomic<intmax_t>  atomic_intmax_t;  typedef atomic<uintmax_t> 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 <class T> +  void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept; + +template <class T> +  void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept; + +#define ATOMIC_VAR_INIT(value) see below + +#define ATOMIC_FLAG_INIT see below +  }  // std  */  #include <__config> +#include <__threading_support>  #include <cstddef>  #include <cstdint> +#include <cstring>  #include <type_traits>  #include <version> @@ -629,6 +652,11 @@ typedef enum memory_order {  #endif // _LIBCPP_STD_VER > 17 +template <typename _Tp> _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<underlying_type<memory_order>::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 <class _Atp, class _Fn> +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 <class _Atp, class _Fn> +_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 <class _Tp> +_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } +template <class _Atp, class _Fn> +_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 <class _Atp, class _Tp> +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 <class _Atp, class _Tp> +_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<T>  template <class _Tp, bool = is_integral<_Tp>::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 <class _Tp> +_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 <class _Tp> +_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 <class _Tp> +_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 <class _Tp> +_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 <class _Tp> +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT +{ +    __o->notify_one(); +} +template <class _Tp> +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT +{ +    __o->notify_one(); +} + +// atomic_notify_one + +template <class _Tp> +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT +{ +    __o->notify_all(); +} +template <class _Tp> +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT +{ +    __o->notify_all(); +} +  // atomic_fetch_add  template <class _Tp> @@ -2280,6 +2483,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);}      _LIBCPP_INLINE_VISIBILITY @@ -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<ptrdiff_t> atomic_ptrdiff_t;  typedef atomic<intmax_t>  atomic_intmax_t;  typedef atomic<uintmax_t> 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 CompletionFunction = see below> +  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 <atomic> +#ifndef _LIBCPP_HAS_NO_TREE_BARRIER +# include <memory> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +# error <barrier> 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 _CompletionF> +class __barrier_base { + +    ptrdiff_t                                               __expected; +    unique_ptr<__barrier_algorithm_base, +               void (*)(__barrier_algorithm_base*)>         __base; +    __atomic_base<ptrdiff_t>                                __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<ptrdiff_t>::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 _CompletionF> +class __barrier_base { + +    __atomic_base<ptrdiff_t> __expected; +    __atomic_base<ptrdiff_t> __arrived; +    _CompletionF             __completion; +    __atomic_base<bool>      __phase; +public: +    using arrival_token = bool; + +    static constexpr ptrdiff_t max() noexcept { +        return numeric_limits<ptrdiff_t>::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<uint64_t>   __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 _CompletionF = __empty_completion> +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 <class T>      constexpr bool ispow2(T x) noexcept; // C++20    template <class T> @@ -24,13 +25,13 @@ namespace std {    template <class T>      constexpr T log2p1(T x) noexcept;    // C++20 -  // 23.20.2, rotating +  // [bit.rotate], rotating    template<class T>      constexpr T rotl(T x, unsigned int s) noexcept; // C++20    template<class T>      constexpr T rotr(T x, unsigned int s) noexcept; // C++20 -  // 23.20.3, counting +  // [bit.count], counting    template<class T>      constexpr int countl_zero(T x) noexcept;  // C++20    template<class T> @@ -42,7 +43,7 @@ namespace std {    template<class T>      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 <type_traits>  #include <limits> @@ -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 <typename _Tp> +_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 <typename _Tp> +_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 <typename _Tp> +_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 <typename _Tp> +_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 <typename _Tp, typename enable_if<is_integral<_Tp>::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 <typename _Tp, typename enable_if<is_integral<_Tp>::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<unsigned>(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 <class _Elem, unsigned long _Maxcode = 0x10ffff, @@ -225,11 +225,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 <class _Elem, unsigned long _Maxcode = 0x10ffff, @@ -453,11 +453,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 <class _Elem, unsigned long _Maxcode = 0x10ffff, diff --git a/libcxx/include/compare b/libcxx/include/compare index e05257bebfa5..717859a1e3af 100644 --- a/libcxx/include/compare +++ b/libcxx/include/compare @@ -43,6 +43,84 @@ namespace std {    template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);    template<class T> constexpr strong_equality strong_equal(const T& a, const T& b);    template<class T> 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<class T, class charT, class traits>  #include <type_traits>  #include <stdexcept>  #include <cmath> +#include <iosfwd>  #include <sstream>  #include <version> @@ -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<class T, class U> +    concept same_as = see below; + +  // [concept.derived], concept derived_from +  template<class Derived, class Base> +    concept derived_from = see below; + +  // [concept.convertible], concept convertible_to +  template<class From, class To> +    concept convertible_to = see below; + +  // [concept.commonref], concept common_reference_with +  template<class T, class U> +    concept common_reference_with = see below; + +  // [concept.common], concept common_with +  template<class T, class U> +    concept common_with = see below; + +  // [concepts.arithmetic], arithmetic concepts +  template<class T> +    concept integral = see below; +  template<class T> +    concept signed_integral = see below; +  template<class T> +    concept unsigned_integral = see below; +  template<class T> +    concept floating_point = see below; + +  // [concept.assignable], concept assignable_from +  template<class LHS, class RHS> +    concept assignable_from = see below; + +  // [concept.swappable], concept swappable +  namespace ranges { +    inline namespace unspecified { +      inline constexpr unspecified swap = unspecified; +    } +  } +  template<class T> +    concept swappable = see below; +  template<class T, class U> +    concept swappable_with = see below; + +  // [concept.destructible], concept destructible +  template<class T> +    concept destructible = see below; + +  // [concept.constructible], concept constructible_from +  template<class T, class... Args> +    concept constructible_from = see below; + +  // [concept.defaultconstructible], concept default_constructible +  template<class T> +    concept default_constructible = see below; + +  // [concept.moveconstructible], concept move_constructible +  template<class T> +    concept move_constructible = see below; + +  // [concept.copyconstructible], concept copy_constructible +  template<class T> +    concept copy_constructible = see below; + +  // [concepts.compare], comparison concepts +  // [concept.boolean], concept boolean +  template<class B> +    concept boolean = see below; + +  // [concept.equalitycomparable], concept equality_comparable +  template<class T> +    concept equality_comparable = see below; +  template<class T, class U> +    concept equality_comparable_with = see below; + +  // [concept.totallyordered], concept totally_ordered +  template<class T> +    concept totally_ordered = see below; +  template<class T, class U> +    concept totally_ordered_with = see below; + +  // [concepts.object], object concepts +  template<class T> +    concept movable = see below; +  template<class T> +    concept copyable = see below; +  template<class T> +    concept semiregular = see below; +  template<class T> +    concept regular = see below; + +  // [concepts.callable], callable concepts +  // [concept.invocable], concept invocable +  template<class F, class... Args> +    concept invocable = see below; + +  // [concept.regularinvocable], concept regular_invocable +  template<class F, class... Args> +    concept regular_invocable = see below; + +  // [concept.predicate], concept predicate +  template<class F, class... Args> +    concept predicate = see below; + +  // [concept.relation], concept relation +  template<class R, class T, class U> +    concept relation = see below; + +  // [concept.equiv], concept equivalence_relation +  template<class R, class T, class U> +    concept equivalence_relation = see below; + +  // [concept.strictweakorder], concept strict_weak_order +  template<class R, class T, class U> +    concept strict_weak_order = see below; +} + +*/ + +#include <__config> +#include <type_traits> +#include <version> + +#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<class _Tp, class _Up> +concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value; + +template<class _Tp, class _Up> +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 <stddef.h> max_align_t where possible. +#if !defined(_LIBCPP_CXX03_LANG)  using ::max_align_t; -#else -typedef long double max_align_t; +#endif + +template <class _Tp> struct __libcpp_is_integral                     { enum { value = 0 }; }; +template <>          struct __libcpp_is_integral<bool>               { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<char>               { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<signed char>        { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<unsigned char>      { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<wchar_t>            { enum { value = 1 }; }; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template <>          struct __libcpp_is_integral<char8_t>            { enum { value = 1 }; }; +#endif +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS +template <>          struct __libcpp_is_integral<char16_t>           { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<char32_t>           { enum { value = 1 }; }; +#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS +template <>          struct __libcpp_is_integral<short>              { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<unsigned short>     { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<int>                { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<unsigned int>       { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<long>               { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<unsigned long>      { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<long long>          { enum { value = 1 }; }; +template <>          struct __libcpp_is_integral<unsigned long long> { 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 <bool> struct __enable_if_integral_imp {}; +template <> struct __enable_if_integral_imp<true> { using type = byte; }; +template <class _Tp> using _EnableByteOverload = typename __enable_if_integral_imp<__libcpp_is_integral<_Tp>::value>::type; +  constexpr byte  operator| (byte  __lhs, byte __rhs) noexcept  {      return static_cast<byte>( @@ -104,10 +131,31 @@ constexpr byte  operator~ (byte __b) noexcept          ~static_cast<unsigned int>(__b)      ));  } - +template <class _Integer> +  constexpr _EnableByteOverload<_Integer> & +  operator<<=(byte& __lhs, _Integer __shift) noexcept +  { return __lhs = __lhs << __shift; } + +template <class _Integer> +  constexpr _EnableByteOverload<_Integer> +  operator<< (byte  __lhs, _Integer __shift) noexcept +  { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) << __shift)); } + +template <class _Integer> +  constexpr _EnableByteOverload<_Integer> & +  operator>>=(byte& __lhs, _Integer __shift) noexcept +  { return __lhs = __lhs >> __shift; } + +template <class _Integer> +  constexpr _EnableByteOverload<_Integer> +  operator>> (byte  __lhs, _Integer __shift) noexcept +  { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); } + +template <class _Integer, class = _EnableByteOverload<_Integer> > +  constexpr _Integer +  to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); }  } -#include <type_traits>  // 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 <class T, class Allocator>           noexcept(noexcept(x.swap(y)));  template <class T, class Allocator, class U> -    void erase(deque<T, Allocator>& c, const U& value);       // C++20 +    typename deque<T, Allocator>::size_type +    erase(deque<T, Allocator>& c, const U& value);       // C++20  template <class T, class Allocator, class Predicate> -    void erase_if(deque<T, Allocator>& c, Predicate pred);    // C++20 +    typename deque<T, Allocator>::size_type +    erase_if(deque<T, Allocator>& 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 <class _Tp, class _Allocator, class _Up> -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 <class _Tp, class _Allocator, class _Predicate> -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 <class T, class Allocator>           noexcept(noexcept(x.swap(y)));  template <class T, class Allocator, class U> -    void erase(forward_list<T, Allocator>& c, const U& value);       // C++20 +    typename forward_list<T, Allocator>::size_type +    erase(forward_list<T, Allocator>& c, const U& value);       // C++20  template <class T, class Allocator, class Predicate> -    void erase_if(forward_list<T, Allocator>& c, Predicate pred);    // C++20 +    typename forward_list<T, Allocator>::size_type +    erase_if(forward_list<T, Allocator>& 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 <class _Tp, class _Allocator, class _Predicate>  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 <class _Tp, class _Allocator, class _Up>  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 <Block.h> +#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 _Fp> 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 _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined  namespace __function  { @@ -1477,6 +1488,12 @@ template <class _Fp>  _LIBCPP_INLINE_VISIBILITY  bool __not_null(function<_Fp> const& __f) { return !!__f; } +#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template <class _Rp, class ..._Args> +_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 _Fp> class __base; +template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;  template<class _Rp, class ..._ArgTypes>  class __base<_Rp(_ArgTypes...)> @@ -2238,6 +2255,72 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>  #endif // _LIBCPP_NO_RTTI  }; +#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC) + +template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes> +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<class _Rp, class ..._ArgTypes> @@ -2255,14 +2338,14 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>      template <class _Fp, bool = _And<          _IsNotSame<__uncvref_t<_Fp>, function>, -        __invokable<_Fp&, _ArgTypes...> +        __invokable<_Fp, _ArgTypes...>      >::value>      struct __callable;      template <class _Fp>          struct __callable<_Fp, true>          {              static const bool value = is_same<void, _Rp>::value || -                is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type, +                is_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,                                 _Rp>::value;          };      template <class _Fp> @@ -2272,7 +2355,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>          };    template <class _Fp> -  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<class _Fp, class = _EnableIfCallable<_Fp>> +    template<class _Fp, class = _EnableIfLValueCallable<_Fp>>      function(_Fp);  #if _LIBCPP_STD_VER <= 14 @@ -2297,14 +2380,14 @@ public:        function(allocator_arg_t, const _Alloc&, const function&);      template<class _Alloc>        function(allocator_arg_t, const _Alloc&, function&&); -    template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>> +    template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>        function(allocator_arg_t, const _Alloc& __a, _Fp __f);  #endif      function& operator=(const function&);      function& operator=(function&&) _NOEXCEPT;      function& operator=(nullptr_t) _NOEXCEPT; -    template<class _Fp, class = _EnableIfCallable<_Fp>> +    template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::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 <class _Container, class _Predicate> -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<char_type, traits_type>* _      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 <class InputIterator>  // constexpr in C++17 -  constexpr void advance(InputIterator& i, -             typename iterator_traits<InputIterator>::difference_type n); +template <class InputIterator, class Distance>  // constexpr in C++17 +  constexpr void advance(InputIterator& i, Distance n);  template <class InputIterator>  // constexpr in C++17    constexpr typename iterator_traits<InputIterator>::difference_type @@ -663,13 +661,14 @@ void __advance(_RandIter& __i,     __i += __n;  } -template <class _InputIter> +template <class _InputIter, class _Distance>  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 <atomic> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +# error <latch> is not supported on this single threaded system +#endif + +#if _LIBCPP_STD_VER >= 14 + +_LIBCPP_BEGIN_NAMESPACE_STD + +class latch +{ +    __atomic_base<ptrdiff_t> __a; + +public: +    static constexpr ptrdiff_t max() noexcept { +        return numeric_limits<ptrdiff_t>::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 <class T, class Alloc>           noexcept(noexcept(x.swap(y)));  template <class T, class Allocator, class U> -    void erase(list<T, Allocator>& c, const U& value);       // C++20 +    typename list<T, Allocator>::size_type +    erase(list<T, Allocator>& c, const U& value);       // C++20  template <class T, class Allocator, class Predicate> -    void erase_if(list<T, Allocator>& c, Predicate pred);    // C++20 +    typename list<T, Allocator>::size_type +    erase_if(list<T, Allocator>& 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 <class _Tp, class _Allocator, class _Predicate> -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 <class _Tp, class _Allocator, class _Up> -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<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)      noexcept(noexcept(x.swap(y)));  template <class Key, class T, class Compare, class Allocator, class Predicate> -  void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20 +typename map<Key, T, Compare, Allocator>::size_type +erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20  template <class Key, class T, class Compare = less<Key>, @@ -469,7 +470,8 @@ swap(multimap<Key, T, Compare, Allocator>& x,      noexcept(noexcept(x.swap(y)));  template <class Key, class T, class Compare, class Allocator, class Predicate> -  void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20 +typename multimap<Key, T, Compare, Allocator>::size_type +erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);  // C++20  }  // std @@ -1653,10 +1655,13 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,  }  #if _LIBCPP_STD_VER > 17 -template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate> +template <class _Key, class _Tp, class _Compare, class _Allocator, +          class _Predicate>  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 <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate> +template <class _Key, class _Tp, class _Compare, class _Allocator, +          class _Predicate>  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 <stdlib.h> -  #include_next <math.h>  #ifdef __cplusplus @@ -308,6 +305,7 @@ long double    truncl(long double x);  // back to C++ linkage before including these C++ headers.  extern "C++" { +#include <stdlib.h>  #include <type_traits>  #include <limits> @@ -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 <stdlib.h> 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 <stdlib.h> 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 <class T> using rebind_alloc  = Alloc::rebind<U>::other | Alloc<T, Args...>; +    template <class T> using rebind_alloc  = Alloc::rebind<T>::other | Alloc<T, Args...>;      template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;      static pointer allocate(allocator_type& a, size_type n);                          // [[nodiscard]] in C++20 @@ -101,7 +101,7 @@ struct allocator_traits  };  template <> -class allocator<void> +class allocator<void> // deprecated in C++17, removed in C++20  {  public:      typedef void*                                 pointer; @@ -115,30 +115,37 @@ template <class T>  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<T>::type       reference; -    typedef typename add_lvalue_reference<const T>::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<T>::type +                      reference;                         // deprecated in C++17, removed in C++20 +    typedef typename add_lvalue_reference<const T>::type +                      const_reference;                   // deprecated in C++17, removed in C++20 -    template <class U> struct rebind {typedef allocator<U> other;}; +    typedef T         value_type; + +    template <class U> struct rebind {typedef allocator<U> 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 <class U>        constexpr allocator(const allocator<U>&) 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<void>::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<class U, class... Args> -        void construct(U* p, Args&&... args); +        void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20      template <class U> -        void destroy(U* p); +        void destroy(U* p);                           // deprecated in C++17, removed in C++20  };  template <class T, class U> @@ -443,6 +450,11 @@ public:      template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;  }; +template<class T> +shared_ptr(weak_ptr<T>) -> shared_ptr<T>; +template<class T, class D> +shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; +  // shared_ptr comparisons:  template<class T, class U>      bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; @@ -541,6 +553,9 @@ public:      template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;  }; +template<class T> +weak_ptr(shared_ptr<T>) -> weak_ptr<T>; +  // weak_ptr specialized algorithms:  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; @@ -705,8 +720,9 @@ _ValueType __libcpp_acquire_load(_ValueType const* __value) {  template <class _Tp> class allocator; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)  template <> -class _LIBCPP_TEMPLATE_VIS allocator<void> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void>  {  public:      typedef void*             pointer; @@ -717,7 +733,7 @@ public:  };  template <> -class _LIBCPP_TEMPLATE_VIS allocator<const void> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<const void>  {  public:      typedef const void*       pointer; @@ -726,6 +742,7 @@ public:      template <class _Up> struct rebind {typedef allocator<_Up> other;};  }; +#endif  // pointer_traits @@ -838,7 +855,9 @@ struct __has_rebind  private:      struct __two {char __lx; char __lxx;};      template <class _Xp> static __two __test(...); +    _LIBCPP_SUPPRESS_DEPRECATED_PUSH      template <class _Xp> 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 <class _Xp> static __two __test(...); +    _LIBCPP_SUPPRESS_DEPRECATED_PUSH      template <class _Xp> 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 <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::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 <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>  struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>  { +    _LIBCPP_SUPPRESS_DEPRECATED_PUSH      typedef _LIBCPP_NODEBUG_TYPE typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type; +    _LIBCPP_SUPPRESS_DEPRECATED_POP  };  template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up> @@ -1297,68 +1320,14 @@ struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>      typedef _LIBCPP_NODEBUG_TYPE _Alloc<_Up, _Args...> type;  }; -#else  // _LIBCPP_HAS_NO_VARIADICS - -template <template <class> class _Alloc, class _Tp, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true> -{ -    typedef typename _Alloc<_Tp>::template rebind<_Up>::other type; -}; - -template <template <class> class _Alloc, class _Tp, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false> -{ -    typedef _Alloc<_Up> type; -}; - -template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true> -{ -    typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type; -}; - -template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false> -{ -    typedef _Alloc<_Up, _A0> type; -}; - -template <template <class, class, class> class _Alloc, class _Tp, class _A0, -                                         class _A1, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true> -{ -    typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type; -}; - -template <template <class, class, class> class _Alloc, class _Tp, class _A0, -                                         class _A1, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false> -{ -    typedef _Alloc<_Up, _A0, _A1> type; -}; - -template <template <class, class, class, class> class _Alloc, class _Tp, class _A0, -                                                class _A1, class _A2, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true> -{ -    typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type; -}; - -template <template <class, class, class, class> class _Alloc, class _Tp, class _A0, -                                                class _A1, class _A2, class _Up> -struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false> -{ -    typedef _Alloc<_Up, _A0, _A1, _A2> type; -}; - -#endif  // _LIBCPP_HAS_NO_VARIADICS -  #ifndef _LIBCPP_CXX03_LANG +_LIBCPP_SUPPRESS_DEPRECATED_PUSH  template <class _Alloc, class _SizeType, class _ConstVoidPtr>  auto  __has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)      -> decltype((void)__a.allocate(__sz, __p), true_type()); +_LIBCPP_SUPPRESS_DEPRECATED_POP  template <class _Alloc, class _SizeType, class _ConstVoidPtr>  auto @@ -1367,12 +1336,9 @@ __has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __  template <class _Alloc, class _SizeType, class _ConstVoidPtr>  struct __has_allocate_hint -    : integral_constant<bool, -        is_same< -            decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(), -                                          declval<_SizeType>(), -                                          declval<_ConstVoidPtr>())), -            true_type>::value> +    : decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(), +                                               declval<_SizeType>(), +                                               declval<_ConstVoidPtr>()))  {  }; @@ -1386,33 +1352,26 @@ struct __has_allocate_hint  #endif  // _LIBCPP_CXX03_LANG -#if !defined(_LIBCPP_CXX03_LANG) +_LIBCPP_SUPPRESS_DEPRECATED_PUSH +template <class _Alloc, class ..._Args, +    class = decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Args>()...))> +static true_type __test_has_construct(int); +_LIBCPP_SUPPRESS_DEPRECATED_POP -template <class _Alloc, class _Tp, class ..._Args> -decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(), -                                           _VSTD::declval<_Args>()...), -                                           true_type()) -__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args); - -template <class _Alloc, class _Pointer, class ..._Args> -false_type -__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args); - -template <class _Alloc, class _Pointer, class ..._Args> -struct __has_construct -    : integral_constant<bool, -        is_same< -            decltype(_VSTD::__has_construct_test(declval<_Alloc>(), -                                          declval<_Pointer>(), -                                          declval<_Args>()...)), -            true_type>::value> -{ -}; +template <class _Alloc, class...> +static false_type __test_has_construct(...); + +template <class _Alloc, class ..._Args> +struct __has_construct : decltype(__test_has_construct<_Alloc, _Args...>(0)) {}; + +#if !defined(_LIBCPP_CXX03_LANG) +_LIBCPP_SUPPRESS_DEPRECATED_PUSH  template <class _Alloc, class _Pointer>  auto  __has_destroy_test(_Alloc&& __a, _Pointer&& __p)      -> decltype(__a.destroy(__p), true_type()); +_LIBCPP_SUPPRESS_DEPRECATED_POP  template <class _Alloc, class _Pointer>  auto @@ -1421,18 +1380,17 @@ __has_destroy_test(const _Alloc& __a, _Pointer&& __p)  template <class _Alloc, class _Pointer>  struct __has_destroy -    : integral_constant<bool, -        is_same< -            decltype(_VSTD::__has_destroy_test(declval<_Alloc>(), -                                        declval<_Pointer>())), -            true_type>::value> +    : decltype(_VSTD::__has_destroy_test(declval<_Alloc>(), +                                         declval<_Pointer>()))  {  }; +_LIBCPP_SUPPRESS_DEPRECATED_PUSH  template <class _Alloc>  auto  __has_max_size_test(_Alloc&& __a)      -> decltype(__a.max_size(), true_type()); +_LIBCPP_SUPPRESS_DEPRECATED_POP  template <class _Alloc>  auto @@ -1441,10 +1399,7 @@ __has_max_size_test(const volatile _Alloc& __a)  template <class _Alloc>  struct __has_max_size -    : integral_constant<bool, -        is_same< -            decltype(_VSTD::__has_max_size_test(declval<_Alloc&>())), -            true_type>::value> +    : decltype(_VSTD::__has_max_size_test(declval<_Alloc&>()))  {  }; @@ -1460,23 +1415,12 @@ __has_select_on_container_copy_construction_test(const volatile _Alloc& __a)  template <class _Alloc>  struct __has_select_on_container_copy_construction -    : integral_constant<bool, -        is_same< -            decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>())), -            true_type>::value> +    : decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>()))  {  };  #else  // _LIBCPP_CXX03_LANG -template <class _Alloc, class _Pointer, class _Tp, class = void> -struct __has_construct : std::false_type {}; - -template <class _Alloc, class _Pointer, class _Tp> -struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t< -    decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>())) ->::type> : std::true_type {}; -  template <class _Alloc, class _Pointer, class = void>  struct __has_destroy : false_type {}; @@ -1588,41 +1532,11 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits      static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT          {__a.deallocate(__p, __n);} -#ifndef _LIBCPP_HAS_NO_VARIADICS      template <class _Tp, class... _Args>          _LIBCPP_INLINE_VISIBILITY          static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)              {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),                           __a, __p, _VSTD::forward<_Args>(__args)...);} -#else  // _LIBCPP_HAS_NO_VARIADICS -    template <class _Tp> -        _LIBCPP_INLINE_VISIBILITY -        static void construct(allocator_type&, _Tp* __p) -            { -                ::new ((void*)__p) _Tp(); -            } -    template <class _Tp, class _A0> -        _LIBCPP_INLINE_VISIBILITY -        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0) -            { -                __construct(__has_construct<allocator_type, _Tp*, const _A0&>(), -                            __a, __p, __a0); -            } -    template <class _Tp, class _A0, class _A1> -        _LIBCPP_INLINE_VISIBILITY -        static void construct(allocator_type&, _Tp* __p, const _A0& __a0, -                              const _A1& __a1) -            { -                ::new ((void*)__p) _Tp(__a0, __a1); -            } -    template <class _Tp, class _A0, class _A1, class _A2> -        _LIBCPP_INLINE_VISIBILITY -        static void construct(allocator_type&, _Tp* __p, const _A0& __a0, -                              const _A1& __a1, const _A2& __a2) -            { -                ::new ((void*)__p) _Tp(__a0, __a1, __a2); -            } -#endif  // _LIBCPP_HAS_NO_VARIADICS      template <class _Tp>          _LIBCPP_INLINE_VISIBILITY @@ -1695,7 +1609,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits          static          typename enable_if          < -            is_trivially_move_constructible<_DestTp>::value && +            is_trivially_copy_constructible<_DestTp>::value &&              is_same<_RawSourceTp, _RawDestTp>::value &&              (__is_default_allocator<allocator_type>::value ||               !__has_construct<allocator_type, _DestTp*, _SourceTp&>::value), @@ -1755,42 +1669,40 @@ private:      _LIBCPP_INLINE_VISIBILITY      static pointer __allocate(allocator_type& __a, size_type __n,          const_void_pointer __hint, true_type) -        {return __a.allocate(__n, __hint);} +        { +            _LIBCPP_SUPPRESS_DEPRECATED_PUSH +            return __a.allocate(__n, __hint); +            _LIBCPP_SUPPRESS_DEPRECATED_POP +        }      _LIBCPP_INLINE_VISIBILITY      static pointer __allocate(allocator_type& __a, size_type __n,          const_void_pointer, false_type)          {return __a.allocate(__n);} -#ifndef _LIBCPP_HAS_NO_VARIADICS      template <class _Tp, class... _Args>          _LIBCPP_INLINE_VISIBILITY          static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args) -            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);} +            { +                _LIBCPP_SUPPRESS_DEPRECATED_PUSH +                __a.construct(__p, _VSTD::forward<_Args>(__args)...); +                _LIBCPP_SUPPRESS_DEPRECATED_POP +            } +      template <class _Tp, class... _Args>          _LIBCPP_INLINE_VISIBILITY          static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)              {                  ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);              } -#else  // _LIBCPP_HAS_NO_VARIADICS -    template <class _Tp, class _A0> -        _LIBCPP_INLINE_VISIBILITY -        static void __construct(true_type, allocator_type& __a, _Tp* __p, -                                const _A0& __a0) -            {__a.construct(__p, __a0);} -    template <class _Tp, class _A0> -        _LIBCPP_INLINE_VISIBILITY -        static void __construct(false_type, allocator_type&, _Tp* __p, -                                const _A0& __a0) -            { -                ::new ((void*)__p) _Tp(__a0); -            } -#endif  // _LIBCPP_HAS_NO_VARIADICS      template <class _Tp>          _LIBCPP_INLINE_VISIBILITY          static void __destroy(true_type, allocator_type& __a, _Tp* __p) -            {__a.destroy(__p);} +            { +                _LIBCPP_SUPPRESS_DEPRECATED_PUSH +                __a.destroy(__p); +                _LIBCPP_SUPPRESS_DEPRECATED_POP +            }      template <class _Tp>          _LIBCPP_INLINE_VISIBILITY          static void __destroy(false_type, allocator_type&, _Tp* __p) @@ -1800,7 +1712,12 @@ private:      _LIBCPP_INLINE_VISIBILITY      static size_type __max_size(true_type, const allocator_type& __a) _NOEXCEPT -            {return __a.max_size();} +            { +                _LIBCPP_SUPPRESS_DEPRECATED_PUSH +                return __a.max_size(); +                _LIBCPP_SUPPRESS_DEPRECATED_POP +            } +      _LIBCPP_INLINE_VISIBILITY      static size_type __max_size(false_type, const allocator_type&) _NOEXCEPT              {return numeric_limits<size_type>::max() / sizeof(value_type);} @@ -1831,19 +1748,22 @@ template <class _Tp>  class _LIBCPP_TEMPLATE_VIS allocator  {  public: -    typedef size_t            size_type; -    typedef ptrdiff_t         difference_type; -    typedef _Tp*              pointer; -    typedef const _Tp*        const_pointer; -    typedef _Tp&              reference; -    typedef const _Tp&        const_reference; -    typedef _Tp               value_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t     size_type; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef ptrdiff_t  difference_type; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp*       pointer; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp&       reference; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference; + +    template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;}; +#endif + +    typedef _Tp value_type;      typedef true_type propagate_on_container_move_assignment;      typedef true_type is_always_equal; -    template <class _Up> struct rebind {typedef allocator<_Up> other;}; -      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17      allocator() _NOEXCEPT {} @@ -1851,103 +1771,67 @@ public:      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17      allocator(const allocator<_Up>&) _NOEXCEPT {} -    _LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY +    pointer address(reference __x) const _NOEXCEPT          {return _VSTD::addressof(__x);} -    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY +    const_pointer address(const_reference __x) const _NOEXCEPT          {return _VSTD::addressof(__x);} -    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY -    pointer allocate(size_type __n, allocator<void>::const_pointer = 0) +#endif + +    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _Tp* allocate(size_t __n)          { -        if (__n > max_size()) +        // TODO(mpark): Replace with `allocator_traits<allocator>::max_size(*this)`. +        if (__n > (size_t(~0) / sizeof(_Tp)))              __throw_length_error("allocator<T>::allocate(size_t n)"                                   " 'n' exceeds maximum supported size"); -        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); +        return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));          } -    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17 +    _Tp* allocate(size_t __n, const void*) { return allocate(__n); } +#endif + +    _LIBCPP_INLINE_VISIBILITY void deallocate(_Tp* __p, size_t __n) _NOEXCEPT          {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));} -    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT          {return size_type(~0) / sizeof(_Tp);} -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) +      template <class _Up, class... _Args> -        _LIBCPP_INLINE_VISIBILITY +        _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY          void          construct(_Up* __p, _Args&&... __args)          {              ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);          } -#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p) -        { -            ::new((void*)__p) _Tp(); -        } -# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - -    template <class _A0> -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p, _A0& __a0) -        { -            ::new((void*)__p) _Tp(__a0); -        } -    template <class _A0> -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p, const _A0& __a0) -        { -            ::new((void*)__p) _Tp(__a0); -        } -# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) -    template <class _A0, class _A1> -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p, _A0& __a0, _A1& __a1) -        { -            ::new((void*)__p) _Tp(__a0, __a1); -        } -    template <class _A0, class _A1> -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p, const _A0& __a0, _A1& __a1) -        { -            ::new((void*)__p) _Tp(__a0, __a1); -        } -    template <class _A0, class _A1> -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p, _A0& __a0, const _A1& __a1) -        { -            ::new((void*)__p) _Tp(__a0, __a1); -        } -    template <class _A0, class _A1> -        _LIBCPP_INLINE_VISIBILITY -        void -        construct(pointer __p, const _A0& __a0, const _A1& __a1) -        { -            ::new((void*)__p) _Tp(__a0, __a1); -        } -#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) -    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();} +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();} +#endif  };  template <class _Tp>  class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>  {  public: -    typedef size_t            size_type; -    typedef ptrdiff_t         difference_type; -    typedef const _Tp*        pointer; -    typedef const _Tp*        const_pointer; -    typedef const _Tp&        reference; -    typedef const _Tp&        const_reference; -    typedef const _Tp         value_type; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t     size_type; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef ptrdiff_t  difference_type; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference; +    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference; + +    template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;}; +#endif + +    typedef const _Tp value_type;      typedef true_type propagate_on_container_move_assignment;      typedef true_type is_always_equal; -    template <class _Up> struct rebind {typedef allocator<_Up> other;}; -      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17      allocator() _NOEXCEPT {} @@ -1955,22 +1839,36 @@ public:      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17      allocator(const allocator<_Up>&) _NOEXCEPT {} -    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY +    const_pointer address(const_reference __x) const _NOEXCEPT          {return _VSTD::addressof(__x);} -    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) +#endif + +    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const _Tp* allocate(size_t __n)      { -        if (__n > max_size()) +        // TODO(mpark): Replace with `allocator_traits<allocator>::max_size(*this)`. +        if (__n > (size_t(~0) / sizeof(_Tp)))              __throw_length_error("allocator<const T>::allocate(size_t n)"                                   " 'n' exceeds maximum supported size"); -        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); +        return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));      } -    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17 +    const _Tp* allocate(size_t __n, const void*) { return allocate(__n); } +#endif + +    _LIBCPP_INLINE_VISIBILITY void deallocate(const _Tp* __p, size_t __n)          {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));} -    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT + +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT          {return size_type(~0) / sizeof(_Tp);} +  #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)      template <class _Up, class... _Args> -        _LIBCPP_INLINE_VISIBILITY +        _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY          void          construct(_Up* __p, _Args&&... __args)          { @@ -2029,7 +1927,8 @@ public:              ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);          }  #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) -    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();} +    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();} +#endif  };  template <class _Tp, class _Up> @@ -2134,39 +2033,39 @@ private:  public:      typedef _Tp element_type; -    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) throw() : __ptr_(__p) {} -    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) throw() : __ptr_(__p.release()) {} -    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) throw() +    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {} +    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {} +    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT          : __ptr_(__p.release()) {} -    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) throw() +    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT          {reset(__p.release()); return *this;} -    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) throw() +    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT          {reset(__p.release()); return *this;} -    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) throw() +    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT          {reset(__p.__ptr_); return *this;} -    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() throw() {delete __ptr_;} +    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;} -    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const throw() +    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT          {return *__ptr_;} -    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const throw() {return __ptr_;} -    _LIBCPP_INLINE_VISIBILITY _Tp* get() const throw() {return __ptr_;} -    _LIBCPP_INLINE_VISIBILITY _Tp* release() throw() +    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;} +    _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;} +    _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT      {          _Tp* __t = __ptr_;          __ptr_ = 0;          return __t;      } -    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) throw() +    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT      {          if (__ptr_ != __p)              delete __ptr_;          __ptr_ = __p;      } -    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) throw() : __ptr_(__p.__ptr_) {} -    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() throw() +    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} +    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT          {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;} -    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() throw() +    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT          {return auto_ptr<_Up>(release());}  }; @@ -3393,6 +3292,8 @@ class _LIBCPP_EXCEPTION_ABI bad_weak_ptr      : public std::exception  {  public: +    bad_weak_ptr() _NOEXCEPT = default; +    bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;      virtual ~bad_weak_ptr() _NOEXCEPT;      virtual const char* what() const  _NOEXCEPT;  }; @@ -3628,15 +3529,25 @@ public:  template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this; +template<class _Tp, class _Up> +struct __compatible_with +#if _LIBCPP_STD_VER > 14 +    : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {}; +#else +    : is_convertible<_Tp*, _Up*> {}; +#endif // _LIBCPP_STD_VER > 14 +  template<class _Tp>  class _LIBCPP_TEMPLATE_VIS shared_ptr  {  public: -    typedef _Tp element_type; -  #if _LIBCPP_STD_VER > 14      typedef weak_ptr<_Tp> weak_type; +    typedef remove_extent_t<_Tp> element_type; +#else +    typedef _Tp element_type;  #endif +  private:      element_type*      __ptr_;      __shared_weak_count* __cntrl_; @@ -3649,13 +3560,13 @@ public:      _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;      template<class _Yp>          explicit shared_ptr(_Yp* __p, -                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()); +                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());      template<class _Yp, class _Dp>          shared_ptr(_Yp* __p, _Dp __d, -                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()); +                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());      template<class _Yp, class _Dp, class _Alloc>          shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, -                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()); +                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());      template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);      template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);      template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT; @@ -3664,13 +3575,13 @@ public:      template<class _Yp>          _LIBCPP_INLINE_VISIBILITY          shared_ptr(const shared_ptr<_Yp>& __r, -                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()) +                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())                         _NOEXCEPT;  #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES      _LIBCPP_INLINE_VISIBILITY      shared_ptr(shared_ptr&& __r) _NOEXCEPT;      template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r, -                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat()) +                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())                         _NOEXCEPT;  #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES      template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r, @@ -3686,7 +3597,6 @@ public:                     typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());  #endif  #endif -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES      template <class _Yp, class _Dp>          shared_ptr(unique_ptr<_Yp, _Dp>&&,                     typename enable_if @@ -3705,26 +3615,6 @@ public:                         is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,                         __nat                     >::type = __nat()); -#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES -    template <class _Yp, class _Dp> -        shared_ptr(unique_ptr<_Yp, _Dp>, -                   typename enable_if -                   < -                       !is_lvalue_reference<_Dp>::value && -                       !is_array<_Yp>::value && -                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, -                       __nat -                   >::type = __nat()); -    template <class _Yp, class _Dp> -        shared_ptr(unique_ptr<_Yp, _Dp>, -                   typename enable_if -                   < -                       is_lvalue_reference<_Dp>::value && -                       !is_array<_Yp>::value && -                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value, -                       __nat -                   >::type = __nat()); -#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES      ~shared_ptr(); @@ -3733,7 +3623,7 @@ public:      template<class _Yp>          typename enable_if          < -            is_convertible<_Yp*, element_type*>::value, +            __compatible_with<_Yp, element_type>::value,              shared_ptr&          >::type          _LIBCPP_INLINE_VISIBILITY @@ -3744,8 +3634,8 @@ public:      template<class _Yp>          typename enable_if          < -            is_convertible<_Yp*, element_type*>::value, -            shared_ptr<_Tp>& +            __compatible_with<_Yp, element_type>::value, +            shared_ptr&          >::type          _LIBCPP_INLINE_VISIBILITY          operator=(shared_ptr<_Yp>&& __r); @@ -3795,7 +3685,7 @@ public:      template<class _Yp>          typename enable_if          < -            is_convertible<_Yp*, element_type*>::value, +            __compatible_with<_Yp, element_type>::value,              void          >::type          _LIBCPP_INLINE_VISIBILITY @@ -3803,7 +3693,7 @@ public:      template<class _Yp, class _Dp>          typename enable_if          < -            is_convertible<_Yp*, element_type*>::value, +            __compatible_with<_Yp, element_type>::value,              void          >::type          _LIBCPP_INLINE_VISIBILITY @@ -3811,7 +3701,7 @@ public:      template<class _Yp, class _Dp, class _Alloc>          typename enable_if          < -            is_convertible<_Yp*, element_type*>::value, +            __compatible_with<_Yp, element_type>::value,              void          >::type          _LIBCPP_INLINE_VISIBILITY @@ -3823,7 +3713,12 @@ public:      typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT          {return *__ptr_;}      _LIBCPP_INLINE_VISIBILITY -    element_type* operator->() const _NOEXCEPT {return __ptr_;} +    element_type* operator->() const _NOEXCEPT +    { +        static_assert(!_VSTD::is_array<_Tp>::value, +                      "std::shared_ptr<T>::operator-> is only valid when T is not an array type."); +        return __ptr_; +    }      _LIBCPP_INLINE_VISIBILITY      long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}      _LIBCPP_INLINE_VISIBILITY @@ -3843,6 +3738,17 @@ public:      __owner_equivalent(const shared_ptr& __p) const          {return __cntrl_ == __p.__cntrl_;} +#if _LIBCPP_STD_VER > 14 +    typename add_lvalue_reference<element_type>::type +    _LIBCPP_INLINE_VISIBILITY +    operator[](ptrdiff_t __i) const +    { +            static_assert(_VSTD::is_array<_Tp>::value, +                          "std::shared_ptr<T>::operator[] is only valid when T is an array type."); +            return __ptr_[__i]; +    } +#endif +  #ifndef _LIBCPP_NO_RTTI      template <class _Dp>          _LIBCPP_INLINE_VISIBILITY @@ -3854,7 +3760,7 @@ public:      template<class _Yp, class _CntrlBlk>      static shared_ptr<_Tp> -    __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) +    __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT      {          shared_ptr<_Tp> __r;          __r.__ptr_ = __p; @@ -3863,11 +3769,6 @@ public:          return __r;      } -    template<class _Alloc, class ..._Args> -        static -        shared_ptr<_Tp> -        allocate_shared(const _Alloc& __a, _Args&& ...__args); -  private:      template <class _Yp, bool = is_function<_Yp>::value>          struct __shared_ptr_default_allocator @@ -3900,10 +3801,28 @@ private:      _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {} +    template <class, class _Yp> +        struct __shared_ptr_default_delete +            : default_delete<_Yp> {}; + +    template <class _Yp, class _Un, size_t _Sz> +        struct __shared_ptr_default_delete<_Yp[_Sz], _Un> +            : default_delete<_Yp[]> {}; + +    template <class _Yp, class _Un> +        struct __shared_ptr_default_delete<_Yp[], _Un> +            : default_delete<_Yp[]> {}; +      template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;      template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;  }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template<class _Tp> +shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; +template<class _Tp, class _Dp> +shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; +#endif  template<class _Tp>  inline @@ -3926,13 +3845,13 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT  template<class _Tp>  template<class _Yp>  shared_ptr<_Tp>::shared_ptr(_Yp* __p, -                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) +                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)      : __ptr_(__p)  {      unique_ptr<_Yp> __hold(__p);      typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; -    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk; -    __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT()); +    typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk; +    __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());      __hold.release();      __enable_weak_this(__p, __p);  } @@ -3940,7 +3859,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p,  template<class _Tp>  template<class _Yp, class _Dp>  shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, -                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) +                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)      : __ptr_(__p)  {  #ifndef _LIBCPP_NO_EXCEPTIONS @@ -3986,7 +3905,7 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)  template<class _Tp>  template<class _Yp, class _Dp, class _Alloc>  shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, -                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) +                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)      : __ptr_(__p)  {  #ifndef _LIBCPP_NO_EXCEPTIONS @@ -4064,7 +3983,7 @@ template<class _Tp>  template<class _Yp>  inline  shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, -                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) +                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)           _NOEXCEPT      : __ptr_(__r.__ptr_),        __cntrl_(__r.__cntrl_) @@ -4089,7 +4008,7 @@ template<class _Tp>  template<class _Yp>  inline  shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r, -                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type) +                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)           _NOEXCEPT      : __ptr_(__r.__ptr_),        __cntrl_(__r.__cntrl_) @@ -4120,11 +4039,7 @@ shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r,  template<class _Tp>  template <class _Yp, class _Dp> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES  shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, -#else -shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, -#endif                              typename enable_if                              <                                  !is_lvalue_reference<_Dp>::value && @@ -4150,11 +4065,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,  template<class _Tp>  template <class _Yp, class _Dp> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES  shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r, -#else -shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, -#endif                              typename enable_if                              <                                  is_lvalue_reference<_Dp>::value && @@ -4174,33 +4085,13 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,          typedef __shared_ptr_pointer<_Yp*,                                       reference_wrapper<typename remove_reference<_Dp>::type>,                                       _AllocT > _CntrlBlk; -        __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), _AllocT()); +        __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());          __enable_weak_this(__r.get(), __r.get());      }      __r.release();  }  template<class _Tp> -template<class _Alloc, class ..._Args> -shared_ptr<_Tp> -shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args) -{ -    static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared" ); -    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; -    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; -    typedef __allocator_destructor<_A2> _D2; -    _A2 __a2(__a); -    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); -    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get()))) -        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...); -    shared_ptr<_Tp> __r; -    __r.__ptr_ = __hold2.get()->get(); -    __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); -    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); -    return __r; -} - -template<class _Tp>  shared_ptr<_Tp>::~shared_ptr()  {      if (__cntrl_) @@ -4221,7 +4112,7 @@ template<class _Yp>  inline  typename enable_if  < -    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, +    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,      shared_ptr<_Tp>&  >::type  shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT @@ -4246,7 +4137,7 @@ template<class _Yp>  inline  typename enable_if  < -    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, +    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,      shared_ptr<_Tp>&  >::type  shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r) @@ -4347,7 +4238,7 @@ template<class _Yp>  inline  typename enable_if  < -    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, +    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,      void  >::type  shared_ptr<_Tp>::reset(_Yp* __p) @@ -4360,7 +4251,7 @@ template<class _Yp, class _Dp>  inline  typename enable_if  < -    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, +    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,      void  >::type  shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) @@ -4373,7 +4264,7 @@ template<class _Yp, class _Dp, class _Alloc>  inline  typename enable_if  < -    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value, +    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,      void  >::type  shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) @@ -4412,7 +4303,19 @@ typename enable_if  >::type  allocate_shared(const _Alloc& __a, _Args&& ...__args)  { -    return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...); +    static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared"); + +    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; +    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; +    typedef __allocator_destructor<_A2> _D2; + +    _A2 __a2(__a); +    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); +    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get()))) +        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...); + +    typename shared_ptr<_Tp>::element_type *__p = __hold2.get()->get(); +    return shared_ptr<_Tp>::__create_with_control_block(__p, _VSTD::addressof(*__hold2.release()));  }  template<class _Tp, class _Up> @@ -4575,41 +4478,41 @@ swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT  template<class _Tp, class _Up>  inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< -    !is_array<_Tp>::value && !is_array<_Up>::value, -    shared_ptr<_Tp> ->::type +shared_ptr<_Tp>  static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT  { -    return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); +    return shared_ptr<_Tp>(__r, +                           static_cast< +                               typename shared_ptr<_Tp>::element_type*>(__r.get()));  }  template<class _Tp, class _Up>  inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< -    !is_array<_Tp>::value && !is_array<_Up>::value, -    shared_ptr<_Tp> ->::type +shared_ptr<_Tp>  dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT  { -    _Tp* __p = dynamic_cast<_Tp*>(__r.get()); +    typedef typename shared_ptr<_Tp>::element_type _ET; +    _ET* __p = dynamic_cast<_ET*>(__r.get());      return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();  }  template<class _Tp, class _Up> -typename enable_if -< -    is_array<_Tp>::value == is_array<_Up>::value, -    shared_ptr<_Tp> ->::type +shared_ptr<_Tp>  const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT  { -    typedef typename remove_extent<_Tp>::type _RTp; +    typedef typename shared_ptr<_Tp>::element_type _RTp;      return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));  } +template<class _Tp, class _Up> +shared_ptr<_Tp> +reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT +{ +    return shared_ptr<_Tp>(__r, +                           reinterpret_cast< +                               typename shared_ptr<_Tp>::element_type*>(__r.get())); +} +  #ifndef _LIBCPP_NO_RTTI  template<class _Dp, class _Tp> @@ -4712,6 +4615,11 @@ public:      template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;  }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template<class _Tp> +weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; +#endif +  template<class _Tp>  inline  _LIBCPP_CONSTEXPR @@ -5008,7 +4916,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >      _LIBCPP_INLINE_VISIBILITY      result_type operator()(const argument_type& __ptr) const _NOEXCEPT      { -        return hash<_Tp*>()(__ptr.get()); +        return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());      }  }; diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 31d39ddf7c8a..b8d2a6669aac 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -231,6 +231,11 @@ module std [system] {      header "atomic"      export *    } +  module barrier { +    requires cplusplus14 +    header "barrier" +    export * +  }    module bit {      header "bit"      export * @@ -262,6 +267,10 @@ module std [system] {      header "complex"      export *    } +  module concepts { +    header "concepts" +    export * +  }    module condition_variable {      header "condition_variable"      export * @@ -334,6 +343,11 @@ module std [system] {      header "iterator"      export *    } +  module latch { +    requires cplusplus14 +    header "latch" +    export * +  }    module limits {      header "limits"      export * @@ -364,6 +378,10 @@ module std [system] {      header "new"      export *    } +  module numbers { +    header "numbers" +    export * +  }    module numeric {      header "numeric"      export * @@ -400,6 +418,11 @@ module std [system] {      header "scoped_allocator"      export *    } +  module semaphore { +    requires cplusplus14 +    header "semaphore" +    export * +  }    module set {      header "set"      export initializer_list diff --git a/libcxx/include/numbers b/libcxx/include/numbers new file mode 100644 index 000000000000..e7d981be4aa4 --- /dev/null +++ b/libcxx/include/numbers @@ -0,0 +1,141 @@ +// -*- C++ -*- +//===---------------------------- numbers ---------------------------------===// +// +// 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_NUMBERS +#define _LIBCPP_NUMBERS + +/* +    numbers synopsis + +namespace std::numbers { +  template<class T> inline constexpr T e_v          = unspecified; +  template<class T> inline constexpr T log2e_v      = unspecified; +  template<class T> inline constexpr T log10e_v     = unspecified; +  template<class T> inline constexpr T pi_v         = unspecified; +  template<class T> inline constexpr T inv_pi_v     = unspecified; +  template<class T> inline constexpr T inv_sqrtpi_v = unspecified; +  template<class T> inline constexpr T ln2_v        = unspecified; +  template<class T> inline constexpr T ln10_v       = unspecified; +  template<class T> inline constexpr T sqrt2_v      = unspecified; +  template<class T> inline constexpr T sqrt3_v      = unspecified; +  template<class T> inline constexpr T inv_sqrt3_v  = unspecified; +  template<class T> inline constexpr T egamma_v     = unspecified; +  template<class T> inline constexpr T phi_v        = unspecified; + +  template<floating_point T> inline constexpr T e_v<T>          = see below; +  template<floating_point T> inline constexpr T log2e_v<T>      = see below; +  template<floating_point T> inline constexpr T log10e_v<T>     = see below; +  template<floating_point T> inline constexpr T pi_v<T>         = see below; +  template<floating_point T> inline constexpr T inv_pi_v<T>     = see below; +  template<floating_point T> inline constexpr T inv_sqrtpi_v<T> = see below; +  template<floating_point T> inline constexpr T ln2_v<T>        = see below; +  template<floating_point T> inline constexpr T ln10_v<T>       = see below; +  template<floating_point T> inline constexpr T sqrt2_v<T>      = see below; +  template<floating_point T> inline constexpr T sqrt3_v<T>      = see below; +  template<floating_point T> inline constexpr T inv_sqrt3_v<T>  = see below; +  template<floating_point T> inline constexpr T egamma_v<T>     = see below; +  template<floating_point T> inline constexpr T phi_v<T>        = see below; + +  inline constexpr double e          = e_v<double>; +  inline constexpr double log2e      = log2e_v<double>; +  inline constexpr double log10e     = log10e_v<double>; +  inline constexpr double pi         = pi_v<double>; +  inline constexpr double inv_pi     = inv_pi_v<double>; +  inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>; +  inline constexpr double ln2        = ln2_v<double>; +  inline constexpr double ln10       = ln10_v<double>; +  inline constexpr double sqrt2      = sqrt2_v<double>; +  inline constexpr double sqrt3      = sqrt3_v<double>; +  inline constexpr double inv_sqrt3  = inv_sqrt3_v<double>; +  inline constexpr double egamma     = egamma_v<double>; +  inline constexpr double phi        = phi_v<double>; +} +*/ + +#include <__config> + +#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L + +#include <type_traits> +#include <version> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace numbers { + +template <class T> +inline constexpr bool __false = false; + +template <class T> +struct __illformed +{ +  static_assert(__false<T>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed."); +}; + +template <class T> inline constexpr T e_v =          __illformed<T>{}; +template <class T> inline constexpr T log2e_v =      __illformed<T>{}; +template <class T> inline constexpr T log10e_v =     __illformed<T>{}; +template <class T> inline constexpr T pi_v =         __illformed<T>{}; +template <class T> inline constexpr T inv_pi_v =     __illformed<T>{}; +template <class T> inline constexpr T inv_sqrtpi_v = __illformed<T>{}; +template <class T> inline constexpr T ln2_v =        __illformed<T>{}; +template <class T> inline constexpr T ln10_v =       __illformed<T>{}; +template <class T> inline constexpr T sqrt2_v =      __illformed<T>{}; +template <class T> inline constexpr T sqrt3_v =      __illformed<T>{}; +template <class T> inline constexpr T inv_sqrt3_v =  __illformed<T>{}; +template <class T> inline constexpr T egamma_v =     __illformed<T>{}; +template <class T> inline constexpr T phi_v =        __illformed<T>{}; + +template <class T> +concept __floating_point = std::is_floating_point_v<T>; + +template <__floating_point T> inline constexpr T e_v<T>          = 2.718281828459045235360287471352662; +template <__floating_point T> inline constexpr T log2e_v<T>      = 1.442695040888963407359924681001892; +template <__floating_point T> inline constexpr T log10e_v<T>     = 0.434294481903251827651128918916605; +template <__floating_point T> inline constexpr T pi_v<T>         = 3.141592653589793238462643383279502; +template <__floating_point T> inline constexpr T inv_pi_v<T>     = 0.318309886183790671537767526745028; +template <__floating_point T> inline constexpr T inv_sqrtpi_v<T> = 0.564189583547756286948079451560772; +template <__floating_point T> inline constexpr T ln2_v<T>        = 0.693147180559945309417232121458176; +template <__floating_point T> inline constexpr T ln10_v<T>       = 2.302585092994045684017991454684364; +template <__floating_point T> inline constexpr T sqrt2_v<T>      = 1.414213562373095048801688724209698; +template <__floating_point T> inline constexpr T sqrt3_v<T>      = 1.732050807568877293527446341505872; +template <__floating_point T> inline constexpr T inv_sqrt3_v<T>  = 0.577350269189625764509148780501957; +template <__floating_point T> inline constexpr T egamma_v<T>     = 0.577215664901532860606512090082402; +template <__floating_point T> inline constexpr T phi_v<T>        = 1.618033988749894848204586834365638; + +inline constexpr double e          = e_v<double>; +inline constexpr double log2e      = log2e_v<double>; +inline constexpr double log10e     = log10e_v<double>; +inline constexpr double pi         = pi_v<double>; +inline constexpr double inv_pi     = inv_pi_v<double>; +inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>; +inline constexpr double ln2        = ln2_v<double>; +inline constexpr double ln10       = ln10_v<double>; +inline constexpr double sqrt2      = sqrt2_v<double>; +inline constexpr double sqrt3      = sqrt3_v<double>; +inline constexpr double inv_sqrt3  = inv_sqrt3_v<double>; +inline constexpr double egamma     = egamma_v<double>; +inline constexpr double phi        = phi_v<double>; + +} // namespace numbers + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L + +#endif // _LIBCPP_NUMBERS diff --git a/libcxx/include/ostream b/libcxx/include/ostream index ea3870532f32..697732d54e6d 100644 --- a/libcxx/include/ostream +++ b/libcxx/include/ostream @@ -999,7 +999,7 @@ basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)  }  template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline  basic_ostream<_CharT, _Traits>&  endl(basic_ostream<_CharT, _Traits>& __os)  { @@ -1009,7 +1009,7 @@ endl(basic_ostream<_CharT, _Traits>& __os)  }  template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline  basic_ostream<_CharT, _Traits>&  ends(basic_ostream<_CharT, _Traits>& __os)  { @@ -1018,7 +1018,7 @@ ends(basic_ostream<_CharT, _Traits>& __os)  }  template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline  basic_ostream<_CharT, _Traits>&  flush(basic_ostream<_CharT, _Traits>& __os)  { diff --git a/libcxx/include/random b/libcxx/include/random index 7c4054f7eea8..ce3d135e064a 100644 --- a/libcxx/include/random +++ b/libcxx/include/random @@ -4048,10 +4048,12 @@ binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)      result_type __rd = __ru;      while (true)      { +        bool __break = true;          if (__rd >= 1)          {              __pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1));              __u -= __pd; +            __break = false;              if (__u < 0)                  return __rd - 1;          } @@ -4062,9 +4064,12 @@ binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)          {              __pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru;              __u -= __pu; +            __break = false;              if (__u < 0)                  return __ru;          } +        if (__break) +            return 0;      }  } diff --git a/libcxx/include/regex b/libcxx/include/regex index 5ac9e325e136..f42f1ecd16a4 100644 --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -21,7 +21,7 @@ namespace std  namespace regex_constants  { -emum syntax_option_type +enum syntax_option_type  {      icase      = unspecified,      nosubs     = unspecified, @@ -631,7 +631,7 @@ template <class OutputIterator, class BidirectionalIterator,                    const basic_regex<charT, traits>& e, const charT* fmt,                    regex_constants::match_flag_type flags = regex_constants::match_default); -template <class traits, class charT, class ST, class SA, class FST, class FSA>> +template <class traits, class charT, class ST, class SA, class FST, class FSA>      basic_string<charT, ST, SA>      regex_replace(const basic_string<charT, ST, SA>& s,                    const basic_regex<charT, traits>& e, @@ -675,9 +675,9 @@ public:      regex_iterator(BidirectionalIterator a, BidirectionalIterator b,                     const regex_type& re,                     regex_constants::match_flag_type m = regex_constants::match_default); -    regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, -                   const regex_type&& __re, -                   regex_constants::match_flag_type __m +    regex_iterator(BidirectionalIterator a, BidirectionalIterator b, +                   const regex_type&& re, +                   regex_constants::match_flag_type m                                       = regex_constants::match_default) = delete; // C++14      regex_iterator(const regex_iterator&);      regex_iterator& operator=(const regex_iterator&); @@ -698,7 +698,7 @@ typedef regex_iterator<string::const_iterator>  sregex_iterator;  typedef regex_iterator<wstring::const_iterator> wsregex_iterator;  template <class BidirectionalIterator, -          class charT = typename iterator_traits< BidirectionalIterator>::value_type, +          class charT = typename iterator_traits<BidirectionalIterator>::value_type,            class traits = regex_traits<charT>>  class regex_token_iterator  { @@ -735,8 +735,8 @@ public:                               regex_constants::match_flag_type m = regex_constants::match_default);      template <size_t N>          regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, -                             const regex_type& re, const int (&submatches)[N], -                             regex_constants::match_flag_type m = regex_constants::match_default) = delete // C++14; +                             const regex_type&& re, const int (&submatches)[N], +                             regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14      regex_token_iterator(const regex_token_iterator&);      regex_token_iterator& operator=(const regex_token_iterator&); @@ -977,7 +977,8 @@ class _LIBCPP_EXCEPTION_ABI regex_error      regex_constants::error_type __code_;  public:      explicit regex_error(regex_constants::error_type __ecode); -    virtual ~regex_error() throw(); +    regex_error(const regex_error&) _NOEXCEPT = default; +    virtual ~regex_error() _NOEXCEPT;       _LIBCPP_INLINE_VISIBILITY      regex_constants::error_type code() const {return __code_;}  }; @@ -1000,7 +1001,19 @@ public:      typedef _CharT                  char_type;      typedef basic_string<char_type> string_type;      typedef locale                  locale_type; +#ifdef __BIONIC__ +    // Originally bionic's ctype_base used its own ctype masks because the +    // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask +    // was only 8 bits wide and already saturated, so it used a wider type here +    // to make room for __regex_word (then a part of this class rather than +    // ctype_base). Bionic has since moved to the builtin ctype_base +    // implementation, but this was not updated to match. Since then Android has +    // needed to maintain a stable libc++ ABI, and this can't be changed without +    // an ABI break. +    typedef uint16_t char_class_type; +#else      typedef ctype_base::mask        char_class_type; +#endif      static const char_class_type __regex_word = ctype_base::__regex_word;  private: @@ -2837,6 +2850,8 @@ private:          __parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,                            basic_string<_CharT>* __str = nullptr); +    bool __test_back_ref(_CharT c); +      _LIBCPP_INLINE_VISIBILITY      void __push_l_anchor();      void __push_r_anchor(); @@ -3408,18 +3423,8 @@ basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,      if (__first != __last)      {          _ForwardIterator __temp = _VSTD::next(__first); -        if (__temp != __last) -        { -            if (*__first == '\\') -            { -                int __val = __traits_.value(*__temp, 10); -                if (__val >= 1 && __val <= 9) -                { -                    __push_back_ref(__val); -                    __first = ++__temp; -                } -            } -        } +        if (__temp != __last && *__first == '\\' && __test_back_ref(*__temp)) +            __first = ++__temp;      }      return __first;  } @@ -3547,6 +3552,8 @@ basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,                  default:                      if (__get_grammar(__flags_) == awk)                          __first = __parse_awk_escape(++__first, __last); +                    else if(__test_back_ref(*__temp)) +                        __first = ++__temp;                      break;                  }              } @@ -4661,6 +4668,22 @@ basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first,  }  template <class _CharT, class _Traits> +bool +basic_regex<_CharT, _Traits>::__test_back_ref(_CharT c) +{ +    unsigned __val = __traits_.value(c, 10); +    if (__val >= 1 && __val <= 9) +    { +        if (__val > mark_count()) +            __throw_regex_error<regex_constants::error_backref>(); +        __push_back_ref(__val); +        return true; +    } + +    return false; +} + +template <class _CharT, class _Traits>  void  basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,          __owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end, @@ -5917,6 +5940,9 @@ basic_regex<_CharT, _Traits>::__search(          match_results<const _CharT*, _Allocator>& __m,          regex_constants::match_flag_type __flags) const  { +    if (__flags & regex_constants::match_prev_avail) +        __flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow); +      __m.__init(1 + mark_count(), __first, __last,                                      __flags & regex_constants::__no_update_pos);      if (__match_at_start(__first, __last, __m, __flags, diff --git a/libcxx/include/semaphore b/libcxx/include/semaphore new file mode 100644 index 000000000000..447bc2f385d1 --- /dev/null +++ b/libcxx/include/semaphore @@ -0,0 +1,235 @@ +// -*- C++ -*- +//===--------------------------- semaphore --------------------------------===// +// +// 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_SEMAPHORE +#define _LIBCPP_SEMAPHORE + +/* +    semaphore synopsis + +namespace std { + +template<ptrdiff_t least_max_value = implementation-defined> +class counting_semaphore +{ +public: +static constexpr ptrdiff_t max() noexcept; + +constexpr explicit counting_semaphore(ptrdiff_t desired); +~counting_semaphore(); + +counting_semaphore(const counting_semaphore&) = delete; +counting_semaphore& operator=(const counting_semaphore&) = delete; + +void release(ptrdiff_t update = 1); +void acquire(); +bool try_acquire() noexcept; +template<class Rep, class Period> +    bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time); +template<class Clock, class Duration> +    bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time); + +private: +ptrdiff_t counter; // exposition only +}; + +using binary_semaphore = counting_semaphore<1>; + +} + +*/ + +#include <__config> +#include <__threading_support> +#include <atomic> +#include <cassert> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifdef _LIBCPP_HAS_NO_THREADS +# error <semaphore> is not supported on this single threaded system +#endif + +#if _LIBCPP_STD_VER >= 14 + +_LIBCPP_BEGIN_NAMESPACE_STD + +/* + +__atomic_semaphore_base is the general-case implementation, to be used for +user-requested least-max values that exceed the OS implementation support +(incl. when the OS has no support of its own) and for binary semaphores. + +It is a typical Dijsktra semaphore algorithm over atomics, wait and notify +functions. It avoids contention against users' own use of those facilities. + +*/ + +class __atomic_semaphore_base +{ +    __atomic_base<ptrdiff_t> __a; + +public: +    _LIBCPP_INLINE_VISIBILITY +    __atomic_semaphore_base(ptrdiff_t __count) : __a(__count) +    { +    } +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    void release(ptrdiff_t __update = 1) +    { +        if(0 < __a.fetch_add(__update, memory_order_release)) +            ; +        else if(__update > 1) +            __a.notify_all(); +        else +            __a.notify_one(); +    } +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    void acquire() +    { +        auto const __test_fn = [=]() -> bool { +            auto __old = __a.load(memory_order_relaxed); +            return (__old != 0) && __a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed); +        }; +        __cxx_atomic_wait(&__a.__a_, __test_fn); +    } +    template <class Rep, class Period> +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time) +    { +        auto const __test_fn = [=]() -> bool { +            auto __old = __a.load(memory_order_acquire); +            while(1) { +                if (__old == 0) +                    return false; +                if(__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed)) +                    return true; +            } +        }; +        return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time); +    } +}; + +#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES + +/* + +__platform_semaphore_base a simple wrapper for the OS semaphore type. That +is, every call is routed to the OS in the most direct manner possible. + +*/ + +class __platform_semaphore_base +{ +    __libcpp_semaphore_t __semaphore; + +public: +    _LIBCPP_INLINE_VISIBILITY +    __platform_semaphore_base(ptrdiff_t __count) : +        __semaphore() +    { +        __libcpp_semaphore_init(&__semaphore, __count); +    } +    _LIBCPP_INLINE_VISIBILITY +    ~__platform_semaphore_base() { +        __libcpp_semaphore_destroy(&__semaphore); +    } +    _LIBCPP_INLINE_VISIBILITY +    void release(ptrdiff_t __update) +    { +        for(; __update; --__update) +            __libcpp_semaphore_post(&__semaphore); +    } +    _LIBCPP_INLINE_VISIBILITY +    void acquire() +    { +        __libcpp_semaphore_wait(&__semaphore); +    } +    _LIBCPP_INLINE_VISIBILITY +    bool try_acquire_for(chrono::nanoseconds __rel_time) +    { +        return __libcpp_semaphore_wait_timed(&__semaphore, __rel_time); +    } +}; + +template<ptrdiff_t __least_max_value> +using __semaphore_base = +    typename conditional<(__least_max_value > 1 && __least_max_value <= _LIBCPP_SEMAPHORE_MAX), +                         __platform_semaphore_base, +                         __atomic_semaphore_base>::type; + +#else + +template<ptrdiff_t __least_max_value> +using __semaphore_base = +    __atomic_semaphore_base; + +#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) + +#endif //_LIBCPP_NO_NATIVE_SEMAPHORES + +template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX> +class counting_semaphore +{ +    __semaphore_base<__least_max_value> __semaphore; + +public: +    static constexpr ptrdiff_t max() noexcept { +        return __least_max_value; +    } + +    _LIBCPP_INLINE_VISIBILITY +    counting_semaphore(ptrdiff_t __count = 0) : __semaphore(__count) { } +    ~counting_semaphore() = default; + +    counting_semaphore(const counting_semaphore&) = delete; +    counting_semaphore& operator=(const counting_semaphore&) = delete; + +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    void release(ptrdiff_t __update = 1) +    { +        __semaphore.release(__update); +    } +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    void acquire() +    { +        __semaphore.acquire(); +    } +    template<class Rep, class Period> +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time) +    { +        return __semaphore.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time)); +    } +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    bool try_acquire() +    { +        return try_acquire_for(chrono::nanoseconds::zero()); +    } +    template <class Clock, class Duration> +    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY +    bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time) +    { +        auto const current = Clock::now(); +        if(current >= __abs_time) +            return try_acquire(); +        else +            return try_acquire_for(__abs_time - current); +    } +}; + +using binary_semaphore = counting_semaphore<1>; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 14 + +#endif //_LIBCPP_SEMAPHORE diff --git a/libcxx/include/set b/libcxx/include/set index ac3fbbe02fc3..d58455bfe219 100644 --- a/libcxx/include/set +++ b/libcxx/include/set @@ -216,7 +216,8 @@ swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)      noexcept(noexcept(x.swap(y)));  template <class Key, class Compare, class Allocator, class Predicate> -  void erase_if(set<Key, Compare, Allocator>& c, Predicate pred);  // C++20 +typename set<Key, Compare, Allocator>::size_type +erase_if(set<Key, Compare, Allocator>& c, Predicate pred);  // C++20  template <class Key, class Compare = less<Key>,            class Allocator = allocator<Key>> @@ -417,7 +418,8 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)      noexcept(noexcept(x.swap(y)));  template <class Key, class Compare, class Allocator, class Predicate> -  void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);  // C++20 +typename multiset<Key, Compare, Allocator>::size_type +erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);  // C++20  }  // std @@ -960,8 +962,10 @@ swap(set<_Key, _Compare, _Allocator>& __x,  #if _LIBCPP_STD_VER > 17  template <class _Key, class _Compare, class _Allocator, class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } +    typename set<_Key, _Compare, _Allocator>::size_type +    erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) { +  return __libcpp_erase_if_container(__c, __pred); +}  #endif  template <class _Key, class _Compare = less<_Key>, @@ -1484,8 +1488,10 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,  #if _LIBCPP_STD_VER > 17  template <class _Key, class _Compare, class _Allocator, class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } +    typename multiset<_Key, _Compare, _Allocator>::size_type +    erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) { +  return __libcpp_erase_if_container(__c, __pred); +}  #endif  _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/span b/libcxx/include/span index 3421ca0f5a8e..b307c98aee20 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -46,15 +46,13 @@ public:      using reference = element_type&;      using const_reference = const element_type&;      using iterator = implementation-defined; -    using const_iterator = implementation-defined;      using reverse_iterator = std::reverse_iterator<iterator>; -    using const_reverse_iterator = std::reverse_iterator<const_iterator>;      static constexpr size_type extent = Extent;      // [span.cons], span constructors, copy, assignment, and destructor      constexpr span() noexcept; -    constexpr span(pointer ptr, size_type count); -    constexpr span(pointer firstElem, pointer lastElem); +    constexpr explicit(Extent != dynamic_extent) span(pointer ptr, size_type count); +    constexpr explicit(Extent != dynamic_extent) span(pointer firstElem, pointer lastElem);      template <size_t N>          constexpr span(element_type (&arr)[N]) noexcept;      template <size_t N> @@ -62,12 +60,12 @@ public:      template <size_t N>          constexpr span(const array<value_type, N>& arr) noexcept;      template <class Container> -        constexpr span(Container& cont); +        constexpr explicit(Extent != dynamic_extent) span(Container& cont);      template <class Container> -        constexpr span(const Container& cont); +        constexpr explicit(Extent != dynamic_extent) span(const Container& cont);      constexpr span(const span& other) noexcept = default;      template <class OtherElementType, size_t OtherExtent> -        constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept; +        constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;      ~span() noexcept = default;      constexpr span& operator=(const span& other) noexcept = default; @@ -97,12 +95,8 @@ public:      // [span.iterators], span iterator support      constexpr iterator begin() const noexcept;      constexpr iterator end() const noexcept; -    constexpr const_iterator cbegin() const noexcept; -    constexpr const_iterator cend() const noexcept;      constexpr reverse_iterator rbegin() const noexcept;      constexpr reverse_iterator rend() const noexcept; -    constexpr const_reverse_iterator crbegin() const noexcept; -    constexpr const_reverse_iterator crend() const noexcept;  private:      pointer data_;    // exposition only @@ -129,11 +123,10 @@ template<class Container>  */  #include <__config> -#include <cstddef>      // for ptrdiff_t -#include <iterator>     // for iterators  #include <array>        // for array -#include <type_traits>  // for remove_cv, etc  #include <cstddef>      // for byte +#include <iterator>     // for iterators +#include <type_traits>  // for remove_cv, etc  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)  #pragma GCC system_header @@ -143,7 +136,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD  #if _LIBCPP_STD_VER > 17 -inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); +inline constexpr size_t dynamic_extent = (numeric_limits<size_t>::max)();  template <typename _Tp, size_t _Extent = dynamic_extent> class span; @@ -202,27 +195,49 @@ public:      using reference              = _Tp &;      using const_reference        = const _Tp &;      using iterator               =  __wrap_iter<pointer>; -    using const_iterator         =  __wrap_iter<const_pointer>;      using reverse_iterator       = _VSTD::reverse_iterator<iterator>; -    using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;      static constexpr size_type extent = _Extent;  // [span.cons], span constructors, copy, assignment, and destructor -    _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} -    { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); } +    template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr> +    _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {}      constexpr span           (const span&) noexcept = default;      constexpr span& operator=(const span&) noexcept = default; -    _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr} +    _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, size_type __count) : __data{__ptr}          { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } -    _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f} +    _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) : __data{__f}          { (void)__l;     _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }      _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent])          noexcept : __data{__arr} {} -    _LIBCPP_INLINE_VISIBILITY constexpr span(      array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {} -    _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {} + +    template <class _OtherElementType, +              enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> +    _LIBCPP_INLINE_VISIBILITY +    constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} + +    template <class _OtherElementType, +              enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> +    _LIBCPP_INLINE_VISIBILITY +    constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} + +    template <class _Container> +    _LIBCPP_INLINE_VISIBILITY +        constexpr explicit span(      _Container& __c, +            enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) +        : __data{_VSTD::data(__c)} { +            _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)"); +        } + +    template <class _Container> +    _LIBCPP_INLINE_VISIBILITY +        constexpr explicit span(const _Container& __c, +            enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) +        : __data{_VSTD::data(__c)} { +            _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)"); +        }      template <class _OtherElementType>      _LIBCPP_INLINE_VISIBILITY @@ -234,7 +249,7 @@ public:      template <class _OtherElementType>      _LIBCPP_INLINE_VISIBILITY -        constexpr span(const span<_OtherElementType, dynamic_extent>& __other, +        constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other,                         enable_if_t<                            is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,                            nullptr_t> = nullptr) noexcept @@ -248,7 +263,7 @@ public:      constexpr span<element_type, _Count> first() const noexcept      {          static_assert(_Count <= _Extent, "Count out of range in span::first()"); -        return {data(), _Count}; +        return span<element_type, _Count>{data(), _Count};      }      template <size_t _Count> @@ -256,7 +271,7 @@ public:      constexpr span<element_type, _Count> last() const noexcept      {          static_assert(_Count <= _Extent, "Count out of range in span::last()"); -        return {data() + size() - _Count, _Count}; +        return span<element_type, _Count>{data() + size() - _Count, _Count};      }      _LIBCPP_INLINE_VISIBILITY @@ -279,7 +294,10 @@ public:          -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>      {          static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); -        return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; +        static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()"); + +        using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; +        return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};      } @@ -291,7 +309,7 @@ public:          _LIBCPP_ASSERT(__count  <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");          if (__count == dynamic_extent)              return {data() + __offset, size() - __offset}; -        _LIBCPP_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)"); +        _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");          return {data() + __offset, __count};      } @@ -301,19 +319,19 @@ public:      _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept      { -        _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds"); +        _LIBCPP_ASSERT(__idx < size(), "span<T,N>[] index out of bounds");          return __data[__idx];      }      _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept      { -        static_assert(_Extent > 0, "span<T,N>[].front() on empty span"); +        _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");          return __data[0];      }      _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept      { -        static_assert(_Extent > 0, "span<T,N>[].back() on empty span"); +        _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");          return __data[size()-1];      } @@ -322,25 +340,14 @@ public:  // [span.iter], span iterator support      _LIBCPP_INLINE_VISIBILITY constexpr iterator                 begin() const noexcept { return iterator(data()); }      _LIBCPP_INLINE_VISIBILITY constexpr iterator                   end() const noexcept { return iterator(data() + size()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_iterator          cbegin() const noexcept { return const_iterator(data()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_iterator            cend() const noexcept { return const_iterator(data() + size()); }      _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator        rbegin() const noexcept { return reverse_iterator(end()); }      _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator          rend() const noexcept { return reverse_iterator(begin()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator   crend() const noexcept { return const_reverse_iterator(cbegin()); } - -    _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept -    { -        pointer __p = __data; -        __data = __other.__data; -        __other.__data = __p; -    }      _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept -    { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } +    { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; }      _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept -    { return {reinterpret_cast<byte *>(data()), size_bytes()}; } +    { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; }  private:      pointer    __data; @@ -363,9 +370,7 @@ public:      using reference              = _Tp &;      using const_reference        = const _Tp &;      using iterator               =  __wrap_iter<pointer>; -    using const_iterator         =  __wrap_iter<const_pointer>;      using reverse_iterator       = _VSTD::reverse_iterator<iterator>; -    using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;      static constexpr size_type extent = dynamic_extent; @@ -382,13 +387,15 @@ public:      _LIBCPP_INLINE_VISIBILITY      constexpr span(element_type (&__arr)[_Sz])          noexcept : __data{__arr}, __size{_Sz} {} -    template <size_t _Sz> +    template <class _OtherElementType, size_t _Sz, +              enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>      _LIBCPP_INLINE_VISIBILITY -    constexpr span(array<value_type, _Sz>& __arr)       noexcept : __data{__arr.data()}, __size{_Sz} {} +    constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} -    template <size_t _Sz> +    template <class _OtherElementType, size_t _Sz, +              enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>      _LIBCPP_INLINE_VISIBILITY -    constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} +    constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}      template <class _Container>      _LIBCPP_INLINE_VISIBILITY @@ -418,7 +425,7 @@ public:      constexpr span<element_type, _Count> first() const noexcept      {          _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); -        return {data(), _Count}; +        return span<element_type, _Count>{data(), _Count};      }      template <size_t _Count> @@ -426,7 +433,7 @@ public:      constexpr span<element_type, _Count> last() const noexcept      {          _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); -        return {data() + size() - _Count, _Count}; +        return span<element_type, _Count>{data() + size() - _Count, _Count};      }      _LIBCPP_INLINE_VISIBILITY @@ -445,11 +452,11 @@ public:      template <size_t _Offset, size_t _Count = dynamic_extent>      _LIBCPP_INLINE_VISIBILITY -    constexpr span<_Tp, dynamic_extent> subspan() const noexcept +    constexpr span<element_type, _Count> subspan() const noexcept      {          _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()"); -        _LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()"); -        return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; +        _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "Offset + count out of range in span::subspan()"); +        return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};      }      constexpr span<element_type, dynamic_extent> @@ -460,7 +467,7 @@ public:          _LIBCPP_ASSERT(__count  <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");          if (__count == dynamic_extent)              return {data() + __offset, size() - __offset}; -        _LIBCPP_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)"); +        _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");          return {data() + __offset, __count};      } @@ -470,7 +477,7 @@ public:      _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept      { -        _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds"); +        _LIBCPP_ASSERT(__idx < size(), "span<T>[] index out of bounds");          return __data[__idx];      } @@ -492,23 +499,8 @@ public:  // [span.iter], span iterator support      _LIBCPP_INLINE_VISIBILITY constexpr iterator                 begin() const noexcept { return iterator(data()); }      _LIBCPP_INLINE_VISIBILITY constexpr iterator                   end() const noexcept { return iterator(data() + size()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_iterator          cbegin() const noexcept { return const_iterator(data()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_iterator            cend() const noexcept { return const_iterator(data() + size()); }      _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator        rbegin() const noexcept { return reverse_iterator(end()); }      _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator          rend() const noexcept { return reverse_iterator(begin()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } -    _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator   crend() const noexcept { return const_reverse_iterator(cbegin()); } - -    _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept -    { -        pointer __p = __data; -        __data = __other.__data; -        __other.__data = __p; - -        size_type __sz = __size; -        __size = __other.__size; -        __other.__size = __sz; -    }      _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept      { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } @@ -521,34 +513,6 @@ private:      size_type __size;  }; -//  tuple interface -template <class _Tp, size_t _Size> -struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, _Size>> -    : public integral_constant<size_t, _Size> {}; - -template <class _Tp> -struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, dynamic_extent>>; // declared but not defined - - -template <size_t _Ip, class _Tp, size_t _Size> -struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>> -{ -    static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span<T, dynamic_extent>"); -    static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)"); -    typedef _Tp type; -}; - -template <size_t _Ip, class _Tp, size_t _Size> -_LIBCPP_INLINE_VISIBILITY constexpr -_Tp& -get(span<_Tp, _Size> __s) noexcept -{ -    static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span<T, dynamic_extent>"); -    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)"); -    return __s[_Ip]; -} - -  //  as_bytes & as_writable_bytes  template <class _Tp, size_t _Extent>  _LIBCPP_INLINE_VISIBILITY @@ -562,12 +526,6 @@ auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept  -> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())>  { return __s.__as_writable_bytes(); } -template <class _Tp, size_t _Extent> -_LIBCPP_INLINE_VISIBILITY -constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept -{ __lhs.swap(__rhs); } - -  //  Deduction guides  template<class _Tp, size_t _Sz>      span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; diff --git a/libcxx/include/stddef.h b/libcxx/include/stddef.h index 6497dcda2af4..35c680b4f9a9 100644 --- a/libcxx/include/stddef.h +++ b/libcxx/include/stddef.h @@ -31,7 +31,7 @@ Types:      ptrdiff_t      size_t -    max_align_t +    max_align_t // C++11      nullptr_t  */ @@ -51,12 +51,6 @@ extern "C++" {  using std::nullptr_t;  } -// Re-use the compiler's <stddef.h> max_align_t where possible. -#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \ -    !defined(__DEFINED_max_align_t) && !defined(__NetBSD__) -typedef long double max_align_t; -#endif -  #endif  #endif  // _LIBCPP_STDDEF_H diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept index 481f9043c50d..7a7f36794099 100644 --- a/libcxx/include/stdexcept +++ b/libcxx/include/stdexcept @@ -129,6 +129,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s)   : logic_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    domain_error(const domain_error&) _NOEXCEPT = default;      virtual ~domain_error() _NOEXCEPT;  #endif  }; @@ -141,6 +142,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s)   : logic_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    invalid_argument(const invalid_argument&) _NOEXCEPT = default;      virtual ~invalid_argument() _NOEXCEPT;  #endif  }; @@ -152,6 +154,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {}      _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s)   : logic_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    length_error(const length_error&) _NOEXCEPT = default;      virtual ~length_error() _NOEXCEPT;  #endif  }; @@ -164,6 +167,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s)   : logic_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    out_of_range(const out_of_range&) _NOEXCEPT = default;      virtual ~out_of_range() _NOEXCEPT;  #endif  }; @@ -176,6 +180,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s)   : runtime_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    range_error(const range_error&) _NOEXCEPT = default;      virtual ~range_error() _NOEXCEPT;  #endif  }; @@ -188,6 +193,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s)   : runtime_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    overflow_error(const overflow_error&) _NOEXCEPT = default;      virtual ~overflow_error() _NOEXCEPT;  #endif  }; @@ -200,6 +206,7 @@ public:      _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s)   : runtime_error(__s) {}  #ifndef _LIBCPP_ABI_VCRUNTIME +    underflow_error(const underflow_error&) _NOEXCEPT = default;      virtual ~underflow_error() _NOEXCEPT;  #endif  }; diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h index 1d6827587037..812ea1024edf 100644 --- a/libcxx/include/stdlib.h +++ b/libcxx/include/stdlib.h @@ -7,16 +7,12 @@  //  //===----------------------------------------------------------------------===// -#if defined(__need_malloc_and_calloc) || defined(_LIBCPP_STDLIB_INCLUDE_NEXT) +#if defined(__need_malloc_and_calloc)  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)  #pragma GCC system_header  #endif -#if defined(_LIBCPP_STDLIB_INCLUDE_NEXT) -#undef _LIBCPP_STDLIB_INCLUDE_NEXT -#endif -  #include_next <stdlib.h>  #elif !defined(_LIBCPP_STDLIB_H) @@ -97,7 +93,63 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11  #include_next <stdlib.h>  #ifdef __cplusplus -#include <math.h> +extern "C++" { +// abs + +#undef abs +#undef labs +#ifndef _LIBCPP_HAS_NO_LONG_LONG +#undef llabs +#endif + +// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined +#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX) +inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT { +  return __builtin_labs(__x); +} +#ifndef _LIBCPP_HAS_NO_LONG_LONG +inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT { +  return __builtin_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 __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h +} + +inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT { +  return __builtin_fabs(__lcpp_x); +} + +inline _LIBCPP_INLINE_VISIBILITY long double +abs(long double __lcpp_x) _NOEXCEPT { +  return __builtin_fabsl(__lcpp_x); +} +#endif // !(defined(_AIX) || defined(__sun__)) + +// div + +#undef div +#undef ldiv +#ifndef _LIBCPP_HAS_NO_LONG_LONG +#undef lldiv +#endif + +// MSVCRT already has the correct prototype in <stdlib.h> 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 +} // extern "C++"  #endif  // __cplusplus  #endif  // _LIBCPP_STDLIB_H diff --git a/libcxx/include/string b/libcxx/include/string index 8a0ac844470c..2f846eda06c5 100644 --- a/libcxx/include/string +++ b/libcxx/include/string @@ -437,9 +437,11 @@ basic_istream<charT, traits>&  getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);  template<class charT, class traits, class Allocator, class U> -void erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20 +typename basic_string<charT, traits, Allocator>::size_type +erase(basic_string<charT, traits, Allocator>& c, const U& value);    // C++20  template<class charT, class traits, class Allocator, class Predicate> -void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20 +typename basic_string<charT, traits, Allocator>::size_type +erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20  typedef basic_string<char>    string;  typedef basic_string<wchar_t> wstring; @@ -643,9 +645,10 @@ struct __libcpp_string_gets_noexcept_iterator      : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};  template <class _CharT, class _Traits, class _Tp> -struct __can_be_converted_to_string_view : public _LIBCPP_BOOL_CONSTANT( -    ( is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && -     !is_convertible<const _Tp&, const _CharT*>::value)) {}; +struct __can_be_converted_to_string_view : public _BoolConstant< +      is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value && +     !is_convertible<const _Tp&, const _CharT*>::value +    > {};  #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT @@ -688,13 +691,8 @@ public:      static_assert(( is_same<typename allocator_type::value_type, value_type>::value),                    "Allocator::value_type must be same type as value_type"); -#if defined(_LIBCPP_RAW_ITERATORS) -    typedef pointer                                      iterator; -    typedef const_pointer                                const_iterator; -#else  // defined(_LIBCPP_RAW_ITERATORS)      typedef __wrap_iter<pointer>                         iterator;      typedef __wrap_iter<const_pointer>                   const_iterator; -#endif  // defined(_LIBCPP_RAW_ITERATORS)      typedef _VSTD::reverse_iterator<iterator>             reverse_iterator;      typedef _VSTD::reverse_iterator<const_iterator>       const_reverse_iterator; @@ -784,6 +782,7 @@ private:      __compressed_pair<__rep, allocator_type> __r_;  public: +    _LIBCPP_FUNC_VIS      static const size_type npos = -1;      _LIBCPP_INLINE_VISIBILITY basic_string() @@ -812,7 +811,7 @@ public:      basic_string(basic_string&& __str, const allocator_type& __a);  #endif  // _LIBCPP_CXX03_LANG -    template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type> +    template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >      _LIBCPP_INLINE_VISIBILITY      basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {        _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); @@ -822,7 +821,7 @@ public:  #   endif      } -    template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type> +    template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >          _LIBCPP_INLINE_VISIBILITY          basic_string(const _CharT* __s, const _Allocator& __a); @@ -833,7 +832,7 @@ public:      _LIBCPP_INLINE_VISIBILITY      basic_string(size_type __n, _CharT __c); -    template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type> +    template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >          _LIBCPP_INLINE_VISIBILITY          basic_string(size_type __n, _CharT __c, const _Allocator& __a); @@ -843,23 +842,24 @@ public:      basic_string(const basic_string& __str, size_type __pos,                   const _Allocator& __a = _Allocator()); -    template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> +    template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >          _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS          basic_string(const _Tp& __t, size_type __pos, size_type __n, -                              const allocator_type& __a = allocator_type()); +                     const allocator_type& __a = allocator_type()); -    template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> +    template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && +                                          !__is_same_uncvref<_Tp, basic_string>::value> >          _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS          explicit basic_string(const _Tp& __t); -    template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> +    template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >          _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS          explicit basic_string(const _Tp& __t, const allocator_type& __a); -    template<class _InputIterator, class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value>::type> +    template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> >          _LIBCPP_INLINE_VISIBILITY          basic_string(_InputIterator __first, _InputIterator __last); -    template<class _InputIterator, class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value>::type> +    template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> >          _LIBCPP_INLINE_VISIBILITY          basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);  #ifndef _LIBCPP_CXX03_LANG @@ -876,7 +876,7 @@ public:      basic_string& operator=(const basic_string& __str); -    template <class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type> +    template <class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >      basic_string& operator=(const _Tp& __t)          {__self_view __sv = __t; return assign(__sv);} @@ -976,11 +976,12 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value +            && !__is_same_uncvref<_Tp, basic_string >::value,              basic_string& -        >::type +        >                                              operator+=(const _Tp& __t)            {__self_view __sv = __t; return append(__sv);}      _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s)     {return append(__s);}      _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c)            {push_back(__c); return *this;} @@ -993,21 +994,22 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if -        < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +    _EnableIf< +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value +            && !__is_same_uncvref<_Tp, basic_string>::value,              basic_string& -        >::type +        >                    append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }      basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value +            && !__is_same_uncvref<_Tp, basic_string>::value,              basic_string& -        >::type +        >                    append(const _Tp& __t, size_type __pos, size_type __n=npos);      basic_string& append(const value_type* __s, size_type __n);      basic_string& append(const value_type* __s); @@ -1021,12 +1023,12 @@ public:      basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);      template<class _InputIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __is_exactly_cpp17_input_iterator<_InputIterator>::value                  || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,              basic_string& -        >::type +        >      _LIBCPP_INLINE_VISIBILITY      append(_InputIterator __first, _InputIterator __last) {        const basic_string __temp (__first, __last, __alloc()); @@ -1035,12 +1037,12 @@ public:      }      template<class _ForwardIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __is_cpp17_forward_iterator<_ForwardIterator>::value                  && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,              basic_string& -        >::type +        >      _LIBCPP_INLINE_VISIBILITY      append(_ForwardIterator __first, _ForwardIterator __last) {        return __append_forward_unsafe(__first, __last); @@ -1061,11 +1063,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              basic_string& -        >::type +        >                   assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }      _LIBCPP_INLINE_VISIBILITY      basic_string& assign(const basic_string& __str) { return *this = __str; } @@ -1078,32 +1080,33 @@ public:      basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value +            && !__is_same_uncvref<_Tp, basic_string>::value,              basic_string& -        >::type +        >                    assign(const _Tp & __t, size_type __pos, size_type __n=npos);      basic_string& assign(const value_type* __s, size_type __n);      basic_string& assign(const value_type* __s);      basic_string& assign(size_type __n, value_type __c);      template<class _InputIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <             __is_exactly_cpp17_input_iterator<_InputIterator>::value                  || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,              basic_string& -        >::type +        >          assign(_InputIterator __first, _InputIterator __last);      template<class _ForwardIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __is_cpp17_forward_iterator<_ForwardIterator>::value                   && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,              basic_string& -        >::type +        >          assign(_ForwardIterator __first, _ForwardIterator __last);  #ifndef _LIBCPP_CXX03_LANG      _LIBCPP_INLINE_VISIBILITY @@ -1115,21 +1118,21 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              basic_string& -        >::type +        >                   insert(size_type __pos1, const _Tp& __t)      { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,              basic_string& -        >::type +        >                    insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);      basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);      basic_string& insert(size_type __pos, const value_type* __s, size_type __n); @@ -1140,21 +1143,21 @@ public:      iterator      insert(const_iterator __pos, size_type __n, value_type __c);      template<class _InputIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <             __is_exactly_cpp17_input_iterator<_InputIterator>::value                  || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,              iterator -        >::type +        >          insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);      template<class _ForwardIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __is_cpp17_forward_iterator<_ForwardIterator>::value                   && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,              iterator -        >::type +        >          insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);  #ifndef _LIBCPP_CXX03_LANG      _LIBCPP_INLINE_VISIBILITY @@ -1173,20 +1176,20 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              basic_string& -        >::type +        >                    replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }      basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,              basic_string& -        >::type +        >                    replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);      basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);      basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); @@ -1196,11 +1199,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              basic_string& -        >::type +        >                    replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }      _LIBCPP_INLINE_VISIBILITY @@ -1211,11 +1214,11 @@ public:      basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);      template<class _InputIterator>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __is_cpp17_input_iterator<_InputIterator>::value,              basic_string& -        >::type +        >          replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);  #ifndef _LIBCPP_CXX03_LANG      _LIBCPP_INLINE_VISIBILITY @@ -1253,11 +1256,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              size_type -        >::type +        >                find(const _Tp& __t, size_type __pos = 0) const;      size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY @@ -1269,11 +1272,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              size_type -        >::type +        >                rfind(const _Tp& __t, size_type __pos = npos) const;      size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY @@ -1285,11 +1288,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              size_type -        >::type +        >                find_first_of(const _Tp& __t, size_type __pos = 0) const;      size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY @@ -1302,11 +1305,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              size_type -        >::type +        >                find_last_of(const _Tp& __t, size_type __pos = npos) const;      size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY @@ -1319,11 +1322,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              size_type -        >::type +        >                find_first_not_of(const _Tp &__t, size_type __pos = 0) const;      size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY @@ -1336,11 +1339,11 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              size_type -        >::type +        >                find_last_not_of(const _Tp& __t, size_type __pos = npos) const;      size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY @@ -1353,20 +1356,20 @@ public:      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              int -        >::type +        >          compare(const _Tp &__t) const;      template <class _Tp>      _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -    typename enable_if +    _EnableIf          <              __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,              int -        >::type +        >           compare(size_type __pos1, size_type __n1, const _Tp& __t) const;      _LIBCPP_INLINE_VISIBILITY @@ -1375,11 +1378,11 @@ public:      template <class _Tp>      inline _LIBCPP_INLINE_VISIBILITY -        typename enable_if +        _EnableIf          < -            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +            __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string>::value,              int -        >::type +        >          compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;      int compare(const value_type* __s) const _NOEXCEPT;      int compare(size_type __pos1, size_type __n1, const value_type* __s) const; @@ -1543,22 +1546,30 @@ private:      inline      void __init(size_type __n, value_type __c); +    // Slow path for the (inlined) copy constructor for 'long' strings. +    // Always externally instantiated and not inlined. +    // Requires that __s is zero terminated. +    // The main reason for this function to exist is because for unstable, we +    // want to allow inlining of the copy constructor. However, we don't want +    // to call the __init() functions as those are marked as inline which may +    // result in over-aggressive inlining by the compiler, where our aim is +    // to only inline the fast path code directly in the ctor. +    void __init_copy_ctor_external(const value_type* __s, size_type __sz); +      template <class _InputIterator>      inline -    typename enable_if +    _EnableIf      < -        __is_exactly_cpp17_input_iterator<_InputIterator>::value, -        void -    >::type +        __is_exactly_cpp17_input_iterator<_InputIterator>::value +    >      __init(_InputIterator __first, _InputIterator __last);      template <class _ForwardIterator>      inline -    typename enable_if +    _EnableIf      < -        __is_cpp17_forward_iterator<_ForwardIterator>::value, -        void -    >::type +        __is_cpp17_forward_iterator<_ForwardIterator>::value +    >      __init(_ForwardIterator __first, _ForwardIterator __last);      void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, @@ -1567,9 +1578,19 @@ private:                                 size_type __n_copy,  size_type __n_del,                                 size_type __n_add, const value_type* __p_new_stuff); +    // __assign_no_alias is invoked for assignment operations where we +    // have proof that the input does not alias the current instance. +    // For example, operator=(basic_string) performs a 'self' check. +    template <bool __is_short> +    basic_string& __assign_no_alias(const value_type* __s, size_type __n); +      _LIBCPP_INLINE_VISIBILITY      void __erase_to_end(size_type __pos); +    // __erase_external_with_move is invoked for erase() invocations where +    // `n ~= npos`, likely requiring memory moves on the string data. +    void __erase_external_with_move(size_type __pos, size_type __n); +      _LIBCPP_INLINE_VISIBILITY      void __copy_assign_alloc(const basic_string& __str)          {__copy_assign_alloc(__str, integral_constant<bool, @@ -1638,6 +1659,19 @@ private:          _NOEXCEPT          {} +    basic_string& __assign_external(const value_type* __s); +    basic_string& __assign_external(const value_type* __s, size_type __n); + +    // Assigns the value in __s, guaranteed to be __n < __min_cap in length. +    inline basic_string& __assign_short(const value_type* __s, size_type __n) { +      pointer __p = __is_long() +                        ? (__set_long_size(__n), __get_long_pointer()) +                        : (__set_short_size(__n), __get_short_pointer()); +      traits_type::move(_VSTD::__to_address(__p), __s, __n); +      traits_type::assign(__p[__n], value_type()); +      return *this; +    } +      _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();      _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type); @@ -1648,12 +1682,23 @@ private:      friend basic_string operator+<>(const basic_string&, value_type);  }; +// These declarations must appear before any functions are implicitly used +// so that they have the correct visibility specifier. +#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION +_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) +_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) +#else +_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char) +_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t) +#endif + +  #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES  template<class _InputIterator,           class _CharT = typename iterator_traits<_InputIterator>::value_type,           class _Allocator = allocator<_CharT>, -         class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value, void>::type, -         class = typename enable_if<__is_allocator<_Allocator>::value, void>::type +         class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>, +         class = _EnableIf<__is_allocator<_Allocator>::value>           >  basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())    -> basic_string<_CharT, char_traits<_CharT>, _Allocator>; @@ -1661,7 +1706,7 @@ basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())  template<class _CharT,           class _Traits,           class _Allocator = allocator<_CharT>, -         class = typename enable_if<__is_allocator<_Allocator>::value, void>::type +         class = _EnableIf<__is_allocator<_Allocator>::value>           >  explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())    -> basic_string<_CharT, _Traits, _Allocator>; @@ -1669,14 +1714,13 @@ explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _A  template<class _CharT,           class _Traits,           class _Allocator = allocator<_CharT>, -         class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, +         class = _EnableIf<__is_allocator<_Allocator>::value>,           class _Sz = typename allocator_traits<_Allocator>::size_type           >  basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())    -> basic_string<_CharT, _Traits, _Allocator>;  #endif -  template <class _CharT, class _Traits, class _Allocator>  inline  void @@ -1837,7 +1881,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st      if (!__str.__is_long())          __r_.first().__r = __str.__r_.first().__r;      else -        __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); +        __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), +                                  __str.__get_long_size()); +  #if _LIBCPP_DEBUG_LEVEL >= 2      __get_db()->__insert_c(this);  #endif @@ -1851,12 +1897,32 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(      if (!__str.__is_long())          __r_.first().__r = __str.__r_.first().__r;      else -        __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); +        __init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()), +                                  __str.__get_long_size());  #if _LIBCPP_DEBUG_LEVEL >= 2      __get_db()->__insert_c(this);  #endif  } +template <class _CharT, class _Traits, class _Allocator> +void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( +    const value_type* __s, size_type __sz) { +  pointer __p; +  if (__sz < __min_cap) { +    __p = __get_short_pointer(); +    __set_short_size(__sz); +  } else { +    if (__sz > max_size()) +      this->__throw_length_error(); +    size_t __cap = __recommend(__sz); +    __p = __alloc_traits::allocate(__alloc(), __cap + 1); +    __set_long_pointer(__p); +    __set_long_cap(__cap + 1); +    __set_long_size(__sz); +  } +  traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1); +} +  #ifndef _LIBCPP_CXX03_LANG  template <class _CharT, class _Traits, class _Allocator> @@ -2014,11 +2080,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _  template <class _CharT, class _Traits, class _Allocator>  template <class _InputIterator> -typename enable_if +_EnableIf  < -    __is_exactly_cpp17_input_iterator<_InputIterator>::value, -    void ->::type +    __is_exactly_cpp17_input_iterator<_InputIterator>::value +>  basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)  {      __zero(); @@ -2041,11 +2106,10 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input  template <class _CharT, class _Traits, class _Allocator>  template <class _ForwardIterator> -typename enable_if +_EnableIf  < -    __is_cpp17_forward_iterator<_ForwardIterator>::value, -    void ->::type +    __is_cpp17_forward_iterator<_ForwardIterator>::value +>  basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)  {      size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last)); @@ -2198,25 +2262,50 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t  // assign  template <class _CharT, class _Traits, class _Allocator> +template <bool __is_short> +basic_string<_CharT, _Traits, _Allocator>& +basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( +    const value_type* __s, size_type __n) { +  size_type __cap = __is_short ? __min_cap : __get_long_cap(); +  if (__n < __cap) { +    pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer(); +    __is_short ? __set_short_size(__n) : __set_long_size(__n); +    traits_type::copy(_VSTD::__to_address(__p), __s, __n); +    traits_type::assign(__p[__n], value_type()); +    __invalidate_iterators_past(__n); +  } else { +    size_type __sz = __is_short ? __get_short_size() : __get_long_size(); +    __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); +  } +  return *this; +} + +template <class _CharT, class _Traits, class _Allocator> +basic_string<_CharT, _Traits, _Allocator>& +basic_string<_CharT, _Traits, _Allocator>::__assign_external( +    const value_type* __s, size_type __n) { +  size_type __cap = capacity(); +  if (__cap >= __n) { +    value_type* __p = _VSTD::__to_address(__get_pointer()); +    traits_type::move(__p, __s, __n); +    traits_type::assign(__p[__n], value_type()); +    __set_size(__n); +    __invalidate_iterators_past(__n); +  } else { +    size_type __sz = size(); +    __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); +  } +  return *this; +} + +template <class _CharT, class _Traits, class _Allocator>  basic_string<_CharT, _Traits, _Allocator>&  basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)  {      _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); -    size_type __cap = capacity(); -    if (__cap >= __n) -    { -        value_type* __p = _VSTD::__to_address(__get_pointer()); -        traits_type::move(__p, __s, __n); -        traits_type::assign(__p[__n], value_type()); -        __set_size(__n); -        __invalidate_iterators_past(__n); -    } -    else -    { -        size_type __sz = size(); -        __grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s); -    } -    return *this; +    return (_LIBCPP_BUILTIN_CONSTANT_P(__n) && __n < __min_cap) +               ? __assign_short(__s, __n) +               : __assign_external(__s, __n);  }  template <class _CharT, class _Traits, class _Allocator> @@ -2263,12 +2352,19 @@ template <class _CharT, class _Traits, class _Allocator>  basic_string<_CharT, _Traits, _Allocator>&  basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)  { -    if (this != &__str) -    { -        __copy_assign_alloc(__str); -        return assign(__str.data(), __str.size()); +  if (this != &__str) { +    __copy_assign_alloc(__str); +    if (!__is_long()) { +      if (!__str.__is_long()) { +        __r_.first().__r = __str.__r_.first().__r; +      } else { +        return __assign_no_alias<true>(__str.data(), __str.size()); +      } +    } else { +      return __assign_no_alias<false>(__str.data(), __str.size());      } -    return *this; +  } +  return *this;  }  #ifndef _LIBCPP_CXX03_LANG @@ -2326,12 +2422,12 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)  template <class _CharT, class _Traits, class _Allocator>  template<class _InputIterator> -typename enable_if +_EnableIf  <       __is_exactly_cpp17_input_iterator <_InputIterator>::value            || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,      basic_string<_CharT, _Traits, _Allocator>& ->::type +>  basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)  {      const basic_string __temp(__first, __last, __alloc()); @@ -2341,12 +2437,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input  template <class _CharT, class _Traits, class _Allocator>  template<class _ForwardIterator> -typename enable_if +_EnableIf  <      __is_cpp17_forward_iterator<_ForwardIterator>::value           && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,      basic_string<_CharT, _Traits, _Allocator>& ->::type +>  basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)  {      size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); @@ -2378,11 +2474,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  < -    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value +    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,      basic_string<_CharT, _Traits, _Allocator>& ->::type +>  basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)  {      __self_view __sv = __t; @@ -2395,12 +2492,21 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p  template <class _CharT, class _Traits, class _Allocator>  basic_string<_CharT, _Traits, _Allocator>& +basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) { +  return __assign_external(__s, traits_type::length(__s)); +} + +template <class _CharT, class _Traits, class _Allocator> +basic_string<_CharT, _Traits, _Allocator>&  basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)  {      _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); -    return assign(__s, traits_type::length(__s)); +    return _LIBCPP_BUILTIN_CONSTANT_P(*__s) +               ? (traits_type::length(__s) < __min_cap +                      ? __assign_short(__s, traits_type::length(__s)) +                      : __assign_external(__s, traits_type::length(__s))) +               : __assign_external(__s);  } -  // append  template <class _CharT, class _Traits, class _Allocator> @@ -2565,11 +2671,11 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -    typename enable_if +    _EnableIf      < -        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +        __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,          basic_string<_CharT, _Traits, _Allocator>& -    >::type +    >  basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)  {      __self_view __sv = __t; @@ -2654,12 +2760,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n  template <class _CharT, class _Traits, class _Allocator>  template<class _InputIterator> -typename enable_if +_EnableIf  <     __is_exactly_cpp17_input_iterator<_InputIterator>::value          || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,     typename basic_string<_CharT, _Traits, _Allocator>::iterator ->::type +>  basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)  {  #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -2673,12 +2779,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt  template <class _CharT, class _Traits, class _Allocator>  template<class _ForwardIterator> -typename enable_if +_EnableIf  <      __is_cpp17_forward_iterator<_ForwardIterator>::value          && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,      typename basic_string<_CharT, _Traits, _Allocator>::iterator ->::type +>  basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)  {  #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -2743,11 +2849,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  < -    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value  && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,      basic_string<_CharT, _Traits, _Allocator>& ->::type +>  basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,                                                    size_type __pos2, size_type __n)  { @@ -2852,8 +2958,8 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __          }          traits_type::move(__p + __pos, __s, __n2);  __finish: -// __sz += __n2 - __n1; in this and the below function below can cause unsigned integer overflow, -// but this is a safe operation, so we disable the check. +// __sz += __n2 - __n1; in this and the below function below can cause unsigned +// integer overflow, but this is a safe operation, so we disable the check.          __sz += __n2 - __n1;          __set_size(__sz);          __invalidate_iterators_past(__sz); @@ -2900,11 +3006,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __  template <class _CharT, class _Traits, class _Allocator>  template<class _InputIterator> -typename enable_if +_EnableIf  <      __is_cpp17_input_iterator<_InputIterator>::value,      basic_string<_CharT, _Traits, _Allocator>& ->::type +>  basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,                                                     _InputIterator __j1, _InputIterator __j2)  { @@ -2933,11 +3039,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  < -    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,      basic_string<_CharT, _Traits, _Allocator>& ->::type +>  basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,                                                     size_type __pos2, size_type __n2)  { @@ -2991,15 +3097,16 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it  // erase +// 'externally instantiated' erase() implementation, called when __n != npos. +// Does not check __pos against size()  template <class _CharT, class _Traits, class _Allocator> -basic_string<_CharT, _Traits, _Allocator>& -basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) +void +basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move( +    size_type __pos, size_type __n)  { -    size_type __sz = size(); -    if (__pos > __sz) -        this->__throw_out_of_range();      if (__n)      { +        size_type __sz = size();          value_type* __p = _VSTD::__to_address(__get_pointer());          __n = _VSTD::min(__n, __sz - __pos);          size_type __n_move = __sz - __pos - __n; @@ -3010,7 +3117,19 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)          __invalidate_iterators_past(__sz);          traits_type::assign(__p[__sz], value_type());      } -    return *this; +} + +template <class _CharT, class _Traits, class _Allocator> +basic_string<_CharT, _Traits, _Allocator>& +basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, +                                                 size_type __n) { +  if (__pos > size()) this->__throw_out_of_range(); +  if (__n == npos) { +    __erase_to_end(__pos); +  } else { +    __erase_external_with_move(__pos, __n); +  } +  return *this;  }  template <class _CharT, class _Traits, class _Allocator> @@ -3356,11 +3475,11 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,  template<class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      typename basic_string<_CharT, _Traits, _Allocator>::size_type ->::type +>  basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,                                                  size_type __pos) const  { @@ -3414,11 +3533,11 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,  template<class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      typename basic_string<_CharT, _Traits, _Allocator>::size_type ->::type +>  basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,                                                  size_type __pos) const  { @@ -3472,11 +3591,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s  template<class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      typename basic_string<_CharT, _Traits, _Allocator>::size_type ->::type +>  basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,                                                  size_type __pos) const  { @@ -3530,11 +3649,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st  template<class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      typename basic_string<_CharT, _Traits, _Allocator>::size_type ->::type +>  basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,                                                  size_type __pos) const  { @@ -3588,11 +3707,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string&  template<class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      typename basic_string<_CharT, _Traits, _Allocator>::size_type ->::type +>  basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,                                                  size_type __pos) const  { @@ -3647,11 +3766,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string&  template<class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      typename basic_string<_CharT, _Traits, _Allocator>::size_type ->::type +>  basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,                                                  size_type __pos) const  { @@ -3685,11 +3804,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      int ->::type +>  basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const  {      __self_view __sv = __t; @@ -3739,11 +3858,11 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  <      __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,      int ->::type +>  basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,                                                     size_type __n1,                                                     const _Tp& __t) const @@ -3764,11 +3883,12 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,  template <class _CharT, class _Traits, class _Allocator>  template <class _Tp> -typename enable_if +_EnableIf  < -    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, +    __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value +    && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,      int ->::type +>  basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,                                                     size_type __n1,                                                     const _Tp& __t, @@ -4230,8 +4350,9 @@ _LIBCPP_FUNC_VIS wstring to_wstring(double __val);  _LIBCPP_FUNC_VIS wstring to_wstring(long double __val);  template<class _CharT, class _Traits, class _Allocator> -    const typename basic_string<_CharT, _Traits, _Allocator>::size_type -                   basic_string<_CharT, _Traits, _Allocator>::npos; +_LIBCPP_FUNC_VIS +const typename basic_string<_CharT, _Traits, _Allocator>::size_type +               basic_string<_CharT, _Traits, _Allocator>::npos;  template <class _CharT, class _Allocator>  struct _LIBCPP_TEMPLATE_VIS @@ -4283,15 +4404,25 @@ getline(basic_istream<_CharT, _Traits>&& __is,  #endif  // _LIBCPP_CXX03_LANG  #if _LIBCPP_STD_VER > 17 -template<class _CharT, class _Traits, class _Allocator, class _Up> +template <class _CharT, class _Traits, class _Allocator, class _Up>  inline _LIBCPP_INLINE_VISIBILITY -void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) -{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); } +    typename basic_string<_CharT, _Traits, _Allocator>::size_type +    erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) { +  auto __old_size = __str.size(); +  __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); +  return __old_size - __str.size(); +} -template<class _CharT, class _Traits, class _Allocator, class _Predicate> +template <class _CharT, class _Traits, class _Allocator, class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) -{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); } +    typename basic_string<_CharT, _Traits, _Allocator>::size_type +    erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, +             _Predicate __pred) { +  auto __old_size = __str.size(); +  __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), +              __str.end()); +  return __old_size - __str.size(); +}  #endif  #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -4330,9 +4461,6 @@ basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator*  #endif  // _LIBCPP_DEBUG_LEVEL >= 2 -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<wchar_t>) -  #if _LIBCPP_STD_VER > 11  // Literal suffixes for basic_string [basic.string.literals]  inline namespace literals diff --git a/libcxx/include/system_error b/libcxx/include/system_error index 05ef07950d05..74e889aa9ac7 100644 --- a/libcxx/include/system_error +++ b/libcxx/include/system_error @@ -469,6 +469,7 @@ public:      system_error(int __ev, const error_category& __ecat, const string& __what_arg);      system_error(int __ev, const error_category& __ecat, const char* __what_arg);      system_error(int __ev, const error_category& __ecat); +    system_error(const system_error&) _NOEXCEPT = default;      ~system_error() _NOEXCEPT;      _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/include/thread b/libcxx/include/thread index 3b55342288d1..6eff1800acdb 100644 --- a/libcxx/include/thread +++ b/libcxx/include/thread @@ -241,12 +241,19 @@ public:  #endif      ~thread(); -#ifndef _LIBCPP_CXX03_LANG      _LIBCPP_INLINE_VISIBILITY -    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = _LIBCPP_NULL_THREAD;} +    thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { +        __t.__t_ = _LIBCPP_NULL_THREAD; +    } +      _LIBCPP_INLINE_VISIBILITY -    thread& operator=(thread&& __t) _NOEXCEPT; -#endif  // _LIBCPP_CXX03_LANG +    thread& operator=(thread&& __t) _NOEXCEPT { +        if (!__libcpp_thread_isnull(&__t_)) +            terminate(); +        __t_ = __t.__t_; +        __t.__t_ = _LIBCPP_NULL_THREAD; +        return *this; +    }      _LIBCPP_INLINE_VISIBILITY      void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} @@ -304,17 +311,6 @@ thread::thread(_Fp&& __f, _Args&&... __args)          __throw_system_error(__ec, "thread constructor failed");  } -inline -thread& -thread::operator=(thread&& __t) _NOEXCEPT -{ -    if (!__libcpp_thread_isnull(&__t_)) -        terminate(); -    __t_ = __t.__t_; -    __t.__t_ = _LIBCPP_NULL_THREAD; -    return *this; -} -  #else  // _LIBCPP_CXX03_LANG  template <class _Fp> @@ -369,9 +365,9 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)      {  #if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)      //  GCC's long double const folding is incomplete for IBM128 long doubles. -        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max(); -#else          _LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ; +#else +        _LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();  #endif          nanoseconds __ns;          if (__d < _Max) diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index c0c3934afccc..be031037d676 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -544,6 +544,18 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp  // is_same +#if __has_keyword(__is_same) + +template <class _Tp, class _Up> +struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp, class _Up> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v = __is_same(_Tp, _Up); +#endif + +#else +  template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same           : public false_type {};  template <class _Tp>            struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {}; @@ -553,6 +565,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v      = is_same<_Tp, _Up>::value;  #endif +#endif // __is_same +  template <class _Tp, class _Up>  using _IsSame = _BoolConstant<  #ifdef __clang__ @@ -656,6 +670,18 @@ struct __two {char __lx[2];};  // is_const +#if __has_keyword(__is_const) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v = __is_const(_Tp); +#endif + +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const            : public false_type {};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; @@ -665,8 +691,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v      = is_const<_Tp>::value;  #endif +#endif // __has_keyword(__is_const) +  // is_volatile +#if __has_keyword(__is_volatile) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v = __is_volatile(_Tp); +#endif + +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile               : public false_type {};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; @@ -676,37 +716,87 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v      = is_volatile<_Tp>::value;  #endif +#endif // __has_keyword(__is_volatile) +  // remove_const +#if __has_keyword(__remove_const) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS remove_const {typedef __remove_const(_Tp) type;}; + +#if _LIBCPP_STD_VER > 11 +template <class _Tp> using remove_const_t = __remove_const(_Tp); +#endif + +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const            {typedef _Tp type;};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};  #if _LIBCPP_STD_VER > 11  template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;  #endif +#endif // __has_keyword(__remove_const) +  // remove_volatile +#if __has_keyword(__remove_volatile) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef __remove_volatile(_Tp) type;}; + +#if _LIBCPP_STD_VER > 11 +template <class _Tp> using remove_volatile_t = __remove_volatile(_Tp); +#endif + +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile               {typedef _Tp type;};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};  #if _LIBCPP_STD_VER > 11  template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;  #endif +#endif // __has_keyword(__remove_volatile) +  // remove_cv +#if __has_keyword(__remove_cv) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef __remove_cv(_Tp) type;}; + +#if _LIBCPP_STD_VER > 11 +template <class _Tp> using remove_cv_t = __remove_cv(_Tp); +#endif + +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv  {typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};  #if _LIBCPP_STD_VER > 11  template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;  #endif +#endif // __has_keyword(__remove_cv) +  // is_void -template <class _Tp> struct __libcpp_is_void       : public false_type {}; -template <>          struct __libcpp_is_void<void> : public true_type {}; +#if __has_keyword(__is_void) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v = __is_void(_Tp); +#endif + +#else  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void -    : public __libcpp_is_void<typename remove_cv<_Tp>::type> {}; +    : public is_same<typename remove_cv<_Tp>::type, void> {};  #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)  template <class _Tp> @@ -714,6 +804,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v      = is_void<_Tp>::value;  #endif +#endif // __has_keyword(__is_void) +  // __is_nullptr_t  template <class _Tp> struct __is_nullptr_t_impl       : public false_type {}; @@ -735,34 +827,20 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_null_pointer_v  // is_integral -template <class _Tp> struct __libcpp_is_integral                     : public false_type {}; -template <>          struct __libcpp_is_integral<bool>               : public true_type {}; -template <>          struct __libcpp_is_integral<char>               : public true_type {}; -template <>          struct __libcpp_is_integral<signed char>        : public true_type {}; -template <>          struct __libcpp_is_integral<unsigned char>      : public true_type {}; -template <>          struct __libcpp_is_integral<wchar_t>            : public true_type {}; -#ifndef _LIBCPP_NO_HAS_CHAR8_T -template <>          struct __libcpp_is_integral<char8_t>            : public true_type {}; -#endif -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS -template <>          struct __libcpp_is_integral<char16_t>           : public true_type {}; -template <>          struct __libcpp_is_integral<char32_t>           : public true_type {}; -#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS -template <>          struct __libcpp_is_integral<short>              : public true_type {}; -template <>          struct __libcpp_is_integral<unsigned short>     : public true_type {}; -template <>          struct __libcpp_is_integral<int>                : public true_type {}; -template <>          struct __libcpp_is_integral<unsigned int>       : public true_type {}; -template <>          struct __libcpp_is_integral<long>               : public true_type {}; -template <>          struct __libcpp_is_integral<unsigned long>      : public true_type {}; -template <>          struct __libcpp_is_integral<long long>          : public true_type {}; -template <>          struct __libcpp_is_integral<unsigned long long> : public true_type {}; -#ifndef _LIBCPP_HAS_NO_INT128 -template <>          struct __libcpp_is_integral<__int128_t>         : public true_type {}; -template <>          struct __libcpp_is_integral<__uint128_t>        : public true_type {}; +#if __has_keyword(__is_integral) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v = __is_integral(_Tp);  #endif +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral -    : public __libcpp_is_integral<typename remove_cv<_Tp>::type> {}; +    : public _BoolConstant<__libcpp_is_integral<typename remove_cv<_Tp>::type>::value> {};  #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)  template <class _Tp> @@ -770,6 +848,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v      = is_integral<_Tp>::value;  #endif +#endif // __has_keyword(__is_integral) +  // is_floating_point  template <class _Tp> struct __libcpp_is_floating_point              : public false_type {}; @@ -788,6 +868,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_floating_point_v  // is_array +#if __has_keyword(__is_array) + +template <class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v = __is_array(_Tp); +#endif + +#else +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array      : public false_type {};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]> @@ -801,8 +893,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v      = is_array<_Tp>::value;  #endif +#endif // __has_keyword(__is_array) +  // is_pointer +// In clang 10.0.0 and earlier __is_pointer didn't work with Objective-C types. +#if __has_keyword(__is_pointer) && _LIBCPP_CLANG_VER > 1000 + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v = __is_pointer(_Tp); +#endif + +#else // __has_keyword(__is_pointer) +  template <class _Tp> struct __libcpp_is_pointer       : public false_type {};  template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {}; @@ -823,8 +930,36 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v      = is_pointer<_Tp>::value;  #endif +#endif // __has_keyword(__is_pointer) +  // is_reference +#if __has_keyword(__is_lvalue_reference) && \ +    __has_keyword(__is_rvalue_reference) && \ +    __has_keyword(__is_reference) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { }; + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { }; + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v = __is_reference(_Tp); + +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v = __is_lvalue_reference(_Tp); + +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = __is_rvalue_reference(_Tp); +#endif + +#else // __has_keyword(__is_lvalue_reference) && etc... +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference       : public false_type {};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; @@ -848,6 +983,9 @@ template <class _Tp>  _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v      = is_rvalue_reference<_Tp>::value;  #endif + +#endif // __has_keyword(__is_lvalue_reference) && etc... +  // is_union  #if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC) @@ -928,6 +1066,19 @@ template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {    };  }; +#if __has_keyword(__is_member_function_pointer) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer +    : _BoolConstant<__is_member_function_pointer(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v +    = __is_member_function_pointer(_Tp); +#endif + +#else // __has_keyword(__is_member_function_pointer)  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer      : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {}; @@ -938,8 +1089,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v      = is_member_function_pointer<_Tp>::value;  #endif +#endif // __has_keyword(__is_member_function_pointer) +  // is_member_pointer +#if __has_keyword(__is_member_pointer) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v = __is_member_pointer(_Tp); +#endif + +#else // __has_keyword(__is_member_pointer) +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer   : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {}; @@ -949,8 +1114,24 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v      = is_member_pointer<_Tp>::value;  #endif +#endif // __has_keyword(__is_member_pointer) +  // is_member_object_pointer +#if __has_keyword(__is_member_object_pointer) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer +    : _BoolConstant<__is_member_object_pointer(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v +    = __is_member_object_pointer(_Tp); +#endif + +#else // __has_keyword(__is_member_object_pointer) +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer      : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj >  {}; @@ -960,6 +1141,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v      = is_member_object_pointer<_Tp>::value;  #endif +#endif // __has_keyword(__is_member_object_pointer) +  // is_enum  #if __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC) @@ -967,6 +1150,11 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum      : public integral_constant<bool, __is_enum(_Tp)> {}; +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_enum_v = __is_enum(_Tp); +#endif +  #else  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum @@ -981,16 +1169,17 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum                                       !is_class<_Tp>::value            &&                                       !is_function<_Tp>::value         > {}; -#endif -  #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)  template <class _Tp>  _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_enum_v      = is_enum<_Tp>::value;  #endif +#endif // __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC) +  // is_arithmetic +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic      : public integral_constant<bool, is_integral<_Tp>::value      ||                                       is_floating_point<_Tp>::value> {}; @@ -1003,6 +1192,20 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_arithmetic_v  // is_fundamental +// In clang 9 and lower, this builtin did not work for nullptr_t. Additionally, in C++03 mode, +// nullptr isn't defined by the compiler so, this builtin won't work. +#if __has_keyword(__is_fundamental) && _LIBCPP_CLANG_VER > 900 && !defined(_LIBCPP_CXX03_LANG) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v = __is_fundamental(_Tp); +#endif + +#else // __has_keyword(__is_fundamental) +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental      : public integral_constant<bool, is_void<_Tp>::value        ||                                       __is_nullptr_t<_Tp>::value || @@ -1014,13 +1217,34 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v      = is_fundamental<_Tp>::value;  #endif +#endif // __has_keyword(__is_fundamental) +  // is_scalar +// >= 11 because in C++03 nullptr isn't actually nullptr +#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v = __is_scalar(_Tp); +#endif + +#else // __has_keyword(__is_scalar) + +template <class _Tp> struct __is_block : false_type {}; +#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) +template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {}; +#endif +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar      : public integral_constant<bool, is_arithmetic<_Tp>::value     ||                                       is_member_pointer<_Tp>::value ||                                       is_pointer<_Tp>::value        ||                                       __is_nullptr_t<_Tp>::value    || +                                     __is_block<_Tp>::value        ||                                       is_enum<_Tp>::value           > {};  template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {}; @@ -1031,8 +1255,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v      = is_scalar<_Tp>::value;  #endif +#endif // __has_keyword(__is_scalar) +  // is_object +#if __has_keyword(__is_object) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v = __is_object(_Tp); +#endif + +#else // __has_keyword(__is_object) +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object      : public integral_constant<bool, is_scalar<_Tp>::value ||                                       is_array<_Tp>::value  || @@ -1045,8 +1283,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v      = is_object<_Tp>::value;  #endif +#endif // __has_keyword(__is_object) +  // is_compound +// >= 11 because in C++03 nullptr isn't actually nullptr +#if __has_keyword(__is_compound) && !defined(_LIBCPP_CXX03_LANG) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v = __is_compound(_Tp); +#endif + +#else // __has_keyword(__is_compound) +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound      : public integral_constant<bool, !is_fundamental<_Tp>::value> {}; @@ -1056,6 +1309,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v      = is_compound<_Tp>::value;  #endif +#endif // __has_keyword(__is_compound)  // __is_referenceable  [defns.referenceable] @@ -1100,6 +1354,13 @@ template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;  // remove_reference +#if __has_keyword(__remove_reference) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS remove_reference { typedef __remove_reference(_Tp) type; }; + +#else // __has_keyword(__remove_reference) +  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference        {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&>  {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; @@ -1108,6 +1369,8 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typede  template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;  #endif +#endif // __has_keyword(__remove_reference) +  // add_lvalue_reference  template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl            { typedef _LIBCPP_NODEBUG_TYPE _Tp  type; }; @@ -1215,6 +1478,19 @@ template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;  // is_signed +// In clang 9 and earlier, this builtin did not work for floating points or enums +#if __has_keyword(__is_signed) && _LIBCPP_CLANG_VER > 900 + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v = __is_signed(_Tp); +#endif + +#else // __has_keyword(__is_signed) +  template <class _Tp, bool = is_integral<_Tp>::value>  struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {}; @@ -1234,8 +1510,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v      = is_signed<_Tp>::value;  #endif +#endif // __has_keyword(__is_signed) +  // is_unsigned +#if __has_keyword(__is_unsigned) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v = __is_unsigned(_Tp); +#endif + +#else // __has_keyword(__is_unsigned) +  template <class _Tp, bool = is_integral<_Tp>::value>  struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {}; @@ -1255,6 +1545,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v      = is_unsigned<_Tp>::value;  #endif +#endif // __has_keyword(__is_unsigned) +  // rank  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank @@ -1272,6 +1564,19 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t rank_v  // extent +#if __has_keyword(__array_extent) + +template<class _Tp, size_t _Dim = 0> +struct _LIBCPP_TEMPLATE_VIS extent +    : integral_constant<size_t, __array_extent(_Tp, _Dim)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp, unsigned _Ip = 0> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v = __array_extent(_Tp, _Ip); +#endif + +#else // __has_keyword(__array_extent) +  template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent      : public integral_constant<size_t, 0> {};  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> @@ -1289,6 +1594,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v      = extent<_Tp, _Ip>::value;  #endif +#endif // __has_keyword(__array_extent) +  // remove_extent  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent @@ -2041,9 +2348,33 @@ struct _LIBCPP_TEMPLATE_VIS make_unsigned  template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;  #endif +#if _LIBCPP_STD_VER > 14 +template <class...> using void_t = void; +#endif + +#if _LIBCPP_STD_VER > 17 +// Let COND_RES(X, Y) be: +template <class _Tp, class _Up> +using __cond_type = decltype(false ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>()); + +template <class _Tp, class _Up, class = void> +struct __common_type3 {}; + +// sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..." +template <class _Tp, class _Up> +struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>> +{ +    using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>; +}; + +template <class _Tp, class _Up, class = void> +struct __common_type2_imp : __common_type3<_Tp, _Up> {}; +#else  template <class _Tp, class _Up, class = void>  struct __common_type2_imp {}; +#endif +// sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."  template <class _Tp, class _Up>  struct __common_type2_imp<_Tp, _Up,                            typename __void_t<decltype( @@ -2107,6 +2438,7 @@ struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>  // bullet 3 - sizeof...(Tp) == 2 +// sub-bullet 1 - "If is_same_v<T1, D1> is false or ..."  template <class _Tp, class _Up>  struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up>      : conditional< @@ -2134,6 +2466,18 @@ template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type  template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; }; +#if __has_keyword(__is_assignable) + +template<class _Tp, class _Up> +struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp, class _Arg> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = __is_assignable(_Tp, _Arg); +#endif + +#else // __has_keyword(__is_assignable) +  template <class _Tp, class _Arg>  typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type  __is_assignable_test(int); @@ -2162,6 +2506,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v      = is_assignable<_Tp, _Arg>::value;  #endif +#endif  // __has_keyword(__is_assignable) +  // is_copy_assignable  template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_assignable @@ -2188,6 +2534,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_assignable_v  // is_destructible +#if __has_keyword(__is_destructible) + +template<class _Tp> +struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { }; + +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +template <class _Tp> +_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v = __is_destructible(_Tp); +#endif + +#else // __has_keyword(__is_destructible) +  //  if it's a reference, return true  //  if it's a function, return false  //  if it's   void,     return false @@ -2250,6 +2608,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v      = is_destructible<_Tp>::value;  #endif +#endif // __has_keyword(__is_destructible) +  // move  template <class _Tp> @@ -3879,7 +4239,6 @@ struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};  template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;  #endif -  template <class _Tp, bool = is_enum<_Tp>::value>  struct __sfinae_underlying_type  { @@ -3962,8 +4321,6 @@ struct __has_operator_addressof  #if _LIBCPP_STD_VER > 14 -template <class...> using void_t = void; -  template <class... _Args>  struct conjunction : _And<_Args...> {};  template<class... _Args> @@ -4040,29 +4397,7 @@ _LIBCPP_END_NAMESPACE_STD  // std::byte  namespace std  // purposefully not versioned  { -template <class _Integer> -  constexpr typename enable_if<is_integral_v<_Integer>, byte>::type & -  operator<<=(byte& __lhs, _Integer __shift) noexcept -  { return __lhs = __lhs << __shift; } - -template <class _Integer> -  constexpr typename enable_if<is_integral_v<_Integer>, byte>::type -  operator<< (byte  __lhs, _Integer __shift) noexcept -  { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) << __shift)); } - -template <class _Integer> -  constexpr typename enable_if<is_integral_v<_Integer>, byte>::type & -  operator>>=(byte& __lhs, _Integer __shift) noexcept -  { return __lhs = __lhs >> __shift; } - -template <class _Integer> -  constexpr typename enable_if<is_integral_v<_Integer>, byte>::type -  operator>> (byte  __lhs, _Integer __shift) noexcept -  { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); } - -template <class _Integer> -  constexpr typename enable_if<is_integral_v<_Integer>, _Integer>::type -  to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); } +  }  #endif diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo index 27601769a83b..7e76da538796 100644 --- a/libcxx/include/typeinfo +++ b/libcxx/include/typeinfo @@ -60,6 +60,7 @@ public:  #include <exception>  #include <cstddef>  #include <cstdint> +#include <type_traits>  #ifdef _LIBCPP_NO_EXCEPTIONS  #include <cstdlib>  #endif @@ -120,6 +121,7 @@ public:  // ========================================================================== //  // ------------------------------------------------------------------------- //  //                               Unique +//               (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1)  // ------------------------------------------------------------------------- //  // This implementation of type_info assumes a unique copy of the RTTI for a  // given type inside a program. This is a valid assumption when abiding to @@ -129,6 +131,7 @@ public:  // a deep string comparison.  // -------------------------------------------------------------------------- //  //                             NonUnique +//               (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 2)  // -------------------------------------------------------------------------- //  // This implementation of type_info does not assume there is always a unique  // copy of the RTTI for a given type inside a program. For various reasons @@ -138,6 +141,7 @@ public:  // comparison is equal.  // -------------------------------------------------------------------------- //  //                          NonUniqueARMRTTIBit +// (selected on ARM64 regardless of _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION)  // -------------------------------------------------------------------------- //  // This implementation of type_info does not assume always a unique copy of  // the RTTI for a given type inside a program. It packs the pointer to the @@ -255,12 +259,12 @@ struct __type_info_implementations {    typedef  #if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__)      __non_unique_arm_rtti_bit_impl -#elif _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT == 0 -    __non_unique_impl -#elif _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT == 1 +#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1      __unique_impl +#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2 +    __non_unique_impl  #else -#   error invalid configuration for _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT +#   error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION  #endif       __impl;  }; @@ -318,6 +322,7 @@ class _LIBCPP_EXCEPTION_ABI bad_cast  {   public:    bad_cast() _NOEXCEPT; +  bad_cast(const bad_cast&) _NOEXCEPT = default;    virtual ~bad_cast() _NOEXCEPT;    virtual const char* what() const _NOEXCEPT;  }; diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index ad17f776c938..6156cfddd7bd 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -386,10 +386,12 @@ template <class Key, class T, class Hash, class Pred, class Alloc>                noexcept(noexcept(x.swap(y)));  template <class K, class T, class H, class P, class A, class Predicate> -    void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred);       // C++20 +    typename unordered_map<K, T, H, P, A>::size_type +    erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);       // C++20  template <class K, class T, class H, class P, class A, class Predicate> -    void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred);  // C++20 +    typename unordered_multimap<K, T, H, P, A>::size_type +    erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);  // C++20  template <class Key, class T, class Hash, class Pred, class Alloc>      bool @@ -1704,10 +1706,14 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,  }  #if _LIBCPP_STD_VER > 17 -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate> +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, +          class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } +    typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type +    erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, +             _Predicate __pred) { +  return __libcpp_erase_if_container(__c, __pred); +}  #endif  template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -2402,10 +2408,14 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,  }  #if _LIBCPP_STD_VER > 17 -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate> +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, +          class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } +    typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type +    erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, +             _Predicate __pred) { +  return __libcpp_erase_if_container(__c, __pred); +}  #endif  template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index 68f777a4ea3e..6c4ad938006f 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -341,10 +341,12 @@ template <class Value, class Hash, class Pred, class Alloc>                noexcept(noexcept(x.swap(y)));  template <class K, class T, class H, class P, class A, class Predicate> -    void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred);       // C++20 +    typename unordered_set<K, T, H, P, A>::size_type +    erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred);       // C++20  template <class K, class T, class H, class P, class A, class Predicate> -    void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred);  // C++20 +    typename unordered_multiset<K, T, H, P, A>::size_type +    erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred);  // C++20  template <class Value, class Hash, class Pred, class Alloc> @@ -1006,10 +1008,14 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,  }  #if _LIBCPP_STD_VER > 17 -template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> +template <class _Value, class _Hash, class _Pred, class _Alloc, +          class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } +    typename unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type +    erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, +             _Predicate __pred) { +  return __libcpp_erase_if_container(__c, __pred); +}  #endif  template <class _Value, class _Hash, class _Pred, class _Alloc> @@ -1637,10 +1643,14 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,  }  #if _LIBCPP_STD_VER > 17 -template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> +template <class _Value, class _Hash, class _Pred, class _Alloc, +          class _Predicate>  inline _LIBCPP_INLINE_VISIBILITY -void erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) -{ __libcpp_erase_if_container(__c, __pred); } +    typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::size_type +    erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, +             _Predicate __pred) { +  return __libcpp_erase_if_container(__c, __pred); +}  #endif  template <class _Value, class _Hash, class _Pred, class _Alloc> diff --git a/libcxx/include/variant b/libcxx/include/variant index 98a62c992fa1..03557239a69e 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -1063,18 +1063,24 @@ public:        }        __impl __tmp(_VSTD::move(*__rhs));  #ifndef _LIBCPP_NO_EXCEPTIONS -      // EXTENSION: When the move construction of `__lhs` into `__rhs` throws -      // and `__tmp` is nothrow move constructible then we move `__tmp` back -      // into `__rhs` and provide the strong exception safety guarantee. -      try { +      if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {          this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); -      } catch (...) { -        if (__tmp.__move_nothrow()) { -          this->__generic_construct(*__rhs, _VSTD::move(__tmp)); +      } else { +        // EXTENSION: When the move construction of `__lhs` into `__rhs` throws +        // and `__tmp` is nothrow move constructible then we move `__tmp` back +        // into `__rhs` and provide the strong exception safety guarantee. +        try { +          this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); +        } catch (...) { +          if (__tmp.__move_nothrow()) { +            this->__generic_construct(*__rhs, _VSTD::move(__tmp)); +          } +          throw;          } -        throw;        }  #else +      // this isn't consolidated with the `if constexpr` branch above due to +      // `throw` being ill-formed with exceptions disabled even when discarded.        this->__generic_construct(*__rhs, _VSTD::move(*__lhs));  #endif        this->__generic_construct(*__lhs, _VSTD::move(__tmp)); diff --git a/libcxx/include/vector b/libcxx/include/vector index 8366bb5d11e8..1007beeaafd0 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -261,9 +261,11 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)      noexcept(noexcept(x.swap(y)));  template <class T, class Allocator, class U> -    void erase(vector<T, Allocator>& c, const U& value);       // C++20 +typename vector<T, Allocator>::size_type +erase(vector<T, Allocator>& c, const U& value);       // C++20  template <class T, class Allocator, class Predicate> -    void erase_if(vector<T, Allocator>& c, Predicate pred);    // C++20 +typename vector<T, Allocator>::size_type +erase_if(vector<T, Allocator>& c, Predicate pred);    // C++20  }  // std @@ -1041,8 +1043,9 @@ void  vector<_Tp, _Allocator>::__construct_at_end(size_type __n)  {      _ConstructTransaction __tx(*this, __n); -    for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) { -      __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_)); +    const_pointer __new_end = __tx.__new_end_; +    for (pointer __pos = __tx.__pos_; __pos != __new_end; ++__pos, __tx.__pos_ = __pos) { +        __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__pos));      }  } @@ -1058,8 +1061,9 @@ void  vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)  {      _ConstructTransaction __tx(*this, __n); -    for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) { -        __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_), __x); +    const_pointer __new_end = __tx.__new_end_; +    for (pointer __pos = __tx.__pos_; __pos != __new_end; ++__pos, __tx.__pos_ = __pos) { +        __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__pos), __x);      }  } @@ -1751,9 +1755,10 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe      {        pointer __i = __from_s + __n;        _ConstructTransaction __tx(*this, __from_e - __i); -      for (; __i < __from_e; ++__i, ++__tx.__pos_) { +      for (pointer __pos = __tx.__pos_; __i < __from_e; +           ++__i, ++__pos, __tx.__pos_ = __pos) {            __alloc_traits::construct(this->__alloc(), -                                    _VSTD::__to_address(__tx.__pos_), +                                    _VSTD::__to_address(__pos),                                      _VSTD::move(*__i));        }      } @@ -1956,8 +1961,8 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs  #endif  // _LIBCPP_NO_EXCEPTIONS      }      __p = _VSTD::rotate(__p, __old_last, this->__end_); -    insert(__make_iter(__p), make_move_iterator(__v.begin()), -                                    make_move_iterator(__v.end())); +    insert(__make_iter(__p), _VSTD::make_move_iterator(__v.begin()), +                             _VSTD::make_move_iterator(__v.end()));      return begin() + __off;  } @@ -3389,14 +3394,20 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)  #if _LIBCPP_STD_VER > 17  template <class _Tp, class _Allocator, class _Up> -inline _LIBCPP_INLINE_VISIBILITY -void erase(vector<_Tp, _Allocator>& __c, const _Up& __v) -{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); } +inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::size_type +erase(vector<_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 <class _Tp, class _Allocator, class _Predicate> -inline _LIBCPP_INLINE_VISIBILITY -void erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) -{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); } +inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::size_type +erase_if(vector<_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  _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/version b/libcxx/include/version index 2abc71e0f382..acedd03073cc 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -21,7 +21,8 @@ __cpp_lib_allocator_traits_is_always_equal              201411L <memory> <scoped                                                                  <unordered_map> <unordered_set>  __cpp_lib_any                                           201606L <any>  __cpp_lib_apply                                         201603L <tuple> -__cpp_lib_array_constexpr                               201603L <iterator> <array> +__cpp_lib_array_constexpr                               201811L <iterator> <array> +                                                        201603L // C++17  __cpp_lib_as_const                                      201510L <utility>  __cpp_lib_atomic_is_always_lock_free                    201603L <atomic>  __cpp_lib_atomic_ref                                    201806L <atomic> @@ -44,7 +45,7 @@ __cpp_lib_constexpr_swap_algorithms                     201806L <algorithm>  __cpp_lib_destroying_delete                             201806L <new>  __cpp_lib_enable_shared_from_this                       201603L <memory>  __cpp_lib_endian                                        201907L <bit> -__cpp_lib_erase_if                                      201811L <string> <deque> <forward_list> +__cpp_lib_erase_if                                      202002L <string> <deque> <forward_list>                                                                  <list> <vector> <map>                                                                  <set> <unordered_map> <unordered_set>  __cpp_lib_exchange_function                             201304L <utility> @@ -74,6 +75,7 @@ __cpp_lib_make_from_tuple                               201606L <tuple>  __cpp_lib_make_reverse_iterator                         201402L <iterator>  __cpp_lib_make_unique                                   201304L <memory>  __cpp_lib_map_try_emplace                               201411L <map> +__cpp_lib_math_constants                                201907L <numbers>  __cpp_lib_math_special_functions                        201603L <cmath>  __cpp_lib_memory_resource                               201603L <memory_resource>  __cpp_lib_node_extract                                  201606L <map> <set> <unordered_map> @@ -98,9 +100,11 @@ __cpp_lib_shared_mutex                                  201505L <shared_mutex>  __cpp_lib_shared_ptr_arrays                             201611L <memory>  __cpp_lib_shared_ptr_weak_type                          201606L <memory>  __cpp_lib_shared_timed_mutex                            201402L <shared_mutex> +__cpp_lib_span                                          202002L <span>  __cpp_lib_string_udls                                   201304L <string>  __cpp_lib_string_view                                   201606L <string> <string_view>  __cpp_lib_three_way_comparison                          201711L <compare> +__cpp_lib_to_array                                      201907L <array>  __cpp_lib_to_chars                                      201611L <utility>  __cpp_lib_transformation_trait_aliases                  201304L <type_traits>  __cpp_lib_transparent_operators                         201510L <functional> @@ -167,7 +171,7 @@ __cpp_lib_void_t                                        201411L <type_traits>  // # define __cpp_lib_execution                            201603L  # define __cpp_lib_filesystem                           201703L  # define __cpp_lib_gcd_lcm                              201606L -# define __cpp_lib_hardware_interference_size           201703L +// # define __cpp_lib_hardware_interference_size           201703L  # if defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)  #   define __cpp_lib_has_unique_object_representations  201606L  # endif @@ -210,6 +214,8 @@ __cpp_lib_void_t                                        201411L <type_traits>  #endif  #if _LIBCPP_STD_VER > 17 +# undef  __cpp_lib_array_constexpr +# define __cpp_lib_array_constexpr                      201811L  # if !defined(_LIBCPP_HAS_NO_THREADS)  // #   define __cpp_lib_atomic_ref                         201806L  # endif @@ -225,15 +231,20 @@ __cpp_lib_void_t                                        201411L <type_traits>  #   define __cpp_lib_destroying_delete                  201806L  # endif  # define __cpp_lib_endian                               201907L -# define __cpp_lib_erase_if                             201811L +# define __cpp_lib_erase_if                             202002L  // # define __cpp_lib_generic_unordered_lookup             201811L  # define __cpp_lib_interpolate                          201902L  # if !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)  #   define __cpp_lib_is_constant_evaluated              201811L  # endif -// # define __cpp_lib_list_remove_return_type              201806L +# define __cpp_lib_list_remove_return_type              201806L +# if defined(__cpp_concepts) && __cpp_concepts >= 201811L +#   define __cpp_lib_math_constants                     201907L +# endif  // # define __cpp_lib_ranges                               201811L +# define __cpp_lib_span                                 202002L  // # define __cpp_lib_three_way_comparison                 201711L +# define __cpp_lib_to_array                             201907L  #endif  #endif // _LIBCPP_VERSIONH diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h index 353c979d2072..b21a78968e23 100644 --- a/libcxx/include/wchar.h +++ b/libcxx/include/wchar.h @@ -106,6 +106,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,  */  #include <__config> +#include <stddef.h>  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)  #pragma GCC system_header  | 
