diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:30 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:30 +0000 |
commit | 243a6be085fe6a7ce49169864c68a8839735e49b (patch) | |
tree | abfecf3c23dc7512ca48e72ac418b149c865e0f3 | |
parent | 1147845301c03308e3419b89c28c77bb6917fe04 (diff) |
Notes
57 files changed, 1261 insertions, 1003 deletions
diff --git a/include/__config b/include/__config index 1ecced9f4792..044cd0ceb007 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 <sys/endian.h> +# include <osreldate.h> # 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 9587d7ab15a1..ca761c409b62 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 d58c55a31dc7..5caff40c4a0c 100644 --- a/include/__libcpp_version +++ b/include/__libcpp_version @@ -1 +1 @@ -9000 +10000 diff --git a/include/__locale b/include/__locale index d382e4d8a94b..2b6982fc6810 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<char_class_type>(_ISbit(15)); + static const mask __regex_word = static_cast<mask>(_ISbit(15)); #else static const mask __regex_word = 0x80; #endif diff --git a/include/__mutex_base b/include/__mutex_base index f828beaf780d..ed75c82380a6 100644 --- a/include/__mutex_base +++ b/include/__mutex_base @@ -15,6 +15,7 @@ #include <system_error> #include <__threading_support> +#include <time.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -65,9 +66,9 @@ public: static_assert(is_nothrow_default_constructible<mutex>::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<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT; +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) + void __do_timed_wait(unique_lock<mutex>& __lk, + chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT; +#endif + template <class _Clock> + void __do_timed_wait(unique_lock<mutex>& __lk, + chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT; }; #endif // !_LIBCPP_HAS_NO_THREADS -template <class _To, class _Rep, class _Period> +template <class _Rep, class _Period> 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 <class _Rep, class _Period> +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<mutex>& __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<mutex>& __lk, using namespace chrono; if (__d <= __d.zero()) return cv_status::timeout; - typedef time_point<system_clock, duration<long double, nano> > __sys_tpf; - typedef time_point<system_clock, nanoseconds> __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<nanoseconds>(__d)); - else - __do_timed_wait(__lk, __sys_tpi::max()); + +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) + using __clock_tp_ns = time_point<steady_clock, nanoseconds>; + __ns_rep __now_count_ns = __safe_nanosecond_cast(__c_now.time_since_epoch()).count(); +#else + using __clock_tp_ns = time_point<system_clock, nanoseconds>; + __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<mutex>& __lk, _VSTD::move(__pred)); } +#if defined(_LIBCPP_HAS_COND_CLOCKWAIT) +inline +void +condition_variable::__do_timed_wait(unique_lock<mutex>& __lk, + chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __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<seconds>(__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 <class _Clock> +inline +void +condition_variable::__do_timed_wait(unique_lock<mutex>& __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 1daa4e5ada3d..095fe8928c6d 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 <class _Tp, class _Allocator> @@ -197,13 +210,10 @@ template <class _Tp, class _Allocator> 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 <class _Tp, class _Allocator> 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 <class _Tp, class _Allocator> @@ -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 a88b976be3c9..b4c8815f72d2 100644 --- a/include/__string +++ b/include/__string @@ -351,6 +351,18 @@ char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size #endif } + +template <class _Traits> +_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<wchar_t>::length(const char_type* __s) _NOEXCEPT diff --git a/include/__threading_support b/include/__threading_support index 589fe2096fd4..0d1f1e681f50 100644 --- a/include/__threading_support +++ b/include/__threading_support @@ -12,6 +12,7 @@ #include <__config> #include <chrono> +#include <iosfwd> #include <errno.h> #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 <pthread.h> # include <sched.h> #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<class _CharT, class _Traits> + 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 196f3c2b5aa5..4da9ec55f354 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 <class ...> - static constexpr bool __enable_default() { return false; } + + static constexpr bool __enable_explicit_default() { return false; } + static constexpr bool __enable_implicit_default() { return false; } template <class ...> static constexpr bool __enable_explicit() { return false; } template <class ...> diff --git a/include/algorithm b/include/algorithm index 0d7862675588..55ea5eb2cc02 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<class _RandomAccessIterator, class _UniformRandomNumberGenerator> 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<value_type*> _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 afb431eda11d..6904dd400032 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 1c0e8ad3ba8b..8800b22b7bcb 100644 --- a/include/bit +++ b/include/bit @@ -42,6 +42,13 @@ namespace std { template<class T> 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 1b907571aa14..0e4cf9aef3ac 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 Duration> class time_of_day; +// 26.9, class template hh_mm_ss +template <class Duration> +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 <class charT, class traits, class Duration> + basic_ostream<charT, traits>& + operator<<(basic_ostream<charT, traits>& os, hh_mm_ss<Duration> 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<hours>; -template<> class time_of_day<minutes>; -template<> class time_of_day<seconds>; -template<class Rep, class Period> class time_of_day<duration<Rep, Period>>; // 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<unsigned char>(__val)) {} + inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__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<unsigned>(__lhs) == static_cast<unsigned>(__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<unsigned>(__lhs) < static_cast<unsigned>(__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<long long>(static_cast<unsigned>(__lhs)) + __rhs.count(); + auto const __mu = static_cast<long long>(__lhs.c_encoding()) + __rhs.count(); auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; return weekday{static_cast<unsigned>(__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<unsigned>(__lhs) - static_cast<unsigned>(__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 _Duration> +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<typename __CommonType::rep, ratio<1, __pow10(fractional_width)>>; + + 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<chrono::hours> (abs(__d))), + __m(duration_cast<chrono::minutes>(abs(__d) - hours())), + __s(duration_cast<chrono::seconds>(abs(__d) - hours() - minutes())), + __f(duration_cast<precision> (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<rep, period> 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 f5864be5e11a..0f06486fb34f 100644 --- a/include/cmath +++ b/include/cmath @@ -303,11 +303,15 @@ long double truncl(long double x); #include <__config> #include <math.h> #include <version> +#include <type_traits> #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 <class _IntT, class _FloatT, + bool _FloatBigger = (numeric_limits<_FloatT>::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 <class _IntT, class _RealT> +_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 675569382344..0f3f42dac2da 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 d3ccf2ef6f71..cb7e4e532719 100644 --- a/include/deque +++ b/include/deque @@ -934,7 +934,7 @@ public: typedef _Allocator allocator_type; typedef allocator_traits<allocator_type> __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<value_type, const_pointer, const_reference, __map_const_pointer, difference_type> 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<iterator> reverse_iterator; typedef _VSTD::reverse_iterator<const_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 <class _InpIter> 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 <class _Tp, class _Allocator> @@ -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 <class _Tp, class _Allocator> @@ -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 <class _Tp, class _Allocator> @@ -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 000000000000..e25cb82d552c --- /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 e2f0a25f77ed..54ec74b9f984 100644 --- a/include/experimental/coroutine +++ b/include/experimental/coroutine @@ -51,7 +51,6 @@ template <class P> struct hash<coroutine_handle<P>>; #include <functional> #include <memory> // for hash<T*> #include <cstddef> -#include <cassert> #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/include/ext/hash_map b/include/ext/hash_map index 24823c6bf0cc..20f778be9710 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 <class InputIterator> - 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 <class InputIterator> + 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<typename __table::iterator> iterator; typedef __hash_map_const_iterator<typename __table::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 <class _InputIterator> 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<typename __table::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 <class _InputIterator> 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 e5141824b601..f0ba8d8ded95 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 <class _InputIterator> 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 <class _InputIterator> 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 3aaa7988a872..9020a12fea18 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 60a05b0d4b95..e9138998bf11 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<FILE, int(*)(FILE*)> __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 bcd74a9ee597..865a28123b97 100644 --- a/include/functional +++ b/include/functional @@ -440,6 +440,13 @@ public: template <typename T> const T* target() const noexcept; }; +// Deduction guides +template<class R, class ...Args> +function(R(*)(Args...)) -> function<R(Args...)>; // since C++17 + +template<class F> +function(F) -> function<see-below>; // since C++17 + // Null pointer comparisons: template <class R, class ... ArgTypes> bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; @@ -2335,6 +2342,53 @@ public: #endif // _LIBCPP_NO_RTTI }; +#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES +template<class _Rp, class ..._Ap> +function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; + +template<class _Fp> +struct __strip_signature; + +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile> { using type = _Rp(_Ap...); }; + +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) &> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const &> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile &> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile &> { using type = _Rp(_Ap...); }; + +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) noexcept> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const noexcept> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile noexcept> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile noexcept> { using type = _Rp(_Ap...); }; + +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) & noexcept> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const & noexcept> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; +template<class _Rp, class _Gp, class ..._Ap> +struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; + +template<class _Fp, class _Stripped = typename __strip_signature<decltype(&_Fp::operator())>::type> +function(_Fp) -> function<_Stripped>; +#endif // !_LIBCPP_HAS_NO_DEDUCTION_GUIDES + template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} diff --git a/include/istream b/include/istream index d6217bbb8009..bfbe5f24728e 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 eb6ae57b011f..b6f89bf5ee54 100644 --- a/include/map +++ b/include/map @@ -1474,26 +1474,26 @@ private: #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>, class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf<!__is_allocator<_Compare>::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 _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>, class _Allocator = allocator<pair<const _Key, _Tp>>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf<!__is_allocator<_Compare>::value, void>, + class = _EnableIf<__is_allocator<_Allocator>::value, void>> map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator()) -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>; template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::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<class _Key, class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> map(initializer_list<pair<_Key, _Tp>>, _Allocator) -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>; #endif @@ -2131,26 +2131,26 @@ private: #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>, class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf<!__is_allocator<_Compare>::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 _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>, class _Allocator = allocator<pair<const _Key, _Tp>>, - class = enable_if_t<!__is_allocator<_Compare>::value, void>, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf<!__is_allocator<_Compare>::value, void>, + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator()) -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>; template<class _InputIterator, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::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<class _Key, class _Tp, class _Allocator, - class = enable_if_t<__is_allocator<_Allocator>::value, void>> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>; #endif diff --git a/include/memory b/include/memory index d9222b3ada7e..96bb8fb5ccbb 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 <tuple> #include <stdexcept> #include <cstring> -#include <cassert> #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include <atomic> #endif @@ -1507,6 +1506,31 @@ struct __is_default_allocator : false_type {}; template <class _Tp> struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {}; + + +template <class _Alloc, + bool = __has_construct<_Alloc, typename _Alloc::value_type*, typename _Alloc::value_type&&>::value && !__is_default_allocator<_Alloc>::value + > +struct __is_cpp17_move_insertable; +template <class _Alloc> +struct __is_cpp17_move_insertable<_Alloc, true> : std::true_type {}; +template <class _Alloc> +struct __is_cpp17_move_insertable<_Alloc, false> : std::is_move_constructible<typename _Alloc::value_type> {}; + +template <class _Alloc, + bool = __has_construct<_Alloc, typename _Alloc::value_type*, const typename _Alloc::value_type&>::value && !__is_default_allocator<_Alloc>::value + > +struct __is_cpp17_copy_insertable; +template <class _Alloc> +struct __is_cpp17_copy_insertable<_Alloc, true> : __is_cpp17_move_insertable<_Alloc> {}; +template <class _Alloc> +struct __is_cpp17_copy_insertable<_Alloc, false> : integral_constant<bool, + std::is_copy_constructible<typename _Alloc::value_type>::value && + __is_cpp17_move_insertable<_Alloc>::value> + {}; + + + template <class _Alloc> 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<allocator_type>::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 <class _Tp> @@ -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<allocator_type>::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<class ..._Args> - static - shared_ptr<_Tp> - make_shared(_Args&& ...__args); + template<class _Yp, class _CntrlBlk> + 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<class _Alloc, class ..._Args> static shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args); -#else // _LIBCPP_HAS_NO_VARIADICS - - static shared_ptr<_Tp> make_shared(); - - template<class _A0> - static shared_ptr<_Tp> make_shared(_A0&); - - template<class _A0, class _A1> - static shared_ptr<_Tp> make_shared(_A0&, _A1&); - - template<class _A0, class _A1, class _A2> - static shared_ptr<_Tp> make_shared(_A0&, _A1&, _A2&); - - template<class _Alloc> - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a); - - template<class _Alloc, class _A0> - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a, _A0& __a0); - - template<class _Alloc, class _A0, class _A1> - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1); - - template<class _Alloc, class _A0, class _A1, class _A2> - static shared_ptr<_Tp> - allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2); - -#endif // _LIBCPP_HAS_NO_VARIADICS - private: template <class _Yp, bool = is_function<_Yp>::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<class _Tp> -template<class ..._Args> -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<class _Tp> template<class _Alloc, class ..._Args> 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<class _Tp> -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<class _Tp> -template<class _A0> -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<class _Tp> -template<class _A0, class _A1> -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<class _Tp> -template<class _A0, class _A1, class _A2> -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<class _Tp> -template<class _Alloc> -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<void*>(_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<class _Tp> -template<class _Alloc, class _A0> -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<void*>(_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<class _Tp> -template<class _Alloc, class _A0, class _A1> -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<void*>(_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<class _Tp> -template<class _Alloc, class _A0, class _A1, class _A2> -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<void*>(_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<class _Tp> 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<class _Tp, class ..._Args> 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<class _Tp, class _Alloc, class ..._Args> @@ -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<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared() -{ - return shared_ptr<_Tp>::make_shared(); -} - -template<class _Tp, class _A0> -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared(_A0& __a0) -{ - return shared_ptr<_Tp>::make_shared(__a0); -} - -template<class _Tp, class _A0, class _A1> -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -make_shared(_A0& __a0, _A1& __a1) -{ - return shared_ptr<_Tp>::make_shared(__a0, __a1); -} - -template<class _Tp, class _A0, class _A1, class _A2> -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<class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -allocate_shared(const _Alloc& __a) -{ - return shared_ptr<_Tp>::allocate_shared(__a); -} - -template<class _Tp, class _Alloc, class _A0> -inline _LIBCPP_INLINE_VISIBILITY -shared_ptr<_Tp> -allocate_shared(const _Alloc& __a, _A0& __a0) -{ - return shared_ptr<_Tp>::allocate_shared(__a, __a0); -} - -template<class _Tp, class _Alloc, class _A0, class _A1> -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<class _Tp, class _Alloc, class _A0, class _A1, class _A2> -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<class _Tp, class _Up> 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 bbfe90ed57f5..31d39ddf7c8a 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 20c3ffc38b63..8fc3c61221b5 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<mutex> lk(__m_); - if (__libcpp_thread_id_equal(__id, __id_)) + if (__id == __id_) { if (__count_ == numeric_limits<size_t>::max()) return false; diff --git a/include/new b/include/new index 85e4c4b3fcf2..40d351e9b770 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 2118704d57f3..854bbfad65ac 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 e6cf9c970f72..ea3870532f32 100644 --- a/include/ostream +++ b/include/ostream @@ -1055,7 +1055,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, template<class _CharT, class _Traits> 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 9fefee081702..afa60b4af048 100644 --- a/include/random +++ b/include/random @@ -3645,7 +3645,7 @@ generate_canonical(_URNG& __g) const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::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 26efac1c620d..d13f9addb70a 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 <class string_traits, class A> basic_regex& assign(const basic_string<charT, string_traits, A>& s, - flag_type f = regex_constants::ECMAScript); + flag_type f = regex_constants::ECMAScript); template <class InputIterator> basic_regex& assign(InputIterator first, InputIterator last, - flag_type f = regex_constants::ECMAScript); - basic_regex& assign(initializer_list<charT>, flag_type = regex_constants::ECMAScript); + flag_type f = regex_constants::ECMAScript); + basic_regex& assign(initializer_list<charT>, 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 <class _ST, class _SA> _LIBCPP_INLINE_VISIBILITY diff --git a/include/set b/include/set index 70ab4d37add2..ac3fbbe02fc3 100644 --- a/include/set +++ b/include/set @@ -852,26 +852,26 @@ public: template<class _InputIterator, class _Compare = less<typename iterator_traits<_InputIterator>::value_type>, class _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if<!__is_allocator<_Compare>::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf<!__is_allocator<_Compare>::value, void>> set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> set<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>; template<class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if<!__is_allocator<_Compare>::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf<!__is_allocator<_Compare>::value, void>> set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> set<_Key, _Compare, _Allocator>; template<class _InputIterator, class _Allocator, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> set(_InputIterator, _InputIterator, _Allocator) -> set<typename iterator_traits<_InputIterator>::value_type, less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<class _Key, class _Allocator, - class = typename enable_if<__is_allocator<_Allocator>::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<class _InputIterator, class _Compare = less<typename iterator_traits<_InputIterator>::value_type>, class _Allocator = allocator<typename iterator_traits<_InputIterator>::value_type>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if<!__is_allocator<_Compare>::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf<!__is_allocator<_Compare>::value, void>> multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) -> multiset<typename iterator_traits<_InputIterator>::value_type, _Compare, _Allocator>; template<class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key>, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type, - class = typename enable_if<!__is_allocator<_Compare>::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>, + class = _EnableIf<!__is_allocator<_Compare>::value, void>> multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) -> multiset<_Key, _Compare, _Allocator>; template<class _InputIterator, class _Allocator, - class = typename enable_if<__is_allocator<_Allocator>::value, void>::type> + class = _EnableIf<__is_allocator<_Allocator>::value, void>> multiset(_InputIterator, _InputIterator, _Allocator) -> multiset<typename iterator_traits<_InputIterator>::value_type, less<typename iterator_traits<_InputIterator>::value_type>, _Allocator>; template<class _Key, class _Allocator, - class = typename enable_if<__is_allocator<_Allocator>::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 1e5b09800c61..3368fb8bfcd5 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 <class = typename enable_if<__is_allocator<_Allocator>::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 <class = typename enable_if<__is_allocator<_Allocator>::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 <class = typename enable_if<__is_allocator<_Allocator>::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 <class _CharT, class _Traits, class _Allocator> -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template <class> -#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 <class _CharT, class _Traits, class _Allocator> -#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES template <class> -#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 04448312ff33..8a684a8f966c 100644 --- a/include/string_view +++ b/include/string_view @@ -173,6 +173,7 @@ namespace std { #include <__config> #include <__string> +#include <iosfwd> #include <algorithm> #include <iterator> #include <limits> @@ -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<basic_string_view<_CharT, _Traits> >::type return __lhs.compare(__rhs) >= 0; } + +template<class _CharT, class _Traits> +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + basic_string_view<_CharT, _Traits> __str); + typedef basic_string_view<char> string_view; #ifndef _LIBCPP_NO_HAS_CHAR8_T typedef basic_string_view<char8_t> u8string_view; diff --git a/include/thread b/include/thread index 3d8d2ac9ce50..02da703c3ccf 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<Rep, Period>& rel_time); _LIBCPP_PUSH_MACROS #include <__undef_macros> -#define __STDCPP_THREADS__ __cplusplus - #ifdef _LIBCPP_HAS_NO_THREADS #error <thread> 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<class _CharT, class _Traits> - 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<class _CharT, class _Traits> +_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 031d25a9854f..e93824f0aa7f 100644 --- a/include/tuple +++ b/include/tuple @@ -19,40 +19,40 @@ namespace std template <class... T> 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 <class... U> - explicit tuple(U&&...); // constexpr in C++14 + explicit(see-below) tuple(U&&...); // constexpr in C++14 tuple(const tuple&) = default; tuple(tuple&&) = default; template <class... U> - tuple(const tuple<U...>&); // constexpr in C++14 + explicit(see-below) tuple(const tuple<U...>&); // constexpr in C++14 template <class... U> - tuple(tuple<U...>&&); // constexpr in C++14 + explicit(see-below) tuple(tuple<U...>&&); // constexpr in C++14 template <class U1, class U2> - tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14 + explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14 template <class U1, class U2> - tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14 + explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++14 // allocator-extended constructors template <class Alloc> tuple(allocator_arg_t, const Alloc& a); template <class Alloc> - tuple(allocator_arg_t, const Alloc& a, const T&...); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); template <class Alloc, class... U> - tuple(allocator_arg_t, const Alloc& a, U&&...); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, const tuple&); template <class Alloc> tuple(allocator_arg_t, const Alloc& a, tuple&&); template <class Alloc, class... U> - tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); template <class Alloc, class... U> - tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); template <class Alloc, class U1, class U2> - tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); template <class Alloc, class U1, class U2> - tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); + explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); tuple& operator=(const tuple&); tuple& @@ -69,6 +69,17 @@ public: void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); }; +template <class ...T> +tuple(T...) -> tuple<T...>; // since C++17 +template <class T1, class T2> +tuple(pair<T1, T2>) -> tuple<T1, T2>; // since C++17 +template <class Alloc, class ...T> +tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>; // since C++17 +template <class Alloc, class T1, class T2> +tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++17 +template <class Alloc, class ...T> +tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17 + inline constexpr unspecified ignore; template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 @@ -488,11 +499,19 @@ class _LIBCPP_TEMPLATE_VIS tuple template <class _Dummy> struct _CheckArgsConstructor<true, _Dummy> { - template <class ..._Args> - static constexpr bool __enable_default() { - return __all<is_default_constructible<_Args>::value...>::value; + template <int&...> + static constexpr bool __enable_implicit_default() { + return __all<__is_implicitly_default_constructible<_Tp>::value... >::value; + } + + template <int&...> + static constexpr bool __enable_explicit_default() { + return + __all<is_default_constructible<_Tp>::value...>::value && + !__enable_implicit_default< >(); } + template <class ..._Args> 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 <bool _Dummy = true, class = typename enable_if< - _CheckArgsConstructor<_Dummy>::template __enable_default<_Tp...>() - >::type> - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR tuple() + template <bool _Dummy = true, _EnableIf< + _CheckArgsConstructor<_Dummy>::__enable_implicit_default() + , void*> = nullptr> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + tuple() + _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} + + template <bool _Dummy = true, _EnableIf< + _CheckArgsConstructor<_Dummy>::__enable_explicit_default() + , void*> = nullptr> + explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + tuple() _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} tuple(tuple const&) = default; tuple(tuple&&) = default; - template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = _EnableIf< - _And< - _IsSame<allocator_arg_t, _AllocArgT>, - __dependent_type<is_default_constructible<_Tp>, _Dummy>... - >::value - > + template <class _AllocArgT, class _Alloc, _EnableIf< + _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default() + , void*> = nullptr > _LIBCPP_INLINE_VISIBILITY tuple(_AllocArgT, _Alloc const& __a) @@ -654,6 +677,17 @@ public: typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), __tuple_types<_Tp...>()) {} + template <class _AllocArgT, class _Alloc, _EnableIf< + _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::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<sizeof...(_Tp), 0>::type(), + __tuple_types<_Tp...>()) {} + template <bool _Dummy = true, typename enable_if < @@ -943,13 +977,16 @@ public: }; #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES -// NOTE: These are not yet standardized, but are required to simulate the -// implicit deduction guide that should be generated had libc++ declared the -// tuple-like constructors "correctly" -template <class _Alloc, class ..._Args> -tuple(allocator_arg_t, const _Alloc&, tuple<_Args...> const&) -> tuple<_Args...>; -template <class _Alloc, class ..._Args> -tuple(allocator_arg_t, const _Alloc&, tuple<_Args...>&&) -> tuple<_Args...>; +template <class ..._Tp> +tuple(_Tp...) -> tuple<_Tp...>; +template <class _Tp1, class _Tp2> +tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; +template <class _Alloc, class ..._Tp> +tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>; +template <class _Alloc, class _Tp1, class _Tp2> +tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>; +template <class _Alloc, class ..._Tp> +tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>; #endif template <class ..._Tp> diff --git a/include/type_traits b/include/type_traits index 5ccafec01f0b..77b57a41e418 100644 --- a/include/type_traits +++ b/include/type_traits @@ -509,8 +509,8 @@ struct _Lazy : _Func<_Args...> {}; // Member detector base -template <template <class...> class _Templ, class ..._Args> -true_type __sfinae_test_impl(_FirstType<int, _Templ<_Args...> >); +template <template <class...> class _Templ, class ..._Args, class = _Templ<_Args...> > +true_type __sfinae_test_impl(int); template <template <class...> class, class ...> false_type __sfinae_test_impl(...); @@ -886,28 +886,15 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_class_v // is_function -namespace __libcpp_is_function_imp -{ -struct __dummy_type {}; -template <class _Tp> char __test(_Tp*); -template <class _Tp> char __test(__dummy_type); -template <class _Tp> __two __test(...); -template <class _Tp> _Tp& __source(int); -template <class _Tp> __dummy_type __source(...); -} - -template <class _Tp, bool = is_class<_Tp>::value || - is_union<_Tp>::value || - is_void<_Tp>::value || - is_reference<_Tp>::value || - __is_nullptr_t<_Tp>::value > -struct __libcpp_is_function - : public integral_constant<bool, sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1> - {}; -template <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {}; - template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_function - : public __libcpp_is_function<_Tp> {}; + : public _BoolConstant< +#ifdef __clang__ + __is_function(_Tp) +#else + !(is_reference<_Tp>::value || is_const<const _Tp>::value) +#endif + > {}; + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> @@ -915,27 +902,24 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_function_v = is_function<_Tp>::value; #endif -// is_member_function_pointer - -// template <class _Tp> struct __libcpp_is_member_function_pointer : public false_type {}; -// template <class _Tp, class _Up> struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {}; -// - -template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> -struct __member_pointer_traits_imp -{ // forward declaration; specializations later +template <class _Tp> struct __libcpp_is_member_pointer { + enum { + __is_member = false, + __is_func = false, + __is_obj = false + }; +}; +template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> { + enum { + __is_member = true, + __is_func = is_function<_Tp>::value, + __is_obj = !__is_func, + }; }; -template <class _Tp> struct __libcpp_is_member_function_pointer - : public false_type {}; - -template <class _Ret, class _Class> -struct __libcpp_is_member_function_pointer<_Ret _Class::*> - : public is_function<_Ret> {}; - template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer - : public __libcpp_is_member_function_pointer<typename remove_cv<_Tp>::type>::type {}; + : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> @@ -945,11 +929,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v // is_member_pointer -template <class _Tp> struct __libcpp_is_member_pointer : public false_type {}; -template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> : public true_type {}; - template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer - : public __libcpp_is_member_pointer<typename remove_cv<_Tp>::type> {}; + : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> @@ -960,8 +941,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v // is_member_object_pointer template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer - : public integral_constant<bool, is_member_pointer<_Tp>::value && - !is_member_function_pointer<_Tp>::value> {}; + : public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> @@ -1080,16 +1060,9 @@ struct __is_referenceable : integral_constant<bool, // add_const -template <class _Tp, bool = is_reference<_Tp>::value || - is_function<_Tp>::value || - is_const<_Tp>::value > -struct __add_const {typedef _LIBCPP_NODEBUG_TYPE _Tp type;}; - -template <class _Tp> -struct __add_const<_Tp, false> {typedef _LIBCPP_NODEBUG_TYPE const _Tp type;}; - -template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const - {typedef _LIBCPP_NODEBUG_TYPE typename __add_const<_Tp>::type type;}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const { + typedef _LIBCPP_NODEBUG_TYPE const _Tp type; +}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_const_t = typename add_const<_Tp>::type; @@ -1097,25 +1070,18 @@ template <class _Tp> using add_const_t = typename add_const<_Tp>::type; // add_volatile -template <class _Tp, bool = is_reference<_Tp>::value || - is_function<_Tp>::value || - is_volatile<_Tp>::value > -struct __add_volatile {typedef _Tp type;}; - -template <class _Tp> -struct __add_volatile<_Tp, false> {typedef volatile _Tp type;}; - -template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile - {typedef _LIBCPP_NODEBUG_TYPE typename __add_volatile<_Tp>::type type;}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile { + typedef _LIBCPP_NODEBUG_TYPE volatile _Tp type; +}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type; #endif // add_cv - -template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv - {typedef _LIBCPP_NODEBUG_TYPE typename add_const<typename add_volatile<_Tp>::type>::type type;}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv { + typedef _LIBCPP_NODEBUG_TYPE const volatile _Tp type; +}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type; @@ -1153,8 +1119,12 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_rvalue_reference template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; #endif +// Suppress deprecation notice for volatile-qualified return type resulting +// from volatile-qualified types _Tp. +_LIBCPP_SUPPRESS_DEPRECATED_PUSH template <class _Tp> _Tp&& __declval(int); template <class _Tp> _Tp __declval(long); +_LIBCPP_SUPPRESS_DEPRECATED_POP template <class _Tp> decltype(_VSTD::__declval<_Tp>(0)) @@ -2307,6 +2277,11 @@ __decay_copy(_Tp&& __t) return _VSTD::forward<_Tp>(__t); } +template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> +struct __member_pointer_traits_imp +{ +}; + template <class _Rp, class _Class, class ..._Param> struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> { @@ -2836,6 +2811,30 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_default_constructible_v = is_default_constructible<_Tp>::value; #endif +#ifndef _LIBCPP_CXX03_LANG +// First of all, we can't implement this check in C++03 mode because the {} +// default initialization syntax isn't valid. +// Second, we implement the trait in a funny manner with two defaulted template +// arguments to workaround Clang's PR43454. +template <class _Tp> +void __test_implicit_default_constructible(_Tp); + +template <class _Tp, class = void, bool = is_default_constructible<_Tp>::value> +struct __is_implicitly_default_constructible + : false_type +{ }; + +template <class _Tp> +struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), true> + : true_type +{ }; + +template <class _Tp> +struct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), false> + : false_type +{ }; +#endif // !C++03 + // is_copy_constructible template <class _Tp> @@ -3681,6 +3680,13 @@ _LIBCPP_INLINE_VAR constexpr bool is_nothrow_invocable_r_v template <class _Tp> struct __is_swappable; template <class _Tp> struct __is_nothrow_swappable; +// swap, swap_ranges + +template <class _ForwardIterator1, class _ForwardIterator2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); + template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_CXX03_LANG @@ -3706,7 +3712,22 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if< __is_swappable<_Tp>::value >::type -swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); +swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) +{ + _VSTD::swap_ranges(__a, __a + _Np, __b); +} + +template <class _ForwardIterator1, class _ForwardIterator2> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 +_ForwardIterator2 +swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) +{ + for(; __first1 != __last1; ++__first1, (void) ++__first2) + swap(*__first1, *__first2); + return __first2; +} + +// iter_swap template <class _ForwardIterator1, class _ForwardIterator2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 @@ -3985,21 +4006,6 @@ struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> #endif -#if _LIBCPP_STD_VER > 17 -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 - #ifndef _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED #if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY diff --git a/include/utility b/include/utility index 3961370dd833..7ac322bfe710 100644 --- a/include/utility +++ b/include/utility @@ -69,11 +69,11 @@ struct pair pair(const pair&) = default; pair(pair&&) = default; - constexpr pair(); - pair(const T1& x, const T2& y); // constexpr in C++14 - template <class U, class V> pair(U&& x, V&& y); // constexpr in C++14 - template <class U, class V> pair(const pair<U, V>& p); // constexpr in C++14 - template <class U, class V> pair(pair<U, V>&& p); // constexpr in C++14 + explicit(see-below) constexpr pair(); + explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14 + template <class U, class V> explicit(see-below) pair(U&& x, V&& y); // constexpr in C++14 + template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14 + template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14 template <class... Args1, class... Args2> pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args); @@ -99,7 +99,7 @@ template <class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); -struct piecewise_construct_t { }; +struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); template <class T> struct tuple_size; @@ -248,29 +248,11 @@ operator>=(const _Tp& __x, const _Tp& __y) } // rel_ops -// swap_ranges +// swap_ranges is defined in <type_traits>` +// swap is defined in <type_traits> -template <class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -_ForwardIterator2 -swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) -{ - for(; __first1 != __last1; ++__first1, (void) ++__first2) - swap(*__first1, *__first2); - return __first2; -} - -// forward declared in <type_traits> -template<class _Tp, size_t _Np> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 -typename enable_if< - __is_swappable<_Tp>::value ->::type -swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) -{ - _VSTD::swap_ranges(__a, __a + _Np, __b); -} +// move_if_noexcept template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -294,7 +276,7 @@ template <class _Tp> constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { r template <class _Tp> void as_const(const _Tp&&) = delete; #endif -struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { }; +struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; }; #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); #else @@ -352,10 +334,17 @@ struct _LIBCPP_TEMPLATE_VIS pair using _EnableB _LIBCPP_NODEBUG_TYPE = typename enable_if<_Val, bool>::type; struct _CheckArgs { - template <class _U1, class _U2> - static constexpr bool __enable_default() { - return is_default_constructible<_U1>::value - && is_default_constructible<_U2>::value; + template <int&...> + static constexpr bool __enable_explicit_default() { + return is_default_constructible<_T1>::value + && is_default_constructible<_T2>::value + && !__enable_implicit_default<>(); + } + + template <int&...> + static constexpr bool __enable_implicit_default() { + return __is_implicitly_default_constructible<_T1>::value + && __is_implicitly_default_constructible<_T2>::value; } template <class _U1, class _U2> @@ -406,7 +395,15 @@ struct _LIBCPP_TEMPLATE_VIS pair >::type; template<bool _Dummy = true, _EnableB< - _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() + _CheckArgsDep<_Dummy>::__enable_explicit_default() + > = false> + explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && + is_nothrow_default_constructible<second_type>::value) + : first(), second() {} + + template<bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::__enable_implicit_default() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && diff --git a/include/vector b/include/vector index 82bf6e0038d9..be4894a89e2f 100644 --- a/include/vector +++ b/include/vector @@ -297,7 +297,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template <bool> -class __vector_base_common +class _LIBCPP_TEMPLATE_VIS __vector_base_common { protected: _LIBCPP_INLINE_VISIBILITY __vector_base_common() {} @@ -864,58 +864,67 @@ private: #else _LIBCPP_INLINE_VISIBILITY void __annotate_contiguous_container(const void*, const void*, const void*, - const void*) const {} + const void*) const _NOEXCEPT {} #endif _LIBCPP_INLINE_VISIBILITY - void __annotate_new(size_type __current_size) const { + void __annotate_new(size_type __current_size) const _NOEXCEPT { __annotate_contiguous_container(data(), data() + capacity(), data() + capacity(), data() + __current_size); } _LIBCPP_INLINE_VISIBILITY - void __annotate_delete() const { + void __annotate_delete() const _NOEXCEPT { __annotate_contiguous_container(data(), data() + capacity(), data() + size(), data() + capacity()); } _LIBCPP_INLINE_VISIBILITY - void __annotate_increase(size_type __n) const + void __annotate_increase(size_type __n) const _NOEXCEPT { __annotate_contiguous_container(data(), data() + capacity(), data() + size(), data() + size() + __n); } _LIBCPP_INLINE_VISIBILITY - void __annotate_shrink(size_type __old_size) const + void __annotate_shrink(size_type __old_size) const _NOEXCEPT { __annotate_contiguous_container(data(), data() + capacity(), data() + __old_size, data() + size()); } + + struct _ConstructTransaction { + explicit _ConstructTransaction(vector &__v, size_type __n) + : __v_(__v), __pos_(__v.__end_), __new_end_(__v.__end_ + __n) { #ifndef _LIBCPP_HAS_NO_ASAN - // The annotation for size increase should happen before the actual increase, - // but if an exception is thrown after that the annotation has to be undone. - struct __RAII_IncreaseAnnotator { - __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1) - : __commit(false), __v(__v), __old_size(__v.size() + __n) { - __v.__annotate_increase(__n); - } - void __done() { __commit = true; } - ~__RAII_IncreaseAnnotator() { - if (__commit) return; - __v.__annotate_shrink(__old_size); + __v_.__annotate_increase(__n); +#endif + } + ~_ConstructTransaction() { + __v_.__end_ = __pos_; +#ifndef _LIBCPP_HAS_NO_ASAN + if (__pos_ != __new_end_) { + __v_.__annotate_shrink(__new_end_ - __v_.__begin_); } - bool __commit; - const vector &__v; - size_type __old_size; - }; -#else - struct __RAII_IncreaseAnnotator { - _LIBCPP_INLINE_VISIBILITY - __RAII_IncreaseAnnotator(const vector &, size_type = 1) {} - _LIBCPP_INLINE_VISIBILITY void __done() {} - }; #endif + } + vector &__v_; + pointer __pos_; + const_pointer const __new_end_; + + private: + _ConstructTransaction(_ConstructTransaction const&) = delete; + _ConstructTransaction& operator=(_ConstructTransaction const&) = delete; + }; + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + void __construct_one_at_end(_Args&& ...__args) { + _ConstructTransaction __tx(*this, 1); + __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_), + _VSTD::forward<_Args>(__args)...); + ++__tx.__pos_; + } }; #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES @@ -938,8 +947,10 @@ template <class _Tp, class _Allocator> void vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v) { + __annotate_delete(); - __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, this->__end_, __v.__begin_); + __alloc_traits::__construct_backward_with_exception_guarantees( + this->__alloc(), this->__begin_, this->__end_, __v.__begin_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -954,8 +965,10 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a { __annotate_delete(); pointer __r = __v.__begin_; - __alloc_traits::__construct_backward(this->__alloc(), this->__begin_, __p, __v.__begin_); - __alloc_traits::__construct_forward(this->__alloc(), __p, this->__end_, __v.__end_); + __alloc_traits::__construct_backward_with_exception_guarantees( + this->__alloc(), this->__begin_, __p, __v.__begin_); + __alloc_traits::__construct_forward_with_exception_guarantees( + this->__alloc(), __p, this->__end_, __v.__end_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -1027,15 +1040,10 @@ template <class _Tp, class _Allocator> void vector<_Tp, _Allocator>::__construct_at_end(size_type __n) { - allocator_type& __a = this->__alloc(); - do - { - __RAII_IncreaseAnnotator __annotator(*this); - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); - ++this->__end_; - --__n; - __annotator.__done(); - } while (__n > 0); + _ConstructTransaction __tx(*this, __n); + for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_)); + } } // Copy constructs __n objects starting at __end_ from __x @@ -1049,15 +1057,10 @@ inline void vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) { - allocator_type& __a = this->__alloc(); - do - { - __RAII_IncreaseAnnotator __annotator(*this); - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); - ++this->__end_; - --__n; - __annotator.__done(); - } while (__n > 0); + _ConstructTransaction __tx(*this, __n); + for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), _VSTD::__to_raw_pointer(__tx.__pos_), __x); + } } template <class _Tp, class _Allocator> @@ -1069,10 +1072,8 @@ typename enable_if >::type vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n) { - allocator_type& __a = this->__alloc(); - __RAII_IncreaseAnnotator __annotator(*this, __n); - __alloc_traits::__construct_range_forward(__a, __first, __last, this->__end_); - __annotator.__done(); + _ConstructTransaction __tx(*this, __n); + __alloc_traits::__construct_range_forward(this->__alloc(), __first, __last, __tx.__pos_); } // Default constructs __n objects starting at __end_ @@ -1633,11 +1634,7 @@ vector<_Tp, _Allocator>::push_back(const_reference __x) { if (this->__end_ != this->__end_cap()) { - __RAII_IncreaseAnnotator __annotator(*this); - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), __x); - __annotator.__done(); - ++this->__end_; + __construct_one_at_end(__x); } else __push_back_slow_path(__x); @@ -1652,12 +1649,7 @@ vector<_Tp, _Allocator>::push_back(value_type&& __x) { if (this->__end_ < this->__end_cap()) { - __RAII_IncreaseAnnotator __annotator(*this); - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), - _VSTD::move(__x)); - __annotator.__done(); - ++this->__end_; + __construct_one_at_end(_VSTD::move(__x)); } else __push_back_slow_path(_VSTD::move(__x)); @@ -1688,12 +1680,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) { if (this->__end_ < this->__end_cap()) { - __RAII_IncreaseAnnotator __annotator(*this); - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), - _VSTD::forward<_Args>(__args)...); - __annotator.__done(); - ++this->__end_; + __construct_one_at_end(_VSTD::forward<_Args>(__args)...); } else __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...); @@ -1761,10 +1748,15 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe { pointer __old_last = this->__end_; difference_type __n = __old_last - __to; - for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_) - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), - _VSTD::move(*__i)); + { + pointer __i = __from_s + __n; + _ConstructTransaction __tx(*this, __from_e - __i); + for (; __i < __from_e; ++__i, ++__tx.__pos_) { + __alloc_traits::construct(this->__alloc(), + _VSTD::__to_raw_pointer(__tx.__pos_), + _VSTD::move(*__i)); + } + } _VSTD::move_backward(__from_s, __from_s + __n, __old_last); } @@ -1780,12 +1772,9 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { - __RAII_IncreaseAnnotator __annotator(*this); if (__p == this->__end_) { - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), __x); - ++this->__end_; + __construct_one_at_end(__x); } else { @@ -1795,7 +1784,6 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) ++__xr; *__p = *__xr; } - __annotator.__done(); } else { @@ -1821,20 +1809,15 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { - __RAII_IncreaseAnnotator __annotator(*this); if (__p == this->__end_) { - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), - _VSTD::move(__x)); - ++this->__end_; + __construct_one_at_end(_VSTD::move(__x)); } else { __move_range(__p, this->__end_, __p + 1); *__p = _VSTD::move(__x); } - __annotator.__done(); } else { @@ -1859,13 +1842,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { - __RAII_IncreaseAnnotator __annotator(*this); if (__p == this->__end_) { - __alloc_traits::construct(this->__alloc(), - _VSTD::__to_raw_pointer(this->__end_), - _VSTD::forward<_Args>(__args)...); - ++this->__end_; + __construct_one_at_end(_VSTD::forward<_Args>(__args)...); } else { @@ -1873,7 +1852,6 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) __move_range(__p, this->__end_, __p + 1); *__p = _VSTD::move(__tmp.get()); } - __annotator.__done(); } else { @@ -1911,9 +1889,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_ } if (__n > 0) { - __RAII_IncreaseAnnotator __annotator(*this, __n); __move_range(__p, __old_last, __p + __old_n); - __annotator.__done(); const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x); if (__p <= __xr && __xr < this->__end_) __xr += __old_n; @@ -1955,11 +1931,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs pointer __old_last = this->__end_; for (; this->__end_ != this->__end_cap() && __first != __last; ++__first) { - __RAII_IncreaseAnnotator __annotator(*this); - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), - *__first); - ++this->__end_; - __annotator.__done(); + __construct_one_at_end(*__first); } __split_buffer<value_type, allocator_type&> __v(__a); if (__first != __last) @@ -2026,9 +1998,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi } if (__n > 0) { - __RAII_IncreaseAnnotator __annotator(*this, __n); __move_range(__p, __old_last, __p + __old_n); - __annotator.__done(); _VSTD::copy(__first, __m, __p); } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31cd24333a5e..120505fe18da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -137,90 +137,17 @@ if (APPLE AND LLVM_USE_SANITIZER) endif() endif() -function(cxx_link_system_libraries target) - target_add_link_flags_if_supported(${target} PRIVATE "-nodefaultlibs") - target_add_compile_flags_if_supported(${target} PRIVATE "/Zl") - target_add_link_flags_if_supported(${target} PRIVATE "/nodefaultlib") - - if (LIBCXX_HAS_SYSTEM_LIB) - target_link_libraries(${target} PUBLIC System) - endif() - - if (LIBCXX_HAS_PTHREAD_LIB) - target_link_libraries(${target} PUBLIC pthread) - endif() - - if (LIBCXX_HAS_C_LIB) - target_link_libraries(${target} PUBLIC c) - endif() - - if (LIBCXX_HAS_M_LIB) - target_link_libraries(${target} PUBLIC m) - endif() - - if (LIBCXX_HAS_RT_LIB) - target_link_libraries(${target} PUBLIC rt) - endif() - - if (LIBCXX_USE_COMPILER_RT) - find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY) - if (LIBCXX_BUILTINS_LIBRARY) - target_link_libraries(${target} PUBLIC "${LIBCXX_BUILTINS_LIBRARY}") - endif() - elseif (LIBCXX_HAS_GCC_S_LIB) - target_link_libraries(${target} PUBLIC gcc_s) - endif() - - if (LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB) - target_link_libraries(${target} PUBLIC atomic) - endif() - - if (MINGW) - target_link_libraries(${target} PUBLIC "${MINGW_LIBRARIES}") - endif() - - if (LIBCXX_TARGETING_MSVC) - if (LIBCXX_DEBUG_BUILD) - set(LIB_SUFFIX "d") - else() - set(LIB_SUFFIX "") - endif() - - target_link_libraries(${target} PUBLIC ucrt${LIB_SUFFIX}) # Universal C runtime - target_link_libraries(${target} PUBLIC vcruntime${LIB_SUFFIX}) # C++ runtime - target_link_libraries(${target} PUBLIC msvcrt${LIB_SUFFIX}) # C runtime startup files - target_link_libraries(${target} PUBLIC msvcprt${LIB_SUFFIX}) # C++ standard library. Required for exception_ptr internals. - # Required for standards-complaint wide character formatting functions - # (e.g. `printfw`/`scanfw`) - target_link_libraries(${target} PUBLIC iso_stdio_wide_specifiers) - endif() -endfunction() +if (LIBCXX_ENABLE_PARALLEL_ALGORITHMS AND NOT TARGET pstl::ParallelSTL) + message(FATAL_ERROR "Could not find ParallelSTL") +endif() function(cxx_set_common_defines name) if(LIBCXX_CXX_ABI_HEADER_TARGET) add_dependencies(${name} ${LIBCXX_CXX_ABI_HEADER_TARGET}) endif() - if(WIN32 AND NOT MINGW) - target_compile_definitions(${name} - PRIVATE - # Ignore the -MSC_VER mismatch, as we may build - # with a different compatibility version. - _ALLOW_MSC_VER_MISMATCH - # Don't check the msvcprt iterator debug levels - # as we will define the iterator types; libc++ - # uses a different macro to identify the debug - # level. - _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH - # We are building the c++ runtime, don't pull in - # msvcprt. - _CRTBLD - # Don't warn on the use of "deprecated" - # "insecure" functions which are standards - # specified. - _CRT_SECURE_NO_WARNINGS - # Use the ISO conforming behaviour for conversion - # in printf, scanf. - _CRT_STDIO_ISO_WIDE_SPECIFIERS) + + if (LIBCXX_ENABLE_PARALLEL_ALGORITHMS) + target_link_libraries(${name} PUBLIC pstl::ParallelSTL) endif() endfunction() @@ -233,7 +160,6 @@ if (LIBCXX_ENABLE_SHARED) if(COMMAND llvm_setup_rpath) llvm_setup_rpath(cxx_shared) endif() - cxx_link_system_libraries(cxx_shared) target_link_libraries(cxx_shared PRIVATE ${LIBCXX_LIBRARIES}) set_target_properties(cxx_shared PROPERTIES @@ -244,18 +170,17 @@ if (LIBCXX_ENABLE_SHARED) SOVERSION "${LIBCXX_ABI_VERSION}" DEFINE_SYMBOL "" ) + cxx_add_common_build_flags(cxx_shared) cxx_set_common_defines(cxx_shared) # Link against LLVM libunwind if (LIBCXXABI_USE_LLVM_UNWINDER) if (NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY AND (TARGET unwind_shared OR HAVE_LIBUNWIND)) target_link_libraries(cxx_shared PUBLIC unwind_shared) - list(APPEND LIBCXX_INTERFACE_LIBRARIES unwind_shared) # For the linker script elseif (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY AND (TARGET unwind_static OR HAVE_LIBUNWIND)) # libunwind is already included in libc++abi else() - target_link_libraries(cxx_shared PRIVATE unwind) - list(APPEND LIBCXX_INTERFACE_LIBRARIES unwind) # For the linker script + target_link_libraries(cxx_shared PUBLIC unwind) endif() endif() @@ -268,7 +193,6 @@ if (LIBCXX_ENABLE_SHARED) endif() else() target_link_libraries(cxx_shared PUBLIC "${LIBCXX_CXX_SHARED_ABI_LIBRARY}") - list(APPEND LIBCXX_INTERFACE_LIBRARIES "${LIBCXX_CXX_SHARED_ABI_LIBRARY}") # For the linker script endif() # Maybe re-export symbols from libc++abi @@ -295,31 +219,10 @@ if (LIBCXX_ENABLE_SHARED) endif() endif() - # Generate a linker script in place of a libc++.so symlink. Rerun this command - # after cxx builds. + # Generate a linker script in place of a libc++.so symlink. if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) - # Get the name of the ABI library and handle the case where CXXABI_LIBNAME - # is a target name and not a library. Ex cxxabi_shared. - set(LIBCXX_INTERFACE_LIBRARY_NAMES) - foreach(lib ${LIBCXX_INTERFACE_LIBRARIES}) - # FIXME: Handle cxxabi_static and unwind_static. - if (TARGET ${lib} OR - (${lib} MATCHES "cxxabi(_static|_shared)?" AND HAVE_LIBCXXABI) OR - (${lib} MATCHES "unwind(_static|_shared)?" AND HAVE_LIBUNWIND)) - list(APPEND LIBCXX_INTERFACE_LIBRARY_NAMES "$<TARGET_PROPERTY:${lib},OUTPUT_NAME>") - else() - list(APPEND LIBCXX_INTERFACE_LIBRARY_NAMES "${lib}") - endif() - endforeach() - add_custom_command(TARGET cxx_shared POST_BUILD - COMMAND - ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/gen_link_script.py - ARGS - --input "$<TARGET_SONAME_FILE:cxx_shared>" - --output "$<TARGET_LINKER_FILE:cxx_shared>" - ${LIBCXX_INTERFACE_LIBRARY_NAMES} - WORKING_DIRECTORY ${LIBCXX_BUILD_DIR} - ) + include(DefineLinkerScript) + define_linker_script(cxx_shared) endif() list(APPEND LIBCXX_BUILD_TARGETS "cxx_shared") @@ -335,7 +238,6 @@ endif() # Build the static library. if (LIBCXX_ENABLE_STATIC) add_library(cxx_static STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) - cxx_link_system_libraries(cxx_static) target_link_libraries(cxx_static PRIVATE ${LIBCXX_LIBRARIES}) set(CMAKE_STATIC_LIBRARY_PREFIX "lib") set_target_properties(cxx_static @@ -344,10 +246,10 @@ if (LIBCXX_ENABLE_STATIC) LINK_FLAGS "${LIBCXX_LINK_FLAGS}" OUTPUT_NAME "c++" ) + cxx_add_common_build_flags(cxx_static) cxx_set_common_defines(cxx_static) if (LIBCXX_HERMETIC_STATIC_LIBRARY) - append_flags_if_supported(CXX_STATIC_LIBRARY_FLAGS -fvisibility=hidden) # If the hermetic library doesn't define the operator new/delete functions # then its code shouldn't declare them with hidden visibility. They might # actually be provided by a shared library at link time. @@ -398,23 +300,25 @@ if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) ) add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES}) if (LIBCXX_ENABLE_SHARED) - target_link_libraries(cxx_experimental cxx_shared) + target_link_libraries(cxx_experimental PRIVATE cxx_shared) else() - target_link_libraries(cxx_experimental cxx_static) + target_link_libraries(cxx_experimental PRIVATE cxx_static) endif() - set(experimental_flags "${LIBCXX_COMPILE_FLAGS}") - check_flag_supported(-std=c++14) - if (NOT MSVC AND LIBCXX_SUPPORTS_STD_EQ_CXX14_FLAG) - string(REPLACE "-std=c++11" "-std=c++14" experimental_flags "${LIBCXX_COMPILE_FLAGS}") - endif() set_target_properties(cxx_experimental PROPERTIES - COMPILE_FLAGS "${experimental_flags}" + COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" OUTPUT_NAME "c++experimental" ) + cxx_add_common_build_flags(cxx_experimental) + # Overwrite the previously-set Standard flag with -std=c++14 if supported + check_flag_supported(-std=c++14) + if (NOT MSVC AND LIBCXX_SUPPORTS_STD_EQ_CXX14_FLAG) + target_compile_options(cxx_experimental PRIVATE "-std=c++14") + endif() endif() + if (LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY) file(GLOB LIBCXX_EXTERNAL_THREADING_SUPPORT_SOURCES ../test/support/external_threads.cpp) diff --git a/src/algorithm.cpp b/src/algorithm.cpp index a110ae8b1a6e..ffdcb5fccde7 100644 --- a/src/algorithm.cpp +++ b/src/algorithm.cpp @@ -10,7 +10,7 @@ #include "random" #ifndef _LIBCPP_HAS_NO_THREADS #include "mutex" -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif #endif diff --git a/src/chrono.cpp b/src/chrono.cpp index 8f533f1059ed..c461d19ddb1f 100644 --- a/src/chrono.cpp +++ b/src/chrono.cpp @@ -37,7 +37,7 @@ #endif #endif -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "rt") #endif diff --git a/src/condition_variable.cpp b/src/condition_variable.cpp index b8426c66fde6..bf89d255dd82 100644 --- a/src/condition_variable.cpp +++ b/src/condition_variable.cpp @@ -15,7 +15,7 @@ #include "system_error" #include "__undef_macros" -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif diff --git a/src/debug.cpp b/src/debug.cpp index c4cc281d586b..1f5ce1052f87 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -15,7 +15,7 @@ #include "__hash_table" #ifndef _LIBCPP_HAS_NO_THREADS #include "mutex" -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif #endif diff --git a/src/experimental/memory_resource.cpp b/src/experimental/memory_resource.cpp index 9aa077942b0d..e98726283173 100644 --- a/src/experimental/memory_resource.cpp +++ b/src/experimental/memory_resource.cpp @@ -12,7 +12,7 @@ #include "atomic" #elif !defined(_LIBCPP_HAS_NO_THREADS) #include "mutex" -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif #endif @@ -116,11 +116,11 @@ __default_memory_resource(bool set = false, memory_resource * new_res = nullptr) new_res = new_res ? new_res : new_delete_resource(); // TODO: Can a weaker ordering be used? return _VSTD::atomic_exchange_explicit( - &__res, new_res, memory_order::memory_order_acq_rel); + &__res, new_res, memory_order_acq_rel); } else { return _VSTD::atomic_load_explicit( - &__res, memory_order::memory_order_acquire); + &__res, memory_order_acquire); } #elif !defined(_LIBCPP_HAS_NO_THREADS) _LIBCPP_SAFE_STATIC static memory_resource * res = &res_init.resources.new_delete_res; diff --git a/src/filesystem/directory_iterator.cpp b/src/filesystem/directory_iterator.cpp index ca88dee06402..e8941b3494b3 100644 --- a/src/filesystem/directory_iterator.cpp +++ b/src/filesystem/directory_iterator.cpp @@ -10,7 +10,7 @@ #include "__config" #if defined(_LIBCPP_WIN32API) #define WIN32_LEAN_AND_MEAN -#include <Windows.h> +#include <windows.h> #else #include <dirent.h> #endif @@ -79,14 +79,14 @@ static file_type get_file_type(const WIN32_FIND_DATA& data) { return file_type::unknown; } static uintmax_t get_file_size(const WIN32_FIND_DATA& data) { - return (data.nFileSizeHight * (MAXDWORD + 1)) + data.nFileSizeLow; + return (data.nFileSizeHigh * (MAXDWORD + 1)) + data.nFileSizeLow; } static file_time_type get_write_time(const WIN32_FIND_DATA& data) { ULARGE_INTEGER tmp; - FILETIME& time = data.ftLastWriteTime; + const FILETIME& time = data.ftLastWriteTime; tmp.u.LowPart = time.dwLowDateTime; tmp.u.HighPart = time.dwHighDateTime; - return file_time_type(file_time_type::duration(time.QuadPart)); + return file_time_type(file_time_type::duration(tmp.QuadPart)); } #endif @@ -110,7 +110,7 @@ public: __dir_stream(const path& root, directory_options opts, error_code& ec) : __stream_(INVALID_HANDLE_VALUE), __root_(root) { - __stream_ = ::FindFirstFileEx(root.c_str(), &__data_); + __stream_ = ::FindFirstFile(root.c_str(), &__data_); if (__stream_ == INVALID_HANDLE_VALUE) { ec = error_code(::GetLastError(), generic_category()); const bool ignore_permission_denied = @@ -140,7 +140,7 @@ public: //cdata.__write_time_ = get_write_time(__data_); __entry_.__assign_iter_entry( __root_ / __data_.cFileName, - directory_entry::__create_iter_result(get_file_type(__data))); + directory_entry::__create_iter_result(detail::get_file_type(__data))); return true; } ec = error_code(::GetLastError(), generic_category()); diff --git a/src/filesystem/int128_builtins.cpp b/src/filesystem/int128_builtins.cpp index a55540fe276e..ed531ee145a2 100644 --- a/src/filesystem/int128_builtins.cpp +++ b/src/filesystem/int128_builtins.cpp @@ -18,7 +18,7 @@ #if !defined(_LIBCPP_HAS_NO_INT128) -extern "C" __attribute__((no_sanitize("undefined"))) +extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS __int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) { const int N = (int)(sizeof(__int128_t) * CHAR_BIT); const __int128_t MIN = (__int128_t)1 << (N - 1); diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp index 69350ddfe9da..4e6cb1427a11 100644 --- a/src/filesystem/operations.cpp +++ b/src/filesystem/operations.cpp @@ -44,7 +44,7 @@ #include <sys/time.h> // for gettimeofday and timeval #endif // !defined(CLOCK_REALTIME) -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "rt") #endif diff --git a/src/iostream.cpp b/src/iostream.cpp index 0a5d6e8d2264..ad1920abc657 100644 --- a/src/iostream.cpp +++ b/src/iostream.cpp @@ -97,7 +97,13 @@ static void force_locale_initialization() { #endif } -ios_base::Init::Init() +class DoIOSInit { +public: + DoIOSInit(); + ~DoIOSInit(); +}; + +DoIOSInit::DoIOSInit() { force_locale_initialization(); @@ -126,7 +132,7 @@ ios_base::Init::Init() #endif } -ios_base::Init::~Init() +DoIOSInit::~DoIOSInit() { #ifndef _LIBCPP_HAS_NO_STDOUT ostream* cout_ptr = reinterpret_cast<ostream*>(cout); @@ -141,4 +147,13 @@ ios_base::Init::~Init() wclog_ptr->flush(); } +ios_base::Init::Init() +{ + static DoIOSInit init_the_streams; // gets initialized once +} + +ios_base::Init::~Init() +{ +} + _LIBCPP_END_NAMESPACE_STD diff --git a/src/memory.cpp b/src/memory.cpp index c8c00383cf92..e89d94f27e4c 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -10,7 +10,7 @@ #ifndef _LIBCPP_HAS_NO_THREADS #include "mutex" #include "thread" -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif #endif diff --git a/src/mutex.cpp b/src/mutex.cpp index 0d69d7cacfa1..7e979cd89041 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -13,7 +13,7 @@ #include "__undef_macros" #ifndef _LIBCPP_HAS_NO_THREADS -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif #endif @@ -21,9 +21,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_THREADS -const defer_lock_t defer_lock = {}; -const try_to_lock_t try_to_lock = {}; -const adopt_lock_t adopt_lock = {}; +const defer_lock_t defer_lock{}; +const try_to_lock_t try_to_lock{}; +const adopt_lock_t adopt_lock{}; // ~mutex is defined elsewhere @@ -132,7 +132,7 @@ timed_mutex::unlock() _NOEXCEPT recursive_timed_mutex::recursive_timed_mutex() : __count_(0), - __id_(0) + __id_{} { } @@ -144,9 +144,9 @@ recursive_timed_mutex::~recursive_timed_mutex() void recursive_timed_mutex::lock() { - __libcpp_thread_id id = __libcpp_thread_get_current_id(); + __thread_id id = this_thread::get_id(); unique_lock<mutex> lk(__m_); - if (__libcpp_thread_id_equal(id, __id_)) + if (id ==__id_) { if (__count_ == numeric_limits<size_t>::max()) __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); @@ -162,9 +162,9 @@ recursive_timed_mutex::lock() bool recursive_timed_mutex::try_lock() _NOEXCEPT { - __libcpp_thread_id id = __libcpp_thread_get_current_id(); + __thread_id id = this_thread::get_id(); unique_lock<mutex> lk(__m_, try_to_lock); - if (lk.owns_lock() && (__count_ == 0 || __libcpp_thread_id_equal(id, __id_))) + if (lk.owns_lock() && (__count_ == 0 || id == __id_)) { if (__count_ == numeric_limits<size_t>::max()) return false; @@ -181,7 +181,7 @@ recursive_timed_mutex::unlock() _NOEXCEPT unique_lock<mutex> lk(__m_); if (--__count_ == 0) { - __id_ = 0; + __id_.__reset(); lk.unlock(); __cv_.notify_one(); } diff --git a/src/shared_mutex.cpp b/src/shared_mutex.cpp index eb3f5f3506f5..9e6d5202aafa 100644 --- a/src/shared_mutex.cpp +++ b/src/shared_mutex.cpp @@ -10,7 +10,7 @@ #ifndef _LIBCPP_HAS_NO_THREADS #include "shared_mutex" -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif diff --git a/src/thread.cpp b/src/thread.cpp index 39bb9e9bac63..cee778f6ee85 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -35,7 +35,7 @@ #include <windows.h> #endif -#if defined(__unix__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) +#if defined(__unix__) && !defined(__ANDROID__) && defined(__ELF__) && defined(_LIBCPP_HAS_COMMENT_LIB_PRAGMA) #pragma comment(lib, "pthread") #endif diff --git a/src/utility.cpp b/src/utility.cpp index 016a5d91b85a..6a690dc2879e 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -10,6 +10,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -const piecewise_construct_t piecewise_construct = {}; +const piecewise_construct_t piecewise_construct{}; _LIBCPP_END_NAMESPACE_STD diff --git a/src/valarray.cpp b/src/valarray.cpp index 7bf0b4175889..64d26583c74b 100644 --- a/src/valarray.cpp +++ b/src/valarray.cpp @@ -12,8 +12,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // These two symbols are part of the v1 ABI but not part of the >=v2 ABI. #if _LIBCPP_ABI_VERSION == 1 -template valarray<size_t>::valarray(size_t); -template valarray<size_t>::~valarray(); +template _LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t); +template _LIBCPP_FUNC_VIS valarray<size_t>::~valarray(); #endif template void valarray<size_t>::resize(size_t, size_t); |