From 243a6be085fe6a7ce49169864c68a8839735e49b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Oct 23 2019 17:52:30 +0000 Subject: Vendor import of stripped libc++ trunk r375505, the last commit before the upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/libcxx/trunk@375505 --- diff --git a/include/__config b/include/__config index 1ecced9..044cd0c 100644 --- a/include/__config +++ b/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 @@ -483,11 +480,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 +523,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 +550,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 +572,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) @@ -958,6 +964,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 @@ -1082,6 +1102,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,17 +1127,35 @@ _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_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) @@ -1129,6 +1177,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 @@ -1224,7 +1280,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 @@ -1411,6 +1467,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/include/__functional_base b/include/__functional_base index 9587d7a..ca761c4 100644 --- a/include/__functional_base +++ b/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/include/__libcpp_version b/include/__libcpp_version index d58c55a..5caff40 100644 --- a/include/__libcpp_version +++ b/include/__libcpp_version @@ -1 +1 @@ -9000 +10000 diff --git a/include/__locale b/include/__locale index d382e4d..2b6982f 100644 --- a/include/__locale +++ b/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/include/__mutex_base b/include/__mutex_base index f828bea..ed75c82 100644 --- a/include/__mutex_base +++ b/include/__mutex_base @@ -15,6 +15,7 @@ #include #include <__threading_support> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -65,9 +66,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 +95,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 +338,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 +424,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 +458,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 +492,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/include/__split_buffer b/include/__split_buffer index 1daa4e5..095fe89 100644 --- a/include/__split_buffer +++ b/include/__split_buffer @@ -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_raw_pointer(__tx.__pos_)); + } } // Copy constructs __n objects starting at __end_ from __x @@ -216,13 +226,11 @@ 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_raw_pointer(__tx.__pos_), __x); + } } template @@ -262,11 +270,10 @@ typename enable_if >::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_raw_pointer(__tx.__pos_), *__first); } } diff --git a/include/__string b/include/__string index a88b976..b4c8815 100644 --- a/include/__string +++ b/include/__string @@ -351,6 +351,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 diff --git a/include/__threading_support b/include/__threading_support index 589fe20..0d1f1e6 100644 --- a/include/__threading_support +++ b/include/__threading_support @@ -12,6 +12,7 @@ #include <__config> #include +#include #include #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -22,16 +23,11 @@ # include <__external_threading> #elif !defined(_LIBCPP_HAS_NO_THREADS) -typedef ::timespec __libcpp_timespec_t; - #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) # include # 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) @@ -46,8 +42,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; @@ -75,7 +79,7 @@ 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_EXTERNAL) // Mutex typedef void* __libcpp_mutex_t; #define _LIBCPP_MUTEX_INITIALIZER 0 @@ -108,8 +112,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); @@ -204,6 +209,8 @@ 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) @@ -394,10 +401,90 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL -_LIBCPP_END_NAMESPACE_STD +class _LIBCPP_TYPE_VIS thread; +class _LIBCPP_TYPE_VIS __thread_id; -_LIBCPP_POP_MACROS +namespace this_thread +{ + +_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; + +} // this_thread + +template<> struct hash<__thread_id>; + +class _LIBCPP_TEMPLATE_VIS __thread_id +{ + // FIXME: pthread_t is a pointer on Darwin but a long on Linux. + // NULL is the no-thread value on Darwin. Someone needs to check + // on other platforms. We assume 0 works everywhere for now. + __libcpp_thread_id __id_; + +public: + _LIBCPP_INLINE_VISIBILITY + __thread_id() _NOEXCEPT : __id_(0) {} + + friend _LIBCPP_INLINE_VISIBILITY + bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT + { // don't pass id==0 to underlying routines + if (__x.__id_ == 0) return __y.__id_ == 0; + if (__y.__id_ == 0) return false; + return __libcpp_thread_id_equal(__x.__id_, __y.__id_); + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT + {return !(__x == __y);} + friend _LIBCPP_INLINE_VISIBILITY + bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT + { // id==0 is always less than any other thread_id + if (__x.__id_ == 0) return __y.__id_ != 0; + if (__y.__id_ == 0) return false; + return __libcpp_thread_id_less(__x.__id_, __y.__id_); + } + friend _LIBCPP_INLINE_VISIBILITY + bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT + {return !(__y < __x);} + friend _LIBCPP_INLINE_VISIBILITY + bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT + {return __y < __x ;} + friend _LIBCPP_INLINE_VISIBILITY + bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT + {return !(__x < __y);} + + _LIBCPP_INLINE_VISIBILITY + void __reset() { __id_ = 0; } + + template + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); + +private: + _LIBCPP_INLINE_VISIBILITY + __thread_id(__libcpp_thread_id __id) : __id_(__id) {} + + friend __thread_id this_thread::get_id() _NOEXCEPT; + friend class _LIBCPP_TYPE_VIS thread; + friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; +}; + +namespace this_thread +{ + +inline _LIBCPP_INLINE_VISIBILITY +__thread_id +get_id() _NOEXCEPT +{ + return __libcpp_thread_get_current_id(); +} + +} // this_thread #endif // !_LIBCPP_HAS_NO_THREADS +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + #endif // _LIBCPP_THREADING_SUPPORT diff --git a/include/__tuple b/include/__tuple index 196f3c2..4da9ec5 100644 --- a/include/__tuple +++ b/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/include/algorithm b/include/algorithm index 0d78626..55ea5eb 100644 --- a/include/algorithm +++ b/include/algorithm @@ -3117,10 +3117,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; @@ -3190,7 +3190,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 +3373,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 +3505,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 +4382,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 +4428,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 +4575,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 +4612,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 +4627,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 +4995,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 +5065,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 +5678,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/include/atomic b/include/atomic index afb431e..6904dd4 100644 --- a/include/atomic +++ b/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/include/bit b/include/bit index 1c0e8ad..8800b22 100644 --- a/include/bit +++ b/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 */ @@ -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/include/chrono b/include/chrono index 1b90757..0e4cf9a 100644 --- a/include/chrono +++ b/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,7 +1852,8 @@ 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; @@ -1842,7 +1873,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 +1881,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 +1897,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 +1910,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}; } @@ -2715,6 +2746,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 +2934,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/include/cmath b/include/cmath index f5864be..0f06486 100644 --- a/include/cmath +++ b/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/include/cstdio b/include/cstdio index 6755693..0f3f42d 100644 --- a/include/cstdio +++ b/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/include/deque b/include/deque index d3ccf2e..cb7e4e5 100644 --- a/include/deque +++ b/include/deque @@ -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_; @@ -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() @@ -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 @@ -1413,15 +1485,53 @@ 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, @@ -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(); } @@ -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_raw_pointer(__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_raw_pointer(__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_raw_pointer(__tx.__pos_), __v); + } + } + } // Create front capacity for one block of elements. @@ -2596,12 +2710,8 @@ deque<_Tp, _Allocator>::pop_front() __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 @@ -2615,11 +2725,7 @@ deque<_Tp, _Allocator>::pop_back() __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/include/execution b/include/execution new file mode 100644 index 0000000..e25cb82 --- /dev/null +++ b/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/include/experimental/coroutine b/include/experimental/coroutine index e2f0a25..54ec74b 100644 --- a/include/experimental/coroutine +++ b/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/include/ext/hash_map b/include/ext/hash_map index 24823c6..20f778b 100644 --- a/include/ext/hash_map +++ b/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&); @@ -502,7 +505,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 +626,6 @@ template hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_map( _InputIterator __first, _InputIterator __last) { - __table_.rehash(193); insert(__first, __last); } @@ -775,7 +777,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 +892,6 @@ template hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( _InputIterator __first, _InputIterator __last) { - __table_.rehash(193); insert(__first, __last); } diff --git a/include/ext/hash_set b/include/ext/hash_set index e514182..f0ba8d8 100644 --- a/include/ext/hash_set +++ b/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/include/filesystem b/include/filesystem index 3aaa798..9020a12 100644 --- a/include/filesystem +++ b/include/filesystem @@ -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/include/fstream b/include/fstream index 60a05b0..e913899 100644 --- a/include/fstream +++ b/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/include/functional b/include/functional index bcd74a9..865a281 100644 --- a/include/functional +++ b/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/include/istream b/include/istream index d6217bb..bfbe5f2 100644 --- a/include/istream +++ b/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/include/map b/include/map index eb6ae57..b6f89bf 100644 --- a/include/map +++ b/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/include/memory b/include/memory index d9222b3..96bb8fb 100644 --- a/include/memory +++ b/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 @@ -1507,6 +1506,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 +1633,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_raw_pointer(__begin2), +#ifdef _LIBCPP_NO_EXCEPTIONS + _VSTD::move(*__begin1) +#else + _VSTD::move_if_noexcept(*__begin1) +#endif + ); } template @@ -1625,7 +1657,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) @@ -1672,12 +1704,20 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits _LIBCPP_INLINE_VISIBILITY static void - __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) + __construct_backward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { + static_assert(__is_cpp17_move_insertable::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_raw_pointer(__end2 - 1), +#ifdef _LIBCPP_NO_EXCEPTIONS + _VSTD::move(*--__end1) +#else + _VSTD::move_if_noexcept(*--__end1) +#endif + ); + --__end2; } } @@ -1691,7 +1731,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; @@ -3831,49 +3871,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 +4199,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 +4219,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 +4400,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 +4409,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 +4434,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 +5363,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/include/module.modulemap b/include/module.modulemap index bbfe90e..31d39dd 100644 --- a/include/module.modulemap +++ b/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/include/mutex b/include/mutex index 20c3ffc..8fc3c61 100644 --- a/include/mutex +++ b/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{}; @@ -280,7 +280,7 @@ class _LIBCPP_TYPE_VIS recursive_timed_mutex mutex __m_; condition_variable __cv_; size_t __count_; - __libcpp_thread_id __id_; + __thread_id __id_; public: recursive_timed_mutex(); ~recursive_timed_mutex(); @@ -307,9 +307,9 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - __libcpp_thread_id __id = __libcpp_thread_get_current_id(); + __thread_id __id = this_thread::get_id(); unique_lock lk(__m_); - if (__libcpp_thread_id_equal(__id, __id_)) + if (__id == __id_) { if (__count_ == numeric_limits::max()) return false; diff --git a/include/new b/include/new index 85e4c4b..40d351e 100644 --- a/include/new +++ b/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/include/numeric b/include/numeric index 2118704..854bbfa 100644 --- a/include/numeric +++ b/include/numeric @@ -586,4 +586,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/include/ostream b/include/ostream index e6cf9c9..ea38705 100644 --- a/include/ostream +++ b/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/include/random b/include/random index 9fefee0..afa60b4 100644 --- a/include/random +++ b/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) diff --git a/include/regex b/include/regex index 26efac1..d13f9ad 100644 --- a/include/regex +++ b/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; @@ -2617,7 +2617,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 diff --git a/include/set b/include/set index 70ab4d3..ac3fbbe 100644 --- a/include/set +++ b/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/include/string b/include/string index 1e5b098..3368fb8 100644 --- a/include/string +++ b/include/string @@ -812,9 +812,7 @@ 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) { _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); @@ -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); @@ -1800,9 +1794,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty } 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) { @@ -1939,9 +1931,7 @@ 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) { @@ -2270,7 +2260,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; } diff --git a/include/string_view b/include/string_view index 0444831..8a684a8 100644 --- a/include/string_view +++ b/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/include/thread b/include/thread index 3d8d2ac..02da703 100644 --- a/include/thread +++ b/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 @@ -200,64 +196,6 @@ __thread_specific_ptr<_Tp>::set_pointer(pointer __p) __libcpp_tls_set(__key_, __p); } -class _LIBCPP_TYPE_VIS thread; -class _LIBCPP_TYPE_VIS __thread_id; - -namespace this_thread -{ - -_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; - -} // this_thread - -template<> struct hash<__thread_id>; - -class _LIBCPP_TEMPLATE_VIS __thread_id -{ - // FIXME: pthread_t is a pointer on Darwin but a long on Linux. - // NULL is the no-thread value on Darwin. Someone needs to check - // on other platforms. We assume 0 works everywhere for now. - __libcpp_thread_id __id_; - -public: - _LIBCPP_INLINE_VISIBILITY - __thread_id() _NOEXCEPT : __id_(0) {} - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT - {return __libcpp_thread_id_equal(__x.__id_, __y.__id_);} - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT - {return !(__x == __y);} - friend _LIBCPP_INLINE_VISIBILITY - bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT - {return __libcpp_thread_id_less(__x.__id_, __y.__id_);} - friend _LIBCPP_INLINE_VISIBILITY - bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT - {return !(__y < __x);} - friend _LIBCPP_INLINE_VISIBILITY - bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT - {return __y < __x ;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT - {return !(__x < __y);} - - template - friend - _LIBCPP_INLINE_VISIBILITY - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) - {return __os << __id.__id_;} - -private: - _LIBCPP_INLINE_VISIBILITY - __thread_id(__libcpp_thread_id __id) : __id_(__id) {} - - friend __thread_id this_thread::get_id() _NOEXCEPT; - friend class _LIBCPP_TYPE_VIS thread; - friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; -}; - template<> struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> : public unary_function<__thread_id, size_t> @@ -269,17 +207,11 @@ struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> } }; -namespace this_thread -{ - -inline _LIBCPP_INLINE_VISIBILITY -__thread_id -get_id() _NOEXCEPT -{ - return __libcpp_thread_get_current_id(); -} - -} // this_thread +template +_LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) +{return __os << __id.__id_;} class _LIBCPP_TYPE_VIS thread { diff --git a/include/tuple b/include/tuple index 031d25a..e93824f 100644 --- a/include/tuple +++ b/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 diff --git a/include/type_traits b/include/type_traits index 5ccafec..77b57a4 100644 --- a/include/type_traits +++ b/include/type_traits @@ -509,8 +509,8 @@ struct _Lazy : _Func<_Args...> {}; // Member detector base -template