diff --git a/lib/libcxx/include/__bit_reference b/lib/libcxx/include/__bit_reference index cce74fb502..3d4da1cbb6 100644 --- a/lib/libcxx/include/__bit_reference +++ b/lib/libcxx/include/__bit_reference @@ -47,6 +47,9 @@ class __bit_reference friend class __bit_const_reference<_Cp>; friend class __bit_iterator<_Cp, false>; public: + _LIBCPP_INLINE_VISIBILITY + __bit_reference(const __bit_reference&) = default; + _LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT {return static_cast(*__seg_ & __mask_);} _LIBCPP_INLINE_VISIBILITY bool operator ~() const _NOEXCEPT @@ -132,6 +135,9 @@ class __bit_const_reference friend typename _Cp::__self; friend class __bit_iterator<_Cp, true>; public: + _LIBCPP_INLINE_VISIBILITY + __bit_const_reference(const __bit_const_reference&) = default; + _LIBCPP_INLINE_VISIBILITY __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT : __seg_(__x.__seg_), __mask_(__x.__mask_) {} @@ -147,7 +153,7 @@ private: __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT : __seg_(__s), __mask_(__m) {} - __bit_const_reference& operator=(const __bit_const_reference& __x); + __bit_const_reference& operator=(const __bit_const_reference&) = delete; }; // find @@ -332,7 +338,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } // do middle whole words __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type)); + _VSTD::memset(_VSTD::__to_address(__first.__seg_), 0, __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; // do last partial word if (__n > 0) @@ -362,7 +368,7 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) } // do middle whole words __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type)); + _VSTD::memset(_VSTD::__to_address(__first.__seg_), -1, __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; // do last partial word if (__n > 0) @@ -429,8 +435,8 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon // __first.__ctz_ == 0; // do middle words __storage_type __nw = __n / __bits_per_word; - _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), - _VSTD::__to_raw_pointer(__first.__seg_), + _VSTD::memmove(_VSTD::__to_address(__result.__seg_), + _VSTD::__to_address(__first.__seg_), __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; __result.__seg_ += __nw; @@ -570,8 +576,8 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C __storage_type __nw = __n / __bits_per_word; __result.__seg_ -= __nw; __last.__seg_ -= __nw; - _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), - _VSTD::__to_raw_pointer(__last.__seg_), + _VSTD::memmove(_VSTD::__to_address(__result.__seg_), + _VSTD::__to_address(__last.__seg_), __nw * sizeof(__storage_type)); __n -= __nw * __bits_per_word; // do last word @@ -1108,8 +1114,12 @@ public: #endif {} + // avoid re-declaring a copy constructor for the non-const version. + using __type_for_copy_to_const = + _If<_IsConst, __bit_iterator<_Cp, false>, struct __private_nat>; + _LIBCPP_INLINE_VISIBILITY - __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT + __bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT diff --git a/lib/libcxx/include/__config b/lib/libcxx/include/__config index 1ecced9f47..ccce227f4d 100644 --- a/lib/libcxx/include/__config +++ b/lib/libcxx/include/__config @@ -32,7 +32,7 @@ # define _GNUC_VER_NEW 0 #endif -#define _LIBCPP_VERSION 9000 +#define _LIBCPP_VERSION 10000 #ifndef _LIBCPP_ABI_VERSION # define _LIBCPP_ABI_VERSION 1 @@ -183,10 +183,6 @@ # define _LIBCPP_COMPILER_IBM #endif -#ifndef _LIBCPP_CLANG_VER -#define _LIBCPP_CLANG_VER 0 -#endif - #if defined(_LIBCPP_COMPILER_GCC) && __cplusplus < 201103L #error "libc++ does not support using GCC with C++03. Please enable C++11" #endif @@ -246,6 +242,7 @@ #ifdef __FreeBSD__ # include +# include # if _BYTE_ORDER == _LITTLE_ENDIAN # define _LIBCPP_LITTLE_ENDIAN # else // _BYTE_ORDER == _LITTLE_ENDIAN @@ -263,7 +260,6 @@ # else // _BYTE_ORDER == _LITTLE_ENDIAN # define _LIBCPP_BIG_ENDIAN # endif // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_HAS_QUICK_EXIT #endif // __NetBSD__ #if defined(_WIN32) @@ -343,9 +339,26 @@ #if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L # if defined(__FreeBSD__) +# define _LIBCPP_HAS_ALIGNED_ALLOC # define _LIBCPP_HAS_QUICK_EXIT # define _LIBCPP_HAS_C11_FEATURES -# elif defined(__Fuchsia__) || defined(__wasi__) +# 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 +# define _LIBCPP_HAS_QUICK_EXIT +# endif +# if __ANDROID_API__ >= 28 +# define _LIBCPP_HAS_ALIGNED_ALLOC +# endif +# if __ANDROID_API__ >= 29 +# define _LIBCPP_HAS_TIMESPEC_GET +# endif +# elif defined(__Fuchsia__) || defined(__wasi__) || defined(__NetBSD__) +# define _LIBCPP_HAS_ALIGNED_ALLOC # define _LIBCPP_HAS_QUICK_EXIT # define _LIBCPP_HAS_TIMESPEC_GET # define _LIBCPP_HAS_C11_FEATURES @@ -355,10 +368,12 @@ # define _LIBCPP_HAS_QUICK_EXIT # endif # if _LIBCPP_GLIBC_PREREQ(2, 17) +# define _LIBCPP_HAS_ALIGNED_ALLOC # define _LIBCPP_HAS_C11_FEATURES # define _LIBCPP_HAS_TIMESPEC_GET # endif # else // defined(_LIBCPP_HAS_MUSL_LIBC) +# define _LIBCPP_HAS_ALIGNED_ALLOC # define _LIBCPP_HAS_QUICK_EXIT # define _LIBCPP_HAS_TIMESPEC_GET # define _LIBCPP_HAS_C11_FEATURES @@ -483,11 +498,14 @@ typedef __char32_t char32_t; #define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) -// No apple compilers support ""d and ""y at this time. -#if _LIBCPP_CLANG_VER < 800 || defined(__apple_build_version__) -#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS +// Literal operators ""d and ""y are supported starting with LLVM Clang 8 and AppleClang 10.0.1 +#if (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 800) || \ + (defined(__apple_build_version__) && __apple_build_version__ < 10010000) +#define _LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS #endif +#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ + #elif defined(_LIBCPP_COMPILER_GCC) #define _ALIGNAS(x) __attribute__((__aligned__(x))) @@ -523,6 +541,8 @@ typedef __char32_t char32_t; #define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) +#define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ + #elif defined(_LIBCPP_COMPILER_MSVC) #define _LIBCPP_TOSTRING2(x) #x @@ -548,6 +568,8 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_NO_VECTOR_EXTENSION +#define _LIBCPP_DISABLE_EXTENSION_WARNING + #elif defined(_LIBCPP_COMPILER_IBM) #define _ALIGNAS(x) __attribute__((__aligned__(x))) @@ -568,6 +590,8 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_NO_VECTOR_EXTENSION +#define _LIBCPP_DISABLE_EXTENSION_WARNING + #endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM] #if defined(_LIBCPP_OBJECT_FORMAT_COFF) @@ -860,6 +884,10 @@ typedef unsigned int char32_t; # endif #endif +#ifndef _LIBCPP_DEBUG_LEVEL +# define _LIBCPP_DEBUG_LEVEL 0 +#endif + #ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE #define _LIBCPP_EXTERN_TEMPLATE(...) #define _LIBCPP_EXTERN_TEMPLATE2(...) @@ -958,6 +986,20 @@ typedef unsigned int char32_t; # define _LIBCPP_DEPRECATED_IN_CXX17 #endif +// Macros to enter and leave a state where deprecation warnings are suppressed. +#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) && \ + (defined(_LIBCPP_COMPILER_CLANG) || defined(_LIBCPP_COMPILER_GCC)) +# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated\"") +# define _LIBCPP_SUPPRESS_DEPRECATED_POP \ + _Pragma("GCC diagnostic pop") +#endif +#if !defined(_LIBCPP_SUPPRESS_DEPRECATED_PUSH) +# define _LIBCPP_SUPPRESS_DEPRECATED_PUSH +# define _LIBCPP_SUPPRESS_DEPRECATED_POP +#endif + #if _LIBCPP_STD_VER <= 11 # define _LIBCPP_EXPLICIT_AFTER_CXX11 #else @@ -982,6 +1024,14 @@ typedef unsigned int char32_t; # define _LIBCPP_CONSTEXPR_AFTER_CXX17 #endif +#if _LIBCPP_STD_VER > 17 && \ + !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) && \ + !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) +# define _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED constexpr +#else +# define _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +#endif + // The _LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other // NODISCARD macros to the correct attribute. #if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC) @@ -1065,7 +1115,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \ !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) # if defined(__FreeBSD__) || \ - defined(__Fuchsia__) || \ defined(__wasi__) || \ defined(__NetBSD__) || \ defined(__linux__) || \ @@ -1075,6 +1124,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( defined(__sun__) || \ (defined(__MINGW32__) && __has_include()) # define _LIBCPP_HAS_THREAD_API_PTHREAD +# elif defined(__Fuchsia__) +# define _LIBCPP_HAS_THREAD_API_C11 # elif defined(_LIBCPP_WIN32API) # define _LIBCPP_HAS_THREAD_API_WIN32 # else @@ -1082,6 +1133,16 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # endif // _LIBCPP_HAS_THREAD_API #endif // _LIBCPP_HAS_NO_THREADS +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#if defined(__ANDROID__) && __ANDROID_API__ >= 30 +#define _LIBCPP_HAS_COND_CLOCKWAIT +#elif defined(_LIBCPP_GLIBC_PREREQ) +#if _LIBCPP_GLIBC_PREREQ(2, 30) +#define _LIBCPP_HAS_COND_CLOCKWAIT +#endif +#endif +#endif + #if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD) #error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ _LIBCPP_HAS_NO_THREADS is not defined. @@ -1097,20 +1158,40 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( _LIBCPP_HAS_NO_THREADS is defined. #endif -// The Apple, glibc, and Bionic implementation of pthreads implements +#if defined(__STDCPP_THREADS__) && defined(_LIBCPP_HAS_NO_THREADS) +#error _LIBCPP_HAS_NO_THREADS cannot be set when __STDCPP_THREADS__ is set. +#endif + +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(__STDCPP_THREADS__) +#define __STDCPP_THREADS__ 1 +#endif + +// The glibc and Bionic implementation of pthreads implements // pthread_mutex_destroy as nop for regular mutexes. Additionally, Win32 // mutexes have no destroy mechanism. -// TODO(EricWF): Enable this optimization on Apple and Bionic platforms after -// speaking to their respective stakeholders. +// +// This optimization can't be performed on Apple platforms, where +// pthread_mutex_destroy can allow the kernel to release resources. +// See https://llvm.org/D64298 for details. +// +// TODO(EricWF): Enable this optimization on Bionic after speaking to their +// respective stakeholders. #if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) \ + || (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) \ || defined(_LIBCPP_HAS_THREAD_API_WIN32) # define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION #endif // Destroying a condvar is a nop on Windows. +// +// This optimization can't be performed on Apple platforms, where +// pthread_cond_destroy can allow the kernel to release resources. +// See https://llvm.org/D64298 for details. +// // TODO(EricWF): This is potentially true for some pthread implementations // as well. -#if defined(_LIBCPP_HAS_THREAD_API_WIN32) +#if (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \ + defined(_LIBCPP_HAS_THREAD_API_WIN32) # define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION #endif @@ -1129,6 +1210,14 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_HAS_NO_STDOUT #endif +// Some systems do not provide gets() in their C library, for security reasons. +#ifndef _LIBCPP_C_HAS_NO_GETS +# if defined(_LIBCPP_MSVCRT) || \ + (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) +# define _LIBCPP_C_HAS_NO_GETS +# endif +#endif + #if defined(__BIONIC__) || defined(__CloudABI__) || \ defined(__Fuchsia__) || defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE @@ -1175,6 +1264,14 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # endif #endif +#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION +# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) +# else +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) +# endif +#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION + #if __has_attribute(require_constant_initialization) # define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__)) #else @@ -1210,7 +1307,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_FALLTHROUGH() [[fallthrough]] #elif __has_cpp_attribute(clang::fallthrough) # define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]] -#elif __has_attribute(fallthough) || _GNUC_VER >= 700 +#elif __has_attribute(fallthrough) || _GNUC_VER >= 700 # define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) #else # define _LIBCPP_FALLTHROUGH() ((void)0) @@ -1224,7 +1321,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #ifndef _LIBCPP_NODEBUG_TYPE #if __has_attribute(__nodebug__) && \ - (defined(_LIBCPP_COMPILER_CLANG) && _LIBCPP_CLANG_VER >= 900) + (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 900) #define _LIBCPP_NODEBUG_TYPE __attribute__((nodebug)) #else #define _LIBCPP_NODEBUG_TYPE @@ -1257,10 +1354,9 @@ _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) && \ @@ -1411,6 +1507,17 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_UNUSED_VAR(x) ((void)(x)) +// Configures the fopen close-on-exec mode character, if any. This string will +// be appended to any mode string used by fstream for fopen/fdopen. +// +// Not all platforms support this, but it helps avoid fd-leaks on platforms that +// do. +#if defined(__BIONIC__) +# define _LIBCPP_FOPEN_CLOEXEC_MODE "e" +#else +# define _LIBCPP_FOPEN_CLOEXEC_MODE +#endif + #endif // __cplusplus #endif // _LIBCPP_CONFIG diff --git a/lib/libcxx/include/__config_site.in b/lib/libcxx/include/__config_site.in index ffbd372edf..1ccc158c63 100644 --- a/lib/libcxx/include/__config_site.in +++ b/lib/libcxx/include/__config_site.in @@ -29,6 +29,7 @@ #cmakedefine _LIBCPP_NO_VCRUNTIME #cmakedefine01 _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT #cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ +#cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS @_LIBCPP_ABI_DEFINES@ diff --git a/lib/libcxx/include/__debug b/lib/libcxx/include/__debug index 524c5ff028..11367413fc 100644 --- a/lib/libcxx/include/__debug +++ b/lib/libcxx/include/__debug @@ -276,4 +276,3 @@ _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_DEBUG_H - diff --git a/lib/libcxx/include/__functional_03 b/lib/libcxx/include/__functional_03 index a90cbb75b2..bf86428dea 100644 --- a/lib/libcxx/include/__functional_03 +++ b/lib/libcxx/include/__functional_03 @@ -104,7 +104,7 @@ class __func<_Fp, _Alloc, _Rp()> { __compressed_pair<_Fp, _Alloc> __f_; public: - explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp()>* __clone() const; virtual void __clone(__base<_Rp()>*) const; @@ -189,7 +189,7 @@ class __func<_Fp, _Alloc, _Rp(_A0)> { __compressed_pair<_Fp, _Alloc> __f_; public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_A0)>* __clone() const; @@ -275,7 +275,7 @@ class __func<_Fp, _Alloc, _Rp(_A0, _A1)> { __compressed_pair<_Fp, _Alloc> __f_; public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_A0, _A1)>* __clone() const; @@ -361,7 +361,7 @@ class __func<_Fp, _Alloc, _Rp(_A0, _A1, _A2)> { __compressed_pair<_Fp, _Alloc> __f_; public: - _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp __f, _Alloc __a) : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} virtual __base<_Rp(_A0, _A1, _A2)>* __clone() const; diff --git a/lib/libcxx/include/__functional_base b/lib/libcxx/include/__functional_base index 9587d7ab15..ca761c409b 100644 --- a/lib/libcxx/include/__functional_base +++ b/lib/libcxx/include/__functional_base @@ -558,7 +558,7 @@ struct __is_transparent<_Tp, _Up, // allocator_arg_t -struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { }; +struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; diff --git a/lib/libcxx/include/__hash_table b/lib/libcxx/include/__hash_table index 0b953f58e9..13ff096897 100644 --- a/lib/libcxx/include/__hash_table +++ b/lib/libcxx/include/__hash_table @@ -776,7 +776,7 @@ public: _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible::value) - : __data_(0) {} + : __data_(0, __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator(const allocator_type& __a, size_type __size) @@ -825,11 +825,13 @@ private: allocator_type& __na_; - __hash_node_destructor& operator=(const __hash_node_destructor&); - public: bool __value_constructed; + __hash_node_destructor(__hash_node_destructor const&) = default; + __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; + + _LIBCPP_INLINE_VISIBILITY explicit __hash_node_destructor(allocator_type& __na, bool __constructed = false) _NOEXCEPT @@ -1416,8 +1418,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() is_nothrow_default_constructible<__node_allocator>::value && is_nothrow_default_constructible::value && is_nothrow_default_constructible::value) - : __p2_(0), - __p3_(1.0f) + : __p2_(0, __default_init_tag()), + __p3_(1.0f, __default_init_tag()) { } @@ -1437,7 +1439,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), + __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __hf), __p3_(1.0f, __eql) { @@ -1446,9 +1448,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), - __p2_(0), - __p3_(1.0f) + __p1_(__default_init_tag(), __node_allocator(__a)), + __p2_(0, __default_init_tag()), + __p3_(1.0f, __default_init_tag()) { } @@ -1458,7 +1460,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) __bucket_list_deleter(allocator_traits<__pointer_allocator>:: select_on_container_copy_construction( __u.__bucket_list_.get_deleter().__alloc()), 0)), - __p1_(__second_tag(), allocator_traits<__node_allocator>:: + __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: select_on_container_copy_construction(__u.__node_alloc())), __p2_(0, __u.hash_function()), __p3_(__u.__p3_) @@ -1469,7 +1471,7 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), + __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __u.hash_function()), __p3_(__u.__p3_) { @@ -1503,7 +1505,7 @@ template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), - __p1_(__second_tag(), __node_allocator(__a)), + __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, _VSTD::move(__u.hash_function())), __p3_(_VSTD::move(__u.__p3_)) { diff --git a/lib/libcxx/include/__libcpp_version b/lib/libcxx/include/__libcpp_version index d58c55a31d..5caff40c4a 100644 --- a/lib/libcxx/include/__libcpp_version +++ b/lib/libcxx/include/__libcpp_version @@ -1 +1 @@ -9000 +10000 diff --git a/lib/libcxx/include/__locale b/lib/libcxx/include/__locale index d382e4d8a9..2b6982fc68 100644 --- a/lib/libcxx/include/__locale +++ b/lib/libcxx/include/__locale @@ -409,7 +409,7 @@ public: static const mask xdigit = _ISxdigit; static const mask blank = _ISblank; #if defined(__mips__) - static const mask __regex_word = static_cast(_ISbit(15)); + static const mask __regex_word = static_cast(_ISbit(15)); #else static const mask __regex_word = 0x80; #endif diff --git a/lib/libcxx/include/__mutex_base b/lib/libcxx/include/__mutex_base index f828beaf78..8b4b74802b 100644 --- a/lib/libcxx/include/__mutex_base +++ b/lib/libcxx/include/__mutex_base @@ -15,6 +15,7 @@ #include #include <__threading_support> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -28,15 +29,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_THREADS -#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION -# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS -# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) -# else -# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) -# endif -#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION - - class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex { __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; @@ -65,9 +57,9 @@ public: static_assert(is_nothrow_default_constructible::value, "the default constructor for std::mutex must be nothrow"); -struct _LIBCPP_TYPE_VIS defer_lock_t {}; -struct _LIBCPP_TYPE_VIS try_to_lock_t {}; -struct _LIBCPP_TYPE_VIS adopt_lock_t {}; +struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; }; +struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; }; +struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; }; #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) @@ -94,10 +86,11 @@ private: mutex_type& __m_; public: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) : __m_(__m) {__m_.lock();} - _LIBCPP_INLINE_VISIBILITY + + _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) : __m_(__m) {} _LIBCPP_INLINE_VISIBILITY @@ -336,23 +329,75 @@ public: private: void __do_timed_wait(unique_lock& __lk, chrono::time_point) _NOEXCEPT; +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) + void __do_timed_wait(unique_lock& __lk, + chrono::time_point) _NOEXCEPT; +#endif + template + void __do_timed_wait(unique_lock& __lk, + chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT; }; #endif // !_LIBCPP_HAS_NO_THREADS -template +template inline _LIBCPP_INLINE_VISIBILITY typename enable_if < - chrono::__is_duration<_To>::value, - _To + is_floating_point<_Rep>::value, + chrono::nanoseconds >::type -__ceil(chrono::duration<_Rep, _Period> __d) +__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { using namespace chrono; - _To __r = duration_cast<_To>(__d); - if (__r < __d) - ++__r; - return __r; + using __ratio = ratio_divide<_Period, nano>; + using __ns_rep = nanoseconds::rep; + _Rep __result_float = __d.count() * __ratio::num / __ratio::den; + + _Rep __result_max = numeric_limits<__ns_rep>::max(); + if (__result_float >= __result_max) { + return nanoseconds::max(); + } + + _Rep __result_min = numeric_limits<__ns_rep>::min(); + if (__result_float <= __result_min) { + return nanoseconds::min(); + } + + return nanoseconds(static_cast<__ns_rep>(__result_float)); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + !is_floating_point<_Rep>::value, + chrono::nanoseconds +>::type +__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) +{ + using namespace chrono; + if (__d.count() == 0) { + return nanoseconds(0); + } + + using __ratio = ratio_divide<_Period, nano>; + using __ns_rep = nanoseconds::rep; + __ns_rep __result_max = std::numeric_limits<__ns_rep>::max(); + if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) { + return nanoseconds::max(); + } + + __ns_rep __result_min = std::numeric_limits<__ns_rep>::min(); + if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) { + return nanoseconds::min(); + } + + __ns_rep __result = __d.count() * __ratio::num / __ratio::den; + if (__result == 0) { + return nanoseconds(1); + } + + return nanoseconds(__result); } #ifndef _LIBCPP_HAS_NO_THREADS @@ -370,7 +415,15 @@ condition_variable::wait_until(unique_lock& __lk, const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - wait_for(__lk, __t - _Clock::now()); + using __clock_tp_ns = time_point<_Clock, nanoseconds>; + + typename _Clock::time_point __now = _Clock::now(); + if (__t <= __now) + return cv_status::timeout; + + __clock_tp_ns __t_ns = __clock_tp_ns(__safe_nanosecond_cast(__t.time_since_epoch())); + + __do_timed_wait(__lk, __t_ns); return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; } @@ -396,15 +449,25 @@ condition_variable::wait_for(unique_lock& __lk, using namespace chrono; if (__d <= __d.zero()) return cv_status::timeout; - typedef time_point > __sys_tpf; - typedef time_point __sys_tpi; - __sys_tpf _Max = __sys_tpi::max(); + using __ns_rep = nanoseconds::rep; steady_clock::time_point __c_now = steady_clock::now(); - system_clock::time_point __s_now = system_clock::now(); - if (_Max - __d > __s_now) - __do_timed_wait(__lk, __s_now + __ceil(__d)); - else - __do_timed_wait(__lk, __sys_tpi::max()); + +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) + using __clock_tp_ns = time_point; + __ns_rep __now_count_ns = __safe_nanosecond_cast(__c_now.time_since_epoch()).count(); +#else + using __clock_tp_ns = time_point; + __ns_rep __now_count_ns = __safe_nanosecond_cast(system_clock::now().time_since_epoch()).count(); +#endif + + __ns_rep __d_ns_count = __safe_nanosecond_cast(__d).count(); + + if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) { + __do_timed_wait(__lk, __clock_tp_ns::max()); + } else { + __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count))); + } + return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout; } @@ -420,6 +483,46 @@ condition_variable::wait_for(unique_lock& __lk, _VSTD::move(__pred)); } +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) +inline +void +condition_variable::__do_timed_wait(unique_lock& __lk, + chrono::time_point __tp) _NOEXCEPT +{ + using namespace chrono; + if (!__lk.owns_lock()) + __throw_system_error(EPERM, + "condition_variable::timed wait: mutex not locked"); + nanoseconds __d = __tp.time_since_epoch(); + timespec __ts; + seconds __s = duration_cast(__d); + using __ts_sec = decltype(__ts.tv_sec); + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = (__d - __s).count(); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = giga::num - 1; + } + int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts); + if (__ec != 0 && __ec != ETIMEDOUT) + __throw_system_error(__ec, "condition_variable timed_wait failed"); +} +#endif // _LIBCPP_HAS_COND_CLOCKWAIT + +template +inline +void +condition_variable::__do_timed_wait(unique_lock& __lk, + chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT +{ + wait_for(__lk, __tp - _Clock::now()); +} + #endif // !_LIBCPP_HAS_NO_THREADS _LIBCPP_END_NAMESPACE_STD diff --git a/lib/libcxx/include/__split_buffer b/lib/libcxx/include/__split_buffer index 1daa4e5ada..fce209f828 100644 --- a/lib/libcxx/include/__split_buffer +++ b/lib/libcxx/include/__split_buffer @@ -116,15 +116,15 @@ public: template typename enable_if < - __is_input_iterator<_InputIter>::value && - !__is_forward_iterator<_InputIter>::value, + __is_cpp17_input_iterator<_InputIter>::value && + !__is_cpp17_forward_iterator<_InputIter>::value, void >::type __construct_at_end(_InputIter __first, _InputIter __last); template typename enable_if < - __is_forward_iterator<_ForwardIterator>::value, + __is_cpp17_forward_iterator<_ForwardIterator>::value, void >::type __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); @@ -161,6 +161,19 @@ private: _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {} + + struct _ConstructTransaction { + explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT + : __pos_(*__p), __end_(*__p + __n), __dest_(__p) { + } + ~_ConstructTransaction() { + *__dest_ = __pos_; + } + pointer __pos_; + const pointer __end_; + private: + pointer *__dest_; + }; }; template @@ -197,13 +210,10 @@ template void __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) { - __alloc_rr& __a = this->__alloc(); - do - { - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); - ++this->__end_; - --__n; - } while (__n > 0); + _ConstructTransaction __tx(&this->__end_, __n); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_)); + } } // Copy constructs __n objects starting at __end_ from __x @@ -216,21 +226,19 @@ template void __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) { - __alloc_rr& __a = this->__alloc(); - do - { - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); - ++this->__end_; - --__n; - } while (__n > 0); + _ConstructTransaction __tx(&this->__end_, __n); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), + _VSTD::__to_address(__tx.__pos_), __x); + } } template template typename enable_if < - __is_input_iterator<_InputIter>::value && - !__is_forward_iterator<_InputIter>::value, + __is_cpp17_input_iterator<_InputIter>::value && + !__is_cpp17_forward_iterator<_InputIter>::value, void >::type __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) @@ -245,10 +253,10 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt __split_buffer __buf(__new_cap, 0, __a); for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_) __alloc_traits::construct(__buf.__alloc(), - _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p)); + _VSTD::__to_address(__buf.__end_), _VSTD::move(*__p)); swap(__buf); } - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); + __alloc_traits::construct(__a, _VSTD::__to_address(this->__end_), *__first); ++this->__end_; } } @@ -257,16 +265,15 @@ template template typename enable_if < - __is_forward_iterator<_ForwardIterator>::value, + __is_cpp17_forward_iterator<_ForwardIterator>::value, void >::type __split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) { - __alloc_rr& __a = this->__alloc(); - for (; __first != __last; ++__first) - { - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); - ++this->__end_; + _ConstructTransaction __tx(&this->__end_, std::distance(__first, __last)); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, ++__first) { + __alloc_traits::construct(this->__alloc(), + _VSTD::__to_address(__tx.__pos_), *__first); } } @@ -276,7 +283,7 @@ void __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) { while (__begin_ != __new_begin) - __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++)); + __alloc_traits::destroy(__alloc(), __to_address(__begin_++)); } template @@ -293,7 +300,7 @@ void __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT { while (__new_last != __end_) - __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_)); + __alloc_traits::destroy(__alloc(), __to_address(--__end_)); } template @@ -317,7 +324,7 @@ template inline __split_buffer<_Tp, _Allocator>::__split_buffer() _NOEXCEPT_(is_nothrow_default_constructible::value) - : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr) + : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) { } @@ -361,7 +368,7 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c) template __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a) - : __end_cap_(__second_tag(), __a) + : __end_cap_(nullptr, __a) { if (__a == __c.__alloc()) { @@ -488,7 +495,7 @@ __split_buffer<_Tp, _Allocator>::push_front(const_reference __x) _VSTD::swap(__end_cap(), __t.__end_cap()); } } - __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x); + __alloc_traits::construct(__alloc(), _VSTD::__to_address(__begin_-1), __x); --__begin_; } @@ -519,7 +526,7 @@ __split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) _VSTD::swap(__end_cap(), __t.__end_cap()); } } - __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), + __alloc_traits::construct(__alloc(), _VSTD::__to_address(__begin_-1), _VSTD::move(__x)); --__begin_; } @@ -552,7 +559,7 @@ __split_buffer<_Tp, _Allocator>::push_back(const_reference __x) _VSTD::swap(__end_cap(), __t.__end_cap()); } } - __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x); + __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), __x); ++__end_; } @@ -583,7 +590,7 @@ __split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) _VSTD::swap(__end_cap(), __t.__end_cap()); } } - __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), + __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), _VSTD::move(__x)); ++__end_; } @@ -614,7 +621,7 @@ __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) _VSTD::swap(__end_cap(), __t.__end_cap()); } } - __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), + __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), _VSTD::forward<_Args>(__args)...); ++__end_; } diff --git a/lib/libcxx/include/__string b/lib/libcxx/include/__string index a88b976be3..056b9b80ea 100644 --- a/lib/libcxx/include/__string +++ b/lib/libcxx/include/__string @@ -31,11 +31,12 @@ struct char_traits static constexpr int compare(const char_type* s1, const char_type* s2, size_t n); static constexpr size_t length(const char_type* s); - static constexpr const char_type* + static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a); - static char_type* move(char_type* s1, const char_type* s2, size_t n); - static char_type* copy(char_type* s1, const char_type* s2, size_t n); - static char_type* assign(char_type* s, size_t n, char_type a); + + static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20 + static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n); // constexpr in C++20 + static constexpr char_type* assign(char_type* s, size_t n, char_type a); // constexpr in C++20 static constexpr int_type not_eof(int_type c) noexcept; static constexpr char_type to_char_type(int_type c) noexcept; @@ -93,11 +94,14 @@ struct _LIBCPP_TEMPLATE_VIS char_traits size_t length(const char_type* __s); _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); + static _LIBCPP_CONSTEXPR_AFTER_CXX17 + char_type* move(char_type* __s1, const char_type* __s2, size_t __n); _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); + static _LIBCPP_CONSTEXPR_AFTER_CXX17 + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); + static _LIBCPP_CONSTEXPR_AFTER_CXX17 + char_type* assign(char_type* __s, size_t __n, char_type __a); static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} @@ -151,9 +155,10 @@ char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a } template -_CharT* +_LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) { + if (__n == 0) return __s1; char_type* __r = __s1; if (__s1 < __s2) { @@ -171,7 +176,7 @@ char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) { @@ -183,7 +188,7 @@ char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) } template -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 _CharT* char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) { @@ -193,6 +198,37 @@ char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) return __r; } +// constexpr versions of move/copy/assign. + +template +static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +_CharT* __move_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +{ + if (__n == 0) return __s1; + if (__s1 < __s2) { + _VSTD::copy(__s2, __s2 + __n, __s1); + } else if (__s2 < __s1) { + _VSTD::copy_backward(__s2, __s2 + __n, __s1 + __n); + } + return __s1; +} + +template +static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +_CharT* __copy_constexpr(_CharT* __s1, const _CharT* __s2, size_t __n) _NOEXCEPT +{ + _VSTD::copy_n(__s2, __n, __s1); + return __s1; +} + +template +static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED +_CharT* __assign_constexpr(_CharT* __s, size_t __n, _CharT __a) _NOEXCEPT +{ + _VSTD::fill_n(__s, __n, __a); + return __s; +} + // char_traits template <> @@ -217,15 +253,28 @@ struct _LIBCPP_TEMPLATE_VIS char_traits length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);} static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT - {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __move_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + return __libcpp_is_constant_evaluated() + ? __copy_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __assign_constexpr(__s, __n, __a) + : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n); } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT - {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} @@ -307,16 +356,28 @@ struct _LIBCPP_TEMPLATE_VIS char_traits size_t length(const char_type* __s) _NOEXCEPT; static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT - {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __move_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : wmemmove(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n); + return __libcpp_is_constant_evaluated() + ? __copy_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : wmemcpy(__s1, __s2, __n); + } + static inline _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __assign_constexpr(__s, __n, __a) + : __n == 0 ? __s : wmemset(__s, __a, __n); } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT - {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);} - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {return eq_int_type(__c, eof()) ? ~eof() : __c;} static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT @@ -351,6 +412,18 @@ char_traits::compare(const char_type* __s1, const char_type* __s2, size #endif } + +template +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR +inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT { +#if _LIBCPP_DEBUG_LEVEL >= 1 + return __s ? _Traits::length(__s) : (_VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, "p == nullptr", "null pointer pass to non-null argument of char_traits<...>::length")), 0); +#else + return _Traits::length(__s); +#endif +} + inline _LIBCPP_CONSTEXPR_AFTER_CXX14 size_t char_traits::length(const char_type* __s) _NOEXCEPT @@ -412,21 +485,34 @@ struct _LIBCPP_TEMPLATE_VIS char_traits static constexpr size_t length(const char_type* __s) _NOEXCEPT; - + _LIBCPP_INLINE_VISIBILITY static constexpr const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT - {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} - - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + + static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __move_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memmove(__s1, __s2, __n); + } + + static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); - } - - static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT - {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + return __libcpp_is_constant_evaluated() + ? __copy_constexpr(__s1, __s2, __n) + : __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + + static _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED + char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + { + return __libcpp_is_constant_evaluated() + ? __assign_constexpr(__s, __n, __a) + : __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n); + } static inline constexpr int_type not_eof(int_type __c) noexcept {return eq_int_type(__c, eof()) ? ~eof() : __c;} @@ -509,11 +595,11 @@ struct _LIBCPP_TEMPLATE_VIS char_traits size_t length(const char_type* __s) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT @@ -565,10 +651,11 @@ char_traits::find(const char_type* __s, size_t __n, const char_type& _ return 0; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char16_t* char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { + if (__n == 0) return __s1; char_type* __r = __s1; if (__s1 < __s2) { @@ -585,7 +672,7 @@ char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char16_t* char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { @@ -596,7 +683,7 @@ char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char16_t* char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { @@ -628,11 +715,11 @@ struct _LIBCPP_TEMPLATE_VIS char_traits size_t length(const char_type* __s) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT @@ -684,10 +771,11 @@ char_traits::find(const char_type* __s, size_t __n, const char_type& _ return 0; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char32_t* char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { + if (__n == 0) return __s1; char_type* __r = __s1; if (__s1 < __s2) { @@ -704,7 +792,7 @@ char_traits::move(char_type* __s1, const char_type* __s2, size_t __n) return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char32_t* char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { @@ -715,7 +803,7 @@ char_traits::copy(char_type* __s1, const char_type* __s2, size_t __n) return __r; } -inline +inline _LIBCPP_CONSTEXPR_AFTER_CXX17 char32_t* char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { @@ -732,7 +820,7 @@ char_traits::assign(char_type* __s, size_t __n, char_type __a) _NOEXCE // __str_find template inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find(const _CharT *__p, _SizeT __sz, +__str_find(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { if (__pos >= __sz) @@ -784,7 +872,7 @@ __search_substring(const _CharT *__first1, const _CharT *__last1, template inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find(const _CharT *__p, _SizeT __sz, +__str_find(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { if (__pos > __sz) @@ -806,7 +894,7 @@ __str_find(const _CharT *__p, _SizeT __sz, template inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_rfind(const _CharT *__p, _SizeT __sz, +__str_rfind(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { if (__sz < 1) @@ -825,7 +913,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, template inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_rfind(const _CharT *__p, _SizeT __sz, +__str_rfind(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { __pos = _VSTD::min(__pos, __sz); @@ -834,7 +922,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, else __pos = __sz; const _CharT* __r = _VSTD::__find_end( - __p, __p + __pos, __s, __s + __n, _Traits::eq, + __p, __p + __pos, __s, __s + __n, _Traits::eq, random_access_iterator_tag(), random_access_iterator_tag()); if (__n > 0 && __r == __p + __pos) return __npos; @@ -963,7 +1051,7 @@ struct __quoted_output_proxy __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e) : __first(__f), __last(__l), __delim(__d), __escape(__e) {} - // This would be a nice place for a string_ref + // This would be a nice place for a string_ref }; _LIBCPP_END_NAMESPACE_STD diff --git a/lib/libcxx/include/__threading_support b/lib/libcxx/include/__threading_support index 0331b7c736..dbf313a1bf 100644 --- a/lib/libcxx/include/__threading_support +++ b/lib/libcxx/include/__threading_support @@ -23,16 +23,13 @@ # include <__external_threading> #elif !defined(_LIBCPP_HAS_NO_THREADS) -typedef ::timespec __libcpp_timespec_t; - #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) # include # include +#elif defined(_LIBCPP_HAS_THREAD_API_C11) +# include #endif -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ defined(_LIBCPP_HAS_THREAD_API_WIN32) @@ -47,8 +44,16 @@ _LIBCPP_PUSH_MACROS #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS #endif +typedef ::timespec __libcpp_timespec_t; +#endif // !defined(_LIBCPP_HAS_NO_THREADS) + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD +#if !defined(_LIBCPP_HAS_NO_THREADS) + #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) // Mutex typedef pthread_mutex_t __libcpp_mutex_t; @@ -76,7 +81,36 @@ typedef pthread_t __libcpp_thread_t; typedef pthread_key_t __libcpp_tls_key; #define _LIBCPP_TLS_DESTRUCTOR_CC -#else +#elif defined(_LIBCPP_HAS_THREAD_API_C11) +// Mutex +typedef mtx_t __libcpp_mutex_t; +// mtx_t is a struct so using {} for initialization is valid. +#define _LIBCPP_MUTEX_INITIALIZER {} + +typedef mtx_t __libcpp_recursive_mutex_t; + +// Condition Variable +typedef cnd_t __libcpp_condvar_t; +// cnd_t is a struct so using {} for initialization is valid. +#define _LIBCPP_CONDVAR_INITIALIZER {} + +// Execute once +typedef once_flag __libcpp_exec_once_flag; +#define _LIBCPP_EXEC_ONCE_INITIALIZER ONCE_FLAG_INIT + +// Thread id +typedef thrd_t __libcpp_thread_id; + +// Thread +#define _LIBCPP_NULL_THREAD 0U + +typedef thrd_t __libcpp_thread_t; + +// Thread Local Storage +typedef tss_t __libcpp_tls_key; + +#define _LIBCPP_TLS_DESTRUCTOR_CC +#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) // Mutex typedef void* __libcpp_mutex_t; #define _LIBCPP_MUTEX_INITIALIZER 0 @@ -109,8 +143,9 @@ typedef void* __libcpp_thread_t; typedef long __libcpp_tls_key; #define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall -#endif +#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) // Mutex _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m); @@ -205,9 +240,38 @@ void *__libcpp_tls_get(__libcpp_tls_key __key); _LIBCPP_THREAD_ABI_VISIBILITY int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); +#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) + #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ - defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \ - defined(_LIBCPP_HAS_THREAD_API_PTHREAD) + defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) + +namespace __thread_detail { + +inline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns) +{ + using namespace chrono; + seconds __s = duration_cast(__ns); + __libcpp_timespec_t __ts; + typedef decltype(__ts.tv_sec) __ts_sec; + const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); + + if (__s.count() < __ts_sec_max) + { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + __ts.tv_nsec = static_cast((__ns - __s).count()); + } + else + { + __ts.tv_sec = __ts_sec_max; + __ts.tv_nsec = 999999999; // (10^9 - 1) + } + + return __ts; +} + +} + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) { @@ -357,23 +421,7 @@ void __libcpp_thread_yield() void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) { - using namespace chrono; - seconds __s = duration_cast(__ns); - __libcpp_timespec_t __ts; - typedef decltype(__ts.tv_sec) ts_sec; - _LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits::max(); - - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast(__s.count()); - __ts.tv_nsec = static_cast((__ns - __s).count()); - } - else - { - __ts.tv_sec = __ts_sec_max; - __ts.tv_nsec = 999999999; // (10^9 - 1) - } - + __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR); } @@ -393,6 +441,165 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) return pthread_setspecific(__key, __p); } +#elif defined(_LIBCPP_HAS_THREAD_API_C11) + +int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) +{ + return mtx_init(__m, mtx_plain | mtx_recursive) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_recursive_mutex_lock(__libcpp_recursive_mutex_t *__m) +{ + return mtx_lock(__m) == thrd_success ? 0 : EINVAL; +} + +bool __libcpp_recursive_mutex_trylock(__libcpp_recursive_mutex_t *__m) +{ + return mtx_trylock(__m) == thrd_success; +} + +int __libcpp_recursive_mutex_unlock(__libcpp_mutex_t *__m) +{ + return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_recursive_mutex_destroy(__libcpp_recursive_mutex_t *__m) +{ + mtx_destroy(__m); + return 0; +} + +int __libcpp_mutex_lock(__libcpp_mutex_t *__m) +{ + return mtx_lock(__m) == thrd_success ? 0 : EINVAL; +} + +bool __libcpp_mutex_trylock(__libcpp_mutex_t *__m) +{ + return mtx_trylock(__m) == thrd_success; +} + +int __libcpp_mutex_unlock(__libcpp_mutex_t *__m) +{ + return mtx_unlock(__m) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_mutex_destroy(__libcpp_mutex_t *__m) +{ + mtx_destroy(__m); + return 0; +} + +// Condition Variable +int __libcpp_condvar_signal(__libcpp_condvar_t *__cv) +{ + return cnd_signal(__cv) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_condvar_broadcast(__libcpp_condvar_t *__cv) +{ + return cnd_broadcast(__cv) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_condvar_wait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m) +{ + return cnd_wait(__cv, __m) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m, + timespec *__ts) +{ + int __ec = cnd_timedwait(__cv, __m, __ts); + return __ec == thrd_timedout ? ETIMEDOUT : __ec; +} + +int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv) +{ + cnd_destroy(__cv); + return 0; +} + +// Execute once +int __libcpp_execute_once(__libcpp_exec_once_flag *flag, + void (*init_routine)(void)) { + ::call_once(flag, init_routine); + return 0; +} + +// Thread id +// Returns non-zero if the thread ids are equal, otherwise 0 +bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) +{ + return thrd_equal(t1, t2) != 0; +} + +// Returns non-zero if t1 < t2, otherwise 0 +bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) +{ + return t1 < t2; +} + +// Thread +bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { + return *__t == 0; +} + +int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), + void *__arg) +{ + int __ec = thrd_create(__t, reinterpret_cast(__func), __arg); + return __ec == thrd_nomem ? ENOMEM : __ec; +} + +__libcpp_thread_id __libcpp_thread_get_current_id() +{ + return thrd_current(); +} + +__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) +{ + return *__t; +} + +int __libcpp_thread_join(__libcpp_thread_t *__t) +{ + return thrd_join(*__t, nullptr) == thrd_success ? 0 : EINVAL; +} + +int __libcpp_thread_detach(__libcpp_thread_t *__t) +{ + return thrd_detach(*__t) == thrd_success ? 0 : EINVAL; +} + +void __libcpp_thread_yield() +{ + thrd_yield(); +} + +void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns) +{ + __libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__ns); + thrd_sleep(&__ts, nullptr); +} + +// Thread local storage +int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *)) +{ + return tss_create(__key, __at_exit) == thrd_success ? 0 : EINVAL; +} + +void *__libcpp_tls_get(__libcpp_tls_key __key) +{ + return tss_get(__key); +} + +int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) +{ + return tss_set(__key, __p) == thrd_success ? 0 : EINVAL; +} + +#endif + #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL class _LIBCPP_TYPE_VIS thread; @@ -447,7 +654,7 @@ public: _LIBCPP_INLINE_VISIBILITY void __reset() { __id_ = 0; } - + template friend _LIBCPP_INLINE_VISIBILITY @@ -475,10 +682,10 @@ get_id() _NOEXCEPT } // this_thread +#endif // !_LIBCPP_HAS_NO_THREADS + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // !_LIBCPP_HAS_NO_THREADS - #endif // _LIBCPP_THREADING_SUPPORT diff --git a/lib/libcxx/include/__tree b/lib/libcxx/include/__tree index 15b03ec857..cb7a1022e6 100644 --- a/lib/libcxx/include/__tree +++ b/lib/libcxx/include/__tree @@ -775,11 +775,14 @@ private: typedef __tree_node_types _NodeTypes; allocator_type& __na_; - __tree_node_destructor& operator=(const __tree_node_destructor&); public: bool __value_constructed; + + __tree_node_destructor(const __tree_node_destructor &) = default; + __tree_node_destructor& operator=(const __tree_node_destructor&) = delete; + _LIBCPP_INLINE_VISIBILITY explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT : __na_(__na), @@ -1574,8 +1577,8 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) template __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) : __begin_node_(__iter_pointer()), - __pair1_(__second_tag(), __node_allocator(__a)), - __pair3_(0) + __pair1_(__default_init_tag(), __node_allocator(__a)), + __pair3_(0, __default_init_tag()) { __begin_node() = __end_node(); } @@ -1584,7 +1587,7 @@ template __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a) : __begin_node_(__iter_pointer()), - __pair1_(__second_tag(), __node_allocator(__a)), + __pair1_(__default_init_tag(), __node_allocator(__a)), __pair3_(0, __comp) { __begin_node() = __end_node(); @@ -1656,7 +1659,7 @@ __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _Fo typedef typename _ITraits::value_type _ItValueType; static_assert((is_same<_ItValueType, __container_value_type>::value), "__assign_unique may only be called with the containers value type"); - static_assert(__is_forward_iterator<_ForwardIterator>::value, + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, "__assign_unique requires a forward iterator"); if (size() != 0) { @@ -1697,7 +1700,7 @@ __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _Input template __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) : __begin_node_(__iter_pointer()), - __pair1_(__second_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())), + __pair1_(__default_init_tag(), __node_traits::select_on_container_copy_construction(__t.__node_alloc())), __pair3_(0, __t.value_comp()) { __begin_node() = __end_node(); @@ -1727,7 +1730,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) template __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __a) - : __pair1_(__second_tag(), __node_allocator(__a)), + : __pair1_(__default_init_tag(), __node_allocator(__a)), __pair3_(0, _VSTD::move(__t.value_comp())) { if (__a == __t.__alloc()) diff --git a/lib/libcxx/include/__tuple b/lib/libcxx/include/__tuple index 196f3c2b5a..4da9ec55f3 100644 --- a/lib/libcxx/include/__tuple +++ b/lib/libcxx/include/__tuple @@ -477,8 +477,9 @@ using __tuple_like_with_size _LIBCPP_NODEBUG_TYPE = __tuple_like_with_size_imp< >; struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { - template - static constexpr bool __enable_default() { return false; } + + static constexpr bool __enable_explicit_default() { return false; } + static constexpr bool __enable_implicit_default() { return false; } template static constexpr bool __enable_explicit() { return false; } template diff --git a/lib/libcxx/include/algorithm b/lib/libcxx/include/algorithm index 0d78626755..83e49f19ab 100644 --- a/lib/libcxx/include/algorithm +++ b/lib/libcxx/include/algorithm @@ -167,20 +167,20 @@ template Size count, const T& value, BinaryPredicate pred); template - OutputIterator + constexpr OutputIterator // constexpr in C++20 copy(InputIterator first, InputIterator last, OutputIterator result); template - OutputIterator + constexpr OutputIterator // constexpr in C++20 copy_if(InputIterator first, InputIterator last, OutputIterator result, Predicate pred); template - OutputIterator + constexpr OutputIterator // constexpr in C++20 copy_n(InputIterator first, Size n, OutputIterator result); template - BidirectionalIterator2 + constexpr BidirectionalIterator2 // constexpr in C++20 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 result); @@ -1631,7 +1631,7 @@ search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const // copy template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Iter __unwrap_iter(_Iter __i) { @@ -1639,7 +1639,7 @@ __unwrap_iter(_Iter __i) } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < is_trivially_copy_assignable<_Tp>::value, @@ -1693,15 +1693,23 @@ __unwrap_iter(__wrap_iter<_Tp*> __i) #endif // _LIBCPP_DEBUG_LEVEL < 2 template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator -__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { for (; __first != __last; ++__first, (void) ++__result) *__result = *__first; return __result; } +template +inline _LIBCPP_INLINE_VISIBILITY +_OutputIterator +__copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +{ + return __copy_constexpr(__first, __last, __result); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -1719,23 +1727,37 @@ __copy(_Tp* __first, _Tp* __last, _Up* __result) } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED _OutputIterator copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { - return _VSTD::__copy(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); + if (__libcpp_is_constant_evaluated()) { + return _VSTD::__copy_constexpr( + __unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); + } else { + return _VSTD::__copy( + __unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); + } } // copy_backward +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_OutputIterator +__copy_backward_constexpr(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) +{ + while (__first != __last) + *--__result = *--__last; + return __result; +} + template inline _LIBCPP_INLINE_VISIBILITY _OutputIterator __copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { - while (__first != __last) - *--__result = *--__last; - return __result; + return __copy_backward_constexpr(__first, __last, __result); } template @@ -1758,20 +1780,26 @@ __copy_backward(_Tp* __first, _Tp* __last, _Up* __result) } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED _BidirectionalIterator2 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { - return _VSTD::__copy_backward(__unwrap_iter(__first), - __unwrap_iter(__last), - __unwrap_iter(__result)); + if (__libcpp_is_constant_evaluated()) { + return _VSTD::__copy_backward_constexpr(__unwrap_iter(__first), + __unwrap_iter(__last), + __unwrap_iter(__result)); + } else { + return _VSTD::__copy_backward(__unwrap_iter(__first), + __unwrap_iter(__last), + __unwrap_iter(__result)); + } } // copy_if template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _OutputIterator copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) @@ -1790,11 +1818,11 @@ copy_if(_InputIterator __first, _InputIterator __last, // copy_n template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED typename enable_if < - __is_input_iterator<_InputIterator>::value && - !__is_random_access_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value && + !__is_cpp17_random_access_iterator<_InputIterator>::value, _OutputIterator >::type copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) @@ -1816,10 +1844,10 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17_WITH_IS_CONSTANT_EVALUATED typename enable_if < - __is_random_access_iterator<_InputIterator>::value, + __is_cpp17_random_access_iterator<_InputIterator>::value, _OutputIterator >::type copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) @@ -2492,7 +2520,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__is_forward_iterator<_ForwardIterator>::value, + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, "std::min_element requires a ForwardIterator"); if (__first != __last) { @@ -2564,7 +2592,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__is_forward_iterator<_ForwardIterator>::value, + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, "std::max_element requires a ForwardIterator"); if (__first != __last) { @@ -2659,7 +2687,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX11 std::pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__is_forward_iterator<_ForwardIterator>::value, + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator"); std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); if (__first != __last) @@ -3117,10 +3145,10 @@ _SampleIterator __sample(_PopulationIterator __first, input_iterator_tag) { _Distance __k = 0; - for (; __first != __last && __k < __n; ++__first, (void)++__k) + for (; __first != __last && __k < __n; ++__first, (void) ++__k) __output_iter[__k] = *__first; _Distance __sz = __k; - for (; __first != __last; ++__first, (void)++__k) { + for (; __first != __last; ++__first, (void) ++__k) { _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); if (__r < __sz) __output_iter[__r] = *__first; @@ -3158,8 +3186,8 @@ _SampleIterator __sample(_PopulationIterator __first, _PopCategory; typedef typename iterator_traits<_PopulationIterator>::difference_type _Difference; - static_assert(__is_forward_iterator<_PopulationIterator>::value || - __is_random_access_iterator<_SampleIterator>::value, + static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || + __is_cpp17_random_access_iterator<_SampleIterator>::value, "SampleIterator must meet the requirements of RandomAccessIterator"); typedef typename common_type<_Distance, _Difference>::type _CommonType; _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); @@ -3190,7 +3218,7 @@ template if (__d > 1) { _Dp __uid; - for (--__last, --__d; __first < __last; ++__first, --__d) + for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) { difference_type __i = __uid(__g, _Pp(0, __d)); if (__i != difference_type(0)) @@ -3373,7 +3401,7 @@ __stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate // All trues now at start of range, all falses in buffer // Move falses back into range, but don't mess up __first which points to first false __i = __first; - for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i) + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) *__i = _VSTD::move(*__t2); // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer return __first; @@ -3505,7 +3533,7 @@ __stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last __i = ++__first; // All trues now at start of range, all falses in buffer // Move falses back into range, but don't mess up __first which points to first false - for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, ++__i) + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) *__i = _VSTD::move(*__t2); // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer return __first; @@ -4382,7 +4410,7 @@ merge(_InputIterator1 __first1, _InputIterator1 __last1, { typedef typename iterator_traits<_InputIterator1>::value_type __v1; typedef typename iterator_traits<_InputIterator2>::value_type __v2; - return merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); + return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); } // inplace_merge @@ -4428,14 +4456,14 @@ __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator if (__len1 <= __len2) { value_type* __p = __buff; - for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p) + for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, (void) ++__p) ::new(__p) value_type(_VSTD::move(*__i)); __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp); } else { value_type* __p = __buff; - for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, ++__p) + for (_BidirectionalIterator __i = __middle; __i != __last; __d.__incr((value_type*)0), (void) ++__i, (void) ++__p) ::new(__p) value_type(_VSTD::move(*__i)); typedef reverse_iterator<_BidirectionalIterator> _RBi; typedef reverse_iterator _Rv; @@ -4575,14 +4603,14 @@ __merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, { if (__first1 == __last1) { - for (; __first2 != __last2; ++__first2, ++__result, __d.__incr((value_type*)0)) + for (; __first2 != __last2; ++__first2, ++__result, (void) __d.__incr((value_type*)0)) ::new (__result) value_type(_VSTD::move(*__first2)); __h.release(); return; } if (__first2 == __last2) { - for (; __first1 != __last1; ++__first1, ++__result, __d.__incr((value_type*)0)) + for (; __first1 != __last1; ++__first1, ++__result, (void) __d.__incr((value_type*)0)) ::new (__result) value_type(_VSTD::move(*__first1)); __h.release(); return; @@ -4612,7 +4640,7 @@ __merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, { if (__first2 == __last2) { - for (; __first1 != __last1; ++__first1, ++__result) + for (; __first1 != __last1; ++__first1, (void) ++__result) *__result = _VSTD::move(*__first1); return; } @@ -4627,7 +4655,7 @@ __merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, ++__first1; } } - for (; __first2 != __last2; ++__first2, ++__result) + for (; __first2 != __last2; ++__first2, (void) ++__result) *__result = _VSTD::move(*__first2); } @@ -4995,7 +5023,7 @@ void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - for (difference_type __n = __last - __first; __n > 1; --__last, --__n) + for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) __pop_heap<_Compare>(__first, __last, __comp, __n); } @@ -5065,7 +5093,7 @@ __partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __r = __result_first; if (__r != __result_last) { - for (; __first != __last && __r != __result_last; (void) ++__first, ++__r) + for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) *__r = *__first; __make_heap<_Compare>(__result_first, __r, __comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; @@ -5678,4 +5706,8 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS +#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 +# include <__pstl_algorithm> +#endif + #endif // _LIBCPP_ALGORITHM diff --git a/lib/libcxx/include/atomic b/lib/libcxx/include/atomic index afb431eda1..6904dd4000 100644 --- a/lib/libcxx/include/atomic +++ b/lib/libcxx/include/atomic @@ -920,7 +920,7 @@ struct __cxx_atomic_base_impl { #endif // _LIBCPP_CXX03_LANG _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {} - _Atomic(_Tp) __a_value; + _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; }; #define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) diff --git a/lib/libcxx/include/bit b/lib/libcxx/include/bit index 1c0e8ad3ba..6dc85b5d01 100644 --- a/lib/libcxx/include/bit +++ b/lib/libcxx/include/bit @@ -42,6 +42,13 @@ namespace std { template constexpr int popcount(T x) noexcept; // C++20 + // 20.15.9, endian + enum class endian { + little = see below, // C++20 + big = see below, // C++20 + native = see below // C++20 +}; + } // namespace std */ @@ -343,7 +350,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)); } @@ -456,6 +463,20 @@ log2p1(_Tp __t) noexcept return __t == 0 ? 0 : __bit_log2(__t) + 1; } + +enum class endian +{ + little = 0xDEAD, + big = 0xFACE, +#if defined(_LIBCPP_LITTLE_ENDIAN) + native = little +#elif defined(_LIBCPP_BIG_ENDIAN) + native = big +#else + native = 0xCAFE +#endif +}; + #endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/lib/libcxx/include/chrono b/lib/libcxx/include/chrono index 1b907571aa..6e5de398b7 100644 --- a/lib/libcxx/include/chrono +++ b/lib/libcxx/include/chrono @@ -612,13 +612,43 @@ constexpr year_month_weekday_last constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, int y) noexcept; -// 25.9, class template time_of_day // C++20 -template class time_of_day; +// 26.9, class template hh_mm_ss +template +class hh_mm_ss +{ + bool is_neg; // exposition only + chrono::hours h; // exposition only + chrono::minutes m; // exposition only + chrono::seconds s; // exposition only + precision ss; // exposition only + +public: + static unsigned constexpr fractional_width = see below; + using precision = see below; + + constexpr hh_mm_ss() noexcept : hh_mm_ss{Duration::zero()} {} + constexpr explicit hh_mm_ss(Duration d) noexcept; + + constexpr bool is_negative() const noexcept; + constexpr chrono::hours hours() const noexcept; + constexpr chrono::minutes minutes() const noexcept; + constexpr chrono::seconds seconds() const noexcept; + constexpr precision subseconds() const noexcept; + + constexpr explicit operator precision() const noexcept; + constexpr precision to_duration() const noexcept; +}; + +template + basic_ostream& + operator<<(basic_ostream& os, hh_mm_ss const& hms); + +// 26.10, 12/24 hour functions +constexpr bool is_am(hours const& h) noexcept; +constexpr bool is_pm(hours const& h) noexcept; +constexpr hours make12(const hours& h) noexcept; +constexpr hours make24(const hours& h, bool is_pm) noexcept; -template<> class time_of_day; -template<> class time_of_day; -template<> class time_of_day; -template class time_of_day>; // 25.10.2, time zone database // C++20 struct tzdb; @@ -1428,7 +1458,7 @@ typename enable_if >::type abs(duration<_Rep, _Period> __d) { - return __d >= __d.zero() ? __d : -__d; + return __d >= __d.zero() ? +__d : -__d; } #endif @@ -1810,7 +1840,7 @@ private: unsigned char __wd; public: weekday() = default; - inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast(__val)) {} + inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast(__val == 7 ? 0 : __val)) {} inline constexpr weekday(const sys_days& __sysd) noexcept : __wd(__weekday_from_days(__sysd.time_since_epoch().count())) {} inline explicit constexpr weekday(const local_days& __locd) noexcept @@ -1822,11 +1852,13 @@ public: inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } constexpr weekday& operator+=(const days& __dd) noexcept; constexpr weekday& operator-=(const days& __dd) noexcept; - inline explicit constexpr operator unsigned() const noexcept { return __wd; } + inline constexpr unsigned c_encoding() const noexcept { return __wd; } + inline constexpr unsigned iso_encoding() const noexcept { return __wd == 0u ? 7 : __wd; } inline constexpr bool ok() const noexcept { return __wd <= 6; } constexpr weekday_indexed operator[](unsigned __index) const noexcept; constexpr weekday_last operator[](last_spec) const noexcept; + // TODO: Make private? static constexpr unsigned char __weekday_from_days(int __days) noexcept; }; @@ -1842,7 +1874,7 @@ unsigned char weekday::__weekday_from_days(int __days) noexcept inline constexpr bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } +{ return __lhs.c_encoding() == __rhs.c_encoding(); } inline constexpr bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept @@ -1850,7 +1882,7 @@ bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept inline constexpr bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept -{ return static_cast(__lhs) < static_cast(__rhs); } +{ return __lhs.c_encoding() < __rhs.c_encoding(); } inline constexpr bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept @@ -1866,7 +1898,7 @@ bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept { - auto const __mu = static_cast(static_cast(__lhs)) + __rhs.count(); + auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; return weekday{static_cast(__mu - __yr * 7)}; } @@ -1879,7 +1911,7 @@ constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept { - const int __wdu = static_cast(__lhs) - static_cast(__rhs); + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; return days{__wdu - __wk * 7}; } @@ -2537,8 +2569,13 @@ public: inline constexpr bool ok() const noexcept { if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; - // TODO: make sure it's a valid date - return true; + if (__wdi.index() <= 4) return true; + auto __nth_weekday_day = + __wdi.weekday() - + chrono::weekday{static_cast(__y / __m / 1)} + + days{(__wdi.index() - 1) * 7 + 1}; + return static_cast(__nth_weekday_day.count()) <= + static_cast((__y / __m / last).day()); } static constexpr year_month_weekday __from_days(days __d) noexcept; @@ -2715,6 +2752,84 @@ inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(co inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +template +class hh_mm_ss +{ +private: + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; + + static constexpr uint64_t __pow10(unsigned __exp) + { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } + + static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) + { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w+1); + return 0; + } + +public: + static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? + __width(__CommonType::period::den) : 6u; + using precision = duration>; + + constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + + constexpr explicit hh_mm_ss(_Duration __d) noexcept : + __is_neg(__d < _Duration(0)), + __h(duration_cast (abs(__d))), + __m(duration_cast(abs(__d) - hours())), + __s(duration_cast(abs(__d) - hours() - minutes())), + __f(duration_cast (abs(__d) - hours() - minutes() - seconds())) + {} + + constexpr bool is_negative() const noexcept { return __is_neg; } + constexpr chrono::hours hours() const noexcept { return __h; } + constexpr chrono::minutes minutes() const noexcept { return __m; } + constexpr chrono::seconds seconds() const noexcept { return __s; } + constexpr precision subseconds() const noexcept { return __f; } + + constexpr precision to_duration() const noexcept + { + auto __dur = __h + __m + __s + __f; + return __is_neg ? -__dur : __dur; + } + + constexpr explicit operator precision() const noexcept { return to_duration(); } + +private: + bool __is_neg; + chrono::hours __h; + chrono::minutes __m; + chrono::seconds __s; + precision __f; +}; + +constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } +constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } + +constexpr hours make12(const hours& __h) noexcept +{ + if (__h == hours( 0)) return hours(12); + else if (__h <= hours(12)) return __h; + else return __h - hours(12); +} + +constexpr hours make24(const hours& __h, bool __is_pm) noexcept +{ + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; +} + #endif // _LIBCPP_STD_VER > 17 } // chrono @@ -2825,6 +2940,7 @@ struct _FilesystemClock { typedef chrono::duration duration; typedef chrono::time_point<_FilesystemClock> time_point; + _LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; diff --git a/lib/libcxx/include/cmath b/lib/libcxx/include/cmath index f5864be5e1..0f06486fb3 100644 --- a/lib/libcxx/include/cmath +++ b/lib/libcxx/include/cmath @@ -303,11 +303,15 @@ long double truncl(long double x); #include <__config> #include #include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD using ::signbit; @@ -632,6 +636,38 @@ lerp(long double __a, long double __b, long double __t) _NOEXCEPT { return __ler #endif // _LIBCPP_STD_VER > 17 +template ::digits > numeric_limits<_IntT>::digits), + int _Bits = (numeric_limits<_IntT>::digits - numeric_limits<_FloatT>::digits)> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR _IntT __max_representable_int_for_float() _NOEXCEPT { + static_assert(is_floating_point<_FloatT>::value, "must be a floating point type"); + static_assert(is_integral<_IntT>::value, "must be an integral type"); + static_assert(numeric_limits<_FloatT>::radix == 2, "FloatT has incorrect radix"); + static_assert((_IsSame<_FloatT, float>::value || _IsSame<_FloatT, double>::value + || _IsSame<_FloatT,long double>::value), "unsupported floating point type"); + return _FloatBigger ? numeric_limits<_IntT>::max() : (numeric_limits<_IntT>::max() >> _Bits << _Bits); +} + +// Convert a floating point number to the specified integral type after +// clamping to the integral types representable range. +// +// The behavior is undefined if `__r` is NaN. +template +_LIBCPP_INLINE_VISIBILITY +_IntT __clamp_to_integral(_RealT __r) _NOEXCEPT { + using _Lim = std::numeric_limits<_IntT>; + const _IntT _MaxVal = std::__max_representable_int_for_float<_IntT, _RealT>(); + if (__r >= ::nextafter(static_cast<_RealT>(_MaxVal), INFINITY)) { + return _Lim::max(); + } else if (__r <= _Lim::lowest()) { + return _Lim::min(); + } + return static_cast<_IntT>(__r); +} + _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP_CMATH diff --git a/lib/libcxx/include/cstdio b/lib/libcxx/include/cstdio index 6755693823..0f3f42dac2 100644 --- a/lib/libcxx/include/cstdio +++ b/lib/libcxx/include/cstdio @@ -152,7 +152,7 @@ using ::tmpnam; #ifndef _LIBCPP_HAS_NO_STDIN using ::getchar; -#if _LIBCPP_STD_VER <= 11 && !defined(_LIBCPP_MSVCRT) +#if _LIBCPP_STD_VER <= 11 && !defined(_LIBCPP_C_HAS_NO_GETS) using ::gets; #endif using ::scanf; diff --git a/lib/libcxx/include/cstdlib b/lib/libcxx/include/cstdlib index 68b3ded3fd..675a12d9e0 100644 --- a/lib/libcxx/include/cstdlib +++ b/lib/libcxx/include/cstdlib @@ -154,7 +154,7 @@ using ::wcstombs; using ::at_quick_exit; using ::quick_exit; #endif -#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES) +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_ALIGNED_ALLOC) using ::aligned_alloc; #endif diff --git a/lib/libcxx/include/ctime b/lib/libcxx/include/ctime index cb8474f8f0..f9f2f1659d 100644 --- a/lib/libcxx/include/ctime +++ b/lib/libcxx/include/ctime @@ -18,7 +18,7 @@ Macros: NULL CLOCKS_PER_SEC TIME_UTC // C++17 - + namespace std { @@ -29,7 +29,7 @@ Types: time_t tm timespec // C++17 - + clock_t clock(); double difftime(time_t time1, time_t time0); time_t mktime(tm* timeptr); @@ -58,7 +58,7 @@ using ::clock_t; using ::size_t; using ::time_t; using ::tm; -#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES) +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET) using ::timespec; #endif using ::clock; diff --git a/lib/libcxx/include/deque b/lib/libcxx/include/deque index d3ccf2ef6f..115b1b6427 100644 --- a/lib/libcxx/include/deque +++ b/lib/libcxx/include/deque @@ -190,7 +190,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> copy(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0); template @@ -212,7 +212,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> copy_backward(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0); template @@ -234,7 +234,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> move(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0); template @@ -256,7 +256,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> move_backward(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0); template @@ -450,7 +450,7 @@ private: copy(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*); template @@ -475,7 +475,7 @@ private: copy_backward(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*); template @@ -500,7 +500,7 @@ private: move(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*); template @@ -525,7 +525,7 @@ private: move_backward(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*); template @@ -558,7 +558,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> copy(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*) { typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; @@ -646,7 +646,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> copy_backward(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*) { typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; @@ -734,7 +734,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> move(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*) { typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; @@ -822,7 +822,7 @@ __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> move_backward(_RAIter __f, _RAIter __l, __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2> __r, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*) { typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::difference_type difference_type; typedef typename __deque_iterator<_V2, _P2, _R2, _M2, _D2, _B2>::pointer pointer; @@ -934,7 +934,7 @@ public: typedef _Allocator allocator_type; typedef allocator_traits __alloc_traits; typedef typename __alloc_traits::size_type size_type; -protected: + typedef _Tp value_type; typedef value_type& reference; typedef const value_type& const_reference; @@ -956,6 +956,74 @@ protected: typedef __deque_iterator const_iterator; + struct __deque_block_range { + explicit __deque_block_range(pointer __b, pointer __e) _NOEXCEPT : __begin_(__b), __end_(__e) {} + const pointer __begin_; + const pointer __end_; + }; + + struct __deque_range { + iterator __pos_; + const iterator __end_; + + __deque_range(iterator __pos, iterator __e) _NOEXCEPT + : __pos_(__pos), __end_(__e) {} + + explicit operator bool() const _NOEXCEPT { + return __pos_ != __end_; + } + + __deque_range begin() const { + return *this; + } + + __deque_range end() const { + return __deque_range(__end_, __end_); + } + __deque_block_range operator*() const _NOEXCEPT { + if (__pos_.__m_iter_ == __end_.__m_iter_) { + return __deque_block_range(__pos_.__ptr_, __end_.__ptr_); + } + return __deque_block_range(__pos_.__ptr_, *__pos_.__m_iter_ + __block_size); + } + + __deque_range& operator++() _NOEXCEPT { + if (__pos_.__m_iter_ == __end_.__m_iter_) { + __pos_ = __end_; + } else { + ++__pos_.__m_iter_; + __pos_.__ptr_ = *__pos_.__m_iter_; + } + return *this; + } + + + friend bool operator==(__deque_range const& __lhs, __deque_range const& __rhs) { + return __lhs.__pos_ == __rhs.__pos_; + } + friend bool operator!=(__deque_range const& __lhs, __deque_range const& __rhs) { + return !(__lhs == __rhs); + } + }; + + + + struct _ConstructTransaction { + _ConstructTransaction(__deque_base* __db, __deque_block_range& __r) + : __pos_(__r.__begin_), __end_(__r.__end_), __begin_(__r.__begin_), __base_(__db) {} + + + ~_ConstructTransaction() { + __base_->size() += (__pos_ - __begin_); + } + + pointer __pos_; + const pointer __end_; + private: + const pointer __begin_; + __deque_base * const __base_; + }; + protected: __map __map_; size_type __start_; @@ -1103,7 +1171,7 @@ template inline __deque_base<_Tp, _Allocator>::__deque_base() _NOEXCEPT_(is_nothrow_default_constructible::value) - : __start_(0), __size_(0) {} + : __start_(0), __size_(0, __default_init_tag()) {} template inline @@ -1222,6 +1290,10 @@ public: typedef _VSTD::reverse_iterator reverse_iterator; typedef _VSTD::reverse_iterator const_reverse_iterator; + using typename __base::__deque_range; + using typename __base::__deque_block_range; + using typename __base::_ConstructTransaction; + // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY deque() @@ -1236,10 +1308,10 @@ public: deque(size_type __n, const value_type& __v, const allocator_type& __a); template deque(_InputIter __f, _InputIter __l, - typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0); template deque(_InputIter __f, _InputIter __l, const allocator_type& __a, - typename enable_if<__is_input_iterator<_InputIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0); deque(const deque& __c); deque(const deque& __c, const allocator_type& __a); @@ -1267,11 +1339,11 @@ public: template void assign(_InputIter __f, _InputIter __l, - typename enable_if<__is_input_iterator<_InputIter>::value && - !__is_random_access_iterator<_InputIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value && + !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0); template void assign(_RAIter __f, _RAIter __l, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type* = 0); + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0); void assign(size_type __n, const value_type& __v); _LIBCPP_INLINE_VISIBILITY @@ -1371,15 +1443,15 @@ public: iterator insert(const_iterator __p, size_type __n, const value_type& __v); template iterator insert(const_iterator __p, _InputIter __f, _InputIter __l, - typename enable_if<__is_input_iterator<_InputIter>::value - &&!__is_forward_iterator<_InputIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value + &&!__is_cpp17_forward_iterator<_InputIter>::value>::type* = 0); template iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, - typename enable_if<__is_forward_iterator<_ForwardIterator>::value - &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type* = 0); + typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value + &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type* = 0); template iterator insert(const_iterator __p, _BiIter __f, _BiIter __l, - typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type* = 0); + typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0); void pop_front(); void pop_back(); @@ -1399,7 +1471,7 @@ public: _LIBCPP_INLINE_VISIBILITY bool __invariants() const {return __base::__invariants();} -private: + typedef typename __base::__map_const_pointer __map_const_pointer; _LIBCPP_INLINE_VISIBILITY @@ -1412,24 +1484,62 @@ private: { return __base::__map_.size() == 0 ? 0 : __base::__map_.size() * __base::__block_size - 1; } + _LIBCPP_INLINE_VISIBILITY + size_type __block_count() const + { + return __base::__map_.size(); + } + _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const { return __base::__start_; } _LIBCPP_INLINE_VISIBILITY + size_type __front_spare_blocks() const { + return __front_spare() / __base::__block_size; + } + _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const { return __capacity() - (__base::__start_ + __base::size()); } + _LIBCPP_INLINE_VISIBILITY + size_type __back_spare_blocks() const { + return __back_spare() / __base::__block_size; + } + + private: + _LIBCPP_INLINE_VISIBILITY + bool __maybe_remove_front_spare(bool __keep_one = true) { + if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { + __alloc_traits::deallocate(__base::__alloc(), __base::__map_.front(), + __base::__block_size); + __base::__map_.pop_front(); + __base::__start_ -= __base::__block_size; + return true; + } + return false; + } + + _LIBCPP_INLINE_VISIBILITY + bool __maybe_remove_back_spare(bool __keep_one = true) { + if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { + __alloc_traits::deallocate(__base::__alloc(), __base::__map_.back(), + __base::__block_size); + __base::__map_.pop_back(); + return true; + } + return false; + } template void __append(_InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value && - !__is_forward_iterator<_InpIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value && + !__is_cpp17_forward_iterator<_InpIter>::value>::type* = 0); template void __append(_ForIter __f, _ForIter __l, - typename enable_if<__is_forward_iterator<_ForIter>::value>::type* = 0); + typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0); void __append(size_type __n); void __append(size_type __n, const value_type& __v); void __erase_to_end(const_iterator __f); @@ -1524,7 +1634,7 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const alloca template template deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, - typename enable_if<__is_input_iterator<_InputIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*) { __append(__f, __l); } @@ -1532,7 +1642,7 @@ deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, template template deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a, - typename enable_if<__is_input_iterator<_InputIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*) : __base(__a) { __append(__f, __l); @@ -1640,8 +1750,8 @@ template template void deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l, - typename enable_if<__is_input_iterator<_InputIter>::value && - !__is_random_access_iterator<_InputIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value && + !__is_cpp17_random_access_iterator<_InputIter>::value>::type*) { iterator __i = __base::begin(); iterator __e = __base::end(); @@ -1657,7 +1767,7 @@ template template void deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l, - typename enable_if<__is_random_access_iterator<_RAIter>::value>::type*) + typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*) { if (static_cast(__l - __f) > __base::size()) { @@ -1727,17 +1837,8 @@ deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT } else { - if (__front_spare() >= __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); - __base::__map_.pop_front(); - __base::__start_ -= __base::__block_size; - } - if (__back_spare() >= __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); - __base::__map_.pop_back(); - } + __maybe_remove_front_spare(/*__keep_one=*/false); + __maybe_remove_back_spare(/*__keep_one=*/false); } __base::__map_.shrink_to_fit(); } @@ -2151,8 +2252,8 @@ template template typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l, - typename enable_if<__is_input_iterator<_InputIter>::value - &&!__is_forward_iterator<_InputIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InputIter>::value + &&!__is_cpp17_forward_iterator<_InputIter>::value>::type*) { __split_buffer __buf(__base::__alloc()); __buf.__construct_at_end(__f, __l); @@ -2164,8 +2265,8 @@ template template typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, - typename enable_if<__is_forward_iterator<_ForwardIterator>::value - &&!__is_bidirectional_iterator<_ForwardIterator>::value>::type*) + typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value + &&!__is_cpp17_bidirectional_iterator<_ForwardIterator>::value>::type*) { size_type __n = _VSTD::distance(__f, __l); __split_buffer __buf(__n, 0, __base::__alloc()); @@ -2178,7 +2279,7 @@ template template typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, - typename enable_if<__is_bidirectional_iterator<_BiIter>::value>::type*) + typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*) { size_type __n = _VSTD::distance(__f, __l); size_type __pos = __p - __base::begin(); @@ -2247,8 +2348,8 @@ template template void deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value && - !__is_forward_iterator<_InpIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value && + !__is_cpp17_forward_iterator<_InpIter>::value>::type*) { for (; __f != __l; ++__f) #ifdef _LIBCPP_CXX03_LANG @@ -2262,7 +2363,7 @@ template template void deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, - typename enable_if<__is_forward_iterator<_ForIter>::value>::type*) + typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*) { size_type __n = _VSTD::distance(__f, __l); allocator_type& __a = __base::__alloc(); @@ -2270,8 +2371,12 @@ deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, if (__n > __back_capacity) __add_back_capacity(__n - __back_capacity); // __n <= __back_capacity - for (iterator __i = __base::end(); __f != __l; ++__i, (void) ++__f, ++__base::size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__i), *__f); + for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { + _ConstructTransaction __tx(this, __br); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { + __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); + } + } } template @@ -2283,8 +2388,12 @@ deque<_Tp, _Allocator>::__append(size_type __n) if (__n > __back_capacity) __add_back_capacity(__n - __back_capacity); // __n <= __back_capacity - for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__i)); + for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { + _ConstructTransaction __tx(this, __br); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); + } + } } template @@ -2296,8 +2405,13 @@ deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) if (__n > __back_capacity) __add_back_capacity(__n - __back_capacity); // __n <= __back_capacity - for (iterator __i = __base::end(); __n; --__n, ++__i, ++__base::size()) - __alloc_traits::construct(__a, _VSTD::addressof(*__i), __v); + for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { + _ConstructTransaction __tx(this, __br); + for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { + __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); + } + } + } // Create front capacity for one block of elements. @@ -2592,16 +2706,12 @@ void deque<_Tp, _Allocator>::pop_front() { allocator_type& __a = __base::__alloc(); - __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() + + __alloc_traits::destroy(__a, __to_address(*(__base::__map_.begin() + __base::__start_ / __base::__block_size) + __base::__start_ % __base::__block_size)); --__base::size(); - if (++__base::__start_ >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); - __base::__map_.pop_front(); - __base::__start_ -= __base::__block_size; - } + ++__base::__start_; + __maybe_remove_front_spare(); } template @@ -2611,15 +2721,11 @@ deque<_Tp, _Allocator>::pop_back() _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque"); allocator_type& __a = __base::__alloc(); size_type __p = __base::size() + __base::__start_ - 1; - __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() + + __alloc_traits::destroy(__a, __to_address(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size)); --__base::size(); - if (__back_spare() >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); - __base::__map_.pop_back(); - } + __maybe_remove_back_spare(); } // move assign [__f, __l) to [__r, __r + (__l-__f)). @@ -2768,23 +2874,14 @@ deque<_Tp, _Allocator>::erase(const_iterator __f) __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); --__base::size(); ++__base::__start_; - if (__front_spare() >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); - __base::__map_.pop_front(); - __base::__start_ -= __base::__block_size; - } + __maybe_remove_front_spare(); } else { // erase from back iterator __i = _VSTD::move(_VSTD::next(__p), __base::end(), __p); __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); --__base::size(); - if (__back_spare() >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); - __base::__map_.pop_back(); - } + __maybe_remove_back_spare(); } return __base::begin() + __pos; } @@ -2807,11 +2904,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); __base::size() -= __n; __base::__start_ += __n; - while (__front_spare() >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.front(), __base::__block_size); - __base::__map_.pop_front(); - __base::__start_ -= __base::__block_size; + while (__maybe_remove_front_spare()) { } } else @@ -2820,10 +2913,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) for (iterator __e = __base::end(); __i != __e; ++__i) __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); __base::size() -= __n; - while (__back_spare() >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); - __base::__map_.pop_back(); + while (__maybe_remove_back_spare()) { } } } @@ -2844,10 +2934,7 @@ deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) for (iterator __p = __b + __pos; __p != __e; ++__p) __alloc_traits::destroy(__a, _VSTD::addressof(*__p)); __base::size() -= __n; - while (__back_spare() >= 2 * __base::__block_size) - { - __alloc_traits::deallocate(__a, __base::__map_.back(), __base::__block_size); - __base::__map_.pop_back(); + while (__maybe_remove_back_spare()) { } } } diff --git a/lib/libcxx/include/execution b/lib/libcxx/include/execution new file mode 100644 index 0000000000..e25cb82d55 --- /dev/null +++ b/lib/libcxx/include/execution @@ -0,0 +1,19 @@ +// -*- C++ -*- +//===------------------------- execution ---------------------------------===// +// +// 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_EXECUTION +#define _LIBCPP_EXECUTION + +#include <__config> + +#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 +# include <__pstl_execution> +#endif + +#endif // _LIBCPP_EXECUTION diff --git a/lib/libcxx/include/experimental/coroutine b/lib/libcxx/include/experimental/coroutine index e2f0a25f77..54ec74b9f9 100644 --- a/lib/libcxx/include/experimental/coroutine +++ b/lib/libcxx/include/experimental/coroutine @@ -51,7 +51,6 @@ template struct hash>; #include #include // for hash #include -#include #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/lib/libcxx/include/experimental/functional b/lib/libcxx/include/experimental/functional index 755eda6415..c7dda2254b 100644 --- a/lib/libcxx/include/experimental/functional +++ b/lib/libcxx/include/experimental/functional @@ -112,7 +112,7 @@ template> class _LIBCPP_TYPE_VIS default_searcher { public: _LIBCPP_INLINE_VISIBILITY - default_searcher(_ForwardIterator __f, _ForwardIterator __l, + default_searcher(_ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate()) : __first_(__f), __last_(__l), __pred_(__p) {} @@ -151,12 +151,12 @@ public: // TODO private: const _Value __default_value_; std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table; - + public: _LIBCPP_INLINE_VISIBILITY _BMSkipTable(std::size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred) : __default_value_(__default), __table(__sz, __hf, __pred) {} - + _LIBCPP_INLINE_VISIBILITY void insert(const key_type &__key, value_type __val) { @@ -170,7 +170,7 @@ public: return __it == __table.end() ? __default_value_ : __it->second; } }; - + // Special case small numeric values; use an array template @@ -189,7 +189,7 @@ public: { std::fill_n(__table.begin(), __table.size(), __default); } - + _LIBCPP_INLINE_VISIBILITY void insert(key_type __key, value_type __val) { @@ -204,8 +204,8 @@ public: }; -template ::value_type>, +template ::value_type>, class _BinaryPredicate = equal_to<>> class _LIBCPP_TYPE_VIS boyer_moore_searcher { private: @@ -217,9 +217,9 @@ private: is_same<_Hash, hash>::value && is_same<_BinaryPredicate, equal_to<>>::value > skip_table_type; - + public: - boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, + boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) : __first_(__f), __last_(__l), __pred_(__pred), __pattern_length_(_VSTD::distance(__first_, __last_)), @@ -232,13 +232,13 @@ public: this->__build_suffix_table ( __first_, __last_, __pred_ ); } - + template pair<_RandomAccessIterator2, _RandomAccessIterator2> operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { static_assert ( std::is_same< - typename std::__uncvref::value_type>::type, + typename std::__uncvref::value_type>::type, typename std::__uncvref::value_type>::type >::value, "Corpus and Pattern iterators must point to the same type" ); @@ -247,13 +247,13 @@ public: if (__first_ == __last_) return make_pair(__f, __f); // empty pattern // If the pattern is larger than the corpus, we can't find it! - if ( __pattern_length_ > _VSTD::distance (__f, __l)) + if ( __pattern_length_ > _VSTD::distance (__f, __l)) return make_pair(__l, __l); - // Do the search + // Do the search return this->__search(__f, __l); } - + public: // TODO private: _RandomAccessIterator1 __first_; _RandomAccessIterator1 __last_; @@ -270,7 +270,7 @@ public: // TODO private: const _RandomAccessIterator2 __last = __l - __pattern_length_; const skip_table_type & __skip = *__skip_.get(); const vector & __suffix = *__suffix_.get(); - + while (__cur <= __last) { @@ -282,7 +282,7 @@ public: // TODO private: if ( __j == 0 ) return make_pair(__cur, __cur + __pattern_length_); } - + // Since we didn't match, figure out how far to skip forward difference_type __k = __skip[__cur [ __j - 1 ]]; difference_type __m = __j - __k - 1; @@ -291,7 +291,7 @@ public: // TODO private: else __cur += __suffix[ __j ]; } - + return make_pair(__l, __l); // We didn't find anything } @@ -300,21 +300,21 @@ public: // TODO private: void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix ) { const std::size_t __count = _VSTD::distance(__f, __l); - + __prefix[0] = 0; std::size_t __k = 0; for ( std::size_t __i = 1; __i < __count; ++__i ) { while ( __k > 0 && !__pred ( __f[__k], __f[__i] )) __k = __prefix [ __k - 1 ]; - + if ( __pred ( __f[__k], __f[__i] )) __k++; __prefix [ __i ] = __k; } } - void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, + void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, _BinaryPredicate __pred) { const std::size_t __count = _VSTD::distance(__f, __l); @@ -322,19 +322,19 @@ public: // TODO private: if (__count > 0) { _VSTD::vector __scratch(__count); - + __compute_bm_prefix(__f, __l, __pred, __scratch); for ( std::size_t __i = 0; __i <= __count; __i++ ) __suffix[__i] = __count - __scratch[__count-1]; - + typedef _VSTD::reverse_iterator<_RandomAccessIterator1> _RevIter; __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch); - + for ( std::size_t __i = 0; __i < __count; __i++ ) { const std::size_t __j = __count - __scratch[__i]; const difference_type __k = __i - __scratch[__i] + 1; - + if (__suffix[__j] > __k) __suffix[__j] = __k; } @@ -343,20 +343,20 @@ public: // TODO private: }; -template::value_type>, +template::value_type>, class _BinaryPredicate = equal_to<>> _LIBCPP_INLINE_VISIBILITY boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> -make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, +make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) { return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); } // boyer-moore-horspool -template ::value_type>, +template ::value_type>, class _BinaryPredicate = equal_to<>> class _LIBCPP_TYPE_VIS boyer_moore_horspool_searcher { private: @@ -370,7 +370,7 @@ private: > skip_table_type; public: - boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, + boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) : __first_(__f), __last_(__l), __pred_(__pred), __pattern_length_(_VSTD::distance(__first_, __last_)), @@ -384,13 +384,13 @@ public: __skip_->insert(*__f, __pattern_length_ - 1 - __i); } } - + template pair<_RandomAccessIterator2, _RandomAccessIterator2> operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { static_assert ( std::is_same< - typename std::__uncvref::value_type>::type, + typename std::__uncvref::value_type>::type, typename std::__uncvref::value_type>::type >::value, "Corpus and Pattern iterators must point to the same type" ); @@ -399,13 +399,13 @@ public: if (__first_ == __last_) return make_pair(__f, __f); // empty pattern // If the pattern is larger than the corpus, we can't find it! - if ( __pattern_length_ > _VSTD::distance (__f, __l)) + if ( __pattern_length_ > _VSTD::distance (__f, __l)) return make_pair(__l, __l); - // Do the search + // Do the search return this->__search(__f, __l); } - + private: _RandomAccessIterator1 __first_; _RandomAccessIterator1 __last_; @@ -433,17 +433,17 @@ private: } __cur += __skip[__cur[__pattern_length_-1]]; } - + return make_pair(__l, __l); } }; -template::value_type>, +template::value_type>, class _BinaryPredicate = equal_to<>> _LIBCPP_INLINE_VISIBILITY boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> -make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, +make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) { return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); diff --git a/lib/libcxx/include/experimental/iterator b/lib/libcxx/include/experimental/iterator index 6a6e51d820..10b0599138 100644 --- a/lib/libcxx/include/experimental/iterator +++ b/lib/libcxx/include/experimental/iterator @@ -26,19 +26,19 @@ namespace std { typedef void difference_type; typedef void pointer; typedef void reference; - + ostream_joiner(ostream_type& s, const DelimT& delimiter); ostream_joiner(ostream_type& s, DelimT&& delimiter); - template + template ostream_joiner& operator=(const T& value); ostream_joiner& operator*() noexcept; ostream_joiner& operator++() noexcept; ostream_joiner& operator++(int) noexcept; private: - ostream_type* out_stream; // exposition only - DelimT delim; // exposition only + ostream_type* out_stream; // exposition only + DelimT delim; // exposition only bool first_element; // exposition only }; @@ -75,10 +75,10 @@ public: ostream_joiner(ostream_type& __os, _Delim&& __d) : __output_iter(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {} - + ostream_joiner(ostream_type& __os, const _Delim& __d) : __output_iter(_VSTD::addressof(__os)), __delim(__d), __first(true) {} - + template ostream_joiner& operator=(const _Tp& __v) diff --git a/lib/libcxx/include/experimental/propagate_const b/lib/libcxx/include/experimental/propagate_const index 092b013bb9..59f50c5e57 100644 --- a/lib/libcxx/include/experimental/propagate_const +++ b/lib/libcxx/include/experimental/propagate_const @@ -575,4 +575,3 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER > 11 #endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST - diff --git a/lib/libcxx/include/experimental/type_traits b/lib/libcxx/include/experimental/type_traits index 19466e9a5a..7ab097226b 100644 --- a/lib/libcxx/include/experimental/type_traits +++ b/lib/libcxx/include/experimental/type_traits @@ -60,7 +60,7 @@ inline namespace fundamentals_v1 { using is_detected_convertible = is_convertible, To>; template class Op, class... Args> constexpr bool is_detected_convertible_v - = is_detected_convertible::value; + = is_detected_convertible::value; } // namespace fundamentals_v1 } // namespace experimental @@ -122,7 +122,7 @@ struct _DETECTOR<_Default, void_t<_Op<_Args...>>, _Op, _Args...> { using value_t = true_type; using type = _Op<_Args...>; }; - + template class _Op, class... _Args> using is_detected = typename _DETECTOR::value_t; @@ -144,7 +144,7 @@ template class _Op, class... _Args> template class _Op, class... _Args> using is_detected_convertible = is_convertible, To>; template class _Op, class... _Args> - _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible::value; + _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible::value; _LIBCPP_END_NAMESPACE_LFTS diff --git a/lib/libcxx/include/ext/hash_map b/lib/libcxx/include/ext/hash_map index 24823c6bf0..7478d74100 100644 --- a/lib/libcxx/include/ext/hash_map +++ b/lib/libcxx/include/ext/hash_map @@ -39,14 +39,17 @@ public: typedef /unspecified/ iterator; typedef /unspecified/ const_iterator; - explicit hash_map(size_type n = 193, const hasher& hf = hasher(), + hash_map(); + explicit hash_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template - hash_map(InputIterator f, InputIterator l, - size_type n = 193, const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + hash_map(InputIterator f, InputIterator l); + template + hash_map(InputIterator f, InputIterator l, + size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); hash_map(const hash_map&); ~hash_map(); hash_map& operator=(const hash_map&); @@ -315,12 +318,13 @@ private: allocator_type& __na_; - __hash_map_node_destructor& operator=(const __hash_map_node_destructor&); - public: bool __first_constructed; bool __second_constructed; + __hash_map_node_destructor(__hash_map_node_destructor const&) = default; + __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete; + _LIBCPP_INLINE_VISIBILITY explicit __hash_map_node_destructor(allocator_type& __na) : __na_(__na), @@ -391,10 +395,10 @@ public: return __t; } - friend _LIBCPP_INLINE_VISIBILITY + friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) {return __x.__i_ == __y.__i_;} - friend _LIBCPP_INLINE_VISIBILITY + friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) {return __x.__i_ != __y.__i_;} @@ -502,7 +506,7 @@ public: typedef __hash_map_iterator iterator; typedef __hash_map_const_iterator const_iterator; - _LIBCPP_INLINE_VISIBILITY hash_map() {__table_.rehash(193);} + _LIBCPP_INLINE_VISIBILITY hash_map() { } explicit hash_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); hash_map(size_type __n, const hasher& __hf, @@ -623,7 +627,6 @@ template hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( _InputIterator __first, _InputIterator __last) { - __table_.rehash(193); insert(__first, __last); } @@ -775,7 +778,7 @@ public: typedef __hash_map_const_iterator const_iterator; _LIBCPP_INLINE_VISIBILITY - hash_multimap() {__table_.rehash(193);} + hash_multimap() { } explicit hash_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); hash_multimap(size_type __n, const hasher& __hf, @@ -890,7 +893,6 @@ template hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( _InputIterator __first, _InputIterator __last) { - __table_.rehash(193); insert(__first, __last); } diff --git a/lib/libcxx/include/ext/hash_set b/lib/libcxx/include/ext/hash_set index e5141824b6..f0ba8d8ded 100644 --- a/lib/libcxx/include/ext/hash_set +++ b/lib/libcxx/include/ext/hash_set @@ -237,7 +237,7 @@ public: typedef typename __table::const_iterator const_iterator; _LIBCPP_INLINE_VISIBILITY - hash_set() {__table_.rehash(193);} + hash_set() { } explicit hash_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, @@ -347,7 +347,6 @@ template hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( _InputIterator __first, _InputIterator __last) { - __table_.rehash(193); insert(__first, __last); } @@ -459,7 +458,7 @@ public: typedef typename __table::const_iterator const_iterator; _LIBCPP_INLINE_VISIBILITY - hash_multiset() {__table_.rehash(193);} + hash_multiset() { } explicit hash_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); hash_multiset(size_type __n, const hasher& __hf, @@ -569,7 +568,6 @@ template hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( _InputIterator __first, _InputIterator __last) { - __table_.rehash(193); insert(__first, __last); } diff --git a/lib/libcxx/include/filesystem b/lib/libcxx/include/filesystem index 3aaa7988a8..0f7a4d5569 100644 --- a/lib/libcxx/include/filesystem +++ b/lib/libcxx/include/filesystem @@ -625,7 +625,7 @@ struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } }; -template ::value, +template ::value, class = void> struct __is_pathable_iter : false_type {}; @@ -708,14 +708,14 @@ template <> struct _PathCVT { template - static typename enable_if<__is_exactly_input_iterator<_Iter>::value>::type + static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type __append_range(string& __dest, _Iter __b, _Iter __e) { for (; __b != __e; ++__b) __dest.push_back(*__b); } template - static typename enable_if<__is_forward_iterator<_Iter>::value>::type + static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type __append_range(string& __dest, _Iter __b, _Iter __e) { __dest.__append_forward_unsafe(__b, __e); } @@ -2583,6 +2583,7 @@ public: void disable_recursion_pending() { __rec_ = false; } private: + _LIBCPP_FUNC_VIS recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec); diff --git a/lib/libcxx/include/forward_list b/lib/libcxx/include/forward_list index d59ddd4ef9..3905745931 100644 --- a/lib/libcxx/include/forward_list +++ b/lib/libcxx/include/forward_list @@ -490,7 +490,7 @@ protected: _LIBCPP_INLINE_VISIBILITY __forward_list_base() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - : __before_begin_(__begin_node()) {} + : __before_begin_(__begin_node(), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY explicit __forward_list_base(const allocator_type& __a) : __before_begin_(__begin_node(), __node_allocator(__a)) {} @@ -670,13 +670,13 @@ public: template forward_list(_InputIterator __f, _InputIterator __l, typename enable_if< - __is_input_iterator<_InputIterator>::value + __is_cpp17_input_iterator<_InputIterator>::value >::type* = nullptr); template forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a, typename enable_if< - __is_input_iterator<_InputIterator>::value + __is_cpp17_input_iterator<_InputIterator>::value >::type* = nullptr); forward_list(const forward_list& __x); forward_list(const forward_list& __x, const allocator_type& __a); @@ -711,7 +711,7 @@ public: template typename enable_if < - __is_input_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value, void >::type assign(_InputIterator __f, _InputIterator __l); @@ -792,7 +792,7 @@ public: _LIBCPP_INLINE_VISIBILITY typename enable_if < - __is_input_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value, iterator >::type insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); @@ -950,7 +950,7 @@ template template forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, typename enable_if< - __is_input_iterator<_InputIterator>::value + __is_cpp17_input_iterator<_InputIterator>::value >::type*) { insert_after(cbefore_begin(), __f, __l); @@ -961,7 +961,7 @@ template forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, const allocator_type& __a, typename enable_if< - __is_input_iterator<_InputIterator>::value + __is_cpp17_input_iterator<_InputIterator>::value >::type*) : base(__a) { @@ -1074,7 +1074,7 @@ template template typename enable_if < - __is_input_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value, void >::type forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) @@ -1270,7 +1270,7 @@ template template typename enable_if < - __is_input_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator >::type forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, @@ -1525,7 +1525,7 @@ forward_list<_Tp, _Alloc>::remove(const value_type& __v) else ++__i; } - + return (__remove_return_type) __count_removed; } @@ -1553,7 +1553,7 @@ forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) else ++__i; } - + return (__remove_return_type) __count_removed; } @@ -1573,7 +1573,7 @@ forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) __deleted_nodes.splice_after(__deleted_nodes.before_begin(), *this, __i, __j); __i = __j; } - + return (__remove_return_type) __count_removed; } diff --git a/lib/libcxx/include/fstream b/lib/libcxx/include/fstream index 60a05b0d4b..e9138998bf 100644 --- a/lib/libcxx/include/fstream +++ b/lib/libcxx/include/fstream @@ -508,34 +508,34 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring( switch (__mode & ~ios_base::ate) { case ios_base::out: case ios_base::out | ios_base::trunc: - return "w"; + return "w" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::out | ios_base::app: case ios_base::app: - return "a"; + return "a" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in: - return "r"; + return "r" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::out: - return "r+"; + return "r+" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::out | ios_base::trunc: - return "w+"; + return "w+" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::out | ios_base::app: case ios_base::in | ios_base::app: - return "a+"; + return "a+" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::out | ios_base::binary: case ios_base::out | ios_base::trunc | ios_base::binary: - return "wb"; + return "wb" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::out | ios_base::app | ios_base::binary: case ios_base::app | ios_base::binary: - return "ab"; + return "ab" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::binary: - return "rb"; + return "rb" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::out | ios_base::binary: - return "r+b"; + return "r+b" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary: - return "w+b"; + return "w+b" _LIBCPP_FOPEN_CLOEXEC_MODE; case ios_base::in | ios_base::out | ios_base::app | ios_base::binary: case ios_base::in | ios_base::app | ios_base::binary: - return "a+b"; + return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE; default: return nullptr; } @@ -697,10 +697,9 @@ basic_filebuf<_CharT, _Traits>::close() unique_ptr __h(__file_, fclose); if (sync()) __rt = 0; - if (fclose(__h.release()) == 0) - __file_ = 0; - else + if (fclose(__h.release())) __rt = 0; + __file_ = 0; setbuf(0, 0); } return __rt; diff --git a/lib/libcxx/include/functional b/lib/libcxx/include/functional index bcd74a9ee5..865a28123b 100644 --- a/lib/libcxx/include/functional +++ b/lib/libcxx/include/functional @@ -440,6 +440,13 @@ public: template const T* target() const noexcept; }; +// Deduction guides +template +function(R(*)(Args...)) -> function; // since C++17 + +template +function(F) -> function; // since C++17 + // Null pointer comparisons: template bool operator==(const function&, nullptr_t) noexcept; @@ -2335,6 +2342,53 @@ public: #endif // _LIBCPP_NO_RTTI }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template +function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; + +template +struct __strip_signature; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); }; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); }; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); }; + +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; +template +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; + +template::type> +function(_Fp) -> function<_Stripped>; +#endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES + template function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} diff --git a/lib/libcxx/include/future b/lib/libcxx/include/future index 6da88c6e62..751d122a60 100644 --- a/lib/libcxx/include/future +++ b/lib/libcxx/include/future @@ -611,7 +611,7 @@ __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) c } template -class _LIBCPP_AVAILABILITY_FUTURE __assoc_state +class _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_HIDDEN __assoc_state : public __assoc_sub_state { typedef __assoc_sub_state base; @@ -1060,7 +1060,7 @@ template class _LIBCPP_TEMPLATE_VIS shared_future; template class _LIBCPP_TEMPLATE_VIS future; template -future<_Rp> +_LIBCPP_INLINE_VISIBILITY future<_Rp> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_deferred_assoc_state(_Fp&& __f); #else @@ -1068,7 +1068,7 @@ __make_deferred_assoc_state(_Fp __f); #endif template -future<_Rp> +_LIBCPP_INLINE_VISIBILITY future<_Rp> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_async_assoc_state(_Fp&& __f); #else @@ -1767,9 +1767,9 @@ class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgType __compressed_pair<_Fp, _Alloc> __f_; public: _LIBCPP_INLINE_VISIBILITY - explicit __packaged_task_func(const _Fp& __f) : __f_(__f) {} + explicit __packaged_task_func(const _Fp& __f) : __f_(__f, __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY - explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f)) {} + explicit __packaged_task_func(_Fp&& __f) : __f_(_VSTD::move(__f), __default_init_tag()) {} _LIBCPP_INLINE_VISIBILITY __packaged_task_func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} @@ -2266,7 +2266,7 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator, _Alloc> : public true_type {}; template -future<_Rp> +_LIBCPP_INLINE_VISIBILITY future<_Rp> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_deferred_assoc_state(_Fp&& __f) #else @@ -2279,7 +2279,7 @@ __make_deferred_assoc_state(_Fp __f) } template -future<_Rp> +_LIBCPP_INLINE_VISIBILITY future<_Rp> #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES __make_async_assoc_state(_Fp&& __f) #else @@ -2293,7 +2293,7 @@ __make_async_assoc_state(_Fp __f) } template -class __async_func +class _LIBCPP_HIDDEN __async_func { tuple<_Fp, _Args...> __f_; diff --git a/lib/libcxx/include/istream b/lib/libcxx/include/istream index d6217bbb80..bfbe5f2472 100644 --- a/lib/libcxx/include/istream +++ b/lib/libcxx/include/istream @@ -1619,7 +1619,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) __is.rdbuf()->sbumpc(); } __x = bitset<_Size>(__str); - if (__c == 0) + if (_Size > 0 && __c == 0) __state |= ios_base::failbit; #ifndef _LIBCPP_NO_EXCEPTIONS } diff --git a/lib/libcxx/include/iterator b/lib/libcxx/include/iterator index 30801ea83d..57dd055b4a 100644 --- a/lib/libcxx/include/iterator +++ b/lib/libcxx/include/iterator @@ -434,12 +434,65 @@ template constexpr const E* data(initializer_list il) noexcept; #endif _LIBCPP_BEGIN_NAMESPACE_STD +template +struct _LIBCPP_TEMPLATE_VIS iterator_traits; struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; +#if _LIBCPP_STD_VER > 17 +// TODO(EricWF) contiguous_iterator_tag is provided as an extension prior to +// C++20 to allow optimizations for users providing wrapped iterator types. +struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag: public random_access_iterator_tag { }; +#endif + +template +struct __iter_traits_cache { + using type = _If< + __is_primary_template >::value, + _Iter, + iterator_traits<_Iter> + >; +}; +template +using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type; + +struct __iter_concept_concept_test { + template + using _Apply = typename _ITER_TRAITS<_Iter>::iterator_concept; +}; +struct __iter_concept_category_test { + template + using _Apply = typename _ITER_TRAITS<_Iter>::iterator_category; +}; +struct __iter_concept_random_fallback { + template + using _Apply = _EnableIf< + __is_primary_template >::value, + random_access_iterator_tag + >; +}; + +template struct __test_iter_concept + : _IsValidExpansion<_Tester::template _Apply, _Iter>, + _Tester +{ +}; + +template +struct __iter_concept_cache { + using type = _Or< + __test_iter_concept<_Iter, __iter_concept_concept_test>, + __test_iter_concept<_Iter, __iter_concept_category_test>, + __test_iter_concept<_Iter, __iter_concept_random_fallback> + >; +}; + +template +using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; + template struct __has_iterator_typedefs @@ -500,7 +553,10 @@ struct __iterator_traits<_Iter, true> template struct _LIBCPP_TEMPLATE_VIS iterator_traits - : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {}; + : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { + + using __primary_template = iterator_traits; +}; template struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> @@ -510,6 +566,9 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> typedef _Tp* pointer; typedef _Tp& reference; typedef random_access_iterator_tag iterator_category; +#if _LIBCPP_STD_VER > 17 + typedef contiguous_iterator_tag iterator_concept; +#endif }; template >::value> @@ -521,19 +580,28 @@ template struct __has_iterator_category_convertible_to<_Tp, _Up, false> : public false_type {}; template -struct __is_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {}; +struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {}; template -struct __is_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {}; +struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {}; template -struct __is_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {}; +struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {}; template -struct __is_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; +struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; + +#if _LIBCPP_STD_VER > 17 +template +struct __is_cpp17_contiguous_iterator : public __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag> {}; +#else +template +struct __is_cpp17_contiguous_iterator : public false_type {}; +#endif + template -struct __is_exactly_input_iterator +struct __is_exactly_cpp17_input_iterator : public integral_constant::value && !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; @@ -600,7 +668,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 void advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n) { - _LIBCPP_ASSERT(__n >= 0 || __is_bidirectional_iterator<_InputIter>::value, + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, "Attempt to advance(it, -n) on a non-bidi iterator"); __advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); } @@ -636,13 +704,13 @@ template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < - __is_input_iterator<_InputIter>::value, + __is_cpp17_input_iterator<_InputIter>::value, _InputIter >::type next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { - _LIBCPP_ASSERT(__n >= 0 || __is_bidirectional_iterator<_InputIter>::value, + _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, "Attempt to next(it, -n) on a non-bidi iterator"); _VSTD::advance(__x, __n); @@ -653,13 +721,13 @@ template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 typename enable_if < - __is_input_iterator<_InputIter>::value, + __is_cpp17_input_iterator<_InputIter>::value, _InputIter >::type prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { - _LIBCPP_ASSERT(__n <= 0 || __is_bidirectional_iterator<_InputIter>::value, + _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, "Attempt to prev(it, +n) on a non-bidi iterator"); _VSTD::advance(__x, -__n); return __x; @@ -1304,8 +1372,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_IF_NODEBUG __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT; -template _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op); -template _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2); +template _Op _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy(_Ip, _Ip, _Op); +template _B2 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 copy_backward(_B1, _B1, _B2); template _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op); template _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2); @@ -1515,8 +1583,8 @@ private: __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT; - template friend _Op copy(_Ip, _Ip, _Op); - template friend _B2 copy_backward(_B1, _B1, _B2); + template friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _Op copy(_Ip, _Ip, _Op); + template friend _LIBCPP_CONSTEXPR_AFTER_CXX17 _B2 copy_backward(_B1, _B1, _B2); template friend _Op move(_Ip, _Ip, _Op); template friend _B2 move_backward(_B1, _B1, _B2); diff --git a/lib/libcxx/include/list b/lib/libcxx/include/list index c92ef79282..ae318ead31 100644 --- a/lib/libcxx/include/list +++ b/lib/libcxx/include/list @@ -715,7 +715,7 @@ template inline __list_imp<_Tp, _Alloc>::__list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) - : __size_alloc_(0) + : __size_alloc_(0, __default_init_tag()) { } @@ -887,10 +887,10 @@ public: list(size_type __n, const value_type& __x, const allocator_type& __a); template list(_InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); template list(_InpIter __f, _InpIter __l, const allocator_type& __a, - typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); list(const list& __c); list(const list& __c, const allocator_type& __a); @@ -922,7 +922,7 @@ public: template void assign(_InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); void assign(size_type __n, const value_type& __x); _LIBCPP_INLINE_VISIBILITY @@ -1039,7 +1039,7 @@ public: iterator insert(const_iterator __p, size_type __n, const value_type& __x); template iterator insert(const_iterator __p, _InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value>::type* = 0); + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0); _LIBCPP_INLINE_VISIBILITY void swap(list& __c) @@ -1252,7 +1252,7 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_ty template template list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1264,7 +1264,7 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, template template list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, - typename enable_if<__is_input_iterator<_InpIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) : base(__a) { #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1403,7 +1403,7 @@ template template void list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { iterator __i = begin(); iterator __e = end(); @@ -1532,7 +1532,7 @@ template template typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, - typename enable_if<__is_input_iterator<_InpIter>::value>::type*) + typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type*) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, @@ -2211,7 +2211,7 @@ list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) __i = __j; } } - + return (__remove_return_type) __deleted_nodes.size(); } diff --git a/lib/libcxx/include/map b/lib/libcxx/include/map index eb6ae57b01..b6f89bf5ee 100644 --- a/lib/libcxx/include/map +++ b/lib/libcxx/include/map @@ -1474,26 +1474,26 @@ private: #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template>, class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf::value, void>, + class = _EnableIf<__is_allocator<_Allocator>::value, void>> map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>; template>, class _Allocator = allocator>, - class = enable_if_t::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf::value, void>, + class = _EnableIf<__is_allocator<_Allocator>::value, void>> map(initializer_list>, _Compare = _Compare(), _Allocator = _Allocator()) -> map, _Tp, _Compare, _Allocator>; template::value, void>> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> map(_InputIterator, _InputIterator, _Allocator) -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, less<__iter_key_type<_InputIterator>>, _Allocator>; template::value, void>> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> map(initializer_list>, _Allocator) -> map, _Tp, less>, _Allocator>; #endif @@ -2131,26 +2131,26 @@ private: #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template>, class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf::value, void>, + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>; template>, class _Allocator = allocator>, - class = enable_if_t::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf::value, void>, + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multimap(initializer_list>, _Compare = _Compare(), _Allocator = _Allocator()) -> multimap, _Tp, _Compare, _Allocator>; template::value, void>> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multimap(_InputIterator, _InputIterator, _Allocator) -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, less<__iter_key_type<_InputIterator>>, _Allocator>; template::value, void>> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multimap(initializer_list>, _Allocator) -> multimap, _Tp, less>, _Allocator>; #endif diff --git a/lib/libcxx/include/math.h b/lib/libcxx/include/math.h index 194df2077b..c9b4733e9c 100644 --- a/lib/libcxx/include/math.h +++ b/lib/libcxx/include/math.h @@ -510,7 +510,11 @@ _LIBCPP_INLINE_VISIBILITY bool __libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT { +#if __has_builtin(__builtin_isnan) + return __builtin_isnan(__lcpp_x); +#else return isnan(__lcpp_x); +#endif } #undef isnan diff --git a/lib/libcxx/include/memory b/lib/libcxx/include/memory index d9222b3ada..34c3e0c0d8 100644 --- a/lib/libcxx/include/memory +++ b/lib/libcxx/include/memory @@ -662,7 +662,6 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include #include #include -#include #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include #endif @@ -1099,40 +1098,51 @@ struct __const_void_pointer<_Ptr, _Alloc, false> #endif }; + +template struct __to_address_helper; + +template <> struct __to_address_helper { + template + using __return_type = decltype(pointer_traits<_Pointer>::to_address(std::declval())); + + template + _LIBCPP_CONSTEXPR + static __return_type<_Pointer> + __do_it(const _Pointer &__p) _NOEXCEPT { return pointer_traits<_Pointer>::to_address(__p); } +}; + +template +using __choose_to_address = __to_address_helper<_IsValidExpansion<__to_address_helper<_Dummy>::template __return_type, _Pointer>::value>; + + template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp* -__to_raw_pointer(_Tp* __p) _NOEXCEPT +__to_address(_Tp* __p) _NOEXCEPT { + static_assert(!is_function<_Tp>::value, "_Tp is a function type"); return __p; } -#if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -typename pointer_traits<_Pointer>::element_type* -__to_raw_pointer(_Pointer __p) _NOEXCEPT -{ - return _VSTD::__to_raw_pointer(__p.operator->()); -} -#else -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__to_raw_pointer(const _Pointer& __p) _NOEXCEPT --> decltype(pointer_traits<_Pointer>::to_address(__p)) -{ - return pointer_traits<_Pointer>::to_address(__p); +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename __choose_to_address<_Pointer>::template __return_type<_Pointer> +__to_address(const _Pointer& __p) _NOEXCEPT { + return __choose_to_address<_Pointer>::__do_it(__p); } -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__to_raw_pointer(const _Pointer& __p, _None...) _NOEXCEPT -{ - return _VSTD::__to_raw_pointer(__p.operator->()); -} +template <> struct __to_address_helper { + template + using __return_type = typename pointer_traits<_Pointer>::element_type*; + template + _LIBCPP_CONSTEXPR + static __return_type<_Pointer> + __do_it(const _Pointer &__p) _NOEXCEPT { return std::__to_address(__p.operator->()); } +}; + + +#if _LIBCPP_STD_VER > 17 template inline _LIBCPP_INLINE_VISIBILITY constexpr _Tp* @@ -1147,7 +1157,7 @@ inline _LIBCPP_INLINE_VISIBILITY auto to_address(const _Pointer& __p) _NOEXCEPT { - return _VSTD::__to_raw_pointer(__p); + return _VSTD::__to_address(__p); } #endif @@ -1507,6 +1517,31 @@ struct __is_default_allocator : false_type {}; template struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {}; + + +template ::value && !__is_default_allocator<_Alloc>::value + > +struct __is_cpp17_move_insertable; +template +struct __is_cpp17_move_insertable<_Alloc, true> : std::true_type {}; +template +struct __is_cpp17_move_insertable<_Alloc, false> : std::is_move_constructible {}; + +template ::value && !__is_default_allocator<_Alloc>::value + > +struct __is_cpp17_copy_insertable; +template +struct __is_cpp17_copy_insertable<_Alloc, true> : __is_cpp17_move_insertable<_Alloc> {}; +template +struct __is_cpp17_copy_insertable<_Alloc, false> : integral_constant::value && + __is_cpp17_move_insertable<_Alloc>::value> + {}; + + + template struct _LIBCPP_TEMPLATE_VIS allocator_traits { @@ -1609,10 +1644,18 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits _LIBCPP_INLINE_VISIBILITY static void - __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) + __construct_forward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { + static_assert(__is_cpp17_move_insertable::value, + "The specified type does not meet the requirements of Cpp17MoveInsertible"); for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) - construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1)); + construct(__a, _VSTD::__to_address(__begin2), +#ifdef _LIBCPP_NO_EXCEPTIONS + _VSTD::move(*__begin1) +#else + _VSTD::move_if_noexcept(*__begin1) +#endif + ); } template @@ -1625,7 +1668,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_forward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) @@ -1642,7 +1685,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits __construct_range_forward(allocator_type& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) { for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) - construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1); + construct(__a, _VSTD::__to_address(__begin2), *__begin1); } template ::value, + "The specified type does not meet the requirements of Cpp17MoveInsertable"); while (__end1 != __begin1) { - construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1)); - --__end2; + construct(__a, _VSTD::__to_address(__end2 - 1), +#ifdef _LIBCPP_NO_EXCEPTIONS + _VSTD::move(*--__end1) +#else + _VSTD::move_if_noexcept(*--__end1) +#endif + ); + --__end2; } } @@ -1691,7 +1742,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_backward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) + __construct_backward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { ptrdiff_t _Np = __end1 - __begin1; __end2 -= _Np; @@ -2127,6 +2178,10 @@ public: }; #endif +// Tag used to default initialize one or both of the pair's elements. +struct __default_init_tag {}; +struct __value_init_tag {}; + template ::value && !__libcpp_is_final<_Tp>::value> @@ -2135,30 +2190,31 @@ struct __compressed_pair_elem { typedef _Tp& reference; typedef const _Tp& const_reference; -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() : __value_() {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __compressed_pair_elem(__default_init_tag) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __compressed_pair_elem(__value_init_tag) : __value_() {} template ::type>::value >::type> _LIBCPP_INLINE_VISIBILITY - constexpr explicit + _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(_Up&& __u) : __value_(_VSTD::forward<_Up>(__u)) { } + +#ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args, __tuple_indices<_Indexes...>) : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {} -#else - _LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_() {} - _LIBCPP_INLINE_VISIBILITY - __compressed_pair_elem(_ParamT __p) : __value_(std::forward<_ParamT>(__p)) {} #endif + _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; } _LIBCPP_INLINE_VISIBILITY const_reference __get() const _NOEXCEPT { return __value_; } @@ -2174,28 +2230,27 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { typedef const _Tp& const_reference; typedef _Tp __value_type; -#ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() = default; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default; + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __compressed_pair_elem(__default_init_tag) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __compressed_pair_elem(__value_init_tag) : __value_type() {} template ::type>::value >::type> _LIBCPP_INLINE_VISIBILITY - constexpr explicit + _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(_Up&& __u) : __value_type(_VSTD::forward<_Up>(__u)) {} +#ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args, __tuple_indices<_Indexes...>) : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {} -#else - _LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_type() {} - _LIBCPP_INLINE_VISIBILITY - __compressed_pair_elem(_ParamT __p) - : __value_type(std::forward<_ParamT>(__p)) {} #endif _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; } @@ -2203,9 +2258,6 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { const_reference __get() const _NOEXCEPT { return *this; } }; -// Tag used to construct the second element of the compressed pair. -struct __second_tag {}; - template class __compressed_pair : private __compressed_pair_elem<_T1, 0>, private __compressed_pair_elem<_T2, 1> { @@ -2222,33 +2274,21 @@ class __compressed_pair : private __compressed_pair_elem<_T1, 0>, "implementation for this configuration"); public: -#ifndef _LIBCPP_CXX03_LANG - template , _Dummy>::value && __dependent_type, _Dummy>::value >::type > _LIBCPP_INLINE_VISIBILITY - constexpr __compressed_pair() {} - - template ::type, - __compressed_pair>::value, - bool>::type = true> - _LIBCPP_INLINE_VISIBILITY constexpr explicit - __compressed_pair(_Tp&& __t) - : _Base1(std::forward<_Tp>(__t)), _Base2() {} - - template - _LIBCPP_INLINE_VISIBILITY constexpr - __compressed_pair(__second_tag, _Tp&& __t) - : _Base1(), _Base2(std::forward<_Tp>(__t)) {} + _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {} template - _LIBCPP_INLINE_VISIBILITY constexpr + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair(_U1&& __t1, _U2&& __t2) : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {} +#ifndef _LIBCPP_CXX03_LANG template _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, @@ -2257,21 +2297,6 @@ public: typename __make_tuple_indices::type()), _Base2(__pc, _VSTD::move(__second_args), typename __make_tuple_indices::type()) {} - -#else - _LIBCPP_INLINE_VISIBILITY - __compressed_pair() {} - - _LIBCPP_INLINE_VISIBILITY explicit - __compressed_pair(_T1 __t1) : _Base1(_VSTD::forward<_T1>(__t1)) {} - - _LIBCPP_INLINE_VISIBILITY - __compressed_pair(__second_tag, _T2 __t2) - : _Base1(), _Base2(_VSTD::forward<_T2>(__t2)) {} - - _LIBCPP_INLINE_VISIBILITY - __compressed_pair(_T1 __t1, _T2 __t2) - : _Base1(_VSTD::forward<_T1>(__t1)), _Base2(_VSTD::forward<_T2>(__t2)) {} #endif _LIBCPP_INLINE_VISIBILITY @@ -2452,17 +2477,17 @@ public: template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer()) {} + _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer()) {} + _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} template > _LIBCPP_INLINE_VISIBILITY - explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p) {} + explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {} template > > @@ -2504,7 +2529,7 @@ public: typename enable_if::value && is_same<_Dp, default_delete<_Tp> >::value, __nat>::type = __nat()) _NOEXCEPT - : __ptr_(__p.release()) {} + : __ptr_(__p.release(), __default_init_tag()) {} #endif _LIBCPP_INLINE_VISIBILITY @@ -2675,19 +2700,19 @@ public: template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer()) {} + _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} template > _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer()) {} + _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {} template , class = _EnableIfPointerConvertible<_Pp> > _LIBCPP_INLINE_VISIBILITY explicit unique_ptr(_Pp __p) _NOEXCEPT - : __ptr_(__p) {} + : __ptr_(__p, __default_init_tag()) {} template >, @@ -3531,24 +3556,20 @@ class __shared_ptr_emplace { __compressed_pair<_Alloc, _Tp> __data_; public: -#ifndef _LIBCPP_HAS_NO_VARIADICS _LIBCPP_INLINE_VISIBILITY __shared_ptr_emplace(_Alloc __a) - : __data_(_VSTD::move(__a)) {} + : __data_(_VSTD::move(__a), __value_init_tag()) {} + +#ifndef _LIBCPP_HAS_NO_VARIADICS template _LIBCPP_INLINE_VISIBILITY __shared_ptr_emplace(_Alloc __a, _Args&& ...__args) : __data_(piecewise_construct, _VSTD::forward_as_tuple(__a), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)) {} - #else // _LIBCPP_HAS_NO_VARIADICS - _LIBCPP_INLINE_VISIBILITY - __shared_ptr_emplace(_Alloc __a) - : __data_(__a) {} - template _LIBCPP_INLINE_VISIBILITY __shared_ptr_emplace(_Alloc __a, _A0& __a0) @@ -3831,49 +3852,22 @@ public: : nullptr);} #endif // _LIBCPP_NO_RTTI -#ifndef _LIBCPP_HAS_NO_VARIADICS - - template - static - shared_ptr<_Tp> - make_shared(_Args&& ...__args); + template + static shared_ptr<_Tp> + __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) + { + shared_ptr<_Tp> __r; + __r.__ptr_ = __p; + __r.__cntrl_ = __cntrl; + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); + return __r; + } template static shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args); -#else // _LIBCPP_HAS_NO_VARIADICS - - static shared_ptr<_Tp> make_shared(); - - template - static shared_ptr<_Tp> make_shared(_A0&); - - template - static shared_ptr<_Tp> make_shared(_A0&, _A1&); - - template - static shared_ptr<_Tp> make_shared(_A0&, _A1&, _A2&); - - template - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a); - - template - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a, _A0& __a0); - - template - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1); - - template - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2); - -#endif // _LIBCPP_HAS_NO_VARIADICS - private: template ::value> struct __shared_ptr_default_allocator @@ -4186,27 +4180,6 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, __r.release(); } -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template -template -shared_ptr<_Tp> -shared_ptr<_Tp>::make_shared(_Args&& ...__args) -{ - static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared" ); - typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk; - typedef allocator<_CntrlBlk> _A2; - typedef __allocator_destructor<_A2> _D2; - _A2 __a2; - unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); - ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...); - shared_ptr<_Tp> __r; - __r.__ptr_ = __hold2.get()->get(); - __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); - return __r; -} - template template shared_ptr<_Tp> @@ -4227,165 +4200,6 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args) return __r; } -#else // _LIBCPP_HAS_NO_VARIADICS - -template -shared_ptr<_Tp> -shared_ptr<_Tp>::make_shared() -{ - static_assert((is_constructible<_Tp>::value), "Can't construct object in make_shared" ); - typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk; - typedef allocator<_CntrlBlk> _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2; - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(__hold2.get()) _CntrlBlk(__alloc2); - shared_ptr<_Tp> __r; - __r.__ptr_ = __hold2.get()->get(); - __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); - return __r; -} - -template -template -shared_ptr<_Tp> -shared_ptr<_Tp>::make_shared(_A0& __a0) -{ - static_assert((is_constructible<_Tp, _A0>::value), "Can't construct object in make_shared" ); - typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk; - typedef allocator<_CntrlBlk> _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2; - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0); - shared_ptr<_Tp> __r; - __r.__ptr_ = __hold2.get()->get(); - __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); - return __r; -} - -template -template -shared_ptr<_Tp> -shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1) -{ - static_assert((is_constructible<_Tp, _A0, _A1>::value), "Can't construct object in make_shared" ); - typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk; - typedef allocator<_CntrlBlk> _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2; - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1); - shared_ptr<_Tp> __r; - __r.__ptr_ = __hold2.get()->get(); - __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); - return __r; -} - -template -template -shared_ptr<_Tp> -shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1, _A2& __a2) -{ - static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't construct object in make_shared" ); - typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk; - typedef allocator<_CntrlBlk> _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2; - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1, __a2); - shared_ptr<_Tp> __r; - __r.__ptr_ = __hold2.get()->get(); - __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); - return __r; -} - -template -template -shared_ptr<_Tp> -shared_ptr<_Tp>::allocate_shared(const _Alloc& __a) -{ - static_assert((is_constructible<_Tp>::value), "Can't construct object in allocate_shared" ); - typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; - typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2(__a); - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__a); - 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 -template -shared_ptr<_Tp> -shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0) -{ - static_assert((is_constructible<_Tp, _A0>::value), "Can't construct object in allocate_shared" ); - typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; - typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2(__a); - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__a, __a0); - 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 -template -shared_ptr<_Tp> -shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1) -{ - static_assert((is_constructible<_Tp, _A0, _A1>::value), "Can't construct object in allocate_shared" ); - typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; - typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2(__a); - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__a, __a0, __a1); - 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 -template -shared_ptr<_Tp> -shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2) -{ - static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't construct object in allocate_shared" ); - typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk; - typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2; - typedef __allocator_destructor<_Alloc2> _D2; - _Alloc2 __alloc2(__a); - unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1)); - ::new(static_cast(_VSTD::addressof(*__hold2.get()))) - _CntrlBlk(__a, __a0, __a1, __a2); - 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; -} - -#endif // _LIBCPP_HAS_NO_VARIADICS - template shared_ptr<_Tp>::~shared_ptr() { @@ -4567,8 +4381,6 @@ shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a) shared_ptr(__p, __d, __a).swap(*this); } -#ifndef _LIBCPP_HAS_NO_VARIADICS - template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -4578,7 +4390,17 @@ typename enable_if >::type make_shared(_Args&& ...__args) { - return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...); + static_assert(is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared"); + typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk; + typedef allocator<_CntrlBlk> _A2; + typedef __allocator_destructor<_A2> _D2; + + _A2 __a2; + unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1)); + ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...); + + _Tp *__ptr = __hold2.get()->get(); + return shared_ptr<_Tp>::__create_with_control_block(__ptr, __hold2.release()); } template @@ -4593,74 +4415,6 @@ allocate_shared(const _Alloc& __a, _Args&& ...__args) return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...); } -#else // _LIBCPP_HAS_NO_VARIADICS - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared() -{ - return shared_ptr<_Tp>::make_shared(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared(_A0& __a0) -{ - return shared_ptr<_Tp>::make_shared(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared(_A0& __a0, _A1& __a1) -{ - return shared_ptr<_Tp>::make_shared(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared(_A0& __a0, _A1& __a1, _A2& __a2) -{ - return shared_ptr<_Tp>::make_shared(__a0, __a1, __a2); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -allocate_shared(const _Alloc& __a) -{ - return shared_ptr<_Tp>::allocate_shared(__a); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -allocate_shared(const _Alloc& __a, _A0& __a0) -{ - return shared_ptr<_Tp>::allocate_shared(__a, __a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1) -{ - return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2) -{ - return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1, __a2); -} - -#endif // _LIBCPP_HAS_NO_VARIADICS - template inline _LIBCPP_INLINE_VISIBILITY bool @@ -5590,4 +5344,8 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS +#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 +# include <__pstl_memory> +#endif + #endif // _LIBCPP_MEMORY diff --git a/lib/libcxx/include/module.modulemap b/lib/libcxx/include/module.modulemap index bbfe90ed57..31d39ddf7c 100644 --- a/lib/libcxx/include/module.modulemap +++ b/lib/libcxx/include/module.modulemap @@ -275,6 +275,10 @@ module std [system] { header "exception" export * } + module execution { + header "execution" + export * + } module filesystem { header "filesystem" export * diff --git a/lib/libcxx/include/mutex b/lib/libcxx/include/mutex index dca62202db..62780bd073 100644 --- a/lib/libcxx/include/mutex +++ b/lib/libcxx/include/mutex @@ -86,9 +86,9 @@ public: void unlock(); }; -struct defer_lock_t {}; -struct try_to_lock_t {}; -struct adopt_lock_t {}; +struct defer_lock_t { explicit defer_lock_t() = default; }; +struct try_to_lock_t { explicit try_to_lock_t() = default; }; +struct adopt_lock_t { explicit adopt_lock_t() = default; }; inline constexpr defer_lock_t defer_lock{}; inline constexpr try_to_lock_t try_to_lock{}; @@ -650,7 +650,7 @@ public: #endif template -void +void _LIBCPP_INLINE_VISIBILITY __call_once_proxy(void* __vp) { __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); diff --git a/lib/libcxx/include/new b/lib/libcxx/include/new index 85e4c4b3fc..40d351e9b7 100644 --- a/lib/libcxx/include/new +++ b/lib/libcxx/include/new @@ -39,7 +39,7 @@ struct destroying_delete_t { // C++20 }; inline constexpr destroying_delete_t destroying_delete{}; // C++20 -struct nothrow_t {}; +struct nothrow_t { explicit nothrow_t() = default; }; extern const nothrow_t nothrow; typedef void (*new_handler)(); new_handler set_new_handler(new_handler new_p) noexcept; @@ -126,7 +126,7 @@ namespace std // purposefully not using versioning namespace { #if !defined(_LIBCPP_ABI_VCRUNTIME) -struct _LIBCPP_TYPE_VIS nothrow_t {}; +struct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; }; extern _LIBCPP_FUNC_VIS const nothrow_t nothrow; class _LIBCPP_EXCEPTION_ABI bad_alloc diff --git a/lib/libcxx/include/numeric b/lib/libcxx/include/numeric index 2118704d57..5ceadc1775 100644 --- a/lib/libcxx/include/numeric +++ b/lib/libcxx/include/numeric @@ -532,17 +532,14 @@ midpoint(_Tp __a, _Tp __b) noexcept _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { using _Up = std::make_unsigned_t<_Tp>; + constexpr _Up __bitshift = std::numeric_limits<_Up>::digits - 1; - int __sign = 1; - _Up __m = __a; - _Up __M = __b; - if (__a > __b) - { - __sign = -1; - __m = __b; - __M = __a; - } - return __a + __sign * _Tp(_Up(__M-__m) >> 1); + _Up __diff = _Up(__b) - _Up(__a); + _Up __sign_bit = __b < __a; + + _Up __half_diff = (__diff / 2) + (__sign_bit << __bitshift) + (__sign_bit & __diff); + + return __a + __half_diff; } @@ -576,7 +573,7 @@ midpoint(_Fp __a, _Fp __b) noexcept return __fp_abs(__a) <= __hi && __fp_abs(__b) <= __hi ? // typical case: overflow is impossible (__a + __b)/2 : // always correctly rounded __fp_abs(__a) < __lo ? __a + __b/2 : // not safe to halve a - __fp_abs(__a) < __lo ? __a/2 + __b : // not safe to halve b + __fp_abs(__b) < __lo ? __a/2 + __b : // not safe to halve b __a/2 + __b/2; // otherwise correctly rounded } @@ -586,4 +583,8 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS +#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 +# include <__pstl_numeric> +#endif + #endif // _LIBCPP_NUMERIC diff --git a/lib/libcxx/include/ostream b/lib/libcxx/include/ostream index e6cf9c970f..ea3870532f 100644 --- a/lib/libcxx/include/ostream +++ b/lib/libcxx/include/ostream @@ -1055,7 +1055,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, - const basic_string_view<_CharT, _Traits> __sv) + basic_string_view<_CharT, _Traits> __sv) { return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size()); } diff --git a/lib/libcxx/include/queue b/lib/libcxx/include/queue index 97ec6f633c..33c25e0dfc 100644 --- a/lib/libcxx/include/queue +++ b/lib/libcxx/include/queue @@ -562,7 +562,7 @@ priority_queue(_Compare, _Container) template::value_type>, class _Container = vector::value_type>, - class = typename enable_if< __is_input_iterator<_InputIterator>::value, nullptr_t>::type, + class = typename enable_if< __is_cpp17_input_iterator<_InputIterator>::value, nullptr_t>::type, class = typename enable_if::value, nullptr_t>::type, class = typename enable_if::value, nullptr_t>::type > diff --git a/lib/libcxx/include/random b/lib/libcxx/include/random index 9fefee0817..7c4054f7ee 100644 --- a/lib/libcxx/include/random +++ b/lib/libcxx/include/random @@ -3645,7 +3645,7 @@ generate_canonical(_URNG& __g) const size_t __logR = __log2::value; #endif const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0); - const _RealType _Rp = _URNG::max() - _URNG::min() + _RealType(1); + const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); _RealType __base = _Rp; _RealType _Sp = __g() - _URNG::min(); for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp) @@ -4592,7 +4592,10 @@ public: template poisson_distribution<_IntType>::param_type::param_type(double __mean) - : __mean_(__mean) + // According to the standard `inf` is a valid input, but it causes the + // distribution to hang, so we replace it with the maximum representable + // mean. + : __mean_(isinf(__mean) ? numeric_limits::max() : __mean) { if (__mean_ < 10) { @@ -4610,7 +4613,7 @@ poisson_distribution<_IntType>::param_type::param_type(double __mean) { __s_ = _VSTD::sqrt(__mean_); __d_ = 6 * __mean_ * __mean_; - __l_ = static_cast(__mean_ - 1.1484); + __l_ = std::trunc(__mean_ - 1.1484); __omega_ = .3989423 / __s_; double __b1_ = .4166667E-1 / __mean_; double __b2_ = .3 * __b1_ * __b1_; @@ -4627,12 +4630,12 @@ template _IntType poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr) { - result_type __x; + double __tx; uniform_real_distribution __urd; if (__pr.__mean_ < 10) { - __x = 0; - for (double __p = __urd(__urng); __p > __pr.__l_; ++__x) + __tx = 0; + for (double __p = __urd(__urng); __p > __pr.__l_; ++__tx) __p *= __urd(__urng); } else @@ -4642,19 +4645,19 @@ poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr double __u; if (__g > 0) { - __x = static_cast(__g); - if (__x >= __pr.__l_) - return __x; - __difmuk = __pr.__mean_ - __x; + __tx = std::trunc(__g); + if (__tx >= __pr.__l_) + return std::__clamp_to_integral(__tx); + __difmuk = __pr.__mean_ - __tx; __u = __urd(__urng); if (__pr.__d_ * __u >= __difmuk * __difmuk * __difmuk) - return __x; + return std::__clamp_to_integral(__tx); } exponential_distribution __edist; for (bool __using_exp_dist = false; true; __using_exp_dist = true) { double __e; - if (__using_exp_dist || __g < 0) + if (__using_exp_dist || __g <= 0) { double __t; do @@ -4664,31 +4667,31 @@ poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr __u += __u - 1; __t = 1.8 + (__u < 0 ? -__e : __e); } while (__t <= -.6744); - __x = __pr.__mean_ + __pr.__s_ * __t; - __difmuk = __pr.__mean_ - __x; + __tx = std::trunc(__pr.__mean_ + __pr.__s_ * __t); + __difmuk = __pr.__mean_ - __tx; __using_exp_dist = true; } double __px; double __py; - if (__x < 10) + if (__tx < 10 && __tx >= 0) { const double __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; __px = -__pr.__mean_; - __py = _VSTD::pow(__pr.__mean_, (double)__x) / __fac[__x]; + __py = _VSTD::pow(__pr.__mean_, (double)__tx) / __fac[static_cast(__tx)]; } else { - double __del = .8333333E-1 / __x; + double __del = .8333333E-1 / __tx; __del -= 4.8 * __del * __del * __del; - double __v = __difmuk / __x; + double __v = __difmuk / __tx; if (_VSTD::abs(__v) > 0.25) - __px = __x * _VSTD::log(1 + __v) - __difmuk - __del; + __px = __tx * _VSTD::log(1 + __v) - __difmuk - __del; else - __px = __x * __v * __v * (((((((.1250060 * __v + -.1384794) * + __px = __tx * __v * __v * (((((((.1250060 * __v + -.1384794) * __v + .1421878) * __v + -.1661269) * __v + .2000118) * __v + -.2500068) * __v + .3333333) * __v + -.5) - __del; - __py = .3989423 / _VSTD::sqrt(__x); + __py = .3989423 / _VSTD::sqrt(__tx); } double __r = (0.5 - __difmuk) / __pr.__s_; double __r2 = __r * __r; @@ -4708,7 +4711,7 @@ poisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr } } } - return __x; + return std::__clamp_to_integral(__tx); } template @@ -6102,6 +6105,7 @@ public: template param_type(size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw); + param_type(param_type const&) = default; param_type & operator=(const param_type& __rhs); _LIBCPP_INLINE_VISIBILITY @@ -6425,6 +6429,7 @@ public: template param_type(size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw); + param_type(param_type const&) = default; param_type & operator=(const param_type& __rhs); _LIBCPP_INLINE_VISIBILITY diff --git a/lib/libcxx/include/regex b/lib/libcxx/include/regex index 26efac1c62..5ac9e325e1 100644 --- a/lib/libcxx/include/regex +++ b/lib/libcxx/include/regex @@ -169,15 +169,15 @@ public: // assign: basic_regex& assign(const basic_regex& that); basic_regex& assign(basic_regex&& that) noexcept; - basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript); - basic_regex& assign(const charT* p, size_t len, flag_type f); + basic_regex& assign(const charT* ptr, flag_type f = regex_constants::ECMAScript); + basic_regex& assign(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript); template basic_regex& assign(const basic_string& s, - flag_type f = regex_constants::ECMAScript); + flag_type f = regex_constants::ECMAScript); template basic_regex& assign(InputIterator first, InputIterator last, - flag_type f = regex_constants::ECMAScript); - basic_regex& assign(initializer_list, flag_type = regex_constants::ECMAScript); + flag_type f = regex_constants::ECMAScript); + basic_regex& assign(initializer_list, flag_type f = regex_constants::ECMAScript); // const operations: unsigned mark_count() const; @@ -965,7 +965,8 @@ enum error_type error_stack, __re_err_grammar, __re_err_empty, - __re_err_unknown + __re_err_unknown, + __re_err_parse }; } // regex_constants @@ -2539,8 +2540,7 @@ public: : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0) { - if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; - __parse(__p, __p + __traits_.length(__p)); + __init(__p, __p + __traits_.length(__p)); } _LIBCPP_INLINE_VISIBILITY @@ -2548,8 +2548,7 @@ public: : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0) { - if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; - __parse(__p, __p + __len); + __init(__p, __p + __len); } // basic_regex(const basic_regex&) = default; @@ -2561,8 +2560,7 @@ public: : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0) { - if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; - __parse(__p.begin(), __p.end()); + __init(__p.begin(), __p.end()); } template @@ -2572,8 +2570,7 @@ public: : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0) { - if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; - __parse(__first, __last); + __init(__first, __last); } #ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY @@ -2582,8 +2579,7 @@ public: : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0) { - if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; - __parse(__il.begin(), __il.end()); + __init(__il.begin(), __il.end()); } #endif // _LIBCPP_CXX03_LANG @@ -2617,7 +2613,7 @@ public: basic_regex& assign(const value_type* __p, flag_type __f = regex_constants::ECMAScript) {return assign(__p, __p + __traits_.length(__p), __f);} _LIBCPP_INLINE_VISIBILITY - basic_regex& assign(const value_type* __p, size_t __len, flag_type __f) + basic_regex& assign(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) {return assign(__p, __p + __len, __f);} template _LIBCPP_INLINE_VISIBILITY @@ -2629,8 +2625,8 @@ public: _LIBCPP_INLINE_VISIBILITY typename enable_if < - __is_input_iterator <_InputIterator>::value && - !__is_forward_iterator<_InputIterator>::value, + __is_cpp17_input_iterator <_InputIterator>::value && + !__is_cpp17_forward_iterator<_InputIterator>::value, basic_regex& >::type assign(_InputIterator __first, _InputIterator __last, @@ -2656,7 +2652,7 @@ public: _LIBCPP_INLINE_VISIBILITY typename enable_if < - __is_forward_iterator<_ForwardIterator>::value, + __is_cpp17_forward_iterator<_ForwardIterator>::value, basic_regex& >::type assign(_ForwardIterator __first, _ForwardIterator __last, @@ -2698,6 +2694,9 @@ private: _LIBCPP_INLINE_VISIBILITY unsigned __loop_count() const {return __loop_count_;} + template + void + __init(_ForwardIterator __first, _ForwardIterator __last); template _ForwardIterator __parse(_ForwardIterator __first, _ForwardIterator __last); @@ -2953,7 +2952,7 @@ private: #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template ::value, nullptr_t>::type + class = typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value, nullptr_t>::type > basic_regex(_ForwardIterator, _ForwardIterator, regex_constants::syntax_option_type = regex_constants::ECMAScript) @@ -3054,6 +3053,17 @@ __lookahead<_CharT, _Traits>::__exec(__state& __s) const } } +template +template +void +basic_regex<_CharT, _Traits>::__init(_ForwardIterator __first, _ForwardIterator __last) +{ + if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript; + _ForwardIterator __temp = __parse(__first, __last); + if ( __temp != __last) + __throw_regex_error(); +} + template template _ForwardIterator diff --git a/lib/libcxx/include/set b/lib/libcxx/include/set index 70ab4d37ad..ac3fbbe02f 100644 --- a/lib/libcxx/include/set +++ b/lib/libcxx/include/set @@ -852,26 +852,26 @@ public: template::value_type>, class _Allocator = allocator::value_type>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf::value, void>> set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> set::value_type, _Compare, _Allocator>; template, class _Allocator = allocator<_Key>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf::value, void>> set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>; template::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> set(_InputIterator, _InputIterator, _Allocator) -> set::value_type, less::value_type>, _Allocator>; template::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> set(initializer_list<_Key>, _Allocator) -> set<_Key, less<_Key>, _Allocator>; #endif @@ -1377,26 +1377,26 @@ public: template::value_type>, class _Allocator = allocator::value_type>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf::value, void>> multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> multiset::value_type, _Compare, _Allocator>; template, class _Allocator = allocator<_Key>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf::value, void>> multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>; template::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multiset(_InputIterator, _InputIterator, _Allocator) -> multiset::value_type, less::value_type>, _Allocator>; template::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multiset(initializer_list<_Key>, _Allocator) -> multiset<_Key, less<_Key>, _Allocator>; #endif diff --git a/lib/libcxx/include/span b/lib/libcxx/include/span index 0694f5115d..3421ca0f5a 100644 --- a/lib/libcxx/include/span +++ b/lib/libcxx/include/span @@ -39,7 +39,7 @@ public: // constants and types using element_type = ElementType; using value_type = remove_cv_t; - using index_type = size_t; + using size_type = size_t; using difference_type = ptrdiff_t; using pointer = element_type*; using const_pointer = const element_type*; @@ -49,11 +49,11 @@ public: using const_iterator = implementation-defined; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr index_type extent = Extent; + static constexpr size_type extent = Extent; // [span.cons], span constructors, copy, assignment, and destructor constexpr span() noexcept; - constexpr span(pointer ptr, index_type count); + constexpr span(pointer ptr, size_type count); constexpr span(pointer firstElem, pointer lastElem); template constexpr span(element_type (&arr)[N]) noexcept; @@ -79,17 +79,17 @@ public: template constexpr span subspan() const; - constexpr span first(index_type count) const; - constexpr span last(index_type count) const; - constexpr span subspan(index_type offset, index_type count = dynamic_extent) const; + constexpr span first(size_type count) const; + constexpr span last(size_type count) const; + constexpr span subspan(size_type offset, size_type count = dynamic_extent) const; // [span.obs], span observers - constexpr index_type size() const noexcept; - constexpr index_type size_bytes() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type size_bytes() const noexcept; constexpr bool empty() const noexcept; // [span.elem], span element access - constexpr reference operator[](index_type idx) const; + constexpr reference operator[](size_type idx) const; constexpr reference front() const; constexpr reference back() const; constexpr pointer data() const noexcept; @@ -105,8 +105,8 @@ public: constexpr const_reverse_iterator crend() const noexcept; private: - pointer data_; // exposition only - index_type size_; // exposition only + pointer data_; // exposition only + size_type size_; // exposition only }; template @@ -195,7 +195,7 @@ public: // constants and types using element_type = _Tp; using value_type = remove_cv_t<_Tp>; - using index_type = size_t; + using size_type = size_t; using difference_type = ptrdiff_t; using pointer = _Tp *; using const_pointer = const _Tp *; @@ -206,7 +206,7 @@ public: using reverse_iterator = _VSTD::reverse_iterator; using const_reverse_iterator = _VSTD::reverse_iterator; - static constexpr index_type extent = _Extent; + static constexpr size_type extent = _Extent; // [span.cons], span constructors, copy, assignment, and destructor _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} @@ -215,7 +215,7 @@ public: constexpr span (const span&) noexcept = default; constexpr span& operator=(const span&) noexcept = default; - _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr} + _LIBCPP_INLINE_VISIBILITY constexpr 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} { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } @@ -260,14 +260,14 @@ public: } _LIBCPP_INLINE_VISIBILITY - constexpr span first(index_type __count) const noexcept + constexpr span first(size_type __count) const noexcept { _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); return {data(), __count}; } _LIBCPP_INLINE_VISIBILITY - constexpr span last(index_type __count) const noexcept + constexpr span last(size_type __count) const noexcept { _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); return {data() + size() - __count, __count}; @@ -285,7 +285,7 @@ public: _LIBCPP_INLINE_VISIBILITY constexpr span - subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); @@ -295,11 +295,11 @@ public: return {data() + __offset, __count}; } - _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; } - _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } - _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } + _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } + _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } + _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } - _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept { _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span[] index out of bounds"); return __data[__idx]; @@ -356,7 +356,7 @@ public: // constants and types using element_type = _Tp; using value_type = remove_cv_t<_Tp>; - using index_type = size_t; + using size_type = size_t; using difference_type = ptrdiff_t; using pointer = _Tp *; using const_pointer = const _Tp *; @@ -367,7 +367,7 @@ public: using reverse_iterator = _VSTD::reverse_iterator; using const_reverse_iterator = _VSTD::reverse_iterator; - static constexpr index_type extent = dynamic_extent; + static constexpr size_type extent = dynamic_extent; // [span.cons], span constructors, copy, assignment, and destructor _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} @@ -375,7 +375,7 @@ public: constexpr span (const span&) noexcept = default; constexpr span& operator=(const span&) noexcept = default; - _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {} + _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {} _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast(distance(__f, __l))} {} template @@ -394,13 +394,13 @@ public: _LIBCPP_INLINE_VISIBILITY constexpr span( _Container& __c, enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) - : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {} + : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} template _LIBCPP_INLINE_VISIBILITY constexpr span(const _Container& __c, enable_if_t<__is_span_compatible_container::value, nullptr_t> = nullptr) - : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {} + : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} template @@ -430,14 +430,14 @@ public: } _LIBCPP_INLINE_VISIBILITY - constexpr span first(index_type __count) const noexcept + constexpr span first(size_type __count) const noexcept { _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); return {data(), __count}; } _LIBCPP_INLINE_VISIBILITY - constexpr span last (index_type __count) const noexcept + constexpr span last (size_type __count) const noexcept { _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); return {data() + size() - __count, __count}; @@ -454,7 +454,7 @@ public: constexpr span _LIBCPP_INLINE_VISIBILITY - subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept + subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); @@ -464,11 +464,11 @@ public: return {data() + __offset, __count}; } - _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; } - _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); } - _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } + _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size; } + _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size * sizeof(element_type); } + _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } - _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept + _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept { _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span[] index out of bounds"); return __data[__idx]; @@ -505,7 +505,7 @@ public: __data = __other.__data; __other.__data = __p; - index_type __sz = __size; + size_type __sz = __size; __size = __other.__size; __other.__size = __sz; } @@ -517,8 +517,8 @@ public: { return {reinterpret_cast(data()), size_bytes()}; } private: - pointer __data; - index_type __size; + pointer __data; + size_type __size; }; // tuple interface diff --git a/lib/libcxx/include/string b/lib/libcxx/include/string index 1e5b09800c..8a0ac84447 100644 --- a/lib/libcxx/include/string +++ b/lib/libcxx/include/string @@ -625,7 +625,7 @@ struct __libcpp_string_gets_noexcept_iterator_impl : public true_type {}; template struct __libcpp_string_gets_noexcept_iterator_impl : public false_type {}; #else -template ::value> +template ::value> struct __libcpp_string_gets_noexcept_iterator_impl : public _LIBCPP_BOOL_CONSTANT(( noexcept(++(declval<_Iter&>())) && is_nothrow_assignable<_Iter&, _Iter>::value && @@ -812,11 +812,9 @@ public: basic_string(basic_string&& __str, const allocator_type& __a); #endif // _LIBCPP_CXX03_LANG -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template ::value, nullptr_t>::type> -#endif _LIBCPP_INLINE_VISIBILITY - basic_string(const _CharT* __s) { + basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); __init(__s, traits_type::length(__s)); # if _LIBCPP_DEBUG_LEVEL >= 2 @@ -824,9 +822,7 @@ public: # endif } -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template ::value, nullptr_t>::type> -#endif _LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s, const _Allocator& __a); @@ -837,9 +833,7 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c); -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template ::value, nullptr_t>::type> -#endif _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, _CharT __c, const _Allocator& __a); @@ -862,10 +856,10 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit basic_string(const _Tp& __t, const allocator_type& __a); - template::value>::type> + template::value>::type> _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); - template::value>::type> + template::value>::type> _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a); #ifndef _LIBCPP_CXX03_LANG @@ -1029,7 +1023,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_exactly_input_iterator<_InputIterator>::value + __is_exactly_cpp17_input_iterator<_InputIterator>::value || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, basic_string& >::type @@ -1043,7 +1037,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_forward_iterator<_ForwardIterator>::value + __is_cpp17_forward_iterator<_ForwardIterator>::value && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, basic_string& >::type @@ -1097,7 +1091,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_exactly_input_iterator<_InputIterator>::value + __is_exactly_cpp17_input_iterator<_InputIterator>::value || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, basic_string& >::type @@ -1106,7 +1100,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_forward_iterator<_ForwardIterator>::value + __is_cpp17_forward_iterator<_ForwardIterator>::value && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, basic_string& >::type @@ -1148,7 +1142,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_exactly_input_iterator<_InputIterator>::value + __is_exactly_cpp17_input_iterator<_InputIterator>::value || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, iterator >::type @@ -1157,7 +1151,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_forward_iterator<_ForwardIterator>::value + __is_cpp17_forward_iterator<_ForwardIterator>::value && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, iterator >::type @@ -1219,7 +1213,7 @@ public: _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS typename enable_if < - __is_input_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value, basic_string& >::type replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); @@ -1245,10 +1239,10 @@ public: _LIBCPP_INLINE_VISIBILITY const value_type* c_str() const _NOEXCEPT {return data();} _LIBCPP_INLINE_VISIBILITY - const value_type* data() const _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} + const value_type* data() const _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} #if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY) _LIBCPP_INLINE_VISIBILITY - value_type* data() _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} + value_type* data() _NOEXCEPT {return _VSTD::__to_address(__get_pointer());} #endif _LIBCPP_INLINE_VISIBILITY @@ -1553,7 +1547,7 @@ private: inline typename enable_if < - __is_exactly_input_iterator<_InputIterator>::value, + __is_exactly_cpp17_input_iterator<_InputIterator>::value, void >::type __init(_InputIterator __first, _InputIterator __last); @@ -1562,7 +1556,7 @@ private: inline typename enable_if < - __is_forward_iterator<_ForwardIterator>::value, + __is_cpp17_forward_iterator<_ForwardIterator>::value, void >::type __init(_ForwardIterator __first, _ForwardIterator __last); @@ -1658,7 +1652,7 @@ private: template::value_type, class _Allocator = allocator<_CharT>, - class = typename enable_if<__is_input_iterator<_InputIterator>::value, void>::type, + class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value, void>::type, class = typename enable_if<__is_allocator<_Allocator>::value, void>::type > basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) @@ -1727,6 +1721,7 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible::value) + : __r_(__default_init_tag(), __default_init_tag()) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1742,7 +1737,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ #else _NOEXCEPT #endif -: __r_(__second_tag(), __a) +: __r_(__default_init_tag(), __a) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1771,7 +1766,7 @@ void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, __set_long_cap(__cap+1); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz); + traits_type::copy(_VSTD::__to_address(__p), __s, __sz); traits_type::assign(__p[__sz], value_type()); } @@ -1795,16 +1790,14 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty __set_long_cap(__cap+1); __set_long_size(__sz); } - traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz); + traits_type::copy(_VSTD::__to_address(__p), __s, __sz); traits_type::assign(__p[__sz], value_type()); } template -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template -#endif basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); __init(__s, traits_type::length(__s)); @@ -1816,6 +1809,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) + : __r_(__default_init_tag(), __default_init_tag()) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); __init(__s, __n); @@ -1827,7 +1821,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); __init(__s, __n); @@ -1838,12 +1832,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ template basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) - : __r_(__second_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) + : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { if (!__str.__is_long()) __r_.first().__r = __str.__r_.first().__r; else - __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size()); + __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif @@ -1852,12 +1846,12 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st template basic_string<_CharT, _Traits, _Allocator>::basic_string( const basic_string& __str, const allocator_type& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { if (!__str.__is_long()) __r_.first().__r = __str.__r_.first().__r; else - __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size()); + __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); #endif @@ -1886,10 +1880,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { if (__str.__is_long() && __a != __str.__alloc()) // copy, not move - __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()), __str.__get_long_size()); + __init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); else { __r_.first().__r = __str.__r_.first().__r; @@ -1924,13 +1918,14 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) __set_long_cap(__cap+1); __set_long_size(__n); } - traits_type::assign(_VSTD::__to_raw_pointer(__p), __n, __c); + traits_type::assign(_VSTD::__to_address(__p), __n, __c); traits_type::assign(__p[__n], value_type()); } template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) + : __r_(__default_init_tag(), __default_init_tag()) { __init(__n, __c); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1939,11 +1934,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __ } template -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template -#endif basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { __init(__n, __c); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1955,7 +1948,7 @@ template basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { size_type __str_sz = __str.size(); if (__pos > __str_sz) @@ -1970,7 +1963,7 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { size_type __str_sz = __str.size(); if (__pos > __str_sz) @@ -1985,7 +1978,7 @@ template template basic_string<_CharT, _Traits, _Allocator>::basic_string( const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { __self_view __sv0 = __t; __self_view __sv = __sv0.substr(__pos, __n); @@ -1998,6 +1991,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( template template basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) + : __r_(__default_init_tag(), __default_init_tag()) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); @@ -2009,7 +2003,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) template template basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { __self_view __sv = __t; __init(__sv.data(), __sv.size()); @@ -2022,7 +2016,7 @@ template template typename enable_if < - __is_exactly_input_iterator<_InputIterator>::value, + __is_exactly_cpp17_input_iterator<_InputIterator>::value, void >::type basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) @@ -2049,7 +2043,7 @@ template template typename enable_if < - __is_forward_iterator<_ForwardIterator>::value, + __is_cpp17_forward_iterator<_ForwardIterator>::value, void >::type basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) @@ -2080,6 +2074,7 @@ template template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) + : __r_(__default_init_tag(), __default_init_tag()) { __init(__first, __last); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -2092,7 +2087,7 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { __init(__first, __last); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -2106,6 +2101,7 @@ template inline basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il) + : __r_(__default_init_tag(), __default_init_tag()) { __init(__il.begin(), __il.end()); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -2118,7 +2114,7 @@ inline basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il, const _Allocator& __a) - : __r_(__second_tag(), __a) + : __r_(__default_init_tag(), __a) { __init(__il.begin(), __il.end()); #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -2154,14 +2150,14 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); __invalidate_all_iterators(); if (__n_copy != 0) - traits_type::copy(_VSTD::__to_raw_pointer(__p), - _VSTD::__to_raw_pointer(__old_p), __n_copy); + traits_type::copy(_VSTD::__to_address(__p), + _VSTD::__to_address(__old_p), __n_copy); if (__n_add != 0) - traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy, __p_new_stuff, __n_add); + traits_type::copy(_VSTD::__to_address(__p) + __n_copy, __p_new_stuff, __n_add); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) - traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add, - _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, __sec_cp_sz); + traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, + _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); if (__old_cap+1 != __min_cap) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); __set_long_pointer(__p); @@ -2186,12 +2182,12 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t pointer __p = __alloc_traits::allocate(__alloc(), __cap+1); __invalidate_all_iterators(); if (__n_copy != 0) - traits_type::copy(_VSTD::__to_raw_pointer(__p), - _VSTD::__to_raw_pointer(__old_p), __n_copy); + traits_type::copy(_VSTD::__to_address(__p), + _VSTD::__to_address(__old_p), __n_copy); size_type __sec_cp_sz = __old_sz - __n_del - __n_copy; if (__sec_cp_sz != 0) - traits_type::copy(_VSTD::__to_raw_pointer(__p) + __n_copy + __n_add, - _VSTD::__to_raw_pointer(__old_p) + __n_copy + __n_del, + traits_type::copy(_VSTD::__to_address(__p) + __n_copy + __n_add, + _VSTD::__to_address(__old_p) + __n_copy + __n_del, __sec_cp_sz); if (__old_cap+1 != __min_cap) __alloc_traits::deallocate(__alloc(), __old_p, __old_cap+1); @@ -2209,7 +2205,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_ty size_type __cap = capacity(); if (__cap >= __n) { - value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); + value_type* __p = _VSTD::__to_address(__get_pointer()); traits_type::move(__p, __s, __n); traits_type::assign(__p[__n], value_type()); __set_size(__n); @@ -2235,7 +2231,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) } else __invalidate_iterators_past(__n); - value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); + value_type* __p = _VSTD::__to_address(__get_pointer()); traits_type::assign(__p, __n, __c); traits_type::assign(__p[__n], value_type()); __set_size(__n); @@ -2270,7 +2266,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) if (this != &__str) { __copy_assign_alloc(__str); - assign(__str.data(), __str.size()); + return assign(__str.data(), __str.size()); } return *this; } @@ -2299,10 +2295,20 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr _NOEXCEPT_(is_nothrow_move_assignable::value) #endif { - __clear_and_shrink(); - __r_.first() = __str.__r_.first(); - __move_assign_alloc(__str); - __str.__zero(); + if (__is_long()) { + __alloc_traits::deallocate(__alloc(), __get_long_pointer(), + __get_long_cap()); +#if _LIBCPP_STD_VER <= 14 + if (!is_nothrow_move_assignable::value) { + __set_short_size(0); + traits_type::assign(__get_short_pointer()[0], value_type()); + } +#endif + } + __move_assign_alloc(__str); + __r_.first() = __str.__r_.first(); + __str.__set_short_size(0); + traits_type::assign(__str.__get_short_pointer()[0], value_type()); } template @@ -2322,7 +2328,7 @@ template template typename enable_if < - __is_exactly_input_iterator <_InputIterator>::value + __is_exactly_cpp17_input_iterator <_InputIterator>::value || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, basic_string<_CharT, _Traits, _Allocator>& >::type @@ -2337,7 +2343,7 @@ template template typename enable_if < - __is_forward_iterator<_ForwardIterator>::value + __is_cpp17_forward_iterator<_ForwardIterator>::value && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, basic_string<_CharT, _Traits, _Allocator>& >::type @@ -2408,7 +2414,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_ty { if (__n) { - value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); + value_type* __p = _VSTD::__to_address(__get_pointer()); traits_type::copy(__p + __sz, __s, __n); __sz += __n; __set_size(__sz); @@ -2431,7 +2437,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) if (__cap - __sz < __n) __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); pointer __p = __get_pointer(); - traits_type::assign(_VSTD::__to_raw_pointer(__p) + __sz, __n, __c); + traits_type::assign(_VSTD::__to_address(__p) + __sz, __n, __c); __sz += __n; __set_size(__sz); traits_type::assign(__p[__sz], value_type()); @@ -2511,7 +2517,7 @@ basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe( _ForwardIterator __first, _ForwardIterator __last) { - static_assert(__is_forward_iterator<_ForwardIterator>::value, + static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, "function requires a ForwardIterator"); size_type __sz = size(); size_type __cap = capacity(); @@ -2596,7 +2602,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_t { if (__n) { - value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); + value_type* __p = _VSTD::__to_address(__get_pointer()); size_type __n_move = __sz - __pos; if (__n_move != 0) { @@ -2628,7 +2634,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n value_type* __p; if (__cap - __sz >= __n) { - __p = _VSTD::__to_raw_pointer(__get_pointer()); + __p = _VSTD::__to_address(__get_pointer()); size_type __n_move = __sz - __pos; if (__n_move != 0) traits_type::move(__p + __pos + __n, __p + __pos, __n_move); @@ -2636,7 +2642,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n else { __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); - __p = _VSTD::__to_raw_pointer(__get_long_pointer()); + __p = _VSTD::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n, __c); __sz += __n; @@ -2650,7 +2656,7 @@ template template typename enable_if < - __is_exactly_input_iterator<_InputIterator>::value + __is_exactly_cpp17_input_iterator<_InputIterator>::value || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, typename basic_string<_CharT, _Traits, _Allocator>::iterator >::type @@ -2669,7 +2675,7 @@ template template typename enable_if < - __is_forward_iterator<_ForwardIterator>::value + __is_cpp17_forward_iterator<_ForwardIterator>::value && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, typename basic_string<_CharT, _Traits, _Allocator>::iterator >::type @@ -2697,7 +2703,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward value_type* __p; if (__cap - __sz >= __n) { - __p = _VSTD::__to_raw_pointer(__get_pointer()); + __p = _VSTD::__to_address(__get_pointer()); size_type __n_move = __sz - __ip; if (__n_move != 0) traits_type::move(__p + __ip + __n, __p + __ip, __n_move); @@ -2705,7 +2711,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward else { __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); - __p = _VSTD::__to_raw_pointer(__get_long_pointer()); + __p = _VSTD::__to_address(__get_long_pointer()); } __sz += __n; __set_size(__sz); @@ -2771,11 +2777,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty if (__cap == __sz) { __grow_by(__cap, 1, __sz, __ip, 0, 1); - __p = _VSTD::__to_raw_pointer(__get_long_pointer()); + __p = _VSTD::__to_address(__get_long_pointer()); } else { - __p = _VSTD::__to_raw_pointer(__get_pointer()); + __p = _VSTD::__to_address(__get_pointer()); size_type __n_move = __sz - __ip; if (__n_move != 0) traits_type::move(__p + __ip + 1, __p + __ip, __n_move); @@ -2816,7 +2822,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ size_type __cap = capacity(); if (__cap - __sz + __n1 >= __n2) { - value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); + value_type* __p = _VSTD::__to_address(__get_pointer()); if (__n1 != __n2) { size_type __n_move = __sz - __pos - __n1; @@ -2871,7 +2877,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ value_type* __p; if (__cap - __sz + __n1 >= __n2) { - __p = _VSTD::__to_raw_pointer(__get_pointer()); + __p = _VSTD::__to_address(__get_pointer()); if (__n1 != __n2) { size_type __n_move = __sz - __pos - __n1; @@ -2882,7 +2888,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ else { __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); - __p = _VSTD::__to_raw_pointer(__get_long_pointer()); + __p = _VSTD::__to_address(__get_long_pointer()); } traits_type::assign(__p + __pos, __n2, __c); __sz += __n2 - __n1; @@ -2896,7 +2902,7 @@ template template typename enable_if < - __is_input_iterator<_InputIterator>::value, + __is_cpp17_input_iterator<_InputIterator>::value, basic_string<_CharT, _Traits, _Allocator>& >::type basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, @@ -2994,7 +3000,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) this->__throw_out_of_range(); if (__n) { - value_type* __p = _VSTD::__to_raw_pointer(__get_pointer()); + value_type* __p = _VSTD::__to_address(__get_pointer()); __n = _VSTD::min(__n, __sz - __pos); size_type __n_move = __sz - __pos - __n; if (__n_move != 0) @@ -3182,8 +3188,8 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg) __was_long = __is_long(); __p = __get_pointer(); } - traits_type::copy(_VSTD::__to_raw_pointer(__new_data), - _VSTD::__to_raw_pointer(__p), size()+1); + traits_type::copy(_VSTD::__to_address(__new_data), + _VSTD::__to_address(__p), size()+1); if (__was_long) __alloc_traits::deallocate(__alloc(), __p, __cap+1); if (__now_long) @@ -4294,23 +4300,23 @@ template bool basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const { - return this->data() <= _VSTD::__to_raw_pointer(__i->base()) && - _VSTD::__to_raw_pointer(__i->base()) < this->data() + this->size(); + return this->data() <= _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) < this->data() + this->size(); } template bool basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const { - return this->data() < _VSTD::__to_raw_pointer(__i->base()) && - _VSTD::__to_raw_pointer(__i->base()) <= this->data() + this->size(); + return this->data() < _VSTD::__to_address(__i->base()) && + _VSTD::__to_address(__i->base()) <= this->data() + this->size(); } template bool basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const { - const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n; + const value_type* __p = _VSTD::__to_address(__i->base()) + __n; return this->data() <= __p && __p <= this->data() + this->size(); } @@ -4318,7 +4324,7 @@ template bool basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const { - const value_type* __p = _VSTD::__to_raw_pointer(__i->base()) + __n; + const value_type* __p = _VSTD::__to_address(__i->base()) + __n; return this->data() <= __p && __p < this->data() + this->size(); } diff --git a/lib/libcxx/include/string_view b/lib/libcxx/include/string_view index 04448312ff..8a684a8f96 100644 --- a/lib/libcxx/include/string_view +++ b/lib/libcxx/include/string_view @@ -173,6 +173,7 @@ namespace std { #include <__config> #include <__string> +#include #include #include #include @@ -235,7 +236,7 @@ public: _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY basic_string_view(const _CharT* __s) - : __data(__s), __size(_Traits::length(__s)) {} + : __data(__s), __size(std::__char_traits_length_checked<_Traits>(__s)) {} // [string.view.iterators], iterators _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY @@ -767,6 +768,12 @@ bool operator>=(typename common_type >::type return __lhs.compare(__rhs) >= 0; } + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + basic_string_view<_CharT, _Traits> __str); + typedef basic_string_view string_view; #ifndef _LIBCPP_NO_HAS_CHAR8_T typedef basic_string_view u8string_view; diff --git a/lib/libcxx/include/support/android/locale_bionic.h b/lib/libcxx/include/support/android/locale_bionic.h index 5b16071d9c..f05a6a0522 100644 --- a/lib/libcxx/include/support/android/locale_bionic.h +++ b/lib/libcxx/include/support/android/locale_bionic.h @@ -27,7 +27,9 @@ extern "C" { #include #include +#if __ANDROID_API__ < 21 #include +#endif // In NDK versions later than 16, locale-aware functions are provided by // legacy_stdlib_inlines.h #if __NDK_MAJOR__ <= 16 diff --git a/lib/libcxx/include/support/ibm/xlocale.h b/lib/libcxx/include/support/ibm/xlocale.h index 9f0522c199..431bf62687 100644 --- a/lib/libcxx/include/support/ibm/xlocale.h +++ b/lib/libcxx/include/support/ibm/xlocale.h @@ -87,7 +87,7 @@ int isxdigit_l(int c, locale_t locale) static inline int iswalnum_l(wchar_t wc, locale_t locale) { - return __xiswalnum(locale, wc); + return __xiswalnum(locale, wc); } static inline @@ -159,7 +159,7 @@ int iswxdigit_l(wchar_t wc, locale_t locale) static inline int iswctype_l(wint_t wc, wctype_t desc, locale_t locale) { - return __xiswctype(locale, wc, desc); + return __xiswctype(locale, wc, desc); } static inline @@ -261,7 +261,7 @@ int vasprintf(char **strp, const char *fmt, va_list ap) str_size = vsnprintf(*strp, str_size + 1, fmt, ap); } return str_size; -} +} #ifdef __cplusplus } diff --git a/lib/libcxx/include/support/solaris/wchar.h b/lib/libcxx/include/support/solaris/wchar.h index 9dc9ac3f00..f01fd743a2 100644 --- a/lib/libcxx/include/support/solaris/wchar.h +++ b/lib/libcxx/include/support/solaris/wchar.h @@ -26,7 +26,7 @@ #define wctype sun_wctype #define _WCHAR_T 1 #include_next "wchar.h" -#undef iswalpha +#undef iswalpha #undef iswupper #undef iswlower #undef iswdigit diff --git a/lib/libcxx/include/support/win32/locale_win32.h b/lib/libcxx/include/support/win32/locale_win32.h index 0d03d834b7..8d7779e0cc 100644 --- a/lib/libcxx/include/support/win32/locale_win32.h +++ b/lib/libcxx/include/support/win32/locale_win32.h @@ -28,14 +28,72 @@ | LC_NUMERIC_MASK \ | LC_TIME_MASK ) +class __lconv_storage { +public: + __lconv_storage(const lconv *__lc_input) { + __lc = *__lc_input; + + __decimal_point = __lc_input->decimal_point; + __thousands_sep = __lc_input->thousands_sep; + __grouping = __lc_input->grouping; + __int_curr_symbol = __lc_input->int_curr_symbol; + __currency_symbol = __lc_input->currency_symbol; + __mon_decimal_point = __lc_input->mon_decimal_point; + __mon_thousands_sep = __lc_input->mon_thousands_sep; + __mon_grouping = __lc_input->mon_grouping; + __positive_sign = __lc_input->positive_sign; + __negative_sign = __lc_input->negative_sign; + + __lc.decimal_point = const_cast(__decimal_point.c_str()); + __lc.thousands_sep = const_cast(__thousands_sep.c_str()); + __lc.grouping = const_cast(__grouping.c_str()); + __lc.int_curr_symbol = const_cast(__int_curr_symbol.c_str()); + __lc.currency_symbol = const_cast(__currency_symbol.c_str()); + __lc.mon_decimal_point = const_cast(__mon_decimal_point.c_str()); + __lc.mon_thousands_sep = const_cast(__mon_thousands_sep.c_str()); + __lc.mon_grouping = const_cast(__mon_grouping.c_str()); + __lc.positive_sign = const_cast(__positive_sign.c_str()); + __lc.negative_sign = const_cast(__negative_sign.c_str()); + } + + lconv *__get() { + return &__lc; + } +private: + lconv __lc; + std::string __decimal_point; + std::string __thousands_sep; + std::string __grouping; + std::string __int_curr_symbol; + std::string __currency_symbol; + std::string __mon_decimal_point; + std::string __mon_thousands_sep; + std::string __mon_grouping; + std::string __positive_sign; + std::string __negative_sign; +}; + class locale_t { public: locale_t() - : __locale(nullptr), __locale_str(nullptr) {} + : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {} locale_t(std::nullptr_t) - : __locale(nullptr), __locale_str(nullptr) {} + : __locale(nullptr), __locale_str(nullptr), __lc(nullptr) {} locale_t(_locale_t __xlocale, const char* __xlocale_str) - : __locale(__xlocale), __locale_str(__xlocale_str) {} + : __locale(__xlocale), __locale_str(__xlocale_str), __lc(nullptr) {} + locale_t(const locale_t &__l) + : __locale(__l.__locale), __locale_str(__l.__locale_str), __lc(nullptr) {} + + ~locale_t() { + delete __lc; + } + + locale_t &operator =(const locale_t &__l) { + __locale = __l.__locale; + __locale_str = __l.__locale_str; + // __lc not copied + return *this; + } friend bool operator==(const locale_t& __left, const locale_t& __right) { return __left.__locale == __right.__locale; @@ -94,9 +152,16 @@ public: operator _locale_t() const { return __locale; } + + lconv *__store_lconv(const lconv *__input_lc) { + delete __lc; + __lc = new __lconv_storage(__input_lc); + return __lc->__get(); + } private: _locale_t __locale; const char* __locale_str; + __lconv_storage *__lc = nullptr; }; // Locale management functions @@ -109,7 +174,7 @@ locale_t newlocale( int mask, const char * locale, locale_t base ); // We can still implement raii even without uselocale though. -lconv *localeconv_l( locale_t loc ); +lconv *localeconv_l( locale_t &loc ); size_t mbrlen_l( const char *__restrict s, size_t n, mbstate_t *__restrict ps, locale_t loc); size_t mbsrtowcs_l( wchar_t *__restrict dst, const char **__restrict src, @@ -173,7 +238,8 @@ isupper_l(int c, _locale_t loc) #define towupper_l _towupper_l #define towlower_l _towlower_l #if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800 -#define strftime_l( __s, __l, __f, __tm, __loc ) strftime( __s, __l, __f, __tm ) +_LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format, + const struct tm *tm, locale_t loc); #else #define strftime_l _strftime_l #endif diff --git a/lib/libcxx/include/thread b/lib/libcxx/include/thread index 0b914317b0..3b55342288 100644 --- a/lib/libcxx/include/thread +++ b/lib/libcxx/include/thread @@ -14,8 +14,6 @@ thread synopsis -#define __STDCPP_THREADS__ __cplusplus - namespace std { @@ -107,8 +105,6 @@ void sleep_for(const chrono::duration& rel_time); _LIBCPP_PUSH_MACROS #include <__undef_macros> -#define __STDCPP_THREADS__ __cplusplus - #ifdef _LIBCPP_HAS_NO_THREADS #error is not supported on this single threaded system #else // !_LIBCPP_HAS_NO_THREADS @@ -278,6 +274,7 @@ __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) } template +_LIBCPP_INLINE_VISIBILITY void* __thread_proxy(void* __vp) { // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...> diff --git a/lib/libcxx/include/tuple b/lib/libcxx/include/tuple index 031d25a985..1f80b70759 100644 --- a/lib/libcxx/include/tuple +++ b/lib/libcxx/include/tuple @@ -19,40 +19,40 @@ namespace std template class tuple { public: - constexpr tuple(); - explicit tuple(const T&...); // constexpr in C++14 + explicit(see-below) constexpr tuple(); + explicit(see-below) tuple(const T&...); // constexpr in C++14 template - explicit tuple(U&&...); // constexpr in C++14 + explicit(see-below) tuple(U&&...); // constexpr in C++14 tuple(const tuple&) = default; tuple(tuple&&) = default; template - tuple(const tuple&); // constexpr in C++14 + explicit(see-below) tuple(const tuple&); // constexpr in C++14 template - tuple(tuple&&); // constexpr in C++14 + explicit(see-below) tuple(tuple&&); // constexpr in C++14 template - tuple(const pair&); // iff sizeof...(T) == 2 // constexpr in C++14 + explicit(see-below) tuple(const pair&); // iff sizeof...(T) == 2 // constexpr in C++14 template - tuple(pair&&); // iff sizeof...(T) == 2 // constexpr in C++14 + explicit(see-below) tuple(pair&&); // iff sizeof...(T) == 2 // constexpr in C++14 // allocator-extended constructors template tuple(allocator_arg_t, const Alloc& a); template - tuple(allocator_arg_t, const Alloc& a, const T&...); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); template - tuple(allocator_arg_t, const Alloc& a, U&&...); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); template tuple(allocator_arg_t, const Alloc& a, const tuple&); template tuple(allocator_arg_t, const Alloc& a, tuple&&); template - tuple(allocator_arg_t, const Alloc& a, const tuple&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple&); template - tuple(allocator_arg_t, const Alloc& a, tuple&&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple&&); template - tuple(allocator_arg_t, const Alloc& a, const pair&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair&); template - tuple(allocator_arg_t, const Alloc& a, pair&&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair&&); tuple& operator=(const tuple&); tuple& @@ -69,6 +69,17 @@ public: void swap(tuple&) noexcept(AND(swap(declval(), declval())...)); }; +template +tuple(T...) -> tuple; // since C++17 +template +tuple(pair) -> tuple; // since C++17 +template +tuple(allocator_arg_t, Alloc, T...) -> tuple; // since C++17 +template +tuple(allocator_arg_t, Alloc, pair) -> tuple; // since C++17 +template +tuple(allocator_arg_t, Alloc, tuple) -> tuple; // since C++17 + inline constexpr unspecified ignore; template tuple make_tuple(T&&...); // constexpr in C++14 @@ -488,11 +499,19 @@ class _LIBCPP_TEMPLATE_VIS tuple template struct _CheckArgsConstructor { - template - static constexpr bool __enable_default() { - return __all::value...>::value; + template + static constexpr bool __enable_implicit_default() { + return __all<__is_implicitly_default_constructible<_Tp>::value... >::value; } + template + static constexpr bool __enable_explicit_default() { + return + __all::value...>::value && + !__enable_implicit_default< >(); + } + + template static constexpr bool __enable_explicit() { return @@ -630,22 +649,26 @@ class _LIBCPP_TEMPLATE_VIS tuple const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT; public: - template ::template __enable_default<_Tp...>() - >::type> - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR tuple() + template ::__enable_implicit_default() + , void*> = nullptr> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + tuple() + _NOEXCEPT_(__all::value...>::value) {} + + template ::__enable_explicit_default() + , void*> = nullptr> + explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + tuple() _NOEXCEPT_(__all::value...>::value) {} tuple(tuple const&) = default; tuple(tuple&&) = default; - template , - __dependent_type, _Dummy>... - >::value - > + template ::value >::__enable_implicit_default() + , void*> = nullptr > _LIBCPP_INLINE_VISIBILITY tuple(_AllocArgT, _Alloc const& __a) @@ -654,6 +677,17 @@ public: typename __make_tuple_indices::type(), __tuple_types<_Tp...>()) {} + template ::value>::__enable_explicit_default() + , void*> = nullptr + > + explicit _LIBCPP_INLINE_VISIBILITY + tuple(_AllocArgT, _Alloc const& __a) + : __base_(allocator_arg_t(), __a, + __tuple_indices<>(), __tuple_types<>(), + typename __make_tuple_indices::type(), + __tuple_types<_Tp...>()) {} + template -tuple(allocator_arg_t, const _Alloc&, tuple<_Args...> const&) -> tuple<_Args...>; -template -tuple(allocator_arg_t, const _Alloc&, tuple<_Args...>&&) -> tuple<_Args...>; +template +tuple(_Tp...) -> tuple<_Tp...>; +template +tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; +template +tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>; +template +tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; +template +tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>; #endif template @@ -1312,8 +1349,9 @@ struct __tuple_cat, __tuple_indices<_I0...>, __tuple_indices<_J typename __tuple_cat_return_ref&&, _Tuple0&&>::type operator()(tuple<_Types...> __t, _Tuple0&& __t0) { - return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., - _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...); + return _VSTD::forward_as_tuple( + _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., + _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...); } template @@ -1324,15 +1362,16 @@ struct __tuple_cat, __tuple_indices<_I0...>, __tuple_indices<_J typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0; typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1; return __tuple_cat< - tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>, - typename __make_tuple_indices::value>::type, - typename __make_tuple_indices::value>::type>() - (forward_as_tuple( - _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., - _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))... - ), - _VSTD::forward<_Tuple1>(__t1), - _VSTD::forward<_Tuples>(__tpls)...); + tuple<_Types..., + typename __apply_cv<_Tuple0, typename tuple_element< + _J0, _T0>::type>::type&&...>, + typename __make_tuple_indices::value>::type, + typename __make_tuple_indices::value>::type>()( + _VSTD::forward_as_tuple( + _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., + _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...), + _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...); } }; diff --git a/lib/libcxx/include/type_traits b/lib/libcxx/include/type_traits index 5ccafec01f..c0c3934afc 100644 --- a/lib/libcxx/include/type_traits +++ b/lib/libcxx/include/type_traits @@ -427,7 +427,6 @@ template struct _LIBCPP_TEMPLATE_VIS pair; template class _LIBCPP_TEMPLATE_VIS reference_wrapper; template struct _LIBCPP_TEMPLATE_VIS hash; - template struct _LIBCPP_TEMPLATE_VIS integral_constant { @@ -509,8 +508,8 @@ struct _Lazy : _Func<_Args...> {}; // Member detector base -template