diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:05:35 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:05:35 +0000 |
commit | 6012fe9abb1f01b1b5b4ca908464804c21ff8602 (patch) | |
tree | a5232179237d9aaa3a03f9c783974fc5f09716c6 /include | |
parent | 315d10f09ee888005b1da55e7bbb57d8a79b8447 (diff) |
Vendor import of libc++ trunk r351319 (just before the release_80vendor/libc++/libc++-trunk-r351319
branch point):
https://llvm.org/svn/llvm-project/libcxx/trunk@351319
Notes
Notes:
svn path=/vendor/libc++/dist/; revision=343177
svn path=/vendor/libc++/libc++-trunk-r351319/; revision=343178; tag=vendor/libc++/libc++-trunk-r351319
Diffstat (limited to 'include')
86 files changed, 4527 insertions, 1717 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index d9def18d725c..73f7cfc4d8e3 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -25,6 +25,7 @@ set(files any array atomic + bit bitset cassert ccomplex @@ -68,7 +69,6 @@ set(files experimental/chrono experimental/coroutine experimental/deque - experimental/dynarray experimental/filesystem experimental/forward_list experimental/functional diff --git a/include/__bit_reference b/include/__bit_reference index 3e4a21d261ff..c208af2b4d76 100644 --- a/include/__bit_reference +++ b/include/__bit_reference @@ -12,6 +12,7 @@ #define _LIBCPP___BIT_REFERENCE #include <__config> +#include <bit> #include <algorithm> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -254,18 +255,18 @@ __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); __storage_type __dn = _VSTD::min(__clz_f, __n); __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __r = _VSTD::__pop_count(*__first.__seg_ & __m); + __r = _VSTD::__popcount(*__first.__seg_ & __m); __n -= __dn; ++__first.__seg_; } // do middle whole words for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) - __r += _VSTD::__pop_count(*__first.__seg_); + __r += _VSTD::__popcount(*__first.__seg_); // do last partial word if (__n > 0) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __r += _VSTD::__pop_count(*__first.__seg_ & __m); + __r += _VSTD::__popcount(*__first.__seg_ & __m); } return __r; } @@ -285,18 +286,18 @@ __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_typ __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); __storage_type __dn = _VSTD::min(__clz_f, __n); __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __r = _VSTD::__pop_count(~*__first.__seg_ & __m); + __r = _VSTD::__popcount(~*__first.__seg_ & __m); __n -= __dn; ++__first.__seg_; } // do middle whole words for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) - __r += _VSTD::__pop_count(~*__first.__seg_); + __r += _VSTD::__popcount(~*__first.__seg_); // do last partial word if (__n > 0) { __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __r += _VSTD::__pop_count(~*__first.__seg_ & __m); + __r += _VSTD::__popcount(~*__first.__seg_ & __m); } return __r; } diff --git a/include/__config b/include/__config index 639d06c9f5d7..f0bc3483facd 100644 --- a/include/__config +++ b/include/__config @@ -33,14 +33,10 @@ # define _GNUC_VER_NEW 0 #endif -#define _LIBCPP_VERSION 7000 +#define _LIBCPP_VERSION 8000 #ifndef _LIBCPP_ABI_VERSION -# ifdef __Fuchsia__ -# define _LIBCPP_ABI_VERSION 2 -# else -# define _LIBCPP_ABI_VERSION 1 -# endif +# define _LIBCPP_ABI_VERSION 1 #endif #ifndef _LIBCPP_STD_VER @@ -99,6 +95,8 @@ // Use the smallest possible integer type to represent the index of the variant. // Previously libc++ used "unsigned int" exclusivly. # define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +// Unstable attempt to provide a more optimized std::function +# define _LIBCPP_ABI_OPTIMIZED_FUNCTION #elif _LIBCPP_ABI_VERSION == 1 # if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support @@ -123,7 +121,9 @@ #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y #define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) -#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) +#ifndef _LIBCPP_ABI_NAMESPACE +# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) +#endif #if __cplusplus < 201103L #define _LIBCPP_CXX03_LANG @@ -328,6 +328,43 @@ # define _LIBCPP_NO_CFI #endif +#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +# if defined(__FreeBSD__) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_C11_FEATURES +# elif defined(__Fuchsia__) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_TIMESPEC_GET +# define _LIBCPP_HAS_C11_FEATURES +# elif defined(__linux__) +# if !defined(_LIBCPP_HAS_MUSL_LIBC) +# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__) +# define _LIBCPP_HAS_QUICK_EXIT +# endif +# if _LIBCPP_GLIBC_PREREQ(2, 17) +# define _LIBCPP_HAS_C11_FEATURES +# define _LIBCPP_HAS_TIMESPEC_GET +# endif +# else // defined(_LIBCPP_HAS_MUSL_LIBC) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_TIMESPEC_GET +# define _LIBCPP_HAS_C11_FEATURES +# endif +# endif // __linux__ +#endif + +#ifndef _LIBCPP_CXX03_LANG +# define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp) +#elif defined(_LIBCPP_COMPILER_CLANG) +# define _LIBCPP_ALIGNOF(_Tp) _Alignof(_Tp) +#else +// This definition is potentially buggy, but it's only taken with GCC in C++03, +// which we barely support anyway. See llvm.org/PR39713 +# define _LIBCPP_ALIGNOF(_Tp) __alignof(_Tp) +#endif + +#define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) + #if defined(_LIBCPP_COMPILER_CLANG) // _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for @@ -342,7 +379,7 @@ # define _ALIGNAS_TYPE(x) alignas(x) # define _ALIGNAS(x) alignas(x) #else -# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +# define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) # define _ALIGNAS(x) __attribute__((__aligned__(x))) #endif @@ -430,28 +467,6 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES #endif -#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L -# if defined(__FreeBSD__) -# define _LIBCPP_HAS_QUICK_EXIT -# define _LIBCPP_HAS_C11_FEATURES -# elif defined(__Fuchsia__) -# define _LIBCPP_HAS_QUICK_EXIT -# define _LIBCPP_HAS_C11_FEATURES -# elif defined(__linux__) -# if !defined(_LIBCPP_HAS_MUSL_LIBC) -# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__) -# define _LIBCPP_HAS_QUICK_EXIT -# endif -# if _LIBCPP_GLIBC_PREREQ(2, 17) -# define _LIBCPP_HAS_C11_FEATURES -# endif -# else // defined(_LIBCPP_HAS_MUSL_LIBC) -# define _LIBCPP_HAS_QUICK_EXIT -# define _LIBCPP_HAS_C11_FEATURES -# endif -# endif // __linux__ -#endif - #if !(__has_feature(cxx_noexcept)) #define _LIBCPP_HAS_NO_NOEXCEPT #endif @@ -464,16 +479,6 @@ typedef __char32_t char32_t; #define _LIBCPP_IS_LITERAL(T) __is_literal(T) #endif -// Inline namespaces are available in Clang regardless of C++ dialect. -#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { -#define _LIBCPP_END_NAMESPACE_STD } } -#define _VSTD std::_LIBCPP_NAMESPACE - -namespace std { - inline namespace _LIBCPP_NAMESPACE { - } -} - #if !defined(_LIBCPP_HAS_NO_ASAN) && !__has_feature(address_sanitizer) #define _LIBCPP_HAS_NO_ASAN #endif @@ -493,10 +498,15 @@ namespace std { #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 +#endif + #elif defined(_LIBCPP_COMPILER_GCC) #define _ALIGNAS(x) __attribute__((__aligned__(x))) -#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) #define _LIBCPP_NORETURN __attribute__((noreturn)) @@ -563,15 +573,6 @@ namespace std { #endif // __GXX_EXPERIMENTAL_CXX0X__ -#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_NAMESPACE { -#define _LIBCPP_END_NAMESPACE_STD } } -#define _VSTD std::_LIBCPP_NAMESPACE - -namespace std { - inline namespace _LIBCPP_NAMESPACE { - } -} - #if !defined(_LIBCPP_HAS_NO_ASAN) && !defined(__SANITIZE_ADDRESS__) #define _LIBCPP_HAS_NO_ASAN #endif @@ -607,13 +608,6 @@ namespace std { #define _ALIGNAS_TYPE(x) alignas(x) #define _LIBCPP_HAS_NO_VARIADICS -#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { -#define _LIBCPP_END_NAMESPACE_STD } -#define _VSTD std - -namespace std { -} - #define _LIBCPP_WEAK #define _LIBCPP_HAS_NO_ASAN @@ -625,7 +619,7 @@ namespace std { #elif defined(_LIBCPP_COMPILER_IBM) #define _ALIGNAS(x) __attribute__((__aligned__(x))) -#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +#define _ALIGNAS_TYPE(x) __attribute__((__aligned__(_LIBCPP_ALIGNOF(x)))) #define _ATTRIBUTE(x) __attribute__((x)) #define _LIBCPP_NORETURN __attribute__((noreturn)) @@ -641,15 +635,6 @@ namespace std { #define __MULTILOCALE_API #endif -#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE { -#define _LIBCPP_END_NAMESPACE_STD } } -#define _VSTD std::_LIBCPP_NAMESPACE - -namespace std { - inline namespace _LIBCPP_NAMESPACE { - } -} - #define _LIBCPP_HAS_NO_ASAN #define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) @@ -658,20 +643,6 @@ namespace std { #endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM] -#if _LIBCPP_STD_VER >= 17 -#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ - _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { -#else -#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ - _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem { -#endif - -#define _LIBCPP_END_NAMESPACE_FILESYSTEM \ - _LIBCPP_END_NAMESPACE_STD } } - -#define _VSTD_FS _VSTD::__fs::filesystem - - #if defined(_LIBCPP_OBJECT_FORMAT_COFF) #ifdef _DLL @@ -685,33 +656,29 @@ namespace std { # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS # define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS # define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_EXPORTED_FROM_ABI #elif defined(_LIBCPP_BUILDING_LIBRARY) # define _LIBCPP_DLL_VIS __declspec(dllexport) # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS # define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS # define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllexport) #else # define _LIBCPP_DLL_VIS __declspec(dllimport) # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS # define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS # define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport) #endif #define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS #define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS -#define _LIBCPP_EXTERN_VIS _LIBCPP_DLL_VIS #define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS #define _LIBCPP_HIDDEN #define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS #define _LIBCPP_TEMPLATE_VIS #define _LIBCPP_ENUM_VIS -#if defined(_LIBCPP_COMPILER_MSVC) -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline -#else -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__)) -#endif - #endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) #ifndef _LIBCPP_HIDDEN @@ -759,8 +726,12 @@ namespace std { # endif #endif -#ifndef _LIBCPP_EXTERN_VIS -#define _LIBCPP_EXTERN_VIS +#ifndef _LIBCPP_EXPORTED_FROM_ABI +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXPORTED_FROM_ABI __attribute__((__visibility__("default"))) +# else +# define _LIBCPP_EXPORTED_FROM_ABI +# endif #endif #ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS @@ -801,21 +772,63 @@ namespace std { # define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE #endif -#ifndef _LIBCPP_HIDE_FROM_ABI -# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE +#if __has_attribute(exclude_from_explicit_instantiation) +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__ ((__exclude_from_explicit_instantiation__)) +#else + // Try to approximate the effect of exclude_from_explicit_instantiation + // (which is that entities are not assumed to be provided by explicit + // template instantitations in the dylib) by always inlining those entities. +# define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE #endif -// Just so we can migrate to _LIBCPP_HIDE_FROM_ABI gradually. -#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI +#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU +# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0 +# else +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1 +# endif +#endif -#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY -# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__)) +#ifndef _LIBCPP_HIDE_FROM_ABI +# if _LIBCPP_HIDE_FROM_ABI_PER_TU +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE # else -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__)) +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION # endif #endif +#ifdef _LIBCPP_BUILDING_LIBRARY +# if _LIBCPP_ABI_VERSION > 1 +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI +# else +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 +# endif +#else +# define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI +#endif + +// Just so we can migrate to the new macros gradually. +#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI + +// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect. +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE { +#define _LIBCPP_END_NAMESPACE_STD } } +#define _VSTD std::_LIBCPP_ABI_NAMESPACE +_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 17 +#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { +#else +#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem { +#endif + +#define _LIBCPP_END_NAMESPACE_FILESYSTEM \ + _LIBCPP_END_NAMESPACE_STD } } + +#define _VSTD_FS _VSTD::__fs::filesystem + #ifndef _LIBCPP_PREFERRED_OVERLOAD # if __has_attribute(__enable_if__) # define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) @@ -976,7 +989,14 @@ template <unsigned> struct __static_assert_check {}; // If we are getting operator new from the MSVC CRT, then allocation overloads // for align_val_t were added in 19.12, aka VS 2017 version 15.3. #if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912 -#define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +#elif defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) +# define _LIBCPP_DEFER_NEW_TO_VCRUNTIME +# if !defined(__cpp_aligned_new) + // We're defering to Microsoft's STL to provide aligned new et al. We don't + // have it unless the language feature test macro is defined. +# define _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION +# endif #endif #if defined(__APPLE__) @@ -984,13 +1004,13 @@ template <unsigned> struct __static_assert_check {}; defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) # define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ # endif -# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) -# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION -# endif -# endif #endif // defined(__APPLE__) +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \ + (defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) || \ + (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606)) +# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#endif #if defined(__APPLE__) || defined(__FreeBSD__) #define _LIBCPP_HAS_DEFAULTRUNELOCALE @@ -1000,18 +1020,46 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_WCTYPE_IS_MASK #endif -#if _LIBCPP_STD_VER > 11 -# define _LIBCPP_DEPRECATED [[deprecated]] +#if _LIBCPP_STD_VER <= 17 || !defined(__cpp_char8_t) +#define _LIBCPP_NO_HAS_CHAR8_T +#endif + +// Deprecation macros. +// Deprecations warnings are only enabled when _LIBCPP_ENABLE_DEPRECATION_WARNINGS is defined. +#if defined(_LIBCPP_ENABLE_DEPRECATION_WARNINGS) +# if __has_attribute(deprecated) +# define _LIBCPP_DEPRECATED __attribute__ ((deprecated)) +# elif _LIBCPP_STD_VER > 11 +# define _LIBCPP_DEPRECATED [[deprecated]] +# else +# define _LIBCPP_DEPRECATED +# endif #else # define _LIBCPP_DEPRECATED #endif +#if !defined(_LIBCPP_CXX03_LANG) +# define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX11 +#endif + +#if _LIBCPP_STD_VER >= 14 +# define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX14 +#endif + +#if _LIBCPP_STD_VER >= 17 +# define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED +#else +# define _LIBCPP_DEPRECATED_IN_CXX17 +#endif + #if _LIBCPP_STD_VER <= 11 # define _LIBCPP_EXPLICIT_AFTER_CXX11 -# define _LIBCPP_DEPRECATED_AFTER_CXX11 #else # define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit -# define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]] #endif #if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) @@ -1032,8 +1080,30 @@ template <unsigned> struct __static_assert_check {}; # define _LIBCPP_CONSTEXPR_AFTER_CXX17 #endif -#if __has_cpp_attribute(nodiscard) && _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) -# define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]] +// The _LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other +// NODISCARD macros to the correct attribute. +#if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC) +# define _LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]] +#elif defined(_LIBCPP_COMPILER_CLANG) && !defined(_LIBCPP_CXX03_LANG) +# define _LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]] +#else +// We can't use GCC's [[gnu::warn_unused_result]] and +// __attribute__((warn_unused_result)), because GCC does not silence them via +// (void) cast. +# define _LIBCPP_NODISCARD_ATTRIBUTE +#endif + +// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not +// specified as such as an extension. +#if defined(_LIBCPP_ENABLE_NODISCARD) && !defined(_LIBCPP_DISABLE_NODISCARD_EXT) +# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD_ATTRIBUTE +#else +# define _LIBCPP_NODISCARD_EXT +#endif + +#if !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && \ + (_LIBCPP_STD_VER > 17 || defined(_LIBCPP_ENABLE_NODISCARD)) +# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD_ATTRIBUTE #else # define _LIBCPP_NODISCARD_AFTER_CXX17 #endif @@ -1090,6 +1160,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( defined(__Fuchsia__) || \ defined(__NetBSD__) || \ defined(__linux__) || \ + defined(__GNU__) || \ defined(__APPLE__) || \ defined(__CloudABI__) || \ defined(__sun__) || \ @@ -1195,8 +1266,12 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_DIAGNOSE_ERROR(...) #endif -#if __has_attribute(fallthough) || _GNUC_VER >= 700 // Use a function like macro to imply that it must be followed by a semicolon +#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough) +# define _LIBCPP_FALLTHROUGH() [[fallthrough]] +#elif __has_cpp_attribute(clang::fallthrough) +# define _LIBCPP_FALLTHROUGH() [[clang::fallthrough]] +#elif __has_attribute(fallthough) || _GNUC_VER >= 700 # define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) #else # define _LIBCPP_FALLTHROUGH() ((void)0) @@ -1250,9 +1325,15 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( __attribute__((availability(ios,strict,introduced=10.0))) \ __attribute__((availability(tvos,strict,introduced=10.0))) \ __attribute__((availability(watchos,strict,introduced=3.0))) -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) -# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH __attribute__((unavailable)) -# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST __attribute__((unavailable)) +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ + __attribute__((availability(macosx,strict,introduced=10.14))) \ + __attribute__((availability(ios,strict,introduced=12.0))) \ + __attribute__((availability(tvos,strict,introduced=12.0))) \ + __attribute__((availability(watchos,strict,introduced=5.0))) +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ + _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS # define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ __attribute__((availability(macosx,strict,introduced=10.12))) \ __attribute__((availability(ios,strict,introduced=10.0))) \ @@ -1276,8 +1357,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( __attribute__((availability(ios,strict,introduced=7.0))) #else # define _LIBCPP_AVAILABILITY_SHARED_MUTEX +# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST # define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS # define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE @@ -1289,26 +1370,30 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( // Define availability that depends on _LIBCPP_NO_EXCEPTIONS. #ifdef _LIBCPP_NO_EXCEPTIONS -# define _LIBCPP_AVAILABILITY_DYNARRAY # define _LIBCPP_AVAILABILITY_FUTURE # define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS #else -# define _LIBCPP_AVAILABILITY_DYNARRAY _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH -# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST \ - _LIBCPP_AVAILABILITY_BAD_ANY_CAST -#endif - -// Availability of stream API in the dylib got dropped and re-added. The -// extern template should effectively be available at: -// availability(macosx,introduced=10.9) -// availability(ios,introduced=7.0) -#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) && \ +# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +#endif + +// The stream API was dropped and re-added in the dylib shipped on macOS +// and iOS. We can only assume the dylib to provide these definitions for +// macosx >= 10.9 and ios >= 7.0. Otherwise, the definitions are available +// from the headers, but not from the dylib. Explicit instantiation +// declarations for streams exist conditionally to this; if we provide +// an explicit instantiation declaration and we try to deploy to a dylib +// that does not provide those symbols, we'll get a load-time error. +#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000)) -#define _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +# define _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB #endif #if defined(_LIBCPP_COMPILER_IBM) @@ -1351,6 +1436,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) #endif // _LIBCPP_NO_AUTO_LINK +#define _LIBCPP_UNUSED_VAR(x) ((void)(x)) + #endif // __cplusplus #endif // _LIBCPP_CONFIG diff --git a/include/__config_site.in b/include/__config_site.in index 8d980ff57cc8..580a6aa4c07b 100644 --- a/include/__config_site.in +++ b/include/__config_site.in @@ -14,6 +14,7 @@ #cmakedefine _LIBCPP_ABI_UNSTABLE #cmakedefine _LIBCPP_ABI_FORCE_ITANIUM #cmakedefine _LIBCPP_ABI_FORCE_MICROSOFT +#cmakedefine _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT #cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE #cmakedefine _LIBCPP_HAS_NO_STDIN #cmakedefine _LIBCPP_HAS_NO_STDOUT @@ -27,6 +28,7 @@ #cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #cmakedefine _LIBCPP_NO_VCRUNTIME +#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ @_LIBCPP_ABI_DEFINES@ diff --git a/include/__debug b/include/__debug index d01bacdf7edc..a8788f68f8f4 100644 --- a/include/__debug +++ b/include/__debug @@ -74,7 +74,7 @@ typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); /// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT /// fails. -extern _LIBCPP_EXTERN_VIS __libcpp_debug_function_type __libcpp_debug_function; +extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; /// __libcpp_abort_debug_function - A debug handler that aborts when called. _LIBCPP_NORETURN _LIBCPP_FUNC_VIS diff --git a/include/__functional_base b/include/__functional_base index 57fdf2b9f663..032be99bf6a5 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -50,7 +50,7 @@ template <class _Tp> #endif struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> { - _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __x < __y;} }; @@ -59,7 +59,7 @@ struct _LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> template <> struct _LIBCPP_TEMPLATE_VIS less<void> { - template <class _T1, class _T2> + template <class _T1, class _T2> _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const _NOEXCEPT_(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) @@ -552,7 +552,7 @@ template <class _Tp, class, class = void> struct __is_transparent : false_type {}; template <class _Tp, class _Up> -struct __is_transparent<_Tp, _Up, +struct __is_transparent<_Tp, _Up, typename __void_t<typename _Tp::is_transparent>::type> : true_type {}; #endif @@ -562,7 +562,7 @@ struct __is_transparent<_Tp, _Up, struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { }; #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) -extern const allocator_arg_t allocator_arg; +extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; #else /* _LIBCPP_INLINE_VAR */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); #endif diff --git a/include/__hash_table b/include/__hash_table index c77de961be6b..6f5b183105e6 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -35,15 +35,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <class _Key, class _Tp> struct __hash_value_type; -template <class _Key, class _Cp, class _Hash, - bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> -class __unordered_map_hasher; - -template <class _Key, class _Cp, class _Pred, - bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value - > -class __unordered_map_equal; - #ifndef _LIBCPP_CXX03_LANG template <class _Tp> struct __is_hash_value_type_imp : false_type {}; @@ -418,7 +409,7 @@ public: _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) { @@ -871,35 +862,32 @@ struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> }; #endif +template <class _Key, class _Hash, class _Equal> +struct __enforce_unordered_container_requirements { #ifndef _LIBCPP_CXX03_LANG -template <class _Key, class _Hash, class _Equal, class _Alloc> -struct __diagnose_hash_table_helper { - static constexpr bool __trigger_diagnostics() - _LIBCPP_DIAGNOSE_WARNING(__check_hash_requirements<_Key, _Hash>::value - && !__invokable<_Hash const&, _Key const&>::value, - "the specified hash functor does not provide a const call operator") - _LIBCPP_DIAGNOSE_WARNING(is_copy_constructible<_Equal>::value - && !__invokable<_Equal const&, _Key const&, _Key const&>::value, - "the specified comparator type does not provide a const call operator") - { static_assert(__check_hash_requirements<_Key, _Hash>::value, - "the specified hash does not meet the Hash requirements"); + "the specified hash does not meet the Hash requirements"); static_assert(is_copy_constructible<_Equal>::value, - "the specified comparator is required to be copy constructible"); - return true; - } + "the specified comparator is required to be copy constructible"); +#endif + typedef int type; }; -template <class _Key, class _Value, class _Hash, class _Equal, class _Alloc> -struct __diagnose_hash_table_helper< - __hash_value_type<_Key, _Value>, - __unordered_map_hasher<_Key, __hash_value_type<_Key, _Value>, _Hash>, - __unordered_map_equal<_Key, __hash_value_type<_Key, _Value>, _Equal>, - _Alloc> -: __diagnose_hash_table_helper<_Key, _Hash, _Equal, _Alloc> -{ -}; -#endif // _LIBCPP_CXX03_LANG +template <class _Key, class _Hash, class _Equal> +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a const call operator") + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a const call operator") +#endif +typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type +__diagnose_unordered_container_requirements(int); + +// This dummy overload is used so that the compiler won't emit a spurious +// "no matching function for call to __diagnose_unordered_xxx" diagnostic +// when the overload above causes a hard error. +template <class _Key, class _Hash, class _Equal> +int __diagnose_unordered_container_requirements(void*); template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table @@ -963,10 +951,6 @@ private: typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; -#ifndef _LIBCPP_CXX03_LANG - static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), ""); -#endif - // --- Member data begin --- __bucket_list __bucket_list_; __compressed_pair<__first_node, __node_allocator> __p1_; @@ -1058,8 +1042,26 @@ public: ); } +private: + _LIBCPP_INLINE_VISIBILITY + __next_pointer __node_insert_multi_prepare(size_t __cp_hash, + value_type& __cp_val); + _LIBCPP_INLINE_VISIBILITY + void __node_insert_multi_perform(__node_pointer __cp, + __next_pointer __pn) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY + __next_pointer __node_insert_unique_prepare(size_t __nd_hash, + value_type& __nd_val); + _LIBCPP_INLINE_VISIBILITY + void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; + +public: + _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> __node_insert_unique(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); @@ -1170,6 +1172,9 @@ public: _LIBCPP_INLINE_VISIBILITY iterator __node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh); + template <class _Table> + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_unique(_Table& __source); template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY @@ -1177,6 +1182,9 @@ public: template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); + template <class _Table> + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_multi(_Table& __source); template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY @@ -1849,73 +1857,112 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT } } + +// Prepare the container for an insertion of the value __value with the hash +// __hash. This does a lookup into the container to see if __value is already +// present, and performs a rehash if necessary. Returns a pointer to the +// existing element if it exists, otherwise nullptr. +// +// Note that this function does forward exceptions if key_eq() throws, and never +// mutates __value or actually inserts into the map. template <class _Tp, class _Hash, class _Equal, class _Alloc> -pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) +_LIBCPP_INLINE_VISIBILITY +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( + size_t __hash, value_type& __value) { - __nd->__hash_ = hash_function()(__nd->__value_); size_type __bc = bucket_count(); - bool __inserted = false; - __next_pointer __ndptr; - size_t __chash; + if (__bc != 0) { - __chash = __constrain_hash(__nd->__hash_, __bc); - __ndptr = __bucket_list_[__chash]; + size_t __chash = __constrain_hash(__hash, __bc); + __next_pointer __ndptr = __bucket_list_[__chash]; if (__ndptr != nullptr) { for (__ndptr = __ndptr->__next_; __ndptr != nullptr && __constrain_hash(__ndptr->__hash(), __bc) == __chash; __ndptr = __ndptr->__next_) { - if (key_eq()(__ndptr->__upcast()->__value_, __nd->__value_)) - goto __done; + if (key_eq()(__ndptr->__upcast()->__value_, __value)) + return __ndptr; } } } + if (size()+1 > __bc * max_load_factor() || __bc == 0) { - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), - size_type(ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); - __chash = __constrain_hash(__nd->__hash_, __bc); - } - // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn == nullptr) - { - __pn =__p1_.first().__ptr(); - __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__nd->__next_ != nullptr) - __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); - } - else - { - __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd->__ptr(); - } - __ndptr = __nd->__ptr(); - // increment size - ++size(); + rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), + size_type(ceil(float(size() + 1) / max_load_factor())))); + } + return nullptr; +} + +// Insert the node __nd into the container by pushing it into the right bucket, +// and updating size(). Assumes that __nd->__hash is up-to-date, and that +// rehashing has already occurred and that no element with the same key exists +// in the map. +template <class _Tp, class _Hash, class _Equal, class _Alloc> +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( + __node_pointer __nd) _NOEXCEPT +{ + size_type __bc = bucket_count(); + size_t __chash = __constrain_hash(__nd->__hash(), __bc); + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) + { + __pn =__p1_.first().__ptr(); + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__nd->__next_ != nullptr) + __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); + } + else + { + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + } + ++size(); +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) +{ + __nd->__hash_ = hash_function()(__nd->__value_); + __next_pointer __existing_node = + __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); + + // Insert the node, unless it already exists in the container. + bool __inserted = false; + if (__existing_node == nullptr) + { + __node_insert_unique_perform(__nd); + __existing_node = __nd->__ptr(); __inserted = true; } -__done: #if _LIBCPP_DEBUG_LEVEL >= 2 - return pair<iterator, bool>(iterator(__ndptr, this), __inserted); + return pair<iterator, bool>(iterator(__existing_node, this), __inserted); #else - return pair<iterator, bool>(iterator(__ndptr), __inserted); + return pair<iterator, bool>(iterator(__existing_node), __inserted); #endif } +// Prepare the container for an insertion of the value __cp_val with the hash +// __cp_hash. This does a lookup into the container to see if __cp_value is +// already present, and performs a rehash if necessary. Returns a pointer to the +// last occurance of __cp_val in the map. +// +// Note that this function does forward exceptions if key_eq() throws, and never +// mutates __value or actually inserts into the map. template <class _Tp, class _Hash, class _Equal, class _Alloc> -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( + size_t __cp_hash, value_type& __cp_val) { - __cp->__hash_ = hash_function()(__cp->__value_); size_type __bc = bucket_count(); if (size()+1 > __bc * max_load_factor() || __bc == 0) { @@ -1923,20 +1970,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c size_type(ceil(float(size() + 1) / max_load_factor())))); __bc = bucket_count(); } - size_t __chash = __constrain_hash(__cp->__hash_, __bc); + size_t __chash = __constrain_hash(__cp_hash, __bc); __next_pointer __pn = __bucket_list_[__chash]; - if (__pn == nullptr) - { - __pn =__p1_.first().__ptr(); - __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__cp->__next_ != nullptr) - __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] - = __cp->__ptr(); - } - else + if (__pn != nullptr) { for (bool __found = false; __pn->__next_ != nullptr && __constrain_hash(__pn->__next_->__hash(), __bc) == __chash; @@ -1947,8 +1983,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c // true true loop // false true set __found to true // true false break - if (__found != (__pn->__next_->__hash() == __cp->__hash_ && - key_eq()(__pn->__next_->__upcast()->__value_, __cp->__value_))) + if (__found != (__pn->__next_->__hash() == __cp_hash && + key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) { if (!__found) __found = true; @@ -1956,6 +1992,35 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c break; } } + } + return __pn; +} + +// Insert the node __cp into the container after __pn (which is the last node in +// the bucket that compares equal to __cp). Rehashing, and checking for +// uniqueness has already been performed (in __node_insert_multi_prepare), so +// all we need to do is update the bucket and size(). Assumes that __cp->__hash +// is up-to-date. +template <class _Tp, class _Hash, class _Equal, class _Alloc> +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( + __node_pointer __cp, __next_pointer __pn) _NOEXCEPT +{ + size_type __bc = bucket_count(); + size_t __chash = __constrain_hash(__cp->__hash_, __bc); + if (__pn == nullptr) + { + __pn =__p1_.first().__ptr(); + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__cp->__next_ != nullptr) + __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] + = __cp->__ptr(); + } + else + { __cp->__next_ = __pn->__next_; __pn->__next_ = __cp->__ptr(); if (__cp->__next_ != nullptr) @@ -1966,6 +2031,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c } } ++size(); +} + + +template <class _Tp, class _Hash, class _Equal, class _Alloc> +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) +{ + __cp->__hash_ = hash_function()(__cp->__value_); + __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); + __node_insert_multi_perform(__cp, __pn); + #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__cp->__ptr(), this); #else @@ -2217,6 +2293,32 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( } template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _Table> +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( + _Table& __source) +{ + static_assert(is_same<__node, typename _Table::__node>::value, ""); + + for (typename _Table::iterator __it = __source.begin(); + __it != __source.end();) + { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __hash = hash_function()(__src_ptr->__value_); + __next_pointer __existing_node = + __node_insert_unique_prepare(__hash, __src_ptr->__value_); + auto __prev_iter = __it++; + if (__existing_node == nullptr) + { + (void)__source.remove(__prev_iter).release(); + __src_ptr->__hash_ = __hash; + __node_insert_unique_perform(__src_ptr); + } + } +} + +template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator @@ -2244,6 +2346,27 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( return __result; } +template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _Table> +_LIBCPP_INLINE_VISIBILITY +void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( + _Table& __source) +{ + static_assert(is_same<typename _Table::__node, __node>::value, ""); + + for (typename _Table::iterator __it = __source.begin(); + __it != __source.end();) + { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __src_hash = hash_function()(__src_ptr->__value_); + __next_pointer __pn = + __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); + (void)__source.remove(__it++).release(); + __src_ptr->__hash_ = __src_hash; + __node_insert_multi_perform(__src_ptr, __pn); + } +} #endif // _LIBCPP_STD_VER > 14 template <class _Tp, class _Hash, class _Equal, class _Alloc> diff --git a/include/__libcpp_version b/include/__libcpp_version index 2bdc6533bec7..e002b3628b34 100644 --- a/include/__libcpp_version +++ b/include/__libcpp_version @@ -1 +1 @@ -7000 +8000 diff --git a/include/__locale b/include/__locale index f43e7b4303d3..cde9cc85f6b5 100644 --- a/include/__locale +++ b/include/__locale @@ -1255,13 +1255,13 @@ struct __narrow_to_utf8<8> }; template <> -struct __narrow_to_utf8<16> +struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> : public codecvt<char16_t, char, mbstate_t> { _LIBCPP_INLINE_VISIBILITY __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} - ~__narrow_to_utf8(); + _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); template <class _OutputIterator, class _CharT> _LIBCPP_INLINE_VISIBILITY @@ -1289,13 +1289,13 @@ struct __narrow_to_utf8<16> }; template <> -struct __narrow_to_utf8<32> +struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> : public codecvt<char32_t, char, mbstate_t> { _LIBCPP_INLINE_VISIBILITY __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} - ~__narrow_to_utf8(); + _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); template <class _OutputIterator, class _CharT> _LIBCPP_INLINE_VISIBILITY @@ -1345,13 +1345,13 @@ struct __widen_from_utf8<8> }; template <> -struct __widen_from_utf8<16> +struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> : public codecvt<char16_t, char, mbstate_t> { _LIBCPP_INLINE_VISIBILITY __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} - ~__widen_from_utf8(); + _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); template <class _OutputIterator> _LIBCPP_INLINE_VISIBILITY @@ -1379,13 +1379,13 @@ struct __widen_from_utf8<16> }; template <> -struct __widen_from_utf8<32> +struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> : public codecvt<char32_t, char, mbstate_t> { _LIBCPP_INLINE_VISIBILITY __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} - ~__widen_from_utf8(); + _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); template <class _OutputIterator> _LIBCPP_INLINE_VISIBILITY diff --git a/include/__mutex_base b/include/__mutex_base index 4659ca9298c9..da21a5f8eb6a 100644 --- a/include/__mutex_base +++ b/include/__mutex_base @@ -76,9 +76,9 @@ struct _LIBCPP_TYPE_VIS adopt_lock_t {}; #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) -extern const defer_lock_t defer_lock; -extern const try_to_lock_t try_to_lock; -extern const adopt_lock_t adopt_lock; +extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock; +extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock; +extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock; #else diff --git a/include/__node_handle b/include/__node_handle index fe09f3c1e51c..a9cf3b7217a3 100644 --- a/include/__node_handle +++ b/include/__node_handle @@ -26,8 +26,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 -#define __cpp_lib_node_extract 201606L - // Specialized in __tree & __hash_table for their _NodeType. template <class _NodeType, class _Alloc> struct __generic_container_node_destructor; diff --git a/include/__sso_allocator b/include/__sso_allocator index 40027363a185..8aca0495d756 100644 --- a/include/__sso_allocator +++ b/include/__sso_allocator @@ -55,14 +55,14 @@ public: __allocated_ = true; return (pointer)&buf_; } - return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); + return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); } - _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) + _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) { if (__p == (pointer)&buf_) __allocated_ = false; else - _VSTD::__libcpp_deallocate(__p, __alignof(_Tp)); + _VSTD::__libcpp_deallocate(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); } _LIBCPP_INLINE_VISIBILITY size_type max_size() const throw() {return size_type(~0) / sizeof(_Tp);} diff --git a/include/__string b/include/__string index 44c55987f9f7..1ddeec7149fb 100644 --- a/include/__string +++ b/include/__string @@ -47,6 +47,7 @@ struct char_traits template <> struct char_traits<char>; template <> struct char_traits<wchar_t>; +template <> struct char_traits<char8_t>; // c++20 } // std @@ -389,6 +390,102 @@ char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __ } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + +template <> +struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> +{ + typedef char8_t char_type; + typedef unsigned int int_type; + typedef streamoff off_type; + typedef u8streampos pos_type; + typedef mbstate_t state_type; + + static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept + {__c1 = __c2;} + static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept + {return __c1 == __c2;} + static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept + {return __c1 < __c2;} + + static constexpr + int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + + static constexpr + size_t length(const char_type* __s) _NOEXCEPT; + + _LIBCPP_INLINE_VISIBILITY static constexpr + const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} + + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + + static inline constexpr int_type not_eof(int_type __c) noexcept + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline constexpr char_type to_char_type(int_type __c) noexcept + {return char_type(__c);} + static inline constexpr int_type to_int_type(char_type __c) noexcept + {return int_type(__c);} + static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept + {return __c1 == __c2;} + static inline constexpr int_type eof() noexcept + {return int_type(EOF);} +}; + +// TODO use '__builtin_strlen' if it ever supports char8_t ?? +inline constexpr +size_t +char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline constexpr +int +char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ +#if __has_feature(cxx_constexpr_string_builtins) + return __builtin_memcmp(__s1, __s2, __n); +#else + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +#endif +} + +// TODO use '__builtin_char_memchr' if it ever supports char8_t ?? +inline constexpr +const char8_t* +char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +#endif // #_LIBCPP_NO_HAS_CHAR8_T + #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS template <> diff --git a/include/__threading_support b/include/__threading_support index 3c1eff22f530..202490062729 100644 --- a/include/__threading_support +++ b/include/__threading_support @@ -70,7 +70,7 @@ typedef pthread_t __libcpp_thread_id; typedef pthread_t __libcpp_thread_t; -// Thrad Local Storage +// Thread Local Storage typedef pthread_key_t __libcpp_tls_key; #define _LIBCPP_TLS_DESTRUCTOR_CC diff --git a/include/__tree b/include/__tree index af9b9616df8a..814851085b98 100644 --- a/include/__tree +++ b/include/__tree @@ -40,10 +40,6 @@ template <class _Tp, class _VoidPtr> class __tree_node; template <class _Key, class _Value> struct __value_type; -template <class _Key, class _CP, class _Compare, - bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value> -class __map_value_compare; - template <class _Allocator> class __map_node_destructor; template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator; template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator; @@ -857,7 +853,7 @@ public: __tree_iterator operator--(int) {__tree_iterator __t(*this); --(*this); return __t;} - friend _LIBCPP_INLINE_VISIBILITY + friend _LIBCPP_INLINE_VISIBILITY bool operator==(const __tree_iterator& __x, const __tree_iterator& __y) {return __x.__ptr_ == __y.__ptr_;} friend _LIBCPP_INLINE_VISIBILITY @@ -966,24 +962,12 @@ private: }; +template<class _Tp, class _Compare> #ifndef _LIBCPP_CXX03_LANG -template <class _Tp, class _Compare, class _Allocator> -struct __diagnose_tree_helper { - static constexpr bool __trigger_diagnostics() - _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value, - "the specified comparator type does not provide a const call operator") - { return true; } -}; - -template <class _Key, class _Value, class _KeyComp, class _Alloc> -struct __diagnose_tree_helper< - __value_type<_Key, _Value>, - __map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>, - _Alloc -> : __diagnose_tree_helper<_Key, _KeyComp, _Alloc> -{ -}; -#endif // !_LIBCPP_CXX03_LANG + _LIBCPP_DIAGNOSE_WARNING(!std::__invokable<_Compare const&, _Tp const&, _Tp const&>::value, + "the specified comparator type does not provide a const call operator") +#endif +int __diagnose_non_const_comparator(); template <class _Tp, class _Compare, class _Allocator> class __tree @@ -1341,15 +1325,20 @@ public: #endif // !_LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> __node_insert_unique(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY iterator __node_insert_unique(const_iterator __p, __node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_INLINE_VISIBILITY iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); - _LIBCPP_INLINE_VISIBILITY iterator __remove_node_pointer(__node_pointer); + _LIBCPP_INLINE_VISIBILITY iterator + __remove_node_pointer(__node_pointer) _NOEXCEPT; #if _LIBCPP_STD_VER > 14 template <class _NodeHandle, class _InsertReturnType> @@ -1358,6 +1347,9 @@ public: template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY iterator __node_handle_insert_unique(const_iterator, _NodeHandle&&); + template <class _Tree> + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_unique(_Tree& __source); template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY @@ -1365,6 +1357,9 @@ public: template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY iterator __node_handle_insert_multi(const_iterator, _NodeHandle&&); + template <class _Tree> + _LIBCPP_INLINE_VISIBILITY + void __node_handle_merge_multi(_Tree& __source); template <class _NodeHandle> @@ -1384,7 +1379,7 @@ public: void __insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, - __node_base_pointer __new_node); + __node_base_pointer __new_node) _NOEXCEPT; template <class _Key> iterator find(const _Key& __v); @@ -1488,7 +1483,7 @@ private: void __copy_assign_alloc(const __tree& __t, true_type) { if (__node_alloc() != __t.__node_alloc()) - clear(); + clear(); __node_alloc() = __t.__node_alloc(); } _LIBCPP_INLINE_VISIBILITY @@ -1830,7 +1825,7 @@ __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) __node_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<value_compare>::value && is_nothrow_move_assignable<__node_allocator>::value) - + { __move_assign(__t, integral_constant<bool, __node_traits::propagate_on_container_move_assignment::value>()); @@ -1844,10 +1839,6 @@ __tree<_Tp, _Compare, _Allocator>::~__tree() { static_assert((is_copy_constructible<value_compare>::value), "Comparator must be copy-constructible."); -#ifndef _LIBCPP_CXX03_LANG - static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>:: - __trigger_diagnostics()), ""); -#endif destroy(__root()); } @@ -2129,10 +2120,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, } template <class _Tp, class _Compare, class _Allocator> -void -__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent, - __node_base_pointer& __child, - __node_base_pointer __new_node) +void __tree<_Tp, _Compare, _Allocator>::__insert_node_at( + __parent_pointer __parent, __node_base_pointer& __child, + __node_base_pointer __new_node) _NOEXCEPT { __new_node->__left_ = nullptr; __new_node->__right_ = nullptr; @@ -2384,7 +2374,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) +__tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _NOEXCEPT { iterator __r(__ptr); ++__r; @@ -2472,6 +2462,30 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_extract(const_iterator __p) } template <class _Tp, class _Compare, class _Allocator> +template <class _Tree> +_LIBCPP_INLINE_VISIBILITY +void +__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_unique(_Tree& __source) +{ + static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); + + for (typename _Tree::iterator __i = __source.begin(); + __i != __source.end();) + { + __node_pointer __src_ptr = __i.__get_np(); + __parent_pointer __parent; + __node_base_pointer& __child = + __find_equal(__parent, _NodeTypes::__get_key(__src_ptr->__value_)); + ++__i; + if (__child != nullptr) + continue; + __source.__remove_node_pointer(__src_ptr); + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__src_ptr)); + } +} + +template <class _Tp, class _Compare, class _Allocator> template <class _NodeHandle> _LIBCPP_INLINE_VISIBILITY typename __tree<_Tp, _Compare, _Allocator>::iterator @@ -2507,6 +2521,28 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_multi( return iterator(__ptr); } +template <class _Tp, class _Compare, class _Allocator> +template <class _Tree> +_LIBCPP_INLINE_VISIBILITY +void +__tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) +{ + static_assert(is_same<typename _Tree::__node_pointer, __node_pointer>::value, ""); + + for (typename _Tree::iterator __i = __source.begin(); + __i != __source.end();) + { + __node_pointer __src_ptr = __i.__get_np(); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high( + __parent, _NodeTypes::__get_key(__src_ptr->__value_)); + ++__i; + __source.__remove_node_pointer(__src_ptr); + __insert_node_at(__parent, __child, + static_cast<__node_base_pointer>(__src_ptr)); + } +} + #endif // _LIBCPP_STD_VER > 14 template <class _Tp, class _Compare, class _Allocator> diff --git a/include/__tuple b/include/__tuple index 69d6ee961113..3b23d78afa1b 100644 --- a/include/__tuple +++ b/include/__tuple @@ -22,36 +22,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size; #if !defined(_LIBCPP_CXX03_LANG) template <class _Tp, class...> using __enable_if_tuple_size_imp = _Tp; template <class _Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const _Tp, typename enable_if<!is_volatile<_Tp>::value>::type, integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> : public integral_constant<size_t, tuple_size<_Tp>::value> {}; template <class _Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< volatile _Tp, typename enable_if<!is_const<_Tp>::value>::type, integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> : public integral_constant<size_t, tuple_size<_Tp>::value> {}; template <class _Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< +struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< const volatile _Tp, integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> : public integral_constant<size_t, tuple_size<_Tp>::value> {}; #else -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; -template <class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; +template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; #endif template <size_t _Ip, class _Tp> class _LIBCPP_TEMPLATE_VIS tuple_element; @@ -165,7 +165,7 @@ template <class ..._Tp> class _LIBCPP_TEMPLATE_VIS tuple; template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; template <class ..._Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> { }; @@ -291,7 +291,7 @@ public: template <class ..._Tp> -class _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> { }; diff --git a/include/algorithm b/include/algorithm index 90f1d246c63d..d102899f2dfc 100644 --- a/include/algorithm +++ b/include/algorithm @@ -645,13 +645,8 @@ template <class BidirectionalIterator, class Compare> #include <functional> #include <iterator> #include <cstddef> - -#if defined(__IBMCPP__) -#include "support/ibm/support.h" -#endif -#if defined(_LIBCPP_COMPILER_MSVC) -#include <intrin.h> -#endif +#include <bit> +#include <version> #include <__debug> @@ -755,6 +750,32 @@ public: bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} }; +// Perform division by two quickly for positive integers (llvm.org/PR39129) + +template <typename _Integral> +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + is_integral<_Integral>::value, + _Integral +>::type +__half_positive(_Integral __value) +{ + return static_cast<_Integral>(static_cast<typename make_unsigned<_Integral>::type>(__value) / 2); +} + +template <typename _Tp> +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +typename enable_if +< + !is_integral<_Tp>::value, + _Tp +>::type +__half_positive(_Tp __value) +{ + return __value / 2; +} + #ifdef _LIBCPP_DEBUG template <class _Compare> @@ -788,135 +809,6 @@ struct __debug_less #endif // _LIBCPP_DEBUG -// Precondition: __x != 0 -inline _LIBCPP_INLINE_VISIBILITY -unsigned __ctz(unsigned __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return static_cast<unsigned>(__builtin_ctz(__x)); -#else - static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); - static_assert(sizeof(unsigned long) == 4, ""); - unsigned long where; - // Search from LSB to MSB for first set bit. - // Returns zero if no set bit is found. - if (_BitScanForward(&where, __x)) - return where; - return 32; -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY -unsigned long __ctz(unsigned long __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return static_cast<unsigned long>(__builtin_ctzl(__x)); -#else - static_assert(sizeof(unsigned long) == sizeof(unsigned), ""); - return __ctz(static_cast<unsigned>(__x)); -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY -unsigned long long __ctz(unsigned long long __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return static_cast<unsigned long long>(__builtin_ctzll(__x)); -#else - unsigned long where; -// Search from LSB to MSB for first set bit. -// Returns zero if no set bit is found. -#if defined(_LIBCPP_HAS_BITSCAN64) - (defined(_M_AMD64) || defined(__x86_64__)) - if (_BitScanForward64(&where, __x)) - return static_cast<int>(where); -#else - // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. - // Scan the Low Word. - if (_BitScanForward(&where, static_cast<unsigned long>(__x))) - return where; - // Scan the High Word. - if (_BitScanForward(&where, static_cast<unsigned long>(__x >> 32))) - return where + 32; // Create a bit offset from the LSB. -#endif - return 64; -#endif // _LIBCPP_COMPILER_MSVC -} - -// Precondition: __x != 0 -inline _LIBCPP_INLINE_VISIBILITY -unsigned __clz(unsigned __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return static_cast<unsigned>(__builtin_clz(__x)); -#else - static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); - static_assert(sizeof(unsigned long) == 4, ""); - unsigned long where; - // Search from LSB to MSB for first set bit. - // Returns zero if no set bit is found. - if (_BitScanReverse(&where, __x)) - return 31 - where; - return 32; // Undefined Behavior. -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY -unsigned long __clz(unsigned long __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return static_cast<unsigned long>(__builtin_clzl (__x)); -#else - static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); - return __clz(static_cast<unsigned>(__x)); -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY -unsigned long long __clz(unsigned long long __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return static_cast<unsigned long long>(__builtin_clzll(__x)); -#else - unsigned long where; -// BitScanReverse scans from MSB to LSB for first set bit. -// Returns 0 if no set bit is found. -#if defined(_LIBCPP_HAS_BITSCAN64) - if (_BitScanReverse64(&where, __x)) - return static_cast<int>(63 - where); -#else - // Scan the high 32 bits. - if (_BitScanReverse(&where, static_cast<unsigned long>(__x >> 32))) - return 63 - (where + 32); // Create a bit offset from the MSB. - // Scan the low 32 bits. - if (_BitScanReverse(&where, static_cast<unsigned long>(__x))) - return 63 - where; -#endif - return 64; // Undefined Behavior. -#endif // _LIBCPP_COMPILER_MSVC -} - -inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return __builtin_popcount (__x); -#else - static_assert(sizeof(unsigned) == 4, ""); - return __popcnt(__x); -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return __builtin_popcountl (__x); -#else - static_assert(sizeof(unsigned long) == 4, ""); - return __popcnt(__x); -#endif -} - -inline _LIBCPP_INLINE_VISIBILITY int __pop_count(unsigned long long __x) { -#ifndef _LIBCPP_COMPILER_MSVC - return __builtin_popcountll(__x); -#else - static_assert(sizeof(unsigned long long) == 8, ""); - return __popcnt64(__x); -#endif -} - // all_of template <class _InputIterator, class _Predicate> @@ -2533,6 +2425,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert(__is_forward_iterator<_ForwardIterator>::value, + "std::min_element requires a ForwardIterator"); if (__first != __last) { _ForwardIterator __i = __first; @@ -2597,6 +2491,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert(__is_forward_iterator<_ForwardIterator>::value, + "std::max_element requires a ForwardIterator"); if (__first != __last) { _ForwardIterator __i = __first; @@ -2683,6 +2579,8 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 std::pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert(__is_forward_iterator<_ForwardIterator>::value, + "std::minmax_element requires a ForwardIterator"); std::pair<_ForwardIterator, _ForwardIterator> __result(__first, __first); if (__first != __last) { @@ -3027,10 +2925,11 @@ template<class _IntType> template<class _URNG> typename uniform_int_distribution<_IntType>::result_type uniform_int_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p) +_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { typedef typename conditional<sizeof(result_type) <= sizeof(uint32_t), uint32_t, uint64_t>::type _UIntType; - const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1); + const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); if (_Rp == 1) return __p.a(); const size_t _Dt = numeric_limits<_UIntType>::digits; @@ -3080,7 +2979,7 @@ public: _LIBCPP_FUNC_VIS __rs_default __rs_get(); template <class _RandomAccessIterator> -void +_LIBCPP_DEPRECATED_IN_CXX14 void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; @@ -3101,7 +3000,7 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) } template <class _RandomAccessIterator, class _RandomNumberGenerator> -void +_LIBCPP_DEPRECATED_IN_CXX14 void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, #ifndef _LIBCPP_CXX03_LANG _RandomNumberGenerator&& __rand) @@ -3116,7 +3015,8 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, for (--__last; __first < __last; ++__first, --__d) { difference_type __i = __rand(__d); - swap(*__first, *(__first + __i)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); } } } @@ -3328,7 +3228,7 @@ partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __ difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__pred(*__m)) @@ -3737,6 +3637,7 @@ __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, // stable, 4-10 compares, 0-9 swaps template <class _Compare, class _ForwardIterator> +_LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _ForwardIterator __x5, _Compare __c) @@ -4195,7 +4096,7 @@ __lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__comp(*__m, __value_)) @@ -4214,14 +4115,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { -#ifdef _LIBCPP_DEBUG - typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; - __debug_less<_Compare> __c(__comp); - return __lower_bound<_Comp_ref>(__first, __last, __value_, __c); -#else // _LIBCPP_DEBUG typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __lower_bound<_Comp_ref>(__first, __last, __value_, __comp); -#endif // _LIBCPP_DEBUG } template <class _ForwardIterator, class _Tp> @@ -4243,7 +4138,7 @@ __upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__comp(__value_, *__m)) @@ -4262,14 +4157,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value_, _Compare __comp) { -#ifdef _LIBCPP_DEBUG - typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; - __debug_less<_Compare> __c(__comp); - return __upper_bound<_Comp_ref>(__first, __last, __value_, __c); -#else // _LIBCPP_DEBUG typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __upper_bound<_Comp_ref>(__first, __last, __value_, __comp); -#endif // _LIBCPP_DEBUG } template <class _ForwardIterator, class _Tp> @@ -4291,7 +4180,7 @@ __equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va difference_type __len = _VSTD::distance(__first, __last); while (__len != 0) { - difference_type __l2 = __len / 2; + difference_type __l2 = _VSTD::__half_positive(__len); _ForwardIterator __m = __first; _VSTD::advance(__m, __l2); if (__comp(*__m, __value_)) diff --git a/include/any b/include/any index 9bd2f53c5601..781eee7869c0 100644 --- a/include/any +++ b/include/any @@ -87,13 +87,14 @@ namespace std { #include <typeinfo> #include <type_traits> #include <cstdlib> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif namespace std { -class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast +class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast { public: virtual const char* what() const _NOEXCEPT; @@ -105,12 +106,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST void __throw_bad_any_cast() { #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_any_cast(); #else - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -576,6 +578,7 @@ any make_any(initializer_list<_Up> __il, _Args&&... __args) { template <class _ValueType> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any const & __v) { using _RawValueType = __uncvref_t<_ValueType>; @@ -590,6 +593,7 @@ _ValueType any_cast(any const & __v) template <class _ValueType> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any & __v) { using _RawValueType = __uncvref_t<_ValueType>; @@ -604,6 +608,7 @@ _ValueType any_cast(any & __v) template <class _ValueType> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _ValueType any_cast(any && __v) { using _RawValueType = __uncvref_t<_ValueType>; diff --git a/include/array b/include/array index 1e6a650198b5..56f6887655aa 100644 --- a/include/array +++ b/include/array @@ -91,7 +91,7 @@ template <class T, size_t N> template <class T, size_t N > void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17 -template <class T> class tuple_size; +template <class T> struct tuple_size; template <size_t I, class T> class tuple_element; template <class T, size_t N> struct tuple_size<array<T, N>>; template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>; @@ -112,6 +112,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce #include <algorithm> #include <stdexcept> #include <cstdlib> // for _LIBCPP_UNREACHABLE +#include <version> #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -367,7 +368,7 @@ array(_Tp, _Args...) template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return _VSTD::equal(__x.begin(), __x.end(), __y.begin()); @@ -375,7 +376,7 @@ operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return !(__x == __y); @@ -383,7 +384,7 @@ operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return _VSTD::lexicographical_compare(__x.begin(), __x.end(), @@ -392,7 +393,7 @@ operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return __y < __x; @@ -400,7 +401,7 @@ operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return !(__y < __x); @@ -408,7 +409,7 @@ operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY -bool +_LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { return !(__x < __y); @@ -429,7 +430,7 @@ swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) } template <class _Tp, size_t _Size> -class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> > +struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> > : public integral_constant<size_t, _Size> {}; template <size_t _Ip, class _Tp, size_t _Size> diff --git a/include/atomic b/include/atomic index 809f78a06d36..d37e7b4b035c 100644 --- a/include/atomic +++ b/include/atomic @@ -544,6 +544,7 @@ void atomic_signal_fence(memory_order m) noexcept; #include <cstddef> #include <cstdint> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -559,10 +560,6 @@ void atomic_signal_fence(memory_order m) noexcept; #error C++ standard library is incompatible with <stdatomic.h> #endif -#if _LIBCPP_STD_VER > 14 -# define __cpp_lib_atomic_is_always_lock_free 201603L -#endif - #define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ __m == memory_order_acquire || \ diff --git a/include/bit b/include/bit new file mode 100644 index 000000000000..db3812e5b5b2 --- /dev/null +++ b/include/bit @@ -0,0 +1,158 @@ +// -*- C++ -*- +//===------------------------------ bit ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP_BIT +#define _LIBCPP_BIT + +/* + bit synopsis + +namespace std { + +} // namespace std + +*/ + +#include <__config> +#include <version> + +#if defined(__IBMCPP__) +#include "support/ibm/support.h" +#endif +#if defined(_LIBCPP_COMPILER_MSVC) +#include <intrin.h> +#endif + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_COMPILER_MSVC + +inline _LIBCPP_INLINE_VISIBILITY +int __ctz(unsigned __x) { return __builtin_ctz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY +int __ctz(unsigned long __x) { return __builtin_ctzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY +int __ctz(unsigned long long __x) { return __builtin_ctzll(__x); } + + +inline _LIBCPP_INLINE_VISIBILITY +int __clz(unsigned __x) { return __builtin_clz(__x); } + +inline _LIBCPP_INLINE_VISIBILITY +int __clz(unsigned long __x) { return __builtin_clzl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY +int __clz(unsigned long long __x) { return __builtin_clzll(__x); } + + +inline _LIBCPP_INLINE_VISIBILITY +int __popcount(unsigned __x) { return __builtin_popcount(__x); } + +inline _LIBCPP_INLINE_VISIBILITY +int __popcount(unsigned long __x) { return __builtin_popcountl(__x); } + +inline _LIBCPP_INLINE_VISIBILITY +int __popcount(unsigned long long __x) { return __builtin_popcountll(__x); } + +#else // _LIBCPP_COMPILER_MSVC + +// Precondition: __x != 0 +inline _LIBCPP_INLINE_VISIBILITY +int __ctz(unsigned __x) { + static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); + static_assert(sizeof(unsigned long) == 4, ""); + unsigned long __where; + if (_BitScanForward(&__where, __x)) + return static_cast<int>(__where); + return 32; +} + +inline _LIBCPP_INLINE_VISIBILITY +int __ctz(unsigned long __x) { + static_assert(sizeof(unsigned long) == sizeof(unsigned), ""); + return __ctz(static_cast<unsigned>(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +int __ctz(unsigned long long __x) { + unsigned long __where; +#if defined(_LIBCPP_HAS_BITSCAN64) + (defined(_M_AMD64) || defined(__x86_64__)) + if (_BitScanForward64(&__where, __x)) + return static_cast<int>(__where); +#else + // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. + if (_BitScanForward(&__where, static_cast<unsigned long>(__x))) + return static_cast<int>(__where); + if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32))) + return static_cast<int>(__where + 32); +#endif + return 64; +} + +// Precondition: __x != 0 +inline _LIBCPP_INLINE_VISIBILITY +int __clz(unsigned __x) { + static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); + static_assert(sizeof(unsigned long) == 4, ""); + unsigned long __where; + if (_BitScanReverse(&__where, __x)) + return static_cast<int>(31 - __where); + return 32; // Undefined Behavior. +} + +inline _LIBCPP_INLINE_VISIBILITY +int __clz(unsigned long __x) { + static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); + return __clz(static_cast<unsigned>(__x)); +} + +inline _LIBCPP_INLINE_VISIBILITY +int __clz(unsigned long long __x) { + unsigned long __where; +#if defined(_LIBCPP_HAS_BITSCAN64) + if (_BitScanReverse64(&__where, __x)) + return static_cast<int>(63 - __where); +#else + // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls. + if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32))) + return static_cast<int>(63 - (__where + 32)); + if (_BitScanReverse(&__where, static_cast<unsigned long>(__x))) + return static_cast<int>(63 - __where); +#endif + return 64; // Undefined Behavior. +} + +inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned __x) { + static_assert(sizeof(unsigned) == 4, ""); + return __popcnt(__x); +} + +inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned long __x) { + static_assert(sizeof(unsigned long) == 4, ""); + return __popcnt(__x); +} + +inline _LIBCPP_INLINE_VISIBILITY int __popcount(unsigned long long __x) { + static_assert(sizeof(unsigned long long) == 8, ""); + return __popcnt64(__x); +} + +#endif // _LIBCPP_COMPILER_MSVC + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_BIT diff --git a/include/bitset b/include/bitset index cd6c289b4c48..98947e027c1c 100644 --- a/include/bitset +++ b/include/bitset @@ -238,9 +238,9 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, false_type) _NOEXCEPT size_t __sz = _Size; for (size_t __i = 0; __i < sizeof(__t)/sizeof(__t[0]); ++__i, __v >>= __bits_per_word, __sz -= __bits_per_word ) if ( __sz < __bits_per_word) - __t[__i] = static_cast<__storage_type>(__v) & ( 1ULL << __sz ) - 1; + __t[__i] = static_cast<__storage_type>(__v) & ( 1ULL << __sz ) - 1; else - __t[__i] = static_cast<__storage_type>(__v); + __t[__i] = static_cast<__storage_type>(__v); _VSTD::copy(__t, __t + sizeof(__t)/sizeof(__t[0]), __first_); _VSTD::fill(__first_ + sizeof(__t)/sizeof(__t[0]), __first_ + sizeof(__first_)/sizeof(__first_[0]), @@ -254,7 +254,7 @@ __bitset<_N_words, _Size>::__init(unsigned long long __v, true_type) _NOEXCEPT { __first_[0] = __v; if (_Size < __bits_per_word) - __first_[0] &= ( 1ULL << _Size ) - 1; + __first_[0] &= ( 1ULL << _Size ) - 1; _VSTD::fill(__first_ + 1, __first_ + sizeof(__first_)/sizeof(__first_[0]), __storage_type(0)); } @@ -269,9 +269,9 @@ __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT #if __SIZEOF_SIZE_T__ == 8 : __first_{__v} #elif __SIZEOF_SIZE_T__ == 4 - : __first_{static_cast<__storage_type>(__v), - _Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word) - : static_cast<__storage_type>((__v >> __bits_per_word) & (__storage_type(1) << (_Size - __bits_per_word)) - 1)} + : __first_{static_cast<__storage_type>(__v), + _Size >= 2 * __bits_per_word ? static_cast<__storage_type>(__v >> __bits_per_word) + : static_cast<__storage_type>((__v >> __bits_per_word) & (__storage_type(1) << (_Size - __bits_per_word)) - 1)} #else #error This constructor has not been ported to this platform #endif @@ -991,7 +991,7 @@ inline size_t bitset<_Size>::count() const _NOEXCEPT { - return static_cast<size_t>(_VSTD::count(base::__make_iter(0), base::__make_iter(_Size), true)); + return static_cast<size_t>(__count_bool_true(base::__make_iter(0), _Size)); } template <size_t _Size> diff --git a/include/charconv b/include/charconv index 7cb790e1beec..064f2e11c3f3 100644 --- a/include/charconv +++ b/include/charconv @@ -87,8 +87,16 @@ namespace std { #pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD +namespace __itoa { +_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); +_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); +} + #if _LIBCPP_STD_VER > 11 enum class _LIBCPP_ENUM_VIS chars_format @@ -147,9 +155,6 @@ static constexpr uint32_t __pow10_32[] = { UINT32_C(1000000000), }; -_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer); -_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer); - template <typename _Tp, typename = void> struct _LIBCPP_HIDDEN __traits_base { @@ -607,4 +612,6 @@ from_chars(const char* __first, const char* __last, _Tp& __value, int __base) _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP_CHARCONV diff --git a/include/chrono b/include/chrono index f6a6f4b24343..96759f9860ee 100644 --- a/include/chrono +++ b/include/chrono @@ -33,9 +33,9 @@ template <class Rep> struct duration_values { public: - static constexpr Rep zero(); - static constexpr Rep max(); - static constexpr Rep min(); + static constexpr Rep zero(); // noexcept in C++20 + static constexpr Rep max(); // noexcept in C++20 + static constexpr Rep min(); // noexcept in C++20 }; // duration @@ -77,22 +77,24 @@ public: constexpr common_type<duration>::type operator+() const; constexpr common_type<duration>::type operator-() const; - constexpr duration& operator++(); - constexpr duration operator++(int); - constexpr duration& operator--(); - constexpr duration operator--(int); + constexpr duration& operator++(); // constexpr in C++17 + constexpr duration operator++(int); // constexpr in C++17 + constexpr duration& operator--(); // constexpr in C++17 + constexpr duration operator--(int); // constexpr in C++17 - constexpr duration& operator+=(const duration& d); - constexpr duration& operator-=(const duration& d); + constexpr duration& operator+=(const duration& d); // constexpr in C++17 + constexpr duration& operator-=(const duration& d); // constexpr in C++17 - duration& operator*=(const rep& rhs); - duration& operator/=(const rep& rhs); + duration& operator*=(const rep& rhs); // constexpr in C++17 + duration& operator/=(const rep& rhs); // constexpr in C++17 + duration& operator%=(const rep& rhs); // constexpr in C++17 + duration& operator%=(const duration& rhs); // constexpr in C++17 // special values - static constexpr duration zero(); - static constexpr duration min(); - static constexpr duration max(); + static constexpr duration zero(); // noexcept in C++20 + static constexpr duration min(); // noexcept in C++20 + static constexpr duration max(); // noexcept in C++20 }; typedef duration<long long, nano> nanoseconds; @@ -127,13 +129,13 @@ public: // arithmetic - time_point& operator+=(const duration& d); - time_point& operator-=(const duration& d); + time_point& operator+=(const duration& d); // constexpr in C++17 + time_point& operator-=(const duration& d); // constexpr in C++17 // special values - static constexpr time_point min(); - static constexpr time_point max(); + static constexpr time_point min(); // noexcept in C++20 + static constexpr time_point max(); // noexcept in C++20 }; } // chrono @@ -323,7 +325,7 @@ struct clock_time_conversion; template<class DestClock, class SourceClock, class Duration> auto clock_cast(const time_point<SourceClock, Duration>& t); - + // 25.8.2, class last_spec // C++20 struct last_spec; @@ -528,7 +530,7 @@ constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept; constexpr year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept; - + // 25.8.18, civil calendar conventional syntax operators // C++20 constexpr year_month operator/(const year& y, const month& m) noexcept; @@ -609,7 +611,7 @@ constexpr year_month_weekday_last constexpr year_month_weekday_last operator/(const month_weekday_last& mwdl, const year& y) noexcept; constexpr year_month_weekday_last - operator/(const month_weekday_last& mwdl, int y) noexcept; + 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; @@ -640,7 +642,7 @@ class ambiguous_local_time; // 25.10.4, information classes // C++20 struct sys_info; struct local_info; - + // 25.10.5, class time_zone // C++20 enum class choose {earliest, latest}; class time_zone; @@ -650,7 +652,7 @@ bool operator<(const time_zone& x, const time_zone& y) noexcept; bool operator>(const time_zone& x, const time_zone& y) noexcept; bool operator<=(const time_zone& x, const time_zone& y) noexcept; bool operator>=(const time_zone& x, const time_zone& y) noexcept; - + // 25.10.6, class template zoned_traits // C++20 template<class T> struct zoned_traits; @@ -724,7 +726,7 @@ template<class charT, class traits, class Alloc, class Streamable> template<class charT, class traits, class Alloc, class Streamable> basic_string<charT, traits, Alloc> format(const locale& loc, const basic_string<charT, traits, Alloc>& fmt, - const Streamable& s); + const Streamable& s); // 25.12, parsing // C++20 template<class charT, class traits, class Alloc, class Parsable> @@ -746,7 +748,8 @@ unspecified parse(const basic_string<charT, traits, Alloc>& format, Parsable& tp, basic_string<charT, traits, Alloc>& abbrev, minutes& offset); -inline constexpr last_spec last{}; // C++20 +// calendrical constants +inline constexpr last_spec last{}; // C++20 inline constexpr chrono::weekday Sunday{0}; // C++20 inline constexpr chrono::weekday Monday{1}; // C++20 inline constexpr chrono::weekday Tuesday{2}; // C++20 @@ -796,6 +799,7 @@ constexpr chrono::year operator ""y(unsigned lo #include <type_traits> #include <ratio> #include <limits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -804,6 +808,11 @@ constexpr chrono::year operator ""y(unsigned lo _LIBCPP_PUSH_MACROS #include <__undef_macros> +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG _LIBCPP_BEGIN_NAMESPACE_STD @@ -920,9 +929,9 @@ template <class _Rep> struct _LIBCPP_TEMPLATE_VIS duration_values { public: - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() {return _Rep(0);} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() {return numeric_limits<_Rep>::max();} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() {return numeric_limits<_Rep>::lowest();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} }; #if _LIBCPP_STD_VER > 14 @@ -1015,7 +1024,7 @@ class _LIBCPP_TEMPLATE_VIS duration typedef ratio<__mul<__n1, __d2, !value>::value, __mul<__n2, __d1, !value>::value> type; }; - + public: typedef _Rep rep; typedef typename _Period::type period; @@ -1077,9 +1086,9 @@ public: // special values - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() {return duration(duration_values<rep>::zero());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() {return duration(duration_values<rep>::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() {return duration(duration_values<rep>::max());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values<rep>::zero());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values<rep>::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values<rep>::max());} }; typedef duration<long long, nano> nanoseconds; @@ -1088,7 +1097,12 @@ typedef duration<long long, milli> milliseconds; typedef duration<long long > seconds; typedef duration< long, ratio< 60> > minutes; typedef duration< long, ratio<3600> > hours; - +#if _LIBCPP_STD_VER > 17 +typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days; +typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks; +typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years; +typedef duration< int, ratio_divide<years::period, ratio<12>>> months; +#endif // Duration == template <class _LhsDuration, class _RhsDuration> @@ -1355,13 +1369,13 @@ public: // arithmetic - _LIBCPP_INLINE_VISIBILITY time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} - _LIBCPP_INLINE_VISIBILITY time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} // special values - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() {return time_point(duration::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() {return time_point(duration::max());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} }; } // chrono @@ -1571,12 +1585,1158 @@ typedef steady_clock high_resolution_clock; typedef system_clock high_resolution_clock; #endif +#if _LIBCPP_STD_VER > 17 +// [time.clock.file], type file_clock +using file_clock = _VSTD_FS::_FilesystemClock; + +template<class _Duration> +using file_time = time_point<file_clock, _Duration>; + + +template <class _Duration> +using sys_time = time_point<system_clock, _Duration>; +using sys_seconds = sys_time<seconds>; +using sys_days = sys_time<days>; + +struct local_t {}; +template<class Duration> +using local_time = time_point<local_t, Duration>; +using local_seconds = local_time<seconds>; +using local_days = local_time<days>; + + +struct _LIBCPP_TYPE_VIS last_spec { explicit last_spec() = default; }; + +class _LIBCPP_TYPE_VIS day { +private: + unsigned char __d; +public: + day() = default; + explicit inline constexpr day(unsigned __val) noexcept : __d(static_cast<unsigned char>(__val)) {} + inline constexpr day& operator++() noexcept { ++__d; return *this; } + inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } + inline constexpr day& operator--() noexcept { --__d; return *this; } + inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } + constexpr day& operator+=(const days& __dd) noexcept; + constexpr day& operator-=(const days& __dd) noexcept; + explicit inline constexpr operator unsigned() const noexcept { return __d; } + inline constexpr bool ok() const noexcept { return __d >= 1 && __d <= 31; } + }; + + +inline constexpr +bool operator==(const day& __lhs, const day& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const day& __lhs, const day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const day& __lhs, const day& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const day& __lhs, const day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const day& __lhs, const day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const day& __lhs, const day& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +day operator+ (const day& __lhs, const days& __rhs) noexcept +{ return day(static_cast<unsigned>(__lhs) + __rhs.count()); } + +inline constexpr +day operator+ (const days& __lhs, const day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +day operator- (const day& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +days operator-(const day& __lhs, const day& __rhs) noexcept +{ return days(static_cast<int>(static_cast<unsigned>(__lhs)) - + static_cast<int>(static_cast<unsigned>(__rhs))); } + +inline constexpr day& day::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +inline constexpr day& day::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + + +class _LIBCPP_TYPE_VIS month { +private: + unsigned char __m; +public: + month() = default; + explicit inline constexpr month(unsigned __val) noexcept : __m(static_cast<unsigned char>(__val)) {} + inline constexpr month& operator++() noexcept { ++__m; return *this; } + inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } + inline constexpr month& operator--() noexcept { --__m; return *this; } + inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } + constexpr month& operator+=(const months& __m1) noexcept; + constexpr month& operator-=(const months& __m1) noexcept; + explicit inline constexpr operator unsigned() const noexcept { return __m; } + inline constexpr bool ok() const noexcept { return __m >= 1 && __m <= 12; } +}; + + +inline constexpr +bool operator==(const month& __lhs, const month& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const month& __lhs, const month& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const month& __lhs, const month& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const month& __lhs, const month& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month& __lhs, const month& __rhs) noexcept +{ return !(__rhs < __lhs); } + +inline constexpr +bool operator>=(const month& __lhs, const month& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +month operator+ (const month& __lhs, const months& __rhs) noexcept +{ + auto const __mu = static_cast<long long>(static_cast<unsigned>(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast<unsigned>(__mu - __yr * 12 + 1)}; +} + +inline constexpr +month operator+ (const months& __lhs, const month& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +month operator- (const month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +months operator-(const month& __lhs, const month& __rhs) noexcept +{ + auto const __dm = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); +} + +inline constexpr month& month::operator+=(const months& __dm) noexcept +{ *this = *this + __dm; return *this; } + +inline constexpr month& month::operator-=(const months& __dm) noexcept +{ *this = *this - __dm; return *this; } + + +class _LIBCPP_TYPE_VIS year { +private: + short __y; +public: + year() = default; + explicit inline constexpr year(int __val) noexcept : __y(static_cast<short>(__val)) {} + + inline constexpr year& operator++() noexcept { ++__y; return *this; }; + inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; }; + inline constexpr year& operator--() noexcept { --__y; return *this; }; + inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; }; + constexpr year& operator+=(const years& __dy) noexcept; + constexpr year& operator-=(const years& __dy) noexcept; + inline constexpr year operator+() const noexcept { return *this; } + inline constexpr year operator-() const noexcept { return year{-__y}; }; + + inline constexpr bool is_leap() const noexcept { return __y % 4 == 0 && (__y % 100 != 0 || __y % 400 == 0); } + explicit inline constexpr operator int() const noexcept { return __y; } + constexpr bool ok() const noexcept; + static inline constexpr year min() noexcept { return year{-32767}; } + static inline constexpr year max() noexcept { return year{ 32767}; } +}; + + +inline constexpr +bool operator==(const year& __lhs, const year& __rhs) noexcept +{ return static_cast<int>(__lhs) == static_cast<int>(__rhs); } + +inline constexpr +bool operator!=(const year& __lhs, const year& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year& __lhs, const year& __rhs) noexcept +{ return static_cast<int>(__lhs) < static_cast<int>(__rhs); } + +inline constexpr +bool operator> (const year& __lhs, const year& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year& __lhs, const year& __rhs) noexcept +{ return !(__rhs < __lhs); } + +inline constexpr +bool operator>=(const year& __lhs, const year& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +year operator+ (const year& __lhs, const years& __rhs) noexcept +{ return year(static_cast<int>(__lhs) + __rhs.count()); } + +inline constexpr +year operator+ (const years& __lhs, const year& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year operator- (const year& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +years operator-(const year& __lhs, const year& __rhs) noexcept +{ return years{static_cast<int>(__lhs) - static_cast<int>(__rhs)}; } + + +inline constexpr year& year::operator+=(const years& __dy) noexcept +{ *this = *this + __dy; return *this; } + +inline constexpr year& year::operator-=(const years& __dy) noexcept +{ *this = *this - __dy; return *this; } + +inline constexpr bool year::ok() const noexcept +{ return static_cast<int>(min()) <= __y && __y <= static_cast<int>(max()); } + +class _LIBCPP_TYPE_VIS weekday_indexed; +class _LIBCPP_TYPE_VIS weekday_last; + +class _LIBCPP_TYPE_VIS weekday { +private: + unsigned char __wd; +public: + weekday() = default; + inline explicit constexpr weekday(unsigned __val) noexcept : __wd(static_cast<unsigned char>(__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 + : __wd(__weekday_from_days(__locd.time_since_epoch().count())) {} + + inline constexpr weekday& operator++() noexcept { __wd = (__wd == 6 ? 0 : __wd + 1); return *this; } + inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } + inline constexpr weekday& operator--() noexcept { __wd = (__wd == 0 ? 6 : __wd - 1); return *this; } + 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 bool ok() const noexcept { return __wd <= 6; } + constexpr weekday_indexed operator[](unsigned __index) const noexcept; + constexpr weekday_last operator[](last_spec) const noexcept; + + static constexpr unsigned char __weekday_from_days(int __days) noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#weekday_from_days +inline constexpr +unsigned char weekday::__weekday_from_days(int __days) noexcept +{ + return static_cast<unsigned char>( + static_cast<unsigned>(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) + ); +} + +inline constexpr +bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) == static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept +{ return static_cast<unsigned>(__lhs) < static_cast<unsigned>(__rhs); } + +inline constexpr +bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept +{ return !(__lhs < __rhs); } + +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 __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast<unsigned>(__mu - __yr * 7)}; +} + +constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept +{ return __lhs + -__rhs; } + +constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept +{ + const int __wdu = static_cast<unsigned>(__lhs) - static_cast<unsigned>(__rhs); + const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; + return days{__wdu - __wk * 7}; +} + +inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept +{ *this = *this + __dd; return *this; } + +inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept +{ *this = *this - __dd; return *this; } + + +class _LIBCPP_TYPE_VIS weekday_indexed { +private: + _VSTD::chrono::weekday __wd; + unsigned char __idx; +public: + weekday_indexed() = default; + inline constexpr weekday_indexed(const _VSTD::chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd{__wdval}, __idx(__idxval) {} + inline constexpr _VSTD::chrono::weekday weekday() const noexcept { return __wd; } + inline constexpr unsigned index() const noexcept { return __idx; } + inline constexpr bool ok() const noexcept { return __wd.ok() && __idx >= 1 && __idx <= 5; } +}; + +inline constexpr +bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } + +inline constexpr +bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +class _LIBCPP_TYPE_VIS weekday_last { +private: + _VSTD::chrono::weekday __wd; +public: + explicit constexpr weekday_last(const _VSTD::chrono::weekday& __val) noexcept + : __wd{__val} {} + constexpr _VSTD::chrono::weekday weekday() const noexcept { return __wd; } + constexpr bool ok() const noexcept { return __wd.ok(); } +}; + +inline constexpr +bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return __lhs.weekday() == __rhs.weekday(); } + +inline constexpr +bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } + +inline constexpr +weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } + + +inline constexpr last_spec last{}; +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; + +inline constexpr month January{1}; +inline constexpr month February{2}; +inline constexpr month March{3}; +inline constexpr month April{4}; +inline constexpr month May{5}; +inline constexpr month June{6}; +inline constexpr month July{7}; +inline constexpr month August{8}; +inline constexpr month September{9}; +inline constexpr month October{10}; +inline constexpr month November{11}; +inline constexpr month December{12}; + + +class _LIBCPP_TYPE_VIS month_day { +private: + chrono::month __m; + chrono::day __d; +public: + month_day() = default; + constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m{__mval}, __d{__dval} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + constexpr bool ok() const noexcept; +}; + +inline constexpr +bool month_day::ok() const noexcept +{ + if (!__m.ok()) return false; + const unsigned __dval = static_cast<unsigned>(__d); + if (__dval < 1 || __dval > 31) return false; + if (__dval <= 29) return true; +// Now we've got either 30 or 31 + const unsigned __mval = static_cast<unsigned>(__m); + if (__mval == 2) return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; +} + +inline constexpr +bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +inline constexpr +bool operator!=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +month_day operator/(const month& __lhs, const day& __rhs) noexcept +{ return month_day{__lhs, __rhs}; } + +constexpr +month_day operator/(const day& __lhs, const month& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +month_day operator/(const month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +constexpr +month_day operator/(int __lhs, const day& __rhs) noexcept +{ return month(__lhs) / __rhs; } + +constexpr +month_day operator/(const day& __lhs, int __rhs) noexcept +{ return month(__rhs) / __lhs; } + + +inline constexpr +bool operator< (const month_day& __lhs, const month_day& __rhs) noexcept +{ return __lhs.month() != __rhs.month() ? __lhs.month() < __rhs.month() : __lhs.day() < __rhs.day(); } + +inline constexpr +bool operator> (const month_day& __lhs, const month_day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const month_day& __lhs, const month_day& __rhs) noexcept +{ return !(__lhs < __rhs); } + + + +class _LIBCPP_TYPE_VIS month_day_last { +private: + chrono::month __m; +public: + explicit constexpr month_day_last(const chrono::month& __val) noexcept + : __m{__val} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr bool ok() const noexcept { return __m.ok(); } +}; + +inline constexpr +bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month(); } + +inline constexpr +bool operator!=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __lhs.month() < __rhs.month(); } + +inline constexpr +bool operator> (const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const month_day_last& __lhs, const month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +month_day_last operator/(const month& __lhs, last_spec) noexcept +{ return month_day_last{__lhs}; } + +inline constexpr +month_day_last operator/(last_spec, const month& __rhs) noexcept +{ return month_day_last{__rhs}; } + +inline constexpr +month_day_last operator/(int __lhs, last_spec) noexcept +{ return month_day_last{month(__lhs)}; } + +inline constexpr +month_day_last operator/(last_spec, int __rhs) noexcept +{ return month_day_last{month(__rhs)}; } + + +class _LIBCPP_TYPE_VIS month_weekday { +private: + chrono::month __m; + chrono::weekday_indexed __wdi; +public: + month_weekday() = default; + constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __m{__mval}, __wdi{__wdival} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } + inline constexpr bool ok() const noexcept { return __m.ok() && __wdi.ok(); } +}; + +inline constexpr +bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +inline constexpr +bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{__lhs, __rhs}; } + +inline constexpr +month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept +{ return month_weekday{month(__lhs), __rhs}; } + +inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept +{ return month_weekday{__rhs, __lhs}; } + +inline constexpr +month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept +{ return month_weekday{month(__rhs), __lhs}; } + + +class _LIBCPP_TYPE_VIS month_weekday_last { + chrono::month __m; + chrono::weekday_last __wdl; + public: + constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __m{__mval}, __wdl{__wdlval} {} + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } + inline constexpr bool ok() const noexcept { return __m.ok() && __wdl.ok(); } +}; + +inline constexpr +bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +inline constexpr +bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +inline constexpr +month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{__lhs, __rhs}; } + +inline constexpr +month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept +{ return month_weekday_last{month(__lhs), __rhs}; } + +inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept +{ return month_weekday_last{__rhs, __lhs}; } + +inline constexpr +month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept +{ return month_weekday_last{month(__rhs), __lhs}; } + + +class _LIBCPP_TYPE_VIS year_month { + chrono::year __y; + chrono::month __m; +public: + year_month() = default; + constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y{__yval}, __m{__mval} {} + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m += __dm; return *this; } + inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m -= __dm; return *this; } + inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y += __dy; return *this; } + inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y -= __dy; return *this; } + inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok(); } +}; + +inline constexpr +year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } + +inline constexpr +year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } + +inline constexpr +bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } + +inline constexpr +bool operator!=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month& __lhs, const year_month& __rhs) noexcept +{ return __lhs.year() != __rhs.year() ? __lhs.year() < __rhs.year() : __lhs.month() < __rhs.month(); } + +inline constexpr +bool operator> (const year_month& __lhs, const year_month& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month& __lhs, const year_month& __rhs) noexcept +{ return !(__lhs < __rhs); } + +constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept +{ + int __dmi = static_cast<int>(static_cast<unsigned>(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast<unsigned>(__dmi)); +} + +constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month(); } + +constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept +{ return __rhs + __lhs; } + +constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept +{ return (__lhs.year() - __rhs.year()) + months(static_cast<unsigned>(__lhs.month()) - static_cast<unsigned>(__rhs.month())); } + +constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +class year_month_day_last; + +class _LIBCPP_TYPE_VIS year_month_day { +private: + chrono::year __y; + chrono::month __m; + chrono::day __d; +public: + year_month_day() = default; + inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y{__yval}, __m{__mval}, __d{__dval} {} + constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} + + constexpr year_month_day& operator+=(const months& __dm) noexcept; + constexpr year_month_day& operator-=(const months& __dm) noexcept; + constexpr year_month_day& operator+=(const years& __dy) noexcept; + constexpr year_month_day& operator-=(const years& __dy) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::day day() const noexcept { return __d; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + + constexpr bool ok() const noexcept; + + static constexpr year_month_day __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; +}; + + +// https://howardhinnant.github.io/date_algorithms.html#civil_from_days +inline constexpr +year_month_day +year_month_day::__from_days(days __d) noexcept +{ + static_assert(std::numeric_limits<unsigned>::digits >= 18, ""); + static_assert(std::numeric_limits<int>::digits >= 20 , ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] + const int __yr = static_cast<int>(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] + const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +} + +// https://howardhinnant.github.io/date_algorithms.html#days_from_civil +inline constexpr days year_month_day::__to_days() const noexcept +{ + static_assert(std::numeric_limits<unsigned>::digits >= 18, ""); + static_assert(std::numeric_limits<int>::digits >= 20 , ""); + + const int __yr = static_cast<int>(__y) - (__m <= February); + const unsigned __mth = static_cast<unsigned>(__m); + const unsigned __dy = static_cast<unsigned>(__d); + + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast<int>(__doe) - 719468}; +} + +inline constexpr +bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } + +inline constexpr +bool operator!=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + if (__lhs.month() < __rhs.month()) return true; + if (__lhs.month() > __rhs.month()) return false; + return __lhs.day() < __rhs.day(); +} + +inline constexpr +bool operator> (const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month_day& __lhs, const year_month_day& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr +year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept +{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_day operator/(const year_month& __lhs, int __rhs) noexcept +{ return __lhs / day(__rhs); } + +inline constexpr +year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept +{ return __lhs / __rhs.month() / __rhs.day(); } + +inline constexpr +year_month_day operator/(int __lhs, const month_day& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_day operator/(const month_day& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept +{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } + +inline constexpr +year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr +year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept +{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } + +inline constexpr +year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept +{ return __lhs + -__rhs; } + +inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class _LIBCPP_TYPE_VIS year_month_day_last { +private: + chrono::year __y; + chrono::month_day_last __mdl; +public: + constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y{__yval}, __mdl{__mdlval} {} + + constexpr year_month_day_last& operator+=(const months& __m) noexcept; + constexpr year_month_day_last& operator-=(const months& __m) noexcept; + constexpr year_month_day_last& operator+=(const years& __y) noexcept; + constexpr year_month_day_last& operator-=(const years& __y) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __mdl.month(); } + inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl; } + constexpr chrono::day day() const noexcept; + inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __mdl.ok(); } +}; + +inline constexpr +chrono::day year_month_day_last::day() const noexcept +{ + constexpr chrono::day __d[] = + { + chrono::day(31), chrono::day(28), chrono::day(31), + chrono::day(30), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(31), chrono::day(30), + chrono::day(31), chrono::day(30), chrono::day(31) + }; + return month() != February || !__y.is_leap() ? + __d[static_cast<unsigned>(month()) - 1] : chrono::day{29}; +} + +inline constexpr +bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } + +inline constexpr +bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ + if (__lhs.year() < __rhs.year()) return true; + if (__lhs.year() > __rhs.year()) return false; + return __lhs.month_day_last() < __rhs.month_day_last(); +} + +inline constexpr +bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs < __lhs; } + +inline constexpr +bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__rhs < __lhs);} + +inline constexpr +bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept +{ return !(__lhs < __rhs); } + +inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept +{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } + +inline constexpr year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{__lhs, __rhs}; } + +inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept +{ return year_month_day_last{year{__lhs}, __rhs}; } + +inline constexpr year_month_day_last operator/(const month_day_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept +{ return year{__rhs} / __lhs; } + + +inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / last; } + +inline constexpr +year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } + +inline constexpr +year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept + : __y{__ymdl.year()}, __m{__ymdl.month()}, __d{__ymdl.day()} {} + +inline constexpr bool year_month_day::ok() const noexcept +{ + if (!__y.ok() || !__m.ok()) return false; + return chrono::day{1} <= __d && __d <= (__y / __m / last).day(); +} + +class _LIBCPP_TYPE_VIS year_month_weekday { + chrono::year __y; + chrono::month __m; + chrono::weekday_indexed __wdi; +public: + year_month_weekday() = default; + constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __y{__yval}, __m{__mval}, __wdi{__wdival} {} + constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + constexpr year_month_weekday& operator+=(const months& m) noexcept; + constexpr year_month_weekday& operator-=(const months& m) noexcept; + constexpr year_month_weekday& operator+=(const years& y) noexcept; + constexpr year_month_weekday& operator-=(const years& y) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday weekday() const noexcept { return __wdi.weekday(); } + inline constexpr unsigned index() const noexcept { return __wdi.index(); } + inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi; } + + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + inline constexpr bool ok() const noexcept + { + if (!__y.ok() || !__m.ok() || !__wdi.ok()) return false; + // TODO: make sure it's a valid date + return true; + } + + static constexpr year_month_weekday __from_days(days __d) noexcept; + constexpr days __to_days() const noexcept; +}; + +inline constexpr +year_month_weekday year_month_weekday::__from_days(days __d) noexcept +{ + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), + __wd[(static_cast<unsigned>(__ymd.day())-1)/7+1]}; +} + +inline constexpr +days year_month_weekday::__to_days() const noexcept +{ + const sys_days __sysd = sys_days(__y/__m/1); + return (__sysd + (__wdi.weekday() - chrono::weekday(__sysd) + days{(__wdi.index()-1)*7})) + .time_since_epoch(); +} + +inline constexpr +bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } + +inline constexpr +bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept +{ return !(__lhs == __rhs); } + +inline constexpr +year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept +{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept +{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } + +inline constexpr +year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } + +inline constexpr +year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } + +inline constexpr +year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + + +inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } +inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } + +class _LIBCPP_TYPE_VIS year_month_weekday_last { +private: + chrono::year __y; + chrono::month __m; + chrono::weekday_last __wdl; +public: + constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __y{__yval}, __m{__mval}, __wdl{__wdlval} {} + constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + + inline constexpr chrono::year year() const noexcept { return __y; } + inline constexpr chrono::month month() const noexcept { return __m; } + inline constexpr chrono::weekday weekday() const noexcept { return __wdl.weekday(); } + inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl; } + inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + inline constexpr bool ok() const noexcept { return __y.ok() && __m.ok() && __wdl.ok(); } + + constexpr days __to_days() const noexcept; + +}; + +inline constexpr +days year_month_weekday_last::__to_days() const noexcept +{ + const sys_days __last = sys_days{__y/__m/last}; + return (__last - (chrono::weekday{__last} - __wdl.weekday())).time_since_epoch(); + +} + +inline constexpr +bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } + +inline constexpr +bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return !(__lhs == __rhs); } + + +inline constexpr +year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } + +inline constexpr +year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept +{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } + +inline constexpr +year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept +{ return year(__lhs) / __rhs; } + +inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept +{ return __rhs / __lhs; } + +inline constexpr +year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept +{ return year(__rhs) / __lhs; } + + +inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } + +inline constexpr +year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr +year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } + +inline constexpr +year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept +{ return __rhs + __lhs; } + +inline constexpr +year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept +{ return __lhs + (-__rhs); } + +inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } +inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } +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; } + +#endif // _LIBCPP_STD_VER > 17 } // chrono #if _LIBCPP_STD_VER > 11 // Suffixes for duration literals [time.duration.literals] inline namespace literals -{ +{ inline namespace chrono_literals { @@ -1633,7 +2793,7 @@ inline namespace literals { return chrono::duration<long double, micro> (__us); } - + constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) { @@ -1645,6 +2805,17 @@ inline namespace literals return chrono::duration<long double, nano> (__ns); } +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX20_CHRONO_LITERALS) + constexpr chrono::day operator ""d(unsigned long long __d) noexcept + { + return chrono::day(static_cast<unsigned>(__d)); + } + + constexpr chrono::year operator ""y(unsigned long long __y) noexcept + { + return chrono::year(static_cast<int>(__y)); + } +#endif }} namespace chrono { // hoist the literals into namespace std::chrono @@ -1655,6 +2826,40 @@ namespace chrono { // hoist the literals into namespace std::chrono _LIBCPP_END_NAMESPACE_STD +#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM +struct _FilesystemClock { +#if !defined(_LIBCPP_HAS_NO_INT128) + typedef __int128_t rep; + typedef nano period; +#else + typedef long long rep; + typedef nano period; +#endif + + typedef chrono::duration<rep, period> duration; + typedef chrono::time_point<_FilesystemClock> time_point; + + static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; + + _LIBCPP_FUNC_VIS static time_point now() noexcept; + + _LIBCPP_INLINE_VISIBILITY + static time_t to_time_t(const time_point& __t) noexcept { + typedef chrono::duration<rep> __secs; + return time_t( + chrono::duration_cast<__secs>(__t.time_since_epoch()).count()); + } + + _LIBCPP_INLINE_VISIBILITY + static time_point from_time_t(time_t __t) noexcept { + typedef chrono::duration<rep> __secs; + return time_point(__secs(__t)); + } +}; +_LIBCPP_END_NAMESPACE_FILESYSTEM +#endif // !_LIBCPP_CXX03_LANG + _LIBCPP_POP_MACROS #endif // _LIBCPP_CHRONO diff --git a/include/cmath b/include/cmath index ffb1c46c7b68..f5f62adcfb8d 100644 --- a/include/cmath +++ b/include/cmath @@ -303,6 +303,7 @@ long double truncl(long double x); #include <__config> #include <math.h> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/include/complex b/include/complex index d692ee319204..8cf6a946d711 100644 --- a/include/complex +++ b/include/complex @@ -245,6 +245,7 @@ template<class T, class charT, class traits> #include <stdexcept> #include <cmath> #include <sstream> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/include/cstddef b/include/cstddef index adeefdac9be6..b4c42b19ddb2 100644 --- a/include/cstddef +++ b/include/cstddef @@ -35,6 +35,7 @@ Types: */ #include <__config> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -50,7 +51,7 @@ using ::ptrdiff_t; using ::size_t; #if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \ - defined(__DEFINED_max_align_t) + defined(__DEFINED_max_align_t) || defined(__NetBSD__) // Re-use the compiler's <stddef.h> max_align_t where possible. using ::max_align_t; #else @@ -66,10 +67,10 @@ enum class byte : unsigned char {}; constexpr byte operator| (byte __lhs, byte __rhs) noexcept { - return static_cast<byte>( - static_cast<unsigned char>( - static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs) - )); + return static_cast<byte>( + static_cast<unsigned char>( + static_cast<unsigned int>(__lhs) | static_cast<unsigned int>(__rhs) + )); } constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept @@ -77,10 +78,10 @@ constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept constexpr byte operator& (byte __lhs, byte __rhs) noexcept { - return static_cast<byte>( - static_cast<unsigned char>( - static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs) - )); + return static_cast<byte>( + static_cast<unsigned char>( + static_cast<unsigned int>(__lhs) & static_cast<unsigned int>(__rhs) + )); } constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept @@ -88,13 +89,13 @@ constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept constexpr byte operator^ (byte __lhs, byte __rhs) noexcept { - return static_cast<byte>( - static_cast<unsigned char>( - static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs) - )); + return static_cast<byte>( + static_cast<unsigned char>( + static_cast<unsigned int>(__lhs) ^ static_cast<unsigned int>(__rhs) + )); } -constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept +constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept { return __lhs = __lhs ^ __rhs; } constexpr byte operator~ (byte __b) noexcept diff --git a/include/cstdlib b/include/cstdlib index 78c428403c37..00c604e67623 100644 --- a/include/cstdlib +++ b/include/cstdlib @@ -151,11 +151,11 @@ using ::mbtowc; using ::wctomb; using ::mbstowcs; using ::wcstombs; -#ifdef _LIBCPP_HAS_QUICK_EXIT +#if !defined(_LIBCPP_CXX03_LANG) && defined(_LIBCPP_HAS_QUICK_EXIT) using ::at_quick_exit; using ::quick_exit; #endif -#ifdef _LIBCPP_HAS_C11_FEATURES +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES) using ::aligned_alloc; #endif diff --git a/include/ctime b/include/ctime index 81cf11a466c2..8264fe33b964 100644 --- a/include/ctime +++ b/include/ctime @@ -73,7 +73,7 @@ using ::gmtime; using ::localtime; #endif using ::strftime; -#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_C11_FEATURES) +#if _LIBCPP_STD_VER > 14 && defined(_LIBCPP_HAS_TIMESPEC_GET) using ::timespec_get; #endif diff --git a/include/deque b/include/deque index bfbd3a5ef543..6f7d04be52be 100644 --- a/include/deque +++ b/include/deque @@ -150,6 +150,11 @@ template <class T, class Allocator> void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(deque<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -161,6 +166,7 @@ template <class T, class Allocator> #include <iterator> #include <algorithm> #include <stdexcept> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -986,7 +992,7 @@ public: #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif protected: @@ -1155,7 +1161,7 @@ __deque_base<_Tp, _Allocator>::swap(__deque_base& __c) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -2341,7 +2347,7 @@ deque<_Tp, _Allocator>::__add_front_capacity() _Dp(__a, __base::__block_size)); __buf.push_back(__hold.get()); __hold.release(); - + for (typename __base::__map_pointer __i = __base::__map_.begin(); __i != __base::__map_.end(); ++__i) __buf.push_back(*__i); @@ -2603,6 +2609,7 @@ template <class _Tp, class _Allocator> void deque<_Tp, _Allocator>::pop_back() { + _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque"); allocator_type& __a = __base::__alloc(); size_type __p = __base::size() + __base::__start_ - 1; __alloc_traits::destroy(__a, __to_raw_pointer(*(__base::__map_.begin() + @@ -2853,7 +2860,7 @@ deque<_Tp, _Allocator>::swap(deque& __c) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -2926,6 +2933,19 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Tp, class _Allocator, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +void erase(deque<_Tp, _Allocator>& __c, const _Up& __v) +{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); } + +template <class _Tp, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); } +#endif + + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/exception b/include/exception index b517486b5a8e..fdd83d10c3da 100644 --- a/include/exception +++ b/include/exception @@ -81,6 +81,7 @@ template <class E> void rethrow_if_nested(const E& e); #include <cstddef> #include <cstdlib> #include <type_traits> +#include <version> #if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) #include <vcruntime_exception.h> @@ -163,7 +164,7 @@ public: }; template<class _Ep> -exception_ptr +_LIBCPP_INLINE_VISIBILITY exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { #ifndef _LIBCPP_NO_EXCEPTIONS @@ -222,7 +223,7 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p); template <class _E> void *__GetExceptionInfo(_E); template<class _Ep> -exception_ptr +_LIBCPP_INLINE_VISIBILITY exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e)); diff --git a/include/experimental/any b/include/experimental/any index 1dcdd0f25ec3..d9c95342589f 100644 --- a/include/experimental/any +++ b/include/experimental/any @@ -1,11 +1,21 @@ // -*- C++ -*- -//===------------------------------ any -----------------------------------===// +//===------------------------------- any ----------------------------------===// // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_ANY +#define _LIBCPP_EXPERIMENTAL_ANY -#error "<experimental/any> has been removed. Use <any> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/any> has been removed. Use <any> instead.") +#else +# warning "<experimental/any> has been removed. Use <any> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_ANY diff --git a/include/experimental/chrono b/include/experimental/chrono index 591cf7160c13..30c7e4a9d5ac 100644 --- a/include/experimental/chrono +++ b/include/experimental/chrono @@ -1,11 +1,21 @@ // -*- C++ -*- -//===------------------------------ chrono ---------------------------------===// +//===---------------------------- chrono ----------------------------------===// // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_CHRONO +#define _LIBCPP_EXPERIMENTAL_CHRONO -#error "<experimental/chrono> has been removed. Use <chrono> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/chrono> has been removed. Use <chrono> instead.") +#else +# warning "<experimental/chrono> has been removed. Use <chrono> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_CHRONO diff --git a/include/experimental/coroutine b/include/experimental/coroutine index 1eb224a535a1..7cb39b81b48f 100644 --- a/include/experimental/coroutine +++ b/include/experimental/coroutine @@ -214,7 +214,7 @@ public: _LIBCPP_INLINE_VISIBILITY _Promise& promise() const { return *static_cast<_Promise*>( - __builtin_coro_promise(this->__handle_, __alignof(_Promise), false)); + __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); } public: @@ -254,7 +254,7 @@ public: coroutine_handle __tmp; __tmp.__handle_ = __builtin_coro_promise( _VSTD::addressof(const_cast<_RawPromise&>(__promise)), - __alignof(_Promise), true); + _LIBCPP_ALIGNOF(_Promise), true); return __tmp; } }; @@ -272,7 +272,7 @@ public: _LIBCPP_INLINE_VISIBILITY _Promise& promise() const { return *static_cast<_Promise*>( - __builtin_coro_promise(this->__handle_, __alignof(_Promise), false)); + __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); } _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; } diff --git a/include/experimental/dynarray b/include/experimental/dynarray deleted file mode 100644 index a60c87c3f970..000000000000 --- a/include/experimental/dynarray +++ /dev/null @@ -1,305 +0,0 @@ -// -*- C++ -*- -//===-------------------------- dynarray ----------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_DYNARRAY -#define _LIBCPP_DYNARRAY - -/* - dynarray synopsis - -namespace std { namespace experimental { - -template< typename T > -class dynarray -{ - // types: - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef implementation-defined iterator; - typedef implementation-defined const_iterator; - typedef reverse_iterator<iterator> reverse_iterator; - typedef reverse_iterator<const_iterator> const_reverse_iterator; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - -public: - // construct/copy/destroy: - explicit dynarray(size_type c); - dynarray(size_type c, const T& v); - dynarray(const dynarray& d); - dynarray(initializer_list<T>); - - template <class Alloc> - dynarray(allocator_arg_t, const Alloc& a, size_type c, const Alloc& alloc); - template <class Alloc> - dynarray(allocator_arg_t, const Alloc& a, size_type c, const T& v, const Alloc& alloc); - template <class Alloc> - dynarray(allocator_arg_t, const Alloc& a, const dynarray& d, const Alloc& alloc); - template <class Alloc> - dynarray(allocator_arg_t, const Alloc& a, initializer_list<T>, const Alloc& alloc); - dynarray& operator=(const dynarray&) = delete; - ~dynarray(); - - // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - const_iterator cbegin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cend() const noexcept; - - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - const_reverse_iterator crbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - const_reverse_iterator crend() const noexcept; - - // capacity: - size_type size() const noexcept; - size_type max_size() const noexcept; - bool empty() const noexcept; - - // element access: - reference operator[](size_type n); - const_reference operator[](size_type n) const; - - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; - - const_reference at(size_type n) const; - reference at(size_type n); - - // data access: - T* data() noexcept; - const T* data() const noexcept; - - // mutating member functions: - void fill(const T& v); -}; - -}} // std::experimental - -*/ -#include <__config> -#if _LIBCPP_STD_VER > 11 - -#include <__functional_base> -#include <iterator> -#include <stdexcept> -#include <initializer_list> -#include <new> -#include <algorithm> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header -#endif - -_LIBCPP_PUSH_MACROS -#include <__undef_macros> - -namespace std { namespace experimental { inline namespace __array_extensions_v1 { - -template <class _Tp> -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_DYNARRAY dynarray -{ -public: - // types: - typedef dynarray __self; - typedef _Tp value_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* iterator; - typedef const value_type* const_iterator; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - -private: - size_t __size_; - value_type * __base_; - _LIBCPP_INLINE_VISIBILITY dynarray () noexcept : __size_(0), __base_(nullptr) {} - - static inline _LIBCPP_INLINE_VISIBILITY - value_type* __allocate(size_t __count) { - if (numeric_limits<size_t>::max() / sizeof (value_type) <= __count) - __throw_bad_array_length(); - - return static_cast<value_type *>( - _VSTD::__libcpp_allocate(sizeof(value_type) * __count, __alignof(value_type))); - } - - static inline _LIBCPP_INLINE_VISIBILITY - void __deallocate_value(value_type* __ptr ) noexcept { - _VSTD::__libcpp_deallocate(static_cast<void *>(__ptr), __alignof(value_type)); - } - -public: - - _LIBCPP_INLINE_VISIBILITY - explicit dynarray(size_type __c); - _LIBCPP_INLINE_VISIBILITY - dynarray(size_type __c, const value_type& __v); - _LIBCPP_INLINE_VISIBILITY - dynarray(const dynarray& __d); - _LIBCPP_INLINE_VISIBILITY - dynarray(initializer_list<value_type>); - -// We're not implementing these right now. -// Updated with the resolution of LWG issue #2255 -// template <typename _Alloc> -// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c); -// template <typename _Alloc> -// dynarray(allocator_arg_t, const _Alloc& __alloc, size_type __c, const value_type& __v); -// template <typename _Alloc> -// dynarray(allocator_arg_t, const _Alloc& __alloc, const dynarray& __d); -// template <typename _Alloc> -// dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>); - - dynarray& operator=(const dynarray&) = delete; - _LIBCPP_INLINE_VISIBILITY - ~dynarray(); - - // iterators: - inline _LIBCPP_INLINE_VISIBILITY iterator begin() noexcept { return iterator(data()); } - inline _LIBCPP_INLINE_VISIBILITY const_iterator begin() const noexcept { return const_iterator(data()); } - inline _LIBCPP_INLINE_VISIBILITY const_iterator cbegin() const noexcept { return const_iterator(data()); } - inline _LIBCPP_INLINE_VISIBILITY iterator end() noexcept { return iterator(data() + __size_); } - inline _LIBCPP_INLINE_VISIBILITY const_iterator end() const noexcept { return const_iterator(data() + __size_); } - inline _LIBCPP_INLINE_VISIBILITY const_iterator cend() const noexcept { return const_iterator(data() + __size_); } - - inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } - inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); } - inline _LIBCPP_INLINE_VISIBILITY reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); } - inline _LIBCPP_INLINE_VISIBILITY const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); } - - // capacity: - inline _LIBCPP_INLINE_VISIBILITY size_type size() const noexcept { return __size_; } - inline _LIBCPP_INLINE_VISIBILITY size_type max_size() const noexcept { return __size_; } - inline _LIBCPP_INLINE_VISIBILITY bool empty() const noexcept { return __size_ == 0; } - - // element access: - inline _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) { return data()[__n]; } - inline _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const { return data()[__n]; } - - inline _LIBCPP_INLINE_VISIBILITY reference front() { return data()[0]; } - inline _LIBCPP_INLINE_VISIBILITY const_reference front() const { return data()[0]; } - inline _LIBCPP_INLINE_VISIBILITY reference back() { return data()[__size_-1]; } - inline _LIBCPP_INLINE_VISIBILITY const_reference back() const { return data()[__size_-1]; } - - inline _LIBCPP_INLINE_VISIBILITY const_reference at(size_type __n) const; - inline _LIBCPP_INLINE_VISIBILITY reference at(size_type __n); - - // data access: - inline _LIBCPP_INLINE_VISIBILITY _Tp* data() noexcept { return __base_; } - inline _LIBCPP_INLINE_VISIBILITY const _Tp* data() const noexcept { return __base_; } - - // mutating member functions: - inline _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __v) { fill_n(begin(), __size_, __v); } -}; - -template <class _Tp> -inline -dynarray<_Tp>::dynarray(size_type __c) : dynarray () -{ - __base_ = __allocate (__c); - value_type *__data = data (); - for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) - ::new (__data) value_type; -} - -template <class _Tp> -inline -dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () -{ - __base_ = __allocate (__c); - value_type *__data = data (); - for ( __size_ = 0; __size_ < __c; ++__size_, ++__data ) - ::new (__data) value_type (__v); -} - -template <class _Tp> -inline -dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () -{ - size_t sz = __il.size(); - __base_ = __allocate (sz); - value_type *__data = data (); - auto src = __il.begin(); - for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) - ::new (__data) value_type (*src); -} - -template <class _Tp> -inline -dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () -{ - size_t sz = __d.size(); - __base_ = __allocate (sz); - value_type *__data = data (); - auto src = __d.begin(); - for ( __size_ = 0; __size_ < sz; ++__size_, ++__data, ++src ) - ::new (__data) value_type (*src); -} - -template <class _Tp> -inline -dynarray<_Tp>::~dynarray() -{ - value_type *__data = data () + __size_; - for ( size_t i = 0; i < __size_; ++i ) - (--__data)->value_type::~value_type(); - __deallocate_value( __base_ ); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename dynarray<_Tp>::reference -dynarray<_Tp>::at(size_type __n) -{ - if (__n >= __size_) - __throw_out_of_range("dynarray::at"); - - return data()[__n]; -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename dynarray<_Tp>::const_reference -dynarray<_Tp>::at(size_type __n) const -{ - if (__n >= __size_) - __throw_out_of_range("dynarray::at"); - - return data()[__n]; -} - -}}} - - -_LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp, class _Alloc> -struct _LIBCPP_TEMPLATE_VIS uses_allocator<std::experimental::dynarray<_Tp>, _Alloc> : true_type {}; -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_POP_MACROS - -#endif // if _LIBCPP_STD_VER > 11 -#endif // _LIBCPP_DYNARRAY diff --git a/include/experimental/memory_resource b/include/experimental/memory_resource index 221ce5b8eacc..83781d462034 100644 --- a/include/experimental/memory_resource +++ b/include/experimental/memory_resource @@ -98,7 +98,7 @@ size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT // 8.5, memory.resource class _LIBCPP_TYPE_VIS memory_resource { - static const size_t __max_align = alignof(max_align_t); + static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t); // 8.5.2, memory.resource.public public: @@ -190,7 +190,7 @@ public: " 'n' exceeds maximum supported size"); } return static_cast<_ValueType*>( - __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType)) + __res_->allocate(__n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)) ); } @@ -198,7 +198,7 @@ public: void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { _LIBCPP_ASSERT(__n <= __max_size(), "deallocate called for size which exceeds max_size()"); - __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType)); + __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)); } template <class _Tp, class ..._Ts> @@ -345,7 +345,7 @@ class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp && is_same<typename _CTraits::pointer, char*>::value && is_same<typename _CTraits::void_pointer, void*>::value, ""); - static const size_t _MaxAlign = alignof(max_align_t); + static const size_t _MaxAlign = _LIBCPP_ALIGNOF(max_align_t); using _Alloc = typename _CTraits::template rebind_alloc< typename aligned_storage<_MaxAlign, _MaxAlign>::type diff --git a/include/experimental/numeric b/include/experimental/numeric index 14a664011b56..19c65313f0f2 100644 --- a/include/experimental/numeric +++ b/include/experimental/numeric @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC +#define _LIBCPP_EXPERIMENTAL_NUMERIC -#error "<experimental/numeric> has been removed. Use <numeric> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/numeric> has been removed. Use <numeric> instead.") +#else +# warning "<experimental/numeric> has been removed. Use <numeric> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_NUMERIC diff --git a/include/experimental/optional b/include/experimental/optional index d68cefdf6c1d..6eb4a2618d2c 100644 --- a/include/experimental/optional +++ b/include/experimental/optional @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL +#define _LIBCPP_EXPERIMENTAL_OPTIONAL -#error "<experimental/optional> has been removed. Use <optional> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/optional> has been removed. Use <optional> instead.") +#else +# warning "<experimental/optional> has been removed. Use <optional> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL diff --git a/include/experimental/ratio b/include/experimental/ratio index 9c2bf2e4624e..52c12004dba0 100644 --- a/include/experimental/ratio +++ b/include/experimental/ratio @@ -1,11 +1,21 @@ // -*- C++ -*- -//===------------------------------ ratio ---------------------------------===// +//===----------------------------- ratio ----------------------------------===// // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_RATIO +#define _LIBCPP_EXPERIMENTAL_RATIO -#error "<experimental/ratio> has been removed. Use <ratio> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/ratio> has been removed. Use <ratio> instead.") +#else +# warning "<experimental/ratio> has been removed. Use <ratio> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_RATIO diff --git a/include/experimental/string_view b/include/experimental/string_view index f13bff54d531..100bdfe72735 100644 --- a/include/experimental/string_view +++ b/include/experimental/string_view @@ -3,9 +3,19 @@ // // The LLVM Compiler Infrastructure // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_STRING_VIEW +#define _LIBCPP_EXPERIMENTAL_STRING_VIEW -#error "<experimental/string_view> has been removed. Use <string_view> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/string_view> has been removed. Use <string_view> instead.") +#else +# warning "<experimental/string_view> has been removed. Use <string_view> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_STRING_VIEW diff --git a/include/experimental/system_error b/include/experimental/system_error index 7937357fa141..1cf84ee01251 100644 --- a/include/experimental/system_error +++ b/include/experimental/system_error @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR +#define _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR -#error "<experimental/system_error> has been removed. Use <system_error> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/system_error> has been removed. Use <system_error> instead.") +#else +# warning "<experimental/system_error> has been removed. Use <system_error> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_SYSTEM_ERROR diff --git a/include/experimental/tuple b/include/experimental/tuple index 1f37a6293bac..6d71bb559b02 100644 --- a/include/experimental/tuple +++ b/include/experimental/tuple @@ -7,5 +7,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_EXPERIMENTAL_TUPLE +#define _LIBCPP_EXPERIMENTAL_TUPLE -#error "<experimental/tuple> has been removed. Use <tuple> instead." +#include <__config> + +#ifdef _LIBCPP_WARNING +_LIBCPP_WARNING("<experimental/tuple> has been removed. Use <tuple> instead.") +#else +# warning "<experimental/tuple> has been removed. Use <tuple> instead." +#endif + +#endif // _LIBCPP_EXPERIMENTAL_TUPLE diff --git a/include/filesystem b/include/filesystem index aa1d71800725..af713a063587 100644 --- a/include/filesystem +++ b/include/filesystem @@ -244,6 +244,7 @@ #include <utility> #include <iomanip> // for quoted #include <string_view> +#include <version> #include <__debug> @@ -256,42 +257,8 @@ _LIBCPP_PUSH_MACROS #ifndef _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER >= 17 -#define __cpp_lib_filesystem 201703 -#endif - _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -struct _FilesystemClock { -#if !defined(_LIBCPP_HAS_NO_INT128) - typedef __int128_t rep; - typedef nano period; -#else - typedef long long rep; - typedef nano period; -#endif - - typedef chrono::duration<rep, period> duration; - typedef chrono::time_point<_FilesystemClock> time_point; - - static _LIBCPP_CONSTEXPR_AFTER_CXX11 const bool is_steady = false; - - _LIBCPP_FUNC_VIS static time_point now() noexcept; - - _LIBCPP_INLINE_VISIBILITY - static time_t to_time_t(const time_point& __t) noexcept { - typedef chrono::duration<rep> __secs; - return time_t( - chrono::duration_cast<__secs>(__t.time_since_epoch()).count()); - } - - _LIBCPP_INLINE_VISIBILITY - static time_point from_time_t(time_t __t) noexcept { - typedef chrono::duration<rep> __secs; - return time_point(__secs(__t)); - } -}; - typedef chrono::time_point<_FilesystemClock> file_time_type; struct _LIBCPP_TYPE_VIS space_info { @@ -590,7 +557,7 @@ template <class _ECharT> typename enable_if<__can_convert_char<_ECharT>::value, bool>::type __is_separator(_ECharT __e) { return __e == _ECharT('/'); -}; +} struct _NullSentinal {}; @@ -1184,6 +1151,31 @@ public: return __is; } + friend _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) == 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) != 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) < 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) <= 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) > 0; + } + friend _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, const path& __rhs) noexcept { + return __lhs.compare(__rhs) >= 0; + } + + friend _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, + const path& __rhs) { + path __result(__lhs); + __result /= __rhs; + return __result; + } private: inline _LIBCPP_INLINE_VISIBILITY path& __assign_view(__string_view const& __s) noexcept { @@ -1200,43 +1192,6 @@ inline _LIBCPP_INLINE_VISIBILITY void swap(path& __lhs, path& __rhs) noexcept { _LIBCPP_FUNC_VIS size_t hash_value(const path& __p) noexcept; -inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) == 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) != 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator<(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) < 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) <= 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator>(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) > 0; -} - -inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const path& __lhs, - const path& __rhs) noexcept { - return __lhs.compare(__rhs) >= 0; -} - -inline _LIBCPP_INLINE_VISIBILITY path operator/(const path& __lhs, - const path& __rhs) { - path __result(__lhs); - __result /= __rhs; - return __result; -} - template <class _Source> _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_pathable<_Source>::value, path>::type diff --git a/include/forward_list b/include/forward_list index 571afdc925b0..b506acd1ff20 100644 --- a/include/forward_list +++ b/include/forward_list @@ -167,6 +167,11 @@ template <class T, class Allocator> void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(forward_list<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -177,6 +182,7 @@ template <class T, class Allocator> #include <limits> #include <iterator> #include <algorithm> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -1743,6 +1749,18 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Tp, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template <class _Tp, class _Allocator, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) +{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/fstream b/include/fstream index 332b4747c1af..711e484e2dcf 100644 --- a/include/fstream +++ b/include/fstream @@ -702,6 +702,7 @@ basic_filebuf<_CharT, _Traits>::close() __file_ = 0; else __rt = 0; + setbuf(0, 0); } return __rt; } diff --git a/include/functional b/include/functional index 6b70f731e1cc..95491879b0c7 100644 --- a/include/functional +++ b/include/functional @@ -68,6 +68,11 @@ template <class T> reference_wrapper<const T> cref(const T& t) noexcept; template <class T> void cref(const T&& t) = delete; template <class T> reference_wrapper<const T> cref(reference_wrapper<T> t) noexcept; +template <class T> struct unwrap_reference; // since C++20 +template <class T> struct unwrap_ref_decay : unwrap_reference<decay_t<T>> { }; // since C++20 +template <class T> using unwrap_reference_t = typename unwrap_reference<T>::type; // since C++20 +template <class T> using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type; // since C++20 + template <class T> // <class T=void> in C++14 struct plus : binary_function<T, T, T> { @@ -183,7 +188,7 @@ struct bit_xor : unary_function<T, bool> }; template <class Predicate> -class unary_negate +class unary_negate // deprecated in C++17 : public unary_function<typename Predicate::argument_type, bool> { public: @@ -191,10 +196,11 @@ public: bool operator()(const typename Predicate::argument_type& x) const; }; -template <class Predicate> unary_negate<Predicate> not1(const Predicate& pred); +template <class Predicate> // deprecated in C++17 +unary_negate<Predicate> not1(const Predicate& pred); template <class Predicate> -class binary_negate +class binary_negate // deprecated in C++17 : public binary_function<typename Predicate::first_argument_type, typename Predicate::second_argument_type, bool> @@ -205,7 +211,8 @@ public: const typename Predicate::second_argument_type& y) const; }; -template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred); +template <class Predicate> // deprecated in C++17 +binary_negate<Predicate> not2(const Predicate& pred); template <class F> unspecified not_fn(F&& f); // C++17 @@ -487,6 +494,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited #include <memory> #include <tuple> #include <utility> +#include <version> #include <__functional_base> @@ -980,7 +988,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void> #endif template <class _Predicate> -class _LIBCPP_TEMPLATE_VIS unary_negate +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate : public unary_function<typename _Predicate::argument_type, bool> { _Predicate __pred_; @@ -994,19 +1002,19 @@ public: }; template <class _Predicate> -inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY unary_negate<_Predicate> not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} template <class _Predicate> -class _LIBCPP_TEMPLATE_VIS binary_negate +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate : public binary_function<typename _Predicate::first_argument_type, typename _Predicate::second_argument_type, bool> { _Predicate __pred_; public: - _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_AFTER_CXX11 binary_negate(const _Predicate& __pred) : __pred_(__pred) {} _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY @@ -1016,13 +1024,13 @@ public: }; template <class _Predicate> -inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY binary_negate<_Predicate> not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) template <class __Operation> -class _LIBCPP_TEMPLATE_VIS binder1st +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st : public unary_function<typename __Operation::second_argument_type, typename __Operation::result_type> { @@ -1042,13 +1050,13 @@ public: }; template <class __Operation, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY binder1st<__Operation> bind1st(const __Operation& __op, const _Tp& __x) {return binder1st<__Operation>(__op, __x);} template <class __Operation> -class _LIBCPP_TEMPLATE_VIS binder2nd +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd : public unary_function<typename __Operation::first_argument_type, typename __Operation::result_type> { @@ -1068,13 +1076,13 @@ public: }; template <class __Operation, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY binder2nd<__Operation> bind2nd(const __Operation& __op, const _Tp& __x) {return binder2nd<__Operation>(__op, __x);} template <class _Arg, class _Result> -class _LIBCPP_TEMPLATE_VIS pointer_to_unary_function +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function : public unary_function<_Arg, _Result> { _Result (*__f_)(_Arg); @@ -1086,13 +1094,13 @@ public: }; template <class _Arg, class _Result> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY pointer_to_unary_function<_Arg,_Result> ptr_fun(_Result (*__f)(_Arg)) {return pointer_to_unary_function<_Arg,_Result>(__f);} template <class _Arg1, class _Arg2, class _Result> -class _LIBCPP_TEMPLATE_VIS pointer_to_binary_function +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function : public binary_function<_Arg1, _Arg2, _Result> { _Result (*__f_)(_Arg1, _Arg2); @@ -1104,13 +1112,14 @@ public: }; template <class _Arg1, class _Arg2, class _Result> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY pointer_to_binary_function<_Arg1,_Arg2,_Result> ptr_fun(_Result (*__f)(_Arg1,_Arg2)) {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);} template<class _Sp, class _Tp> -class _LIBCPP_TEMPLATE_VIS mem_fun_t : public unary_function<_Tp*, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t + : public unary_function<_Tp*, _Sp> { _Sp (_Tp::*__p_)(); public: @@ -1121,7 +1130,8 @@ public: }; template<class _Sp, class _Tp, class _Ap> -class _LIBCPP_TEMPLATE_VIS mem_fun1_t : public binary_function<_Tp*, _Ap, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t + : public binary_function<_Tp*, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap); public: @@ -1132,19 +1142,20 @@ public: }; template<class _Sp, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY mem_fun_t<_Sp,_Tp> mem_fun(_Sp (_Tp::*__f)()) {return mem_fun_t<_Sp,_Tp>(__f);} template<class _Sp, class _Tp, class _Ap> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY mem_fun1_t<_Sp,_Tp,_Ap> mem_fun(_Sp (_Tp::*__f)(_Ap)) {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);} template<class _Sp, class _Tp> -class _LIBCPP_TEMPLATE_VIS mem_fun_ref_t : public unary_function<_Tp, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t + : public unary_function<_Tp, _Sp> { _Sp (_Tp::*__p_)(); public: @@ -1155,7 +1166,8 @@ public: }; template<class _Sp, class _Tp, class _Ap> -class _LIBCPP_TEMPLATE_VIS mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t + : public binary_function<_Tp, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap); public: @@ -1166,19 +1178,20 @@ public: }; template<class _Sp, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY mem_fun_ref_t<_Sp,_Tp> mem_fun_ref(_Sp (_Tp::*__f)()) {return mem_fun_ref_t<_Sp,_Tp>(__f);} template<class _Sp, class _Tp, class _Ap> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY mem_fun1_ref_t<_Sp,_Tp,_Ap> mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} template <class _Sp, class _Tp> -class _LIBCPP_TEMPLATE_VIS const_mem_fun_t : public unary_function<const _Tp*, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t + : public unary_function<const _Tp*, _Sp> { _Sp (_Tp::*__p_)() const; public: @@ -1189,7 +1202,8 @@ public: }; template <class _Sp, class _Tp, class _Ap> -class _LIBCPP_TEMPLATE_VIS const_mem_fun1_t : public binary_function<const _Tp*, _Ap, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t + : public binary_function<const _Tp*, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap) const; public: @@ -1200,19 +1214,20 @@ public: }; template <class _Sp, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY const_mem_fun_t<_Sp,_Tp> mem_fun(_Sp (_Tp::*__f)() const) {return const_mem_fun_t<_Sp,_Tp>(__f);} template <class _Sp, class _Tp, class _Ap> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY const_mem_fun1_t<_Sp,_Tp,_Ap> mem_fun(_Sp (_Tp::*__f)(_Ap) const) {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);} template <class _Sp, class _Tp> -class _LIBCPP_TEMPLATE_VIS const_mem_fun_ref_t : public unary_function<_Tp, _Sp> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t + : public unary_function<_Tp, _Sp> { _Sp (_Tp::*__p_)() const; public: @@ -1223,7 +1238,7 @@ public: }; template <class _Sp, class _Tp, class _Ap> -class _LIBCPP_TEMPLATE_VIS const_mem_fun1_ref_t +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t : public binary_function<_Tp, _Ap, _Sp> { _Sp (_Tp::*__p_)(_Ap) const; @@ -1235,13 +1250,13 @@ public: }; template <class _Sp, class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY const_mem_fun_ref_t<_Sp,_Tp> mem_fun_ref(_Sp (_Tp::*__f)() const) {return const_mem_fun_ref_t<_Sp,_Tp>(__f);} template <class _Sp, class _Tp, class _Ap> -inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY const_mem_fun1_ref_t<_Sp,_Tp,_Ap> mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} @@ -1405,7 +1420,7 @@ void __throw_bad_function_call() #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_function_call(); #else - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -1458,6 +1473,81 @@ bool __not_null(function<_Fp> const& __f) { return !!__f; } namespace __function { +// __alloc_func holds a functor and an allocator. + +template <class _Fp, class _Ap, class _FB> class __alloc_func; + +template <class _Fp, class _Ap, class _Rp, class... _ArgTypes> +class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> +{ + __compressed_pair<_Fp, _Ap> __f_; + + public: + typedef _Fp _Target; + typedef _Ap _Alloc; + + _LIBCPP_INLINE_VISIBILITY + const _Target& __target() const { return __f_.first(); } + + _LIBCPP_INLINE_VISIBILITY + const _Alloc& __allocator() const { return __f_.second(); } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple()) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, const _Alloc& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(__a)) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(const _Target& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + explicit __alloc_func(_Target&& __f, _Alloc&& __a) + : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), + _VSTD::forward_as_tuple(_VSTD::move(__a))) + { + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __arg) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), + _VSTD::forward<_ArgTypes>(__arg)...); + } + + _LIBCPP_INLINE_VISIBILITY + __alloc_func* __clone() const + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef + typename __rebind_alloc_helper<__alloc_traits, __alloc_func>::type + _AA; + _AA __a(__f_.second()); + typedef __allocator_destructor<_AA> _Dp; + unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); + return __hold.release(); + } + + _LIBCPP_INLINE_VISIBILITY + void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } +}; + +// __base provides an abstract interface for copyable functors. + template<class _Fp> class __base; template<class _Rp, class ..._ArgTypes> @@ -1479,37 +1569,37 @@ public: #endif // _LIBCPP_NO_RTTI }; +// __func implements __base for a given functor type. + template<class _FD, class _Alloc, class _FB> class __func; template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { - __compressed_pair<_Fp, _Alloc> __f_; + __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; public: _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp&& __f) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), - _VSTD::forward_as_tuple()) {} + : __f_(_VSTD::move(__f)) {} + _LIBCPP_INLINE_VISIBILITY explicit __func(const _Fp& __f, const _Alloc& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), - _VSTD::forward_as_tuple(__a)) {} + : __f_(__f, __a) {} _LIBCPP_INLINE_VISIBILITY explicit __func(const _Fp& __f, _Alloc&& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), - _VSTD::forward_as_tuple(_VSTD::move(__a))) {} + : __f_(__f, _VSTD::move(__a)) {} _LIBCPP_INLINE_VISIBILITY explicit __func(_Fp&& __f, _Alloc&& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), - _VSTD::forward_as_tuple(_VSTD::move(__a))) {} + : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + virtual __base<_Rp(_ArgTypes...)>* __clone() const; virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; virtual void destroy() _NOEXCEPT; virtual void destroy_deallocate() _NOEXCEPT; - virtual _Rp operator()(_ArgTypes&& ... __arg); + virtual _Rp operator()(_ArgTypes&&... __arg); #ifndef _LIBCPP_NO_RTTI virtual const void* target(const type_info&) const _NOEXCEPT; virtual const std::type_info& target_type() const _NOEXCEPT; @@ -1522,10 +1612,10 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); + _Ap __a(__f_.__allocator()); typedef __allocator_destructor<_Ap> _Dp; unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) __func(__f_.first(), _Alloc(__a)); + ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); return __hold.release(); } @@ -1533,14 +1623,14 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { - ::new (__p) __func(__f_.first(), __f_.second()); + ::new (__p) __func(__f_.__target(), __f_.__allocator()); } template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { - __f_.~__compressed_pair<_Fp, _Alloc>(); + __f_.destroy(); } template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> @@ -1549,8 +1639,8 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { typedef allocator_traits<_Alloc> __alloc_traits; typedef typename __rebind_alloc_helper<__alloc_traits, __func>::type _Ap; - _Ap __a(__f_.second()); - __f_.~__compressed_pair<_Fp, _Alloc>(); + _Ap __a(__f_.__allocator()); + __f_.destroy(); __a.deallocate(this, 1); } @@ -1558,8 +1648,7 @@ template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> _Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), _VSTD::forward<_ArgTypes>(__arg)...); + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI @@ -1569,7 +1658,7 @@ const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { if (__ti == typeid(_Fp)) - return &__f_.first(); + return &__f_.__target(); return (const void*)0; } @@ -1582,6 +1671,493 @@ __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT #endif // _LIBCPP_NO_RTTI +// __value_func creates a value-type from a __func. + +template <class _Fp> class __value_func; + +template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)> +{ + typename aligned_storage<3 * sizeof(void*)>::type __buf_; + + typedef __base<_Rp(_ArgTypes...)> __func; + __func* __f_; + + _LIBCPP_NO_CFI static __func* __as_base(void* p) + { + return reinterpret_cast<__func*>(p); + } + + public: + _LIBCPP_INLINE_VISIBILITY + __value_func() _NOEXCEPT : __f_(0) {} + + template <class _Fp, class _Alloc> + _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc __a) + : __f_(0) + { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + + if (__function::__not_null(__f)) + { + _FunAlloc __af(__a); + if (sizeof(_Fun) <= sizeof(__buf_) && + is_nothrow_copy_constructible<_Fp>::value && + is_nothrow_copy_constructible<_FunAlloc>::value) + { + __f_ = + ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + __value_func(const __value_func& __f) + { + if (__f.__f_ == 0) + __f_ = 0; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + __f_ = __f.__f_->__clone(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func(__value_func&& __f) _NOEXCEPT + { + if (__f.__f_ == 0) + __f_ = 0; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__value_func() + { + if ((void*)__f_ == &__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(__value_func&& __f) + { + *this = nullptr; + if (__f.__f_ == 0) + __f_ = 0; + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + else + { + __f_ = __f.__f_; + __f.__f_ = 0; + } + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __value_func& operator=(nullptr_t) + { + __func* __f = __f_; + __f_ = 0; + if ((void*)__f == &__buf_) + __f->destroy(); + else if (__f) + __f->destroy_deallocate(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + if (__f_ == 0) + __throw_bad_function_call(); + return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__value_func& __f) _NOEXCEPT + { + if (&__f == this) + return; + if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) + { + typename aligned_storage<sizeof(__buf_)>::type __tempbuf; + __func* __t = __as_base(&__tempbuf); + __f_->__clone(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f_ == &__buf_) + { + __f_->__clone(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = __as_base(&__f.__buf_); + } + else if ((void*)__f.__f_ == &__f.__buf_) + { + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = __as_base(&__buf_); + } + else + _VSTD::swap(__f_, __f.__f_); + } + + _LIBCPP_INLINE_VISIBILITY + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { return __f_ != 0; } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + if (__f_ == 0) + return typeid(void); + return __f_->target_type(); + } + + template <typename _Tp> + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__f_ == 0) + return 0; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +#endif // _LIBCPP_NO_RTTI +}; + +// Storage for a functor object, to be used with __policy to manage copy and +// destruction. +union __policy_storage +{ + mutable char __small[sizeof(void*) * 2]; + void* __large; +}; + +// True if _Fun can safely be held in __policy_storage.__small. +template <typename _Fun> +struct __use_small_storage + : public _VSTD::integral_constant< + bool, sizeof(_Fun) <= sizeof(__policy_storage) && + _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && + _VSTD::is_trivially_copy_constructible<_Fun>::value && + _VSTD::is_trivially_destructible<_Fun>::value> {}; + +// Policy contains information about how to copy, destroy, and move the +// underlying functor. You can think of it as a vtable of sorts. +struct __policy +{ + // Used to copy or destroy __large values. null for trivial objects. + void* (*const __clone)(const void*); + void (*const __destroy)(void*); + + // True if this is the null policy (no value). + const bool __is_null; + + // The target type. May be null if RTTI is disabled. + const std::type_info* const __type_info; + + // Returns a pointer to a static policy object suitable for the functor + // type. + template <typename _Fun> + _LIBCPP_INLINE_VISIBILITY static const __policy* __create() + { + return __choose_policy<_Fun>(__use_small_storage<_Fun>()); + } + + _LIBCPP_INLINE_VISIBILITY + static const __policy* __create_empty() + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, + true, +#ifndef _LIBCPP_NO_RTTI + &typeid(void) +#else + nullptr +#endif + }; + return &__policy_; + } + + private: + template <typename _Fun> static void* __large_clone(const void* __s) + { + const _Fun* __f = static_cast<const _Fun*>(__s); + return __f->__clone(); + } + + template <typename _Fun> static void __large_destroy(void* __s) + { + typedef allocator_traits<typename _Fun::_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + _Fun* __f = static_cast<_Fun*>(__s); + _FunAlloc __a(__f->__allocator()); + __f->destroy(); + __a.deallocate(__f, 1); + } + + template <typename _Fun> + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ false_type) + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + &__large_clone<_Fun>, &__large_destroy<_Fun>, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } + + template <typename _Fun> + _LIBCPP_INLINE_VISIBILITY static const __policy* + __choose_policy(/* is_small = */ true_type) + { + static const _LIBCPP_CONSTEXPR __policy __policy_ = { + nullptr, nullptr, false, +#ifndef _LIBCPP_NO_RTTI + &typeid(typename _Fun::_Target) +#else + nullptr +#endif + }; + return &__policy_; + } +}; + +// Used to choose between perfect forwarding or pass-by-value. Pass-by-value is +// faster for types that can be passed in registers. +template <typename _Tp> +using __fast_forward = + typename _VSTD::conditional<_VSTD::is_scalar<_Tp>::value, _Tp, _Tp&&>::type; + +// __policy_invoker calls an instance of __alloc_func held in __policy_storage. + +template <class _Fp> struct __policy_invoker; + +template <class _Rp, class... _ArgTypes> +struct __policy_invoker<_Rp(_ArgTypes...)> +{ + typedef _Rp (*__Call)(const __policy_storage*, + __fast_forward<_ArgTypes>...); + + __Call __call_; + + // Creates an invoker that throws bad_function_call. + _LIBCPP_INLINE_VISIBILITY + __policy_invoker() : __call_(&__call_empty) {} + + // Creates an invoker that calls the given instance of __func. + template <typename _Fun> + _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() + { + return __policy_invoker(&__call_impl<_Fun>); + } + + private: + _LIBCPP_INLINE_VISIBILITY + explicit __policy_invoker(__Call __c) : __call_(__c) {} + + static _Rp __call_empty(const __policy_storage*, + __fast_forward<_ArgTypes>...) + { + __throw_bad_function_call(); + } + + template <typename _Fun> + static _Rp __call_impl(const __policy_storage* __buf, + __fast_forward<_ArgTypes>... __args) + { + _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value + ? &__buf->__small + : __buf->__large); + return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); + } +}; + +// __policy_func uses a __policy and __policy_invoker to create a type-erased, +// copyable functor. + +template <class _Fp> class __policy_func; + +template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)> +{ + // Inline storage for small objects. + __policy_storage __buf_; + + // Calls the value stored in __buf_. This could technically be part of + // policy, but storing it here eliminates a level of indirection inside + // operator(). + typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; + __invoker __invoker_; + + // The policy that describes how to move / copy / destroy __buf_. Never + // null, even if the function is empty. + const __policy* __policy_; + + public: + _LIBCPP_INLINE_VISIBILITY + __policy_func() : __policy_(__policy::__create_empty()) {} + + template <class _Fp, class _Alloc> + _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) + : __policy_(__policy::__create_empty()) + { + typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef allocator_traits<_Alloc> __alloc_traits; + typedef typename __rebind_alloc_helper<__alloc_traits, _Fun>::type + _FunAlloc; + + if (__function::__not_null(__f)) + { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + + _FunAlloc __af(__a); + if (__use_small_storage<_Fun>()) + { + ::new ((void*)&__buf_.__small) + _Fun(_VSTD::move(__f), _Alloc(__af)); + } + else + { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) + _Fun(_VSTD::move(__f), _Alloc(__af)); + __buf_.__large = __hold.release(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(const __policy_func& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__clone) + __buf_.__large = __policy_->__clone(__f.__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func(__policy_func&& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), + __policy_(__f.__policy_) + { + if (__policy_->__destroy) + { + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + } + } + + _LIBCPP_INLINE_VISIBILITY + ~__policy_func() + { + if (__policy_->__destroy) + __policy_->__destroy(__buf_.__large); + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(__policy_func&& __f) + { + *this = nullptr; + __buf_ = __f.__buf_; + __invoker_ = __f.__invoker_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __policy_func& operator=(nullptr_t) + { + const __policy* __p = __policy_; + __policy_ = __policy::__create_empty(); + __invoker_ = __invoker(); + if (__p->__destroy) + __p->__destroy(__buf_.__large); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + _Rp operator()(_ArgTypes&&... __args) const + { + return __invoker_.__call_(_VSTD::addressof(__buf_), + _VSTD::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(__policy_func& __f) + { + _VSTD::swap(__invoker_, __f.__invoker_); + _VSTD::swap(__policy_, __f.__policy_); + _VSTD::swap(__buf_, __f.__buf_); + } + + _LIBCPP_INLINE_VISIBILITY + explicit operator bool() const _NOEXCEPT + { + return !__policy_->__is_null; + } + +#ifndef _LIBCPP_NO_RTTI + _LIBCPP_INLINE_VISIBILITY + const std::type_info& target_type() const _NOEXCEPT + { + return *__policy_->__type_info; + } + + template <typename _Tp> + _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT + { + if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) + return nullptr; + if (__policy_->__clone) // Out of line storage. + return reinterpret_cast<const _Tp*>(__buf_.__large); + else + return reinterpret_cast<const _Tp*>(&__buf_.__small); + } +#endif // _LIBCPP_NO_RTTI +}; + } // __function template<class _Rp, class ..._ArgTypes> @@ -1589,13 +2165,13 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { - typedef __function::__base<_Rp(_ArgTypes...)> __base; - typename aligned_storage<3*sizeof(void*)>::type __buf_; - __base* __f_; +#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION + typedef __function::__value_func<_Rp(_ArgTypes...)> __func; +#else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +#endif - _LIBCPP_NO_CFI static __base *__as_base(void *p) { - return reinterpret_cast<__base*>(p); - } + __func __f_; template <class _Fp, bool = __lazy_and< integral_constant<bool, !is_same<__uncvref_t<_Fp>, function>::value>, @@ -1622,9 +2198,9 @@ public: // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY - function() _NOEXCEPT : __f_(0) {} + function() _NOEXCEPT { } _LIBCPP_INLINE_VISIBILITY - function(nullptr_t) _NOEXCEPT : __f_(0) {} + function(nullptr_t) _NOEXCEPT {} function(const function&); function(function&&) _NOEXCEPT; template<class _Fp, class = _EnableIfCallable<_Fp>> @@ -1633,10 +2209,10 @@ public: #if _LIBCPP_STD_VER <= 14 template<class _Alloc> _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {} + function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} template<class _Alloc> _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT : __f_(0) {} + function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} template<class _Alloc> function(allocator_arg_t, const _Alloc&, const function&); template<class _Alloc> @@ -1665,7 +2241,9 @@ public: // function capacity: _LIBCPP_INLINE_VISIBILITY - _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return __f_;} + _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT { + return static_cast<bool>(__f_); + } // deleted overloads close possible hole in the type system template<class _R2, class... _ArgTypes2> @@ -1685,125 +2263,38 @@ public: }; template<class _Rp, class ..._ArgTypes> -function<_Rp(_ArgTypes...)>::function(const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} +function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} #if _LIBCPP_STD_VER <= 14 template<class _Rp, class ..._ArgTypes> template <class _Alloc> function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - const function& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); -} + const function& __f) : __f_(__f.__f_) {} #endif -template<class _Rp, class ..._ArgTypes> +template <class _Rp, class... _ArgTypes> function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = 0; - } -} + : __f_(_VSTD::move(__f.__f_)) {} #if _LIBCPP_STD_VER <= 14 template<class _Rp, class ..._ArgTypes> template <class _Alloc> function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - function&& __f) -{ - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = 0; - } -} + function&& __f) + : __f_(_VSTD::move(__f.__f_)) {} #endif -template<class _Rp, class ..._ArgTypes> +template <class _Rp, class... _ArgTypes> template <class _Fp, class> function<_Rp(_ArgTypes...)>::function(_Fp __f) - : __f_(0) -{ - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; - if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) - { - __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f)); - } - else - { - typedef allocator<_FF> _Ap; - _Ap __a; - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(_VSTD::move(__f), allocator<_Fp>(__a)); - __f_ = __hold.release(); - } - } -} + : __f_(_VSTD::move(__f), allocator<_Fp>()) {} #if _LIBCPP_STD_VER <= 14 -template<class _Rp, class ..._ArgTypes> +template <class _Rp, class... _ArgTypes> template <class _Fp, class _Alloc, class> -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f) - : __f_(0) -{ - typedef allocator_traits<_Alloc> __alloc_traits; - if (__function::__not_null(__f)) - { - typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF; - typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap; - _Ap __a(__a0); - if (sizeof(_FF) <= sizeof(__buf_) && - is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) - { - __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a)); - } - else - { - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__base, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new (__hold.get()) _FF(_VSTD::move(__f), _Alloc(__a)); - __f_ = __hold.release(); - } - } -} +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, + _Fp __f) + : __f_(_VSTD::move(__f), __a) {} #endif template<class _Rp, class ..._ArgTypes> @@ -1818,19 +2309,7 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { - *this = nullptr; - if (__f.__f_ == 0) - __f_ = 0; - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = 0; - } + __f_ = std::move(__f.__f_); return *this; } @@ -1838,12 +2317,7 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { - __base* __t = __f_; - __f_ = 0; - if ((void *)__t == &__buf_) - __t->destroy(); - else if (__t) - __t->destroy_deallocate(); + __f_ = nullptr; return *this; } @@ -1857,60 +2331,20 @@ function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) } template<class _Rp, class ..._ArgTypes> -function<_Rp(_ArgTypes...)>::~function() -{ - if ((void *)__f_ == &__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); -} +function<_Rp(_ArgTypes...)>::~function() {} template<class _Rp, class ..._ArgTypes> void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { - if (_VSTD::addressof(__f) == this) - return; - if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_) - { - typename aligned_storage<sizeof(__buf_)>::type __tempbuf; - __base* __t = __as_base(&__tempbuf); - __f_->__clone(__t); - __f_->destroy(); - __f_ = 0; - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = 0; - __f_ = __as_base(&__buf_); - __t->__clone(__as_base(&__f.__buf_)); - __t->destroy(); - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void *)__f_ == &__buf_) - { - __f_->__clone(__as_base(&__f.__buf_)); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void *)__f.__f_ == &__f.__buf_) - { - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = __as_base(&__buf_); - } - else - _VSTD::swap(__f_, __f.__f_); + __f_.swap(__f.__f_); } template<class _Rp, class ..._ArgTypes> _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { - if (__f_ == 0) - __throw_bad_function_call(); - return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); + return __f_(_VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI @@ -1919,9 +2353,7 @@ template<class _Rp, class ..._ArgTypes> const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { - if (__f_ == 0) - return typeid(void); - return __f_->target_type(); + return __f_.target_type(); } template<class _Rp, class ..._ArgTypes> @@ -1929,9 +2361,7 @@ template <typename _Tp> _Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { - if (__f_ == 0) - return nullptr; - return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp))); + return (_Tp*)(__f_.template target<_Tp>()); } template<class _Rp, class ..._ArgTypes> @@ -1939,9 +2369,7 @@ template <typename _Tp> const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { - if (__f_ == 0) - return nullptr; - return (const _Tp*)__f_->target(typeid(_Tp)); + return __f_.template target<_Tp>(); } #endif // _LIBCPP_NO_RTTI @@ -2105,53 +2533,53 @@ __mu(_Ti& __ti, _Uj&) template <class _Ti, bool IsReferenceWrapper, bool IsBindEx, bool IsPh, class _TupleUj> -struct ____mu_return; +struct __mu_return_impl; template <bool _Invokable, class _Ti, class ..._Uj> -struct ____mu_return_invokable // false +struct __mu_return_invokable // false { typedef __nat type; }; template <class _Ti, class ..._Uj> -struct ____mu_return_invokable<true, _Ti, _Uj...> +struct __mu_return_invokable<true, _Ti, _Uj...> { typedef typename __invoke_of<_Ti&, _Uj...>::type type; }; template <class _Ti, class ..._Uj> -struct ____mu_return<_Ti, false, true, false, tuple<_Uj...> > - : public ____mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> +struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> > + : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> { }; template <class _Ti, class _TupleUj> -struct ____mu_return<_Ti, false, false, true, _TupleUj> +struct __mu_return_impl<_Ti, false, false, true, _TupleUj> { typedef typename tuple_element<is_placeholder<_Ti>::value - 1, _TupleUj>::type&& type; }; template <class _Ti, class _TupleUj> -struct ____mu_return<_Ti, true, false, false, _TupleUj> +struct __mu_return_impl<_Ti, true, false, false, _TupleUj> { typedef typename _Ti::type& type; }; template <class _Ti, class _TupleUj> -struct ____mu_return<_Ti, false, false, false, _TupleUj> +struct __mu_return_impl<_Ti, false, false, false, _TupleUj> { typedef _Ti& type; }; template <class _Ti, class _TupleUj> struct __mu_return - : public ____mu_return<_Ti, - __is_reference_wrapper<_Ti>::value, - is_bind_expression<_Ti>::value, - 0 < is_placeholder<_Ti>::value && - is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, - _TupleUj> + : public __mu_return_impl<_Ti, + __is_reference_wrapper<_Ti>::value, + is_bind_expression<_Ti>::value, + 0 < is_placeholder<_Ti>::value && + is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, + _TupleUj> { }; @@ -2340,8 +2768,6 @@ bind(_Fp&& __f, _BoundArgs&&... __bound_args) #if _LIBCPP_STD_VER > 14 -#define __cpp_lib_invoke 201411 - template <class _Fn, class ..._Args> result_of_t<_Fn&&(_Args&&...)> invoke(_Fn&& __f, _Args&&... __args) @@ -2497,7 +2923,7 @@ template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> class _LIBCPP_TYPE_VIS default_searcher { public: _LIBCPP_INLINE_VISIBILITY - default_searcher(_ForwardIterator __f, _ForwardIterator __l, + default_searcher(_ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate()) : __first_(__f), __last_(__l), __pred_(__p) {} @@ -2519,6 +2945,26 @@ private: #endif // _LIBCPP_STD_VER > 14 +#if _LIBCPP_STD_VER > 17 +template <class _Tp> +using unwrap_reference_t = typename unwrap_reference<_Tp>::type; + +template <class _Tp> +using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; +#endif // > C++17 + +template <class _Container, class _Predicate> +inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred) +{ + for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;) + { + if (__pred(*__iter)) + __iter = __c.erase(__iter); + else + ++__iter; + } +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_FUNCTIONAL diff --git a/include/future b/include/future index 0f6d42678ef5..b3ffc7e35177 100644 --- a/include/future +++ b/include/future @@ -556,13 +556,14 @@ public: {return (__state_ & __constructed) || (__exception_ != nullptr);} _LIBCPP_INLINE_VISIBILITY - void __set_future_attached() - { + void __attach_future() { lock_guard<mutex> __lk(__mut_); + bool __has_future_attached = (__state_ & __future_attached) != 0; + if (__has_future_attached) + __throw_future_error(future_errc::future_already_retrieved); + this->__add_shared(); __state_ |= __future_attached; } - _LIBCPP_INLINE_VISIBILITY - bool __has_future_attached() const {return (__state_ & __future_attached) != 0;} _LIBCPP_INLINE_VISIBILITY void __set_deferred() {__state_ |= deferred;} @@ -1154,10 +1155,7 @@ template <class _Rp> future<_Rp>::future(__assoc_state<_Rp>* __state) : __state_(__state) { - if (__state_->__has_future_attached()) - __throw_future_error(future_errc::future_already_retrieved); - __state_->__add_shared(); - __state_->__set_future_attached(); + __state_->__attach_future(); } struct __release_shared_count @@ -1257,10 +1255,7 @@ template <class _Rp> future<_Rp&>::future(__assoc_state<_Rp&>* __state) : __state_(__state) { - if (__state_->__has_future_attached()) - __throw_future_error(future_errc::future_already_retrieved); - __state_->__add_shared(); - __state_->__set_future_attached(); + __state_->__attach_future(); } template <class _Rp> diff --git a/include/iomanip b/include/iomanip index a6bee736f45b..36c11167a44e 100644 --- a/include/iomanip +++ b/include/iomanip @@ -46,6 +46,7 @@ template <class charT, class traits, class Allocator> #include <__config> #include <__string> #include <istream> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/include/iosfwd b/include/iosfwd index d4384859e418..31f1902e5f59 100644 --- a/include/iosfwd +++ b/include/iosfwd @@ -18,6 +18,12 @@ namespace std { template<class charT> struct char_traits; +template<> struct char_traits<char>; +template<> struct char_traits<char8_t>; // C++20 +template<> struct char_traits<char16_t>; +template<> struct char_traits<char32_t>; +template<> struct char_traits<wchar_t>; + template<class T> class allocator; class ios_base; @@ -98,6 +104,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS ios_base; template<class _CharT> struct _LIBCPP_TEMPLATE_VIS char_traits; +template<> struct char_traits<char>; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template<> struct char_traits<char8_t>; +#endif +template<> struct char_traits<char16_t>; +template<> struct char_traits<char32_t>; +template<> struct char_traits<wchar_t>; + template<class _Tp> class _LIBCPP_TEMPLATE_VIS allocator; template <class _CharT, class _Traits = char_traits<_CharT> > @@ -175,6 +189,9 @@ typedef basic_fstream<wchar_t> wfstream; template <class _State> class _LIBCPP_TEMPLATE_VIS fpos; typedef fpos<mbstate_t> streampos; typedef fpos<mbstate_t> wstreampos; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef fpos<mbstate_t> u8streampos; +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef fpos<mbstate_t> u16streampos; typedef fpos<mbstate_t> u32streampos; diff --git a/include/istream b/include/istream index 71c162b0d41a..30ee4f4b8710 100644 --- a/include/istream +++ b/include/istream @@ -160,6 +160,7 @@ template <class charT, class traits, class T> */ #include <__config> +#include <version> #include <ostream> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -186,7 +187,7 @@ public: typedef typename traits_type::off_type off_type; // 27.7.1.1.1 Constructor/destructor: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb) : __gc_(0) { this->init(__sb); } virtual ~basic_istream(); @@ -200,7 +201,7 @@ protected: basic_istream& operator=(basic_istream&& __rhs); #endif - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_istream& __rhs) { _VSTD::swap(__gc_, __rhs.__gc_); basic_ios<char_type, traits_type>::swap(__rhs); @@ -216,16 +217,16 @@ public: class _LIBCPP_TEMPLATE_VIS sentry; // 27.7.1.2 Formatted input: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) { return __pf(*this); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type, traits_type>&)) { __pf(*this); return *this; } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) { __pf(*this); return *this; } @@ -249,7 +250,7 @@ public: streamsize gcount() const {return __gc_;} int_type get(); - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type& __c) { int_type __ch = get(); if (__ch != traits_type::eof()) @@ -257,19 +258,19 @@ public: return *this; } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(char_type* __s, streamsize __n) { return get(__s, __n, this->widen('\n')); } basic_istream& get(char_type* __s, streamsize __n, char_type __dlm); - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) { return get(__sb, this->widen('\n')); } basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm); - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_istream& getline(char_type* __s, streamsize __n) { return getline(__s, __n, this->widen('\n')); } @@ -517,8 +518,9 @@ basic_istream<_CharT, _Traits>::operator>>(int& __n) } template<class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) +__input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n) { #ifndef _LIBCPP_NO_EXCEPTIONS try @@ -527,13 +529,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) typename basic_istream<_CharT, _Traits>::sentry __sen(__is); if (__sen) { - streamsize __n = __is.width(); - if (__n <= 0) - __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1; - streamsize __c = 0; + auto __s = __p; const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc()); ios_base::iostate __err = ios_base::goodbit; - while (__c < __n-1) + while (__s != __p + (__n-1)) { typename _Traits::int_type __i = __is.rdbuf()->sgetc(); if (_Traits::eq_int_type(__i, _Traits::eof())) @@ -545,12 +544,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) if (__ct.is(__ct.space, __ch)) break; *__s++ = __ch; - ++__c; __is.rdbuf()->sbumpc(); } *__s = _CharT(); __is.width(0); - if (__c == 0) + if (__s == __p) __err |= ios_base::failbit; __is.setstate(__err); } @@ -564,6 +562,48 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) return __is; } +#if _LIBCPP_STD_VER > 17 + +template<class _CharT, class _Traits, size_t _Np> +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, _CharT (&__buf)[_Np]) +{ + auto __n = _Np; + if (__is.width() > 0) + __n = _VSTD::min(size_t(__is.width()), _Np); + return _VSTD::__input_c_string(__is, __buf, __n); +} + +template<class _Traits, size_t _Np> +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<char, _Traits>& +operator>>(basic_istream<char, _Traits>& __is, unsigned char (&__buf)[_Np]) +{ + return __is >> (char(&)[_Np])__buf; +} + +template<class _Traits, size_t _Np> +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<char, _Traits>& +operator>>(basic_istream<char, _Traits>& __is, signed char (&__buf)[_Np]) +{ + return __is >> (char(&)[_Np])__buf; +} + +#else + +template<class _CharT, class _Traits> +inline _LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) +{ + streamsize __n = __is.width(); + if (__n <= 0) + __n = numeric_limits<streamsize>::max() / sizeof(_CharT) - 1; + return _VSTD::__input_c_string(__is, __s, size_t(__n)); +} + template<class _Traits> inline _LIBCPP_INLINE_VISIBILITY basic_istream<char, _Traits>& @@ -580,6 +620,8 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s) return __is >> (char*)__s; } +#endif // _LIBCPP_STD_VER > 17 + template<class _CharT, class _Traits> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) @@ -1238,7 +1280,7 @@ public: typedef typename traits_type::off_type off_type; // constructor/destructor - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb) : basic_istream<_CharT, _Traits>(__sb) {} @@ -1253,7 +1295,7 @@ protected: inline _LIBCPP_INLINE_VISIBILITY basic_iostream& operator=(basic_iostream&& __rhs); #endif - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_iostream& __rhs) { basic_istream<char_type, traits_type>::swap(__rhs); } public: @@ -1463,7 +1505,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) return __is; } -#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>) diff --git a/include/iterator b/include/iterator index 9415e0b83967..bda177e11e6c 100644 --- a/include/iterator +++ b/include/iterator @@ -418,6 +418,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; #include <type_traits> #include <cstddef> #include <initializer_list> +#include <version> #ifdef __APPLE__ #include <Availability.h> #endif @@ -437,6 +438,23 @@ struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; template <class _Tp> +struct __has_iterator_typedefs +{ +private: + struct __two {char __lx; char __lxx;}; + template <class _Up> static __two __test(...); + template <class _Up> static char __test(typename std::__void_t<typename _Up::iterator_category>::type* = 0, + typename std::__void_t<typename _Up::difference_type>::type* = 0, + typename std::__void_t<typename _Up::value_type>::type* = 0, + typename std::__void_t<typename _Up::reference>::type* = 0, + typename std::__void_t<typename _Up::pointer>::type* = 0 + ); +public: + static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1; +}; + + +template <class _Tp> struct __has_iterator_category { private: @@ -478,7 +496,7 @@ struct __iterator_traits<_Iter, true> template <class _Iter> struct _LIBCPP_TEMPLATE_VIS iterator_traits - : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {}; + : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {}; template<class _Tp> struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> diff --git a/include/limits b/include/limits index f530507f7246..5ea9a9e6fdfa 100644 --- a/include/limits +++ b/include/limits @@ -82,6 +82,7 @@ template<> class numeric_limits<cv char>; template<> class numeric_limits<cv signed char>; template<> class numeric_limits<cv unsigned char>; template<> class numeric_limits<cv wchar_t>; +template<> class numeric_limits<cv char8_t>; // C++20 template<> class numeric_limits<cv char16_t>; template<> class numeric_limits<cv char32_t>; @@ -118,6 +119,7 @@ template<> class numeric_limits<cv long double>; _LIBCPP_PUSH_MACROS #include <__undef_macros> +#include <version> _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/include/list b/include/list index d2e78cd66afb..c69e31d93a44 100644 --- a/include/list +++ b/include/list @@ -169,6 +169,11 @@ template <class T, class Alloc> void swap(list<T,Alloc>& x, list<T,Alloc>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(list<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(list<T, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -181,6 +186,7 @@ template <class T, class Alloc> #include <iterator> #include <algorithm> #include <type_traits> +#include <version> #include <__debug> @@ -1169,7 +1175,7 @@ list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) base::__end_.__next_ = __f; } -// Link in nodes [__f, __l] at the front of the list +// Link in nodes [__f, __l] at the back of the list template <class _Tp, class _Alloc> inline void @@ -2208,7 +2214,7 @@ template <class _Comp> void list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) { - if (this != &__c) + if (this != _VSTD::addressof(__c)) { iterator __f1 = begin(); iterator __e1 = end(); @@ -2449,6 +2455,18 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Tp, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.remove_if(__pred); } + +template <class _Tp, class _Allocator, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +void erase(list<_Tp, _Allocator>& __c, const _Up& __v) +{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); } +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/locale b/include/locale index e240799f3831..2043892fa2dc 100644 --- a/include/locale +++ b/include/locale @@ -187,6 +187,7 @@ template <class charT> class messages_byname; #include <streambuf> #include <iterator> #include <limits> +#include <version> #ifndef __APPLE__ #include <cstdarg> #endif @@ -727,7 +728,7 @@ locale::id num_get<_CharT, _InputIterator>::id; template <class _Tp> -_Tp +_LIBCPP_HIDDEN _Tp __num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) { @@ -762,7 +763,7 @@ __num_get_signed_integral(const char* __a, const char* __a_end, } template <class _Tp> -_Tp +_LIBCPP_HIDDEN _Tp __num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) { @@ -2408,6 +2409,23 @@ private: string_type __analyze(char __fmt, const ctype<_CharT>&); }; +#define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ +template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ +template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ +template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ +template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ +template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ +extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ +extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ +extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ +extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ +extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ +/**/ + +_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) +_LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(wchar_t) +#undef _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION + template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > class _LIBCPP_TEMPLATE_VIS time_get_byname : public time_get<_CharT, _InputIterator>, @@ -3550,6 +3568,7 @@ messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); return __cat; #else // !_LIBCPP_HAS_CATOPEN + _LIBCPP_UNUSED_VAR(__nm); return -1; #endif // _LIBCPP_HAS_CATOPEN } @@ -3573,6 +3592,9 @@ messages<_CharT>::do_get(catalog __c, int __set, int __msgid, __n, __n + strlen(__n)); return __w; #else // !_LIBCPP_HAS_CATOPEN + _LIBCPP_UNUSED_VAR(__c); + _LIBCPP_UNUSED_VAR(__set); + _LIBCPP_UNUSED_VAR(__msgid); return __dflt; #endif // _LIBCPP_HAS_CATOPEN } @@ -3586,6 +3608,8 @@ messages<_CharT>::do_close(catalog __c) const __c <<= 1; nl_catd __cat = (nl_catd)__c; catclose(__cat); +#else // !_LIBCPP_HAS_CATOPEN + _LIBCPP_UNUSED_VAR(__c); #endif // _LIBCPP_HAS_CATOPEN } diff --git a/include/map b/include/map index 559ec484aca0..616bb46cfccd 100644 --- a/include/map +++ b/include/map @@ -167,6 +167,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class C2> + void merge(map<Key, T, C2, Allocator>& source); // C++17 + template<class C2> + void merge(map<Key, T, C2, Allocator>&& source); // C++17 + template<class C2> + void merge(multimap<Key, T, C2, Allocator>& source); // C++17 + template<class C2> + void merge(multimap<Key, T, C2, Allocator>&& source); // C++17 + void swap(map& m) noexcept(allocator_traits<allocator_type>::is_always_equal::value && is_nothrow_swappable<key_compare>::value); // C++17 @@ -245,6 +254,10 @@ void swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class T, class Compare, class Allocator, class Predicate> + void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 + + template <class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> class multimap @@ -368,6 +381,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class C2> + void merge(multimap<Key, T, C2, Allocator>& source); // C++17 + template<class C2> + void merge(multimap<Key, T, C2, Allocator>&& source); // C++17 + template<class C2> + void merge(map<Key, T, C2, Allocator>& source); // C++17 + template<class C2> + void merge(map<Key, T, C2, Allocator>&& source); // C++17 + void swap(multimap& m) noexcept(allocator_traits<allocator_type>::is_always_equal::value && is_nothrow_swappable<key_compare>::value); // C++17 @@ -447,6 +469,9 @@ swap(multimap<Key, T, Compare, Allocator>& x, multimap<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class T, class Compare, class Allocator, class Predicate> + void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -460,6 +485,7 @@ swap(multimap<Key, T, Compare, Allocator>& x, #include <functional> #include <initializer_list> #include <type_traits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -467,7 +493,8 @@ swap(multimap<Key, T, Compare, Allocator>& x, _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Key, class _CP, class _Compare, bool _IsSmall> +template <class _Key, class _CP, class _Compare, + bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value> class __map_value_compare : private _Compare { @@ -881,6 +908,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -925,6 +953,11 @@ public: typedef __insert_return_type<iterator, node_type> insert_return_type; #endif + template <class _Key2, class _Value2, class _Comp2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS map; + template <class _Key2, class _Value2, class _Comp2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS multimap; + _LIBCPP_INLINE_VISIBILITY map() _NOEXCEPT_( @@ -1299,6 +1332,38 @@ public: { return __tree_.template __node_handle_extract<node_type>(__it.__i_); } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -1556,6 +1621,14 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + + template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > > class _LIBCPP_TEMPLATE_VIS multimap @@ -1570,6 +1643,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -1614,6 +1688,11 @@ public: typedef __map_node_handle<typename __base::__node, allocator_type> node_type; #endif + template <class _Key2, class _Value2, class _Comp2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS map; + template <class _Key2, class _Value2, class _Comp2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS multimap; + _LIBCPP_INLINE_VISIBILITY multimap() _NOEXCEPT_( @@ -1881,10 +1960,42 @@ public: return __tree_.template __node_handle_extract<node_type>( __it.__i_); } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __tree_.__node_handle_merge_multi(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __tree_.__node_handle_merge_multi(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __tree_.__node_handle_merge_multi(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __tree_.__node_handle_merge_multi(__source.__tree_); + } #endif _LIBCPP_INLINE_VISIBILITY - void clear() {__tree_.clear();} + void clear() _NOEXCEPT {__tree_.clear();} _LIBCPP_INLINE_VISIBILITY void swap(multimap& __m) @@ -2055,6 +2166,13 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MAP diff --git a/include/memory b/include/memory index a4bf89b495ad..ce2c35766233 100644 --- a/include/memory +++ b/include/memory @@ -43,7 +43,7 @@ struct pointer_traits<T*> template <class U> using rebind = U*; - static pointer pointer_to(<details>) noexcept; + static pointer pointer_to(<details>) noexcept; // constexpr in C++20 }; template <class T> constexpr T* to_address(T* p) noexcept; // C++20 @@ -212,10 +212,10 @@ template <class ForwardIterator> template <class ForwardIterator, class Size> ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); -template <class Y> struct auto_ptr_ref {}; // removed in C++17 +template <class Y> struct auto_ptr_ref {}; // deprecated in C++11, removed in C++17 template<class X> -class auto_ptr // removed in C++17 +class auto_ptr // deprecated in C++11, removed in C++17 { public: typedef X element_type; @@ -667,6 +667,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include <atomic> #endif +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -983,7 +984,7 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*> private: struct __nat {}; public: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 static pointer pointer_to(typename conditional<is_void<element_type>::value, __nat, element_type>::type& __r) _NOEXCEPT {return _VSTD::addressof(__r);} @@ -1459,29 +1460,21 @@ struct __has_select_on_container_copy_construction #else // _LIBCPP_CXX03_LANG -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Alloc, class _Pointer, class ..._Args> -struct __has_construct - : false_type -{ -}; - -#else // _LIBCPP_HAS_NO_VARIADICS +template <class _Alloc, class _Pointer, class _Tp, class = void> +struct __has_construct : std::false_type {}; -template <class _Alloc, class _Pointer, class _Args> -struct __has_construct - : false_type -{ -}; +template <class _Alloc, class _Pointer, class _Tp> +struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t< + decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>())) +>::type> : std::true_type {}; -#endif // _LIBCPP_HAS_NO_VARIADICS +template <class _Alloc, class _Pointer, class = void> +struct __has_destroy : false_type {}; template <class _Alloc, class _Pointer> -struct __has_destroy - : false_type -{ -}; +struct __has_destroy<_Alloc, _Pointer, typename __void_t< + decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>())) +>::type> : std::true_type {}; template <class _Alloc> struct __has_max_size @@ -1509,6 +1502,12 @@ struct __alloc_traits_difference_type<_Alloc, _Ptr, true> typedef typename _Alloc::difference_type type; }; +template <class _Tp> +struct __is_default_allocator : false_type {}; + +template <class _Tp> +struct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {}; + template <class _Alloc> struct _LIBCPP_TEMPLATE_VIS allocator_traits { @@ -1570,9 +1569,10 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits } template <class _Tp, class _A0> _LIBCPP_INLINE_VISIBILITY - static void construct(allocator_type&, _Tp* __p, const _A0& __a0) + static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0) { - ::new ((void*)__p) _Tp(__a0); + __construct(__has_construct<allocator_type, _Tp*, const _A0&>(), + __a, __p, __a0); } template <class _Tp, class _A0, class _A1> _LIBCPP_INLINE_VISIBILITY @@ -1612,7 +1612,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits void __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) { - for (; __begin1 != __end1; ++__begin1, ++__begin2) + for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1)); } @@ -1621,7 +1621,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits static typename enable_if < - (is_same<allocator_type, allocator<_Tp> >::value + (__is_default_allocator<allocator_type>::value || !__has_construct<allocator_type, _Tp*, _Tp>::value) && is_trivially_move_constructible<_Tp>::value, void @@ -1646,23 +1646,25 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1); } - template <class _Tp> + template <class _SourceTp, class _DestTp, + class _RawSourceTp = typename remove_const<_SourceTp>::type, + class _RawDestTp = typename remove_const<_DestTp>::type> _LIBCPP_INLINE_VISIBILITY static typename enable_if < - (is_same<allocator_type, allocator<_Tp> >::value - || !__has_construct<allocator_type, _Tp*, _Tp>::value) && - is_trivially_move_constructible<_Tp>::value, + is_trivially_move_constructible<_DestTp>::value && + is_same<_RawSourceTp, _RawDestTp>::value && + (__is_default_allocator<allocator_type>::value || + !__has_construct<allocator_type, _DestTp*, _SourceTp&>::value), void >::type - __construct_range_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2) { - typedef typename remove_const<_Tp>::type _Vp; ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) { - _VSTD::memcpy(const_cast<_Vp*>(__begin2), __begin1, _Np * sizeof(_Tp)); + _VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp)); __begin2 += _Np; } } @@ -1685,7 +1687,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits static typename enable_if < - (is_same<allocator_type, allocator<_Tp> >::value + (__is_default_allocator<allocator_type>::value || !__has_construct<allocator_type, _Tp*, _Tp>::value) && is_trivially_move_constructible<_Tp>::value, void @@ -1720,6 +1722,19 @@ private: { ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...); } +#else // _LIBCPP_HAS_NO_VARIADICS + template <class _Tp, class _A0> + _LIBCPP_INLINE_VISIBILITY + static void __construct(true_type, allocator_type& __a, _Tp* __p, + const _A0& __a0) + {__a.construct(__p, __a0);} + template <class _Tp, class _A0> + _LIBCPP_INLINE_VISIBILITY + static void __construct(false_type, allocator_type&, _Tp* __p, + const _A0& __a0) + { + ::new ((void*)__p) _Tp(__a0); + } #endif // _LIBCPP_HAS_NO_VARIADICS template <class _Tp> @@ -1782,7 +1797,7 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator() _NOEXCEPT {} - template <class _Up> + template <class _Up> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator(const allocator<_Up>&) _NOEXCEPT {} @@ -1790,16 +1805,16 @@ public: {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY + _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) { if (__n > max_size()) __throw_length_error("allocator<T>::allocate(size_t n)" " 'n' exceeds maximum supported size"); - return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); + return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); } - _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT - {_VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp));} + _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT + {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) @@ -1887,7 +1902,7 @@ public: allocator() _NOEXCEPT {} template <class _Up> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 allocator(const allocator<_Up>&) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT @@ -1897,10 +1912,10 @@ public: if (__n > max_size()) __throw_length_error("allocator<const T>::allocate(size_t n)" " 'n' exceeds maximum supported size"); - return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), __alignof(_Tp))); + return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); } - _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT - {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __alignof(_Tp));} + _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT + {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {return size_type(~0) / sizeof(_Tp);} #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) @@ -1989,10 +2004,10 @@ public: _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {} _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;} _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element) - {::new(&*__x_) _Tp(__element); return *this;} + {::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;} #if _LIBCPP_STD_VER >= 14 _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element) - {::new(&*__x_) _Tp(_VSTD::move(__element)); return *this;} + {::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;} #endif _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;} _LIBCPP_INLINE_VISIBILITY raw_storage_iterator operator++(int) @@ -2003,7 +2018,7 @@ public: }; template <class _Tp> -_LIBCPP_NO_CFI +_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI pair<_Tp*, ptrdiff_t> get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT { @@ -2016,7 +2031,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT while (__n > 0) { #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - if (__is_overaligned_for_new(__alignof(_Tp))) + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { std::align_val_t __al = std::align_val_t(std::alignment_of<_Tp>::value); @@ -2027,7 +2042,7 @@ get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT __n * sizeof(_Tp), nothrow)); } #else - if (__is_overaligned_for_new(__alignof(_Tp))) + if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp))) { // Since aligned operator new is unavailable, return an empty // buffer rather than one with invalid alignment. @@ -2051,18 +2066,18 @@ template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY void return_temporary_buffer(_Tp* __p) _NOEXCEPT { - _VSTD::__libcpp_deallocate((void*)__p, __alignof(_Tp)); + _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp)); } #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) template <class _Tp> -struct auto_ptr_ref +struct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref { _Tp* __ptr_; }; template<class _Tp> -class _LIBCPP_TEMPLATE_VIS auto_ptr +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr { private: _Tp* __ptr_; @@ -2106,7 +2121,7 @@ public: }; template <> -class _LIBCPP_TEMPLATE_VIS auto_ptr<void> +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void> { public: typedef void element_type; @@ -2130,7 +2145,9 @@ struct __compressed_pair_elem { _LIBCPP_INLINE_VISIBILITY constexpr explicit __compressed_pair_elem(_Up&& __u) - : __value_(_VSTD::forward<_Up>(__u)){}; + : __value_(_VSTD::forward<_Up>(__u)) + { + } template <class... _Args, size_t... _Indexes> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -2167,7 +2184,8 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { _LIBCPP_INLINE_VISIBILITY constexpr explicit __compressed_pair_elem(_Up&& __u) - : __value_type(_VSTD::forward<_Up>(__u)){}; + : __value_type(_VSTD::forward<_Up>(__u)) + {} template <class... _Args, size_t... _Indexes> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -3682,7 +3700,7 @@ private: virtual void __on_zero_shared_weak() _NOEXCEPT; public: _LIBCPP_INLINE_VISIBILITY - _Tp* get() _NOEXCEPT {return &__data_.second();} + _Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());} }; template <class _Tp, class _Alloc> @@ -5624,15 +5642,18 @@ template <class _Tp, class _Alloc> struct __temp_value { typedef allocator_traits<_Alloc> _Traits; - typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v; + typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v; _Alloc &__a; _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } _Tp & get() { return *__addr(); } template<class... _Args> - __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) - { _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); } + _LIBCPP_NO_CFI + __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) { + _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)), + _VSTD::forward<_Args>(__args)...); + } ~__temp_value() { _Traits::destroy(__a, __addr()); } }; diff --git a/include/module.modulemap b/include/module.modulemap index 089505586fb3..6d88f52113cb 100644 --- a/include/module.modulemap +++ b/include/module.modulemap @@ -228,6 +228,10 @@ module std [system] { header "atomic" export * } + module bit { + header "bit" + export * + } module bitset { header "bitset" export string @@ -520,10 +524,6 @@ module std [system] { header "experimental/deque" export * } - module dynarray { - header "experimental/dynarray" - export * - } module filesystem { header "experimental/filesystem" export * diff --git a/include/mutex b/include/mutex index 52e39b0fb1f8..6d2de2b460e2 100644 --- a/include/mutex +++ b/include/mutex @@ -194,6 +194,7 @@ template<class Callable, class ...Args> #ifndef _LIBCPP_CXX03_LANG #include <tuple> #endif +#include <version> #include <__threading_support> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -488,7 +489,7 @@ public: }; template <class _Mutex> -class _LIBCPP_TEMPLATE_VIS scoped_lock<_Mutex> { +class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) scoped_lock<_Mutex> { public: typedef _Mutex mutex_type; private: diff --git a/include/new b/include/new index e70b9c621570..24ffcad5a6bc 100644 --- a/include/new +++ b/include/new @@ -27,12 +27,6 @@ public: virtual const char* what() const noexcept; }; -class bad_array_length : public bad_alloc // FIXME: Not part of C++ -{ -public: - bad_array_length() noexcept; -}; - class bad_array_new_length : public bad_alloc // C++14 { public: @@ -91,6 +85,7 @@ void operator delete[](void* ptr, void*) noexcept; #include <exception> #include <type_traits> #include <cstddef> +#include <version> #ifdef _LIBCPP_NO_EXCEPTIONS #include <cstdlib> #endif @@ -103,23 +98,23 @@ void operator delete[](void* ptr, void*) noexcept; #pragma GCC system_header #endif -#if !(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER >= 14 || \ - (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)) -# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation < 201309L +#define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION #endif -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \ - (!(defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_STD_VER > 14 || \ - (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606))) -# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \ + defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) +# define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION #endif +#if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \ + defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) +# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#endif #if !__has_builtin(__builtin_operator_new) || \ - __has_builtin(__builtin_operator_new) < 201802L || \ - defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || \ - !defined(__cpp_aligned_new) || __cpp_aligned_new < 201606 -#define _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE + __has_builtin(__builtin_operator_new) < 201802L +#define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE #endif namespace std // purposefully not using versioning namespace @@ -155,29 +150,14 @@ _LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT; _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec -#if defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11) - -class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH - bad_array_length : public bad_alloc { -public: - bad_array_length() _NOEXCEPT; - virtual ~bad_array_length() _NOEXCEPT; - virtual const char* what() const _NOEXCEPT; -}; - -#define _LIBCPP_BAD_ARRAY_LENGTH_DEFINED - -#endif // defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11) - -#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME) -#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) || _LIBCPP_STD_VER > 14 +#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \ + !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME) #ifndef _LIBCPP_CXX03_LANG enum class _LIBCPP_ENUM_VIS align_val_t : size_t { }; #else enum align_val_t { __zero = 0, __max = (size_t)-1 }; #endif #endif -#endif } // std @@ -187,13 +167,13 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 }; #define _THROW_BAD_ALLOC #endif -#if !defined(_LIBCPP_ABI_MICROSOFT) || defined(_LIBCPP_NO_VCRUNTIME) +#if !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME) _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC; _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; -#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; #endif @@ -201,16 +181,16 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[]( _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; -#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; #endif -#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; -#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; #endif @@ -218,7 +198,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[]( _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT; _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; -#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; #endif #endif @@ -228,7 +208,7 @@ _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator ne inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {} inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {} -#endif // !_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME +#endif // !_LIBCPP_DEFER_NEW_TO_VCRUNTIME _LIBCPP_BEGIN_NAMESPACE_STD @@ -244,7 +224,7 @@ inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t _ #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION if (__is_overaligned_for_new(__align)) { const align_val_t __align_val = static_cast<align_val_t>(__align); -# ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE +# ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE return ::operator new(__size, __align_val); # else return __builtin_operator_new(__size, __align_val); @@ -260,43 +240,98 @@ inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t _ #endif } -inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __align) { -#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION - if (__is_overaligned_for_new(__align)) { - const align_val_t __align_val = static_cast<align_val_t>(__align); -# ifdef _LIBCPP_HAS_NO_BUILTIN_ALIGNED_OPERATOR_NEW_DELETE - return ::operator delete(__ptr, __align_val); -# else - return __builtin_operator_delete(__ptr, __align_val); -# endif +struct _DeallocateCaller { + static inline _LIBCPP_INLINE_VISIBILITY + void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) { +#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + ((void)__align); + return __do_deallocate_handle_size(__ptr, __size); +#else + if (__is_overaligned_for_new(__align)) { + const align_val_t __align_val = static_cast<align_val_t>(__align); + return __do_deallocate_handle_size(__ptr, __size, __align_val); + } else { + return __do_deallocate_handle_size(__ptr, __size); + } +#endif + } + + static inline _LIBCPP_INLINE_VISIBILITY + void __do_deallocate_handle_align(void *__ptr, size_t __align) { +#if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + ((void)__align); + return __do_call(__ptr); +#else + if (__is_overaligned_for_new(__align)) { + const align_val_t __align_val = static_cast<align_val_t>(__align); + return __do_call(__ptr, __align_val); + } else { + return __do_call(__ptr); + } +#endif } + + private: + static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) { +#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION + ((void)__size); + return __do_call(__ptr); #else - ((void)__align); + return __do_call(__ptr, __size); #endif -#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE - return ::operator delete(__ptr); + } + +#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION + static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) { +#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION + ((void)__size); + return __do_call(__ptr, __align); #else - return __builtin_operator_delete(__ptr); + return __do_call(__ptr, __size, __align); +#endif + } #endif -} -#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED -_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_NO_EXCEPTIONS -_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH +private: + template <class _A1, class _A2> + static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) { +#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ + defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) + return ::operator delete(__ptr, __a1, __a2); +#else + return __builtin_operator_delete(__ptr, __a1, __a2); #endif -void __throw_bad_array_length() -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_array_length(); + } + + template <class _A1> + static inline void __do_call(void *__ptr, _A1 __a1) { +#if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ + defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) + return ::operator delete(__ptr, __a1); #else - _VSTD::abort(); + return __builtin_operator_delete(__ptr, __a1); #endif -} + } + + static inline void __do_call(void *__ptr) { +#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE + return ::operator delete(__ptr); +#else + return __builtin_operator_delete(__ptr); #endif + } +}; + +inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) { + _DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align); +} + +inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) { + _DeallocateCaller::__do_deallocate_handle_align(__ptr, __align); +} template <class _Tp> -_LIBCPP_NODISCARD_AFTER_CXX17 inline +_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT { static_assert (!(is_function<_Tp>::value), "can't launder functions" ); diff --git a/include/numeric b/include/numeric index b33b6a398eb0..4e68239d059e 100644 --- a/include/numeric +++ b/include/numeric @@ -104,15 +104,15 @@ template<class InputIterator, class OutputIterator, class T, template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation> - OutputIterator - transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator + transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op); // C++17 template<class InputIterator, class OutputIterator, class BinaryOperation, class UnaryOperation, class T> - OutputIterator - transform_inclusive_scan(InputIterator first, InputIterator last, + OutputIterator + transform_inclusive_scan(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op, UnaryOperation unary_op, T init); // C++17 @@ -142,6 +142,7 @@ template <class M, class N> #include <iterator> #include <limits> // for numeric_limits #include <functional> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/include/optional b/include/optional index a76f8d18976e..70422068e285 100644 --- a/include/optional +++ b/include/optional @@ -105,8 +105,8 @@ namespace std { // 23.6.3.3, assignment optional &operator=(nullopt_t) noexcept; - optional &operator=(const optional &); - optional &operator=(optional &&) noexcept(see below ); + optional &operator=(const optional &); // constexpr in C++20 + optional &operator=(optional &&) noexcept(see below); // constexpr in C++20 template <class U = T> optional &operator=(U &&); template <class U> optional &operator=(const optional<U> &); template <class U> optional &operator=(optional<U> &&); @@ -156,6 +156,7 @@ template<class T> #include <stdexcept> #include <type_traits> #include <utility> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -168,7 +169,7 @@ _LIBCPP_PUSH_MACROS namespace std // purposefully not using versioning namespace { -class _LIBCPP_EXCEPTION_ABI bad_optional_access +class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access : public exception { public: @@ -185,6 +186,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS void __throw_bad_optional_access() { #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_optional_access(); @@ -932,6 +934,7 @@ public: using __base::__get; _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const& value() const& { if (!this->has_value()) @@ -940,6 +943,7 @@ public: } _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type& value() & { if (!this->has_value()) @@ -948,6 +952,7 @@ public: } _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type&& value() && { if (!this->has_value()) @@ -956,6 +961,7 @@ public: } _LIBCPP_INLINE_VISIBILITY + _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS constexpr value_type const&& value() const&& { if (!this->has_value()) diff --git a/include/ostream b/include/ostream index 5404e0dca6c8..d700a369b34a 100644 --- a/include/ostream +++ b/include/ostream @@ -140,6 +140,7 @@ template <class charT, class traits, class T> #include <locale> #include <iterator> #include <bitset> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -160,7 +161,7 @@ public: typedef typename traits_type::off_type off_type; // 27.7.2.2 Constructor/destructor: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) { this->init(__sb); } virtual ~basic_ostream(); @@ -173,7 +174,7 @@ protected: inline _LIBCPP_INLINE_VISIBILITY basic_ostream& operator=(basic_ostream&& __rhs); #endif - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void swap(basic_ostream& __rhs) { basic_ios<char_type, traits_type>::swap(__rhs); } @@ -190,16 +191,16 @@ public: class _LIBCPP_TEMPLATE_VIS sentry; // 27.7.2.6 Formatted output: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) { return __pf(*this); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(basic_ios<char_type, traits_type>& (*__pf)(basic_ios<char_type,traits_type>&)) { __pf(*this); return *this; } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) { __pf(*this); return *this; } @@ -224,11 +225,11 @@ public: basic_ostream& flush(); // 27.7.2.5 seeks: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type tellp(); - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(pos_type __pos); - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_ostream& seekp(off_type __off, ios_base::seekdir __dir); protected: @@ -1092,7 +1093,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) use_facet<ctype<_CharT> >(__os.getloc()).widen('1')); } -#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>) #endif diff --git a/include/random b/include/random index 89664a6ca331..724bd0fc2154 100644 --- a/include/random +++ b/include/random @@ -2337,7 +2337,7 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, for (size_t __i = 1; __i < __n; ++__i) if (__x_[__i] != 0) return; - __x_[0] = _Max; + __x_[0] = result_type(1) << (__w - 1); } } @@ -2363,7 +2363,7 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, for (size_t __i = 1; __i < __n; ++__i) if (__x_[__i] != 0) return; - __x_[0] = _Max; + __x_[0] = result_type(1) << (__w - 1); } } diff --git a/include/regex b/include/regex index 84aacc029edc..bd83d7c10ca7 100644 --- a/include/regex +++ b/include/regex @@ -769,6 +769,7 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; #include <memory> #include <vector> #include <deque> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -989,6 +990,10 @@ public: #if defined(__mips__) && defined(__GLIBC__) static const char_class_type __regex_word = static_cast<char_class_type>(_ISbit(15)); +#elif defined(__NetBSD__) + // NetBSD defines classes up to 0x2000 + // see sys/ctype_bits.h, _CTYPE_Q + static const char_class_type __regex_word = 0x8000; #else static const char_class_type __regex_word = 0x80; #endif @@ -1351,9 +1356,9 @@ public: virtual ~__node() {} _LIBCPP_INLINE_VISIBILITY - virtual void __exec(__state&) const {}; + virtual void __exec(__state&) const {} _LIBCPP_INLINE_VISIBILITY - virtual void __exec_split(bool, __state&) const {}; + virtual void __exec_split(bool, __state&) const {} }; // __end_state @@ -2414,20 +2419,17 @@ __bracket_expression<_CharT, _Traits>::__exec(__state& __s) const goto __exit; } } - // set of "__found" chars = + // When there's at least one of __neg_chars_ and __neg_mask_, the set + // of "__found" chars is // union(complement(union(__neg_chars_, __neg_mask_)), // other cases...) // - // __neg_chars_ and __neg_mask_'d better be handled together, as there - // are no short circuit opportunities. - // - // In addition, when __neg_mask_/__neg_chars_ is empty, they should be - // treated as all ones/all chars. + // It doesn't make sense to check this when there are no __neg_chars_ + // and no __neg_mask_. + if (!(__neg_mask_ == 0 && __neg_chars_.empty())) { - const bool __in_neg_mask = (__neg_mask_ == 0) || - __traits_.isctype(__ch, __neg_mask_); + const bool __in_neg_mask = __traits_.isctype(__ch, __neg_mask_); const bool __in_neg_chars = - __neg_chars_.empty() || std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) != __neg_chars_.end(); if (!(__in_neg_mask || __in_neg_chars)) diff --git a/include/scoped_allocator b/include/scoped_allocator index 4760d946def7..bdbb0136b5c3 100644 --- a/include/scoped_allocator +++ b/include/scoped_allocator @@ -108,6 +108,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs> #include <__config> #include <memory> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/include/set b/include/set index 108a9e97f88d..a0155f0b2758 100644 --- a/include/set +++ b/include/set @@ -128,6 +128,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class C2> + void merge(set<Key, C2, Allocator>& source); // C++17 + template<class C2> + void merge(set<Key, C2, Allocator>&& source); // C++17 + template<class C2> + void merge(multiset<Key, C2, Allocator>& source); // C++17 + template<class C2> + void merge(multiset<Key, C2, Allocator>&& source); // C++17 + void swap(set& s) noexcept( __is_nothrow_swappable<key_compare>::value && @@ -207,6 +216,9 @@ void swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class Compare, class Allocator, class Predicate> + void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20 + template <class Key, class Compare = less<Key>, class Allocator = allocator<Key>> class multiset @@ -316,6 +328,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class C2> + void merge(multiset<Key, C2, Allocator>& source); // C++17 + template<class C2> + void merge(multiset<Key, C2, Allocator>&& source); // C++17 + template<class C2> + void merge(set<Key, C2, Allocator>& source); // C++17 + template<class C2> + void merge(set<Key, C2, Allocator>&& source); // C++17 + void swap(multiset& s) noexcept( __is_nothrow_swappable<key_compare>::value && @@ -394,6 +415,9 @@ void swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class Key, class Compare, class Allocator, class Predicate> + void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -402,6 +426,7 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) #include <__tree> #include <__node_handle> #include <functional> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -409,6 +434,9 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y) _LIBCPP_BEGIN_NAMESPACE_STD +template <class _Key, class _Compare, class _Allocator> +class multiset; + template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > class _LIBCPP_TEMPLATE_VIS set @@ -423,6 +451,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -448,6 +477,11 @@ public: typedef __insert_return_type<iterator, node_type> insert_return_type; #endif + template <class _Key2, class _Compare2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS set; + template <class _Key2, class _Compare2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS multiset; + _LIBCPP_INLINE_VISIBILITY set() _NOEXCEPT_( @@ -486,7 +520,7 @@ public: #if _LIBCPP_STD_VER > 11 template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY set(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : set(__f, __l, key_compare(), __a) {} #endif @@ -542,7 +576,7 @@ public: } #if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY set(initializer_list<value_type> __il, const allocator_type& __a) : set(__il, key_compare(), __a) {} #endif @@ -680,6 +714,38 @@ public: { return __tree_.template __node_handle_extract<node_type>(__it); } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(set<key_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(set<key_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multiset<key_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multiset<key_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_unique(__source.__tree_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -852,6 +918,13 @@ swap(set<_Key, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Compare, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Key, class _Compare = less<_Key>, class _Allocator = allocator<_Key> > class _LIBCPP_TEMPLATE_VIS multiset @@ -866,6 +939,7 @@ public: typedef value_type& reference; typedef const value_type& const_reference; + static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); static_assert((is_same<typename allocator_type::value_type, value_type>::value), "Allocator::value_type must be same type as value_type"); @@ -890,6 +964,11 @@ public: typedef __set_node_handle<typename __base::__node, allocator_type> node_type; #endif + template <class _Key2, class _Compare2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS set; + template <class _Key2, class _Compare2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS multiset; + // construct/copy/destroy: _LIBCPP_INLINE_VISIBILITY multiset() @@ -920,7 +999,7 @@ public: #if _LIBCPP_STD_VER > 11 template <class _InputIterator> - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : multiset(__f, __l, key_compare(), __a) {} #endif @@ -984,7 +1063,7 @@ public: } #if _LIBCPP_STD_VER > 11 - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY multiset(initializer_list<value_type> __il, const allocator_type& __a) : multiset(__il, key_compare(), __a) {} #endif @@ -1121,6 +1200,38 @@ public: { return __tree_.template __node_handle_extract<node_type>(__it); } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multiset<key_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_multi(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(multiset<key_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_multi(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(set<key_type, _Compare2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_multi(__source.__tree_); + } + template <class _Compare2> + _LIBCPP_INLINE_VISIBILITY + void merge(set<key_type, _Compare2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __tree_.__node_handle_merge_multi(__source.__tree_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -1294,6 +1405,13 @@ swap(multiset<_Key, _Compare, _Allocator>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Compare, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_SET diff --git a/include/shared_mutex b/include/shared_mutex index a7735d6732c5..3daf74d26c74 100644 --- a/include/shared_mutex +++ b/include/shared_mutex @@ -124,6 +124,7 @@ template <class Mutex> */ #include <__config> +#include <version> _LIBCPP_PUSH_MACROS #include <__undef_macros> @@ -143,7 +144,8 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base +struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex")) +__shared_mutex_base { mutex __mut_; condition_variable __gate1_; @@ -160,14 +162,14 @@ struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base __shared_mutex_base& operator=(const __shared_mutex_base&) = delete; // Exclusive ownership - void lock(); // blocking - bool try_lock(); - void unlock(); + void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking + bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); + void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); // Shared ownership - void lock_shared(); // blocking - bool try_lock_shared(); - void unlock_shared(); + void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking + bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true)); + void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability()); // typedef implementation-defined native_handle_type; // See 30.2.3 // native_handle_type native_handle(); // See 30.2.3 diff --git a/include/span b/include/span index db8f836f9184..cebe98760f27 100644 --- a/include/span +++ b/include/span @@ -23,27 +23,13 @@ inline constexpr ptrdiff_t dynamic_extent = -1; template <class ElementType, ptrdiff_t Extent = dynamic_extent> class span; -// [span.comparison], span comparison operators -template <class T, ptrdiff_t X, class U, ptrdiff_t Y> - constexpr bool operator==(span<T, X> l, span<U, Y> r); -template <class T, ptrdiff_t X, class U, ptrdiff_t Y> - constexpr bool operator!=(span<T, X> l, span<U, Y> r); -template <class T, ptrdiff_t X, class U, ptrdiff_t Y> - constexpr bool operator<(span<T, X> l, span<U, Y> r); -template <class T, ptrdiff_t X, class U, ptrdiff_t Y> - constexpr bool operator<=(span<T, X> l, span<U, Y> r); -template <class T, ptrdiff_t X, class U, ptrdiff_t Y> - constexpr bool operator>(span<T, X> l, span<U, Y> r); -template <class T, ptrdiff_t X, class U, ptrdiff_t Y> - constexpr bool operator>=(span<T, X> l, span<U, Y> r); - // [span.objectrep], views of object representation template <class ElementType, ptrdiff_t Extent> - span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : + span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : (static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; template <class ElementType, ptrdiff_t Extent> - span< byte, ((Extent == dynamic_extent) ? dynamic_extent : + span< byte, ((Extent == dynamic_extent) ? dynamic_extent : (static_cast<ptrdiff_t>(sizeof(ElementType)) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; @@ -123,7 +109,7 @@ private: template<class T, size_t N> span(T (&)[N]) -> span<T, N>; - + template<class T, size_t N> span(array<T, N>&) -> span<T, N>; @@ -194,8 +180,8 @@ struct __is_span_compatible_container<_Tp, _ElementType, decltype(size(declval<_Tp>())), // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[] typename enable_if< - is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[], - _ElementType(*)[]>, + is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[], + _ElementType(*)[]>, nullptr_t>::type >> : public true_type {}; @@ -221,7 +207,7 @@ public: static constexpr index_type extent = _Extent; static_assert (_Extent >= 0, "Can't have a span with an extent < 0"); -// [span.cons], span constructors, copy, assignment, and destructor +// [span.cons], span constructors, copy, assignment, and destructor _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); } @@ -242,7 +228,7 @@ public: constexpr span( _Container& __c, enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) : __data{_VSTD::data(__c)} - { _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container))"); } + { _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container)"); } template <class _Container> inline _LIBCPP_INLINE_VISIBILITY @@ -287,7 +273,7 @@ public: static_assert(_Count <= _Extent, "Count out of range in span::last()"); return {data() + size() - _Count, _Count}; } - + _LIBCPP_INLINE_VISIBILITY constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept { @@ -315,7 +301,7 @@ public: inline _LIBCPP_INLINE_VISIBILITY constexpr span<element_type, dynamic_extent> subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept - { + { _LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)"); _LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); if (__count == dynamic_extent) @@ -331,14 +317,14 @@ public: _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept { _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds"); - return __data[__idx]; - } + return __data[__idx]; + } _LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept { _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>() index out of bounds"); - return __data[__idx]; - } + return __data[__idx]; + } _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } @@ -358,7 +344,7 @@ public: __data = __other.__data; __other.__data = __p; } - + _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } @@ -392,7 +378,7 @@ public: static constexpr index_type extent = dynamic_extent; -// [span.cons], span constructors, copy, assignment, and destructor +// [span.cons], span constructors, copy, assignment, and destructor _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} constexpr span (const span&) noexcept = default; @@ -408,7 +394,7 @@ public: template <size_t _Sz> inline _LIBCPP_INLINE_VISIBILITY constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} - + template <size_t _Sz> inline _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} @@ -440,7 +426,7 @@ public: inline _LIBCPP_INLINE_VISIBILITY constexpr span<element_type, _Count> first() const noexcept { - static_assert(_Count >= 0); + static_assert(_Count >= 0, "Count must be >= 0 in span::first()"); _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); return {data(), _Count}; } @@ -449,7 +435,7 @@ public: inline _LIBCPP_INLINE_VISIBILITY constexpr span<element_type, _Count> last() const noexcept { - static_assert(_Count >= 0); + static_assert(_Count >= 0, "Count must be >= 0 in span::last()"); _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); return {data() + size() - _Count, _Count}; } @@ -460,7 +446,7 @@ public: _LIBCPP_ASSERT(__count >= 0 && __count <= size(), "Count out of range in span::first(count)"); return {data(), __count}; } - + _LIBCPP_INLINE_VISIBILITY constexpr span<element_type, dynamic_extent> last (index_type __count) const noexcept { @@ -480,7 +466,7 @@ public: constexpr span<element_type, dynamic_extent> inline _LIBCPP_INLINE_VISIBILITY subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept - { + { _LIBCPP_ASSERT( __offset >= 0 && __offset <= size(), "Offset out of range in span::subspan(offset, count)"); _LIBCPP_ASSERT((__count >= 0 && __count <= size()) || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); if (__count == dynamic_extent) @@ -496,14 +482,14 @@ public: _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept { _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds"); - return __data[__idx]; - } + return __data[__idx]; + } _LIBCPP_INLINE_VISIBILITY constexpr reference operator()(index_type __idx) const noexcept { _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>() index out of bounds"); - return __data[__idx]; - } + return __data[__idx]; + } _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } @@ -539,39 +525,9 @@ private: index_type __size; }; -template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> - constexpr bool - operator==(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) - { return equal(__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); } - -template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> - constexpr bool - operator!=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) - { return !(__rhs == __lhs); } - -template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> - constexpr bool - operator< (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) - { return lexicographical_compare (__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); } - -template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> - constexpr bool - operator<=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) - { return !(__rhs < __lhs); } - -template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> - constexpr bool - operator> (const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) - { return __rhs < __lhs; } - -template <class _Tp1, ptrdiff_t _Extent1, class _Tp2, ptrdiff_t _Extent2> - constexpr bool - operator>=(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) - { return !(__lhs < __rhs); } - // as_bytes & as_writeable_bytes template <class _Tp, ptrdiff_t _Extent> - auto as_bytes(span<_Tp, _Extent> __s) noexcept + auto as_bytes(span<_Tp, _Extent> __s) noexcept -> decltype(__s.__as_bytes()) { return __s.__as_bytes(); } @@ -588,7 +544,7 @@ template <class _Tp, ptrdiff_t _Extent> // Deduction guides template<class _Tp, size_t _Sz> span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; - + template<class _Tp, size_t _Sz> span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; diff --git a/include/sstream b/include/sstream index b01f47b6872c..9c3ee13bfbad 100644 --- a/include/sstream +++ b/include/sstream @@ -473,12 +473,12 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s) { while (__sz > INT_MAX) { - this->pbump(INT_MAX); - __sz -= INT_MAX; + this->pbump(INT_MAX); + __sz -= INT_MAX; } if (__sz > 0) - this->pbump(__sz); - } + this->pbump(__sz); + } } } diff --git a/include/stddef.h b/include/stddef.h index faf8552d8ce7..f65065d869a8 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -54,7 +54,7 @@ using std::nullptr_t; // Re-use the compiler's <stddef.h> max_align_t where possible. #if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \ - !defined(__DEFINED_max_align_t) + !defined(__DEFINED_max_align_t) && !defined(__NetBSD__) typedef long double max_align_t; #endif diff --git a/include/stdexcept b/include/stdexcept index 6533497e4ea5..3ec79349aa92 100644 --- a/include/stdexcept +++ b/include/stdexcept @@ -192,7 +192,7 @@ void __throw_logic_error(const char*__msg) throw logic_error(__msg); #else ((void)__msg); - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -203,7 +203,7 @@ void __throw_domain_error(const char*__msg) throw domain_error(__msg); #else ((void)__msg); - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -214,7 +214,7 @@ void __throw_invalid_argument(const char*__msg) throw invalid_argument(__msg); #else ((void)__msg); - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -225,7 +225,7 @@ void __throw_length_error(const char*__msg) throw length_error(__msg); #else ((void)__msg); - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -236,7 +236,7 @@ void __throw_out_of_range(const char*__msg) throw out_of_range(__msg); #else ((void)__msg); - _VSTD::abort(); + _VSTD::abort(); #endif } @@ -247,7 +247,7 @@ void __throw_range_error(const char*__msg) throw range_error(__msg); #else ((void)__msg); - _VSTD::abort(); + _VSTD::abort(); #endif } diff --git a/include/streambuf b/include/streambuf index 37a653237161..dd293dc639b9 100644 --- a/include/streambuf +++ b/include/streambuf @@ -138,7 +138,7 @@ public: virtual ~basic_streambuf(); // 27.6.2.2.1 locales: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale pubimbue(const locale& __loc) { imbue(__loc); locale __r = __loc_; @@ -146,70 +146,70 @@ public: return __r; } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 locale getloc() const { return __loc_; } // 27.6.2.2.2 buffer and positioning: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) { return setbuf(__s, __n); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type pubseekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which = ios_base::in | ios_base::out) { return seekoff(__off, __way, __which); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 pos_type pubseekpos(pos_type __sp, ios_base::openmode __which = ios_base::in | ios_base::out) { return seekpos(__sp, __which); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int pubsync() { return sync(); } // Get and put areas: // 27.6.2.2.3 Get area: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize in_avail() { if (__ninp_ < __einp_) return static_cast<streamsize>(__einp_ - __ninp_); return showmanyc(); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type snextc() { if (sbumpc() == traits_type::eof()) return traits_type::eof(); return sgetc(); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sbumpc() { if (__ninp_ == __einp_) return uflow(); return traits_type::to_int_type(*__ninp_++); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sgetc() { if (__ninp_ == __einp_) return underflow(); return traits_type::to_int_type(*__ninp_); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sgetn(char_type* __s, streamsize __n) { return xsgetn(__s, __n); } // 27.6.2.2.4 Putback: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputbackc(char_type __c) { if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1])) return pbackfail(traits_type::to_int_type(__c)); return traits_type::to_int_type(*--__ninp_); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sungetc() { if (__binp_ == __ninp_) return pbackfail(); @@ -217,7 +217,7 @@ public: } // 27.6.2.2.5 Put area: - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 int_type sputc(char_type __c) { if (__nout_ == __eout_) return overflow(traits_type::to_int_type(__c)); @@ -225,7 +225,7 @@ public: return traits_type::to_int_type(__c); } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 streamsize sputn(const char_type* __s, streamsize __n) { return xsputn(__s, __n); } @@ -240,10 +240,10 @@ protected: _LIBCPP_INLINE_VISIBILITY char_type* gptr() const {return __ninp_;} _LIBCPP_INLINE_VISIBILITY char_type* egptr() const {return __einp_;} - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void gbump(int __n) { __ninp_ += __n; } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) { __binp_ = __gbeg; __ninp_ = __gnext; @@ -255,13 +255,13 @@ protected: _LIBCPP_INLINE_VISIBILITY char_type* pptr() const {return __nout_;} _LIBCPP_INLINE_VISIBILITY char_type* epptr() const {return __eout_;} - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void pbump(int __n) { __nout_ += __n; } _LIBCPP_INLINE_VISIBILITY void __pbump(streamsize __n) { __nout_ += __n; } - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 void setp(char_type* __pbeg, char_type* __pend) { __bout_ = __nout_ = __pbeg; __eout_ = __pend; @@ -486,7 +486,7 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type) return traits_type::eof(); } -#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE +#ifndef _LIBCPP_DO_NOT_ASSUME_STREAMS_EXPLICIT_INSTANTIATION_IN_DYLIB _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>) _LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>) diff --git a/include/string b/include/string index 162e54058c42..fb838d1e5dd2 100644 --- a/include/string +++ b/include/string @@ -437,6 +437,11 @@ template<class charT, class traits, class Allocator> basic_istream<charT, traits>& getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str); +template<class charT, class traits, class Allocator, class U> +void erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20 +template<class charT, class traits, class Allocator, class Predicate> +void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20 + typedef basic_string<char> string; typedef basic_string<wchar_t> wstring; typedef basic_string<char16_t> u16string; @@ -510,6 +515,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #include <type_traits> #include <initializer_list> #include <__functional_base> +#include <version> #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS #include <cstdint> #endif @@ -579,6 +585,7 @@ basic_string<_CharT, _Traits, _Allocator> operator+(_CharT __x, const basic_string<_CharT,_Traits,_Allocator>& __y); template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, const _CharT* __y); @@ -806,7 +813,9 @@ 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"); @@ -816,7 +825,9 @@ 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); @@ -827,7 +838,9 @@ 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); @@ -948,7 +961,11 @@ public: void resize(size_type __n, value_type __c); _LIBCPP_INLINE_VISIBILITY void resize(size_type __n) {resize(__n, value_type());} - void reserve(size_type __res_arg = 0); + void reserve(size_type __res_arg); + _LIBCPP_INLINE_VISIBILITY void __resize_default_init(size_type __n); + + _LIBCPP_INLINE_VISIBILITY + void reserve() _NOEXCEPT {reserve(0);} _LIBCPP_INLINE_VISIBILITY void shrink_to_fit() _NOEXCEPT {reserve();} _LIBCPP_INLINE_VISIBILITY @@ -1002,6 +1019,10 @@ public: basic_string& append(const value_type* __s, size_type __n); basic_string& append(const value_type* __s); basic_string& append(size_type __n, value_type __c); + + _LIBCPP_INLINE_VISIBILITY + void __append_default_init(size_type __n); + template <class _ForwardIterator> _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator); @@ -1664,7 +1685,7 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _ template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() { @@ -1674,7 +1695,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_all_iterators() } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1704,7 +1725,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) { @@ -1715,7 +1736,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string() } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __a) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_copy_constructible<allocator_type>::value) @@ -1780,7 +1801,9 @@ 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) { @@ -1792,7 +1815,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n) { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); @@ -1803,7 +1826,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_ } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) : __r_(__second_tag(), __a) { @@ -1844,7 +1867,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) #if _LIBCPP_STD_VER <= 14 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) @@ -1862,7 +1885,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&& __str, const allocator_type& __a) : __r_(__second_tag(), __a) { @@ -1907,7 +1930,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c) { __init(__n, __c); @@ -1917,7 +1940,9 @@ 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) { @@ -1943,7 +1968,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a) : __r_(__second_tag(), __a) @@ -2054,7 +2079,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last) { __init(__first, __last); @@ -2065,7 +2090,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, template <class _CharT, class _Traits, class _Allocator> template<class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) : __r_(__second_tag(), __a) @@ -2079,7 +2104,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first, #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il) { @@ -2090,7 +2115,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string( } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>::basic_string( initializer_list<_CharT> __il, const _Allocator& __a) @@ -2254,7 +2279,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) #ifndef _LIBCPP_CXX03_LANG template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, false_type) _NOEXCEPT_(__alloc_traits::is_always_equal::value) @@ -2266,7 +2291,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, fa } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) #if _LIBCPP_STD_VER > 14 @@ -2282,7 +2307,7 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str) _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)) @@ -2416,6 +2441,23 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> +inline void +basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) +{ + if (__n) + { + size_type __cap = capacity(); + size_type __sz = size(); + if (__cap - __sz < __n) + __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + pointer __p = __get_pointer(); + __sz += __n; + __set_size(__sz); + traits_type::assign(__p[__sz], value_type()); + } +} + +template <class _CharT, class _Traits, class _Allocator> void basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) { @@ -2499,7 +2541,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe( } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str) { @@ -2676,7 +2718,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_string& __str) { @@ -2746,7 +2788,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_ty } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, size_type __n, value_type __c) { @@ -2866,7 +2908,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const basic_string& __str) { @@ -2910,7 +2952,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { @@ -2919,7 +2961,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { @@ -2927,7 +2969,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, const value_type* __s) { @@ -2935,7 +2977,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c) { @@ -2967,7 +3009,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) { @@ -2985,7 +3027,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::iterator basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) { @@ -3002,7 +3044,7 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_i } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::pop_back() { @@ -3024,7 +3066,7 @@ basic_string<_CharT, _Traits, _Allocator>::pop_back() } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT { @@ -3042,7 +3084,7 @@ basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::__erase_to_end(size_type __pos) { @@ -3071,7 +3113,18 @@ basic_string<_CharT, _Traits, _Allocator>::resize(size_type __n, value_type __c) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void +basic_string<_CharT, _Traits, _Allocator>::__resize_default_init(size_type __n) +{ + size_type __sz = size(); + if (__n > __sz) { + __append_default_init(__n - __sz); + } else + __erase_to_end(__n); +} + +template <class _CharT, class _Traits, class _Allocator> +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::max_size() const _NOEXCEPT { @@ -3147,7 +3200,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT { @@ -3156,7 +3209,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NO } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT { @@ -3183,7 +3236,7 @@ basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::front() { @@ -3192,7 +3245,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::front() const { @@ -3201,7 +3254,7 @@ basic_string<_CharT, _Traits, _Allocator>::front() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::reference basic_string<_CharT, _Traits, _Allocator>::back() { @@ -3210,7 +3263,7 @@ basic_string<_CharT, _Traits, _Allocator>::back() } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::const_reference basic_string<_CharT, _Traits, _Allocator>::back() const { @@ -3231,7 +3284,7 @@ basic_string<_CharT, _Traits, _Allocator>::copy(value_type* __s, size_type __n, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_string<_CharT, _Traits, _Allocator> basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n) const { @@ -3239,7 +3292,7 @@ basic_string<_CharT, _Traits, _Allocator>::substr(size_type __pos, size_type __n } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 @@ -3287,7 +3340,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3312,7 +3365,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3345,7 +3398,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3370,7 +3423,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3403,7 +3456,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3428,7 +3481,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3439,7 +3492,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3461,7 +3514,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3486,7 +3539,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3497,7 +3550,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3519,7 +3572,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3544,7 +3597,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3555,7 +3608,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3578,7 +3631,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT @@ -3603,7 +3656,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT @@ -3614,7 +3667,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ } template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT @@ -3649,7 +3702,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline int basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT { @@ -3695,7 +3748,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3753,7 +3806,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, // __invariants template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_string<_CharT, _Traits, _Allocator>::__invariants() const { @@ -3771,7 +3824,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const // __clear_and_shrink template<class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_string<_CharT, _Traits, _Allocator>::__clear_and_shrink() _NOEXCEPT { @@ -4025,6 +4078,7 @@ operator+(_CharT __lhs, const basic_string<_CharT,_Traits,_Allocator>& __rhs) } template<class _CharT, class _Traits, class _Allocator> +inline basic_string<_CharT, _Traits, _Allocator> operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT* __rhs) { @@ -4121,11 +4175,13 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, __lhs.swap(__rhs); } -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef basic_string<char8_t> u8string; +#endif +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS typedef basic_string<char16_t> u16string; typedef basic_string<char32_t> u32string; - #endif // _LIBCPP_HAS_NO_UNICODE_CHARS _LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = 0, int __base = 10); @@ -4225,6 +4281,18 @@ getline(basic_istream<_CharT, _Traits>&& __is, #endif // _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 +template<class _CharT, class _Traits, class _Allocator, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) +{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); } + +template<class _CharT, class _Traits, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred) +{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); } +#endif + #if _LIBCPP_DEBUG_LEVEL >= 2 template<class _CharT, class _Traits, class _Allocator> @@ -4282,6 +4350,14 @@ inline namespace literals return basic_string<wchar_t> (__str, __len); } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY + basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) _NOEXCEPT + { + return basic_string<char8_t> (__str, __len); + } +#endif + inline _LIBCPP_INLINE_VISIBILITY basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) { diff --git a/include/string_view b/include/string_view index 6377aeb6d648..7d783122f123 100644 --- a/include/string_view +++ b/include/string_view @@ -178,6 +178,7 @@ namespace std { #include <iterator> #include <limits> #include <stdexcept> +#include <version> #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -768,6 +769,9 @@ bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type } typedef basic_string_view<char> string_view; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +typedef basic_string_view<char8_t> u8string_view; +#endif typedef basic_string_view<char16_t> u16string_view; typedef basic_string_view<char32_t> u32string_view; typedef basic_string_view<wchar_t> wstring_view; @@ -777,17 +781,12 @@ template<class _CharT, class _Traits> struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> > : public unary_function<basic_string_view<_CharT, _Traits>, size_t> { - size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT { + return __do_string_hash(__val.data(), __val.data() + __val.size()); + } }; -template<class _CharT, class _Traits> -size_t -hash<basic_string_view<_CharT, _Traits> >::operator()( - const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT -{ - return __do_string_hash(__val.data(), __val.data() + __val.size()); -} - #if _LIBCPP_STD_VER > 11 inline namespace literals @@ -806,6 +805,14 @@ inline namespace literals return basic_string_view<wchar_t> (__str, __len); } +#ifndef _LIBCPP_NO_HAS_CHAR8_T + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT + { + return basic_string_view<char8_t> (__str, __len); + } +#endif + inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT { diff --git a/include/support/win32/locale_win32.h b/include/support/win32/locale_win32.h index 68682c9624b8..c7c6d786cb83 100644 --- a/include/support/win32/locale_win32.h +++ b/include/support/win32/locale_win32.h @@ -35,8 +35,8 @@ public: : __locale(nullptr), __locale_str(nullptr) {} locale_t(std::nullptr_t) : __locale(nullptr), __locale_str(nullptr) {} - locale_t(_locale_t __locale, const char* __locale_str) - : __locale(__locale), __locale_str(__locale_str) {} + locale_t(_locale_t __xlocale, const char* __xlocale_str) + : __locale(__xlocale), __locale_str(__xlocale_str) {} friend bool operator==(const locale_t& __left, const locale_t& __right) { return __left.__locale == __right.__locale; diff --git a/include/thread b/include/thread index 0629d70efda4..8c0115f8708d 100644 --- a/include/thread +++ b/include/thread @@ -151,7 +151,7 @@ class __thread_specific_ptr __thread_specific_ptr(const __thread_specific_ptr&); __thread_specific_ptr& operator=(const __thread_specific_ptr&); - static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*); + _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*); public: typedef _Tp* pointer; diff --git a/include/tuple b/include/tuple index b3a17e7b7354..4cc69030b9ab 100644 --- a/include/tuple +++ b/include/tuple @@ -65,7 +65,7 @@ public: template <class U1, class U2> tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 template <class U1, class U2> - tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2 + tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); }; @@ -84,8 +84,8 @@ template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t); // C++17 // 20.4.1.4, tuple helper classes: -template <class T> class tuple_size; // undefined -template <class... T> class tuple_size<tuple<T...>>; +template <class T> struct tuple_size; // undefined +template <class... T> struct tuple_size<tuple<T...>>; template <class T> inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 template <size_t I, class T> class tuple_element; // undefined @@ -141,6 +141,7 @@ template <class... Types> #include <type_traits> #include <__functional_base> #include <utility> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -1077,30 +1078,12 @@ namespace { _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); } -template <class _Tp> -struct __make_tuple_return_impl -{ - typedef _Tp type; -}; - -template <class _Tp> -struct __make_tuple_return_impl<reference_wrapper<_Tp> > -{ - typedef _Tp& type; -}; - -template <class _Tp> -struct __make_tuple_return -{ - typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type; -}; - template <class... _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -tuple<typename __make_tuple_return<_Tp>::type...> +tuple<typename __unwrap_ref_decay<_Tp>::type...> make_tuple(_Tp&&... __t) { - return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); + return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); } template <class... _Tp> diff --git a/include/type_traits b/include/type_traits index 30bfb161c0d4..8b30511a4ecb 100644 --- a/include/type_traits +++ b/include/type_traits @@ -75,6 +75,10 @@ namespace std template <class T> struct remove_pointer; template <class T> struct add_pointer; + template<class T> struct type_identity; // C++20 + template<class T> + using type_identity_t = typename type_identity<T>::type; // C++20 + // Integral properties: template <class T> struct is_signed; template <class T> struct is_unsigned; @@ -400,6 +404,7 @@ namespace std */ #include <__config> #include <cstddef> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -704,6 +709,9 @@ template <> struct __libcpp_is_integral<char> : public tr template <> struct __libcpp_is_integral<signed char> : public true_type {}; template <> struct __libcpp_is_integral<unsigned char> : public true_type {}; template <> struct __libcpp_is_integral<wchar_t> : public true_type {}; +#ifndef _LIBCPP_NO_HAS_CHAR8_T +template <> struct __libcpp_is_integral<char8_t> : public true_type {}; +#endif #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS template <> struct __libcpp_is_integral<char16_t> : public true_type {}; template <> struct __libcpp_is_integral<char32_t> : public true_type {}; @@ -733,12 +741,6 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v // is_floating_point template <class _Tp> struct __libcpp_is_floating_point : public false_type {}; -#ifdef __clang__ -template <> struct __libcpp_is_floating_point<__fp16> : public true_type {}; -#endif -#ifdef __FLT16_MANT_DIG__ -template <> struct __libcpp_is_floating_point<_Float16> : public true_type {}; -#endif template <> struct __libcpp_is_floating_point<float> : public true_type {}; template <> struct __libcpp_is_floating_point<double> : public true_type {}; template <> struct __libcpp_is_floating_point<long double> : public true_type {}; @@ -1226,6 +1228,12 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_pointer template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type; #endif +// type_identity +#if _LIBCPP_STD_VER > 17 +template<class _Tp> struct type_identity { typedef _Tp type; }; +template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type; +#endif + // is_signed template <class _Tp, bool = is_integral<_Tp>::value> @@ -1644,7 +1652,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool has_unique_object_representations_v // alignment_of template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of - : public integral_constant<size_t, __alignof__(_Tp)> {}; + : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template <class _Tp> @@ -1674,7 +1682,7 @@ struct __nat template <class _Tp> struct __align_type { - static const size_t value = alignment_of<_Tp>::value; + static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); typedef _Tp type; }; @@ -1807,8 +1815,8 @@ struct __static_max<_I0, _I1, _In...> template <size_t _Len, class _Type0, class ..._Types> struct aligned_union { - static const size_t alignment_value = __static_max<__alignof__(_Type0), - __alignof__(_Types)...>::value; + static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), + _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value; static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value; typedef typename aligned_storage<__len, alignment_value>::type type; @@ -4748,7 +4756,6 @@ struct __has_operator_addressof #if _LIBCPP_STD_VER > 14 -#define __cpp_lib_void_t 201411 template <class...> using void_t = void; # ifndef _LIBCPP_HAS_NO_VARIADICS diff --git a/include/typeinfo b/include/typeinfo index f32ea6e76f17..8411532860bd 100644 --- a/include/typeinfo +++ b/include/typeinfo @@ -73,12 +73,8 @@ public: #include <vcruntime_typeinfo.h> #else -#if !defined(_LIBCPP_ABI_MICROSOFT) -#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) -#define _LIBCPP_HAS_NONUNIQUE_TYPEINFO -#else -#define _LIBCPP_HAS_UNIQUE_TYPEINFO -#endif +#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) && !defined(_LIBCPP_ABI_MICROSOFT) +# define _LIBCPP_HAS_NONUNIQUE_TYPEINFO #endif namespace std // purposefully not using versioning namespace @@ -232,7 +228,7 @@ void __throw_bad_cast() #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_cast(); #else - _VSTD::abort(); + _VSTD::abort(); #endif } _LIBCPP_END_NAMESPACE_STD diff --git a/include/unordered_map b/include/unordered_map index 348f57923b52..6035b05dc61c 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -153,6 +153,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class H2, class P2> + void merge(unordered_map<Key, T, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // C++17 + template<class H2, class P2> + void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // C++17 + void swap(unordered_map&) noexcept( (!allocator_type::propagate_on_container_swap::value || @@ -325,6 +334,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class H2, class P2> + void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // C++17 + template<class H2, class P2> + void merge(unordered_map<Key, T, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // C++17 + void swap(unordered_multimap&) noexcept( (!allocator_type::propagate_on_container_swap::value || @@ -366,6 +384,12 @@ template <class Key, class T, class Hash, class Pred, class Alloc> unordered_multimap<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20 + +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20 + template <class Key, class T, class Hash, class Pred, class Alloc> bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x, @@ -386,6 +410,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <functional> #include <stdexcept> #include <tuple> +#include <version> #include <__debug> @@ -395,7 +420,8 @@ template <class Key, class T, class Hash, class Pred, class Alloc> _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Key, class _Cp, class _Hash, bool _IsEmpty> +template <class _Key, class _Cp, class _Hash, + bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> class __unordered_map_hasher : private _Hash { @@ -463,7 +489,8 @@ swap(__unordered_map_hasher<_Key, _Cp, _Hash, __b>& __x, __x.swap(__y); } -template <class _Key, class _Cp, class _Pred, bool _IsEmpty> +template <class _Key, class _Cp, class _Pred, + bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value> class __unordered_map_equal : private _Pred { @@ -807,6 +834,9 @@ public: template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; }; +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> +class unordered_multimap; + template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>, class _Alloc = allocator<pair<const _Key, _Tp> > > class _LIBCPP_TEMPLATE_VIS unordered_map @@ -823,6 +853,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); private: typedef __hash_value_type<key_type, mapped_type> __value_type; @@ -864,6 +895,11 @@ public: typedef __insert_return_type<iterator, node_type> insert_return_type; #endif + template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + _LIBCPP_INLINE_VISIBILITY unordered_map() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -1187,6 +1223,39 @@ public: return __table_.template __node_handle_extract<node_type>( __it.__i_); } + + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_unique(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_unique(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_unique(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_unique(__source.__table_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -1563,6 +1632,13 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, @@ -1607,6 +1683,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Key, _Hash, _Pred>(0)), ""); private: typedef __hash_value_type<key_type, mapped_type> __value_type; @@ -1645,6 +1722,11 @@ public: typedef __map_node_handle<__node, allocator_type> node_type; #endif + template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template <class _Key2, class _Tp2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + _LIBCPP_INLINE_VISIBILITY unordered_multimap() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -1846,6 +1928,39 @@ public: return __table_.template __node_handle_extract<node_type>( __it.__i_); } + + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -2141,6 +2256,13 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, diff --git a/include/unordered_set b/include/unordered_set index 9b8560da494a..b4e61da89eec 100644 --- a/include/unordered_set +++ b/include/unordered_set @@ -127,6 +127,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class H2, class P2> + void merge(unordered_set<Key, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_set<Key, H2, P2, Allocator>&& source); // C++17 + template<class H2, class P2> + void merge(unordered_multiset<Key, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // C++17 + void swap(unordered_set&) noexcept(allocator_traits<Allocator>::is_always_equal::value && noexcept(swap(declval<hasher&>(), declval<hasher&>())) && @@ -282,6 +291,15 @@ public: iterator erase(const_iterator first, const_iterator last); void clear() noexcept; + template<class H2, class P2> + void merge(unordered_multiset<Key, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // C++17 + template<class H2, class P2> + void merge(unordered_set<Key, H2, P2, Allocator>& source); // C++17 + template<class H2, class P2> + void merge(unordered_set<Key, H2, P2, Allocator>&& source); // C++17 + void swap(unordered_multiset&) noexcept(allocator_traits<Allocator>::is_always_equal::value && noexcept(swap(declval<hasher&>(), declval<hasher&>())) && @@ -321,6 +339,13 @@ template <class Value, class Hash, class Pred, class Alloc> unordered_multiset<Value, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20 + +template <class K, class T, class H, class P, class A, class Predicate> + void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20 + + template <class Value, class Hash, class Pred, class Alloc> bool operator==(const unordered_multiset<Value, Hash, Pred, Alloc>& x, @@ -338,6 +363,7 @@ template <class Value, class Hash, class Pred, class Alloc> #include <__hash_table> #include <__node_handle> #include <functional> +#include <version> #include <__debug> @@ -347,6 +373,9 @@ template <class Value, class Hash, class Pred, class Alloc> _LIBCPP_BEGIN_NAMESPACE_STD +template <class _Value, class _Hash, class _Pred, class _Alloc> +class unordered_multiset; + template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>, class _Alloc = allocator<_Value> > class _LIBCPP_TEMPLATE_VIS unordered_set @@ -362,6 +391,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); private: typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; @@ -384,6 +414,11 @@ public: typedef __insert_return_type<iterator, node_type> insert_return_type; #endif + template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_set; + template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_multiset; + _LIBCPP_INLINE_VISIBILITY unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -589,6 +624,39 @@ public: { return __table_.template __node_handle_extract<node_type>(__it); } + + template<class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __table_.__node_handle_merge_unique(__source.__table_); + } + template<class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __table_.__node_handle_merge_unique(__source.__table_); + } + template<class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __table_.__node_handle_merge_unique(__source.__table_); + } + template<class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + __table_.__node_handle_merge_unique(__source.__table_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -873,6 +941,13 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Value, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, @@ -916,6 +991,7 @@ public: typedef const value_type& const_reference; static_assert((is_same<value_type, typename allocator_type::value_type>::value), "Invalid allocator::value_type"); + static_assert(sizeof(__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); private: typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; @@ -937,6 +1013,11 @@ public: typedef __set_node_handle<typename __table::__node, allocator_type> node_type; #endif + template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_set; + template <class _Value2, class _Hash2, class _Pred2, class _Alloc2> + friend class _LIBCPP_TEMPLATE_VIS unordered_multiset; + _LIBCPP_INLINE_VISIBILITY unordered_multiset() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) @@ -1101,6 +1182,39 @@ public: { return __table_.template __node_handle_extract<node_type>(__key); } + + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } + template <class _H2, class _P2> + _LIBCPP_INLINE_VISIBILITY + void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) + { + _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), + "merging container with incompatible allocator"); + return __table_.__node_handle_merge_multi(__source.__table_); + } #endif _LIBCPP_INLINE_VISIBILITY @@ -1397,6 +1511,13 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred) +{ __libcpp_erase_if_container(__c, __pred); } +#endif + template <class _Value, class _Hash, class _Pred, class _Alloc> bool operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, diff --git a/include/utility b/include/utility index ed9bf030d499..74bbc5cf34f9 100644 --- a/include/utility +++ b/include/utility @@ -103,7 +103,7 @@ swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); struct piecewise_construct_t { }; inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); -template <class T> class tuple_size; +template <class T> struct tuple_size; template <size_t I, class T> class tuple_element; template <class T1, class T2> struct tuple_size<pair<T1, T2> >; @@ -203,6 +203,7 @@ template <size_t I> #include <cstddef> #include <cstring> #include <cstdint> +#include <version> #include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -296,12 +297,13 @@ template <class _Tp> void as_const(const _Tp&&) = delete; struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { }; #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) -extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); +extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); #else /* _LIBCPP_INLINE_VAR */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); #endif #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +template <class, class> struct __non_trivially_copyable_base { _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY __non_trivially_copyable_base() _NOEXCEPT {} @@ -313,7 +315,7 @@ struct __non_trivially_copyable_base { template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS pair #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) -: private __non_trivially_copyable_base +: private __non_trivially_copyable_base<_T1, _T2> #endif { typedef _T1 first_type; @@ -408,13 +410,17 @@ struct _LIBCPP_TEMPLATE_VIS pair _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - pair() : first(), second() {} + 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>::template __enable_explicit<_T1 const&, _T2 const&>() > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && + is_nothrow_copy_constructible<second_type>::value) : first(__t1), second(__t2) {} template<bool _Dummy = true, _EnableB< @@ -422,6 +428,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_T1 const& __t1, _T2 const& __t2) + _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && + is_nothrow_copy_constructible<second_type>::value) : first(__t1), second(__t2) {} template<class _U1, class _U2, _EnableB< @@ -429,6 +437,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && + is_nothrow_constructible<second_type, _U2>::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template<class _U1, class _U2, _EnableB< @@ -436,6 +446,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(_U1&& __u1, _U2&& __u2) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && + is_nothrow_constructible<second_type, _U2>::value)) : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} template<class _U1, class _U2, _EnableB< @@ -443,6 +455,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && + is_nothrow_constructible<second_type, _U2 const&>::value)) : first(__p.first), second(__p.second) {} template<class _U1, class _U2, _EnableB< @@ -450,6 +464,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2> const& __p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && + is_nothrow_constructible<second_type, _U2 const&>::value)) : first(__p.first), second(__p.second) {} template<class _U1, class _U2, _EnableB< @@ -457,6 +473,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit pair(pair<_U1, _U2>&&__p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && + is_nothrow_constructible<second_type, _U2&&>::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template<class _U1, class _U2, _EnableB< @@ -464,6 +482,8 @@ struct _LIBCPP_TEMPLATE_VIS pair > = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 pair(pair<_U1, _U2>&& __p) + _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && + is_nothrow_constructible<second_type, _U2&&>::value)) : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} template<class _Tuple, _EnableB< @@ -486,6 +506,8 @@ struct _LIBCPP_TEMPLATE_VIS pair _LIBCPP_INLINE_VISIBILITY pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) + _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value && + is_nothrow_constructible<second_type, _Args2...>::value)) : pair(__pc, __first_args, __second_args, typename __make_tuple_indices<sizeof...(_Args1)>::type(), typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} @@ -615,32 +637,37 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) __x.swap(__y); } -#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +struct __unwrap_reference { typedef _Tp type; }; template <class _Tp> -struct __make_pair_return_impl -{ - typedef _Tp type; -}; +struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _Tp& type; }; +#if _LIBCPP_STD_VER > 17 template <class _Tp> -struct __make_pair_return_impl<reference_wrapper<_Tp>> -{ - typedef _Tp& type; -}; +struct unwrap_reference : __unwrap_reference<_Tp> { }; template <class _Tp> -struct __make_pair_return -{ - typedef typename __make_pair_return_impl<typename decay<_Tp>::type>::type type; -}; +struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { }; +#endif // > C++17 + +template <class _Tp> +struct __unwrap_ref_decay +#if _LIBCPP_STD_VER > 17 + : unwrap_ref_decay<_Tp> +#else + : __unwrap_reference<typename decay<_Tp>::type> +#endif +{ }; + +#ifndef _LIBCPP_CXX03_LANG template <class _T1, class _T2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type> +pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> make_pair(_T1&& __t1, _T2&& __t2) { - return pair<typename __make_pair_return<_T1>::type, typename __make_pair_return<_T2>::type> + return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); } @@ -657,7 +684,7 @@ make_pair(_T1 __x, _T2 __y) #endif // _LIBCPP_CXX03_LANG template <class _T1, class _T2> - class _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > + struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {}; template <size_t _Ip, class _T1, class _T2> @@ -988,8 +1015,10 @@ __murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) { case 3: __h ^= __data[2] << 16; + _LIBCPP_FALLTHROUGH(); case 2: __h ^= __data[1] << 8; + _LIBCPP_FALLTHROUGH(); case 1: __h ^= __data[0]; __h *= __m; @@ -1453,7 +1482,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<float> size_t operator()(float __v) const _NOEXCEPT { // -0.0 and 0.0 should return same hash - if (__v == 0) + if (__v == 0.0) return 0; return __scalar_hash<float>::operator()(__v); } @@ -1467,7 +1496,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<double> size_t operator()(double __v) const _NOEXCEPT { // -0.0 and 0.0 should return same hash - if (__v == 0) + if (__v == 0.0) return 0; return __scalar_hash<double>::operator()(__v); } @@ -1481,7 +1510,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<long double> size_t operator()(long double __v) const _NOEXCEPT { // -0.0 and 0.0 should return same hash - if (__v == 0) + if (__v == 0.0) return 0; #if defined(__i386__) // Zero out padding bits diff --git a/include/valarray b/include/valarray index 8d3892ad35d9..07f38c811509 100644 --- a/include/valarray +++ b/include/valarray @@ -803,7 +803,7 @@ public: // construct/destroy: _LIBCPP_INLINE_VISIBILITY valarray() : __begin_(0), __end_(0) {} - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 explicit valarray(size_t __n); _LIBCPP_INLINE_VISIBILITY valarray(const value_type& __x, size_t __n); @@ -818,7 +818,7 @@ public: valarray(const gslice_array<value_type>& __ga); valarray(const mask_array<value_type>& __ma); valarray(const indirect_array<value_type>& __ia); - inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + inline _LIBCPP_HIDE_FROM_ABI_AFTER_V1 ~valarray(); // assignment: @@ -1054,7 +1054,8 @@ private: const _Up* end(const valarray<_Up>& __v); - void __clear(); + _LIBCPP_INLINE_VISIBILITY + void __clear(size_t __capacity); valarray& __assign_range(const value_type* __f, const value_type* __l); }; @@ -2739,7 +2740,7 @@ __val_expr<_ValExpr>::operator valarray<__val_expr::result_type>() const __r.__begin_ = __r.__end_ = static_cast<result_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(result_type), __alignof(result_type))); + _VSTD::__libcpp_allocate(__n * sizeof(result_type), _LIBCPP_ALIGNOF(result_type))); for (size_t __i = 0; __i != __n; ++__r.__end_, ++__i) ::new (__r.__end_) result_type(__expr_[__i]); } @@ -2757,18 +2758,18 @@ valarray<_Tp>::valarray(size_t __n) if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; --__n, ++__end_) + for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) ::new (__end_) value_type(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2792,18 +2793,18 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n) if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; ++__end_, ++__p, --__n) + for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left) ::new (__end_) value_type(*__p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2818,7 +2819,7 @@ valarray<_Tp>::valarray(const valarray& __v) if (__v.size()) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__v.size() * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2829,7 +2830,7 @@ valarray<_Tp>::valarray(const valarray& __v) } catch (...) { - __clear(); + __clear(__v.size()); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2852,22 +2853,23 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il) : __begin_(0), __end_(0) { - size_t __n = __il.size(); + const size_t __n = __il.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( -_VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); +_VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - for (const value_type* __p = __il.begin(); __n; ++__end_, ++__p, --__n) + size_t __n_left = __n; + for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left) ::new (__end_) value_type(*__p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2881,22 +2883,23 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) : __begin_(0), __end_(0) { - size_t __n = __sa.__size_; + const size_t __n = __sa.__size_; if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - for (const value_type* __p = __sa.__vp_; __n; ++__end_, __p += __sa.__stride_, --__n) + size_t __n_left = __n; + for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left) ::new (__end_) value_type(*__p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2908,11 +2911,11 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) : __begin_(0), __end_(0) { - size_t __n = __ga.__1d_.size(); + const size_t __n = __ga.__1d_.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2926,7 +2929,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2938,11 +2941,11 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) : __begin_(0), __end_(0) { - size_t __n = __ma.__1d_.size(); + const size_t __n = __ma.__1d_.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2956,7 +2959,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2968,11 +2971,11 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) : __begin_(0), __end_(0) { - size_t __n = __ia.__1d_.size(); + const size_t __n = __ia.__1d_.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -2986,7 +2989,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2997,7 +3000,7 @@ template <class _Tp> inline valarray<_Tp>::~valarray() { - __clear(); + __clear(size()); } template <class _Tp> @@ -3007,9 +3010,9 @@ valarray<_Tp>::__assign_range(const value_type* __f, const value_type* __l) size_t __n = __l - __f; if (size() != __n) { - __clear(); + __clear(size()); __begin_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); __end_ = __begin_ + __n; _VSTD::uninitialized_copy(__f, __l, __begin_); } else { @@ -3034,7 +3037,7 @@ inline valarray<_Tp>& valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT { - __clear(); + __clear(size()); __begin_ = __v.__begin_; __end_ = __v.__end_; __v.__begin_ = nullptr; @@ -3265,7 +3268,7 @@ valarray<_Tp>::operator+() const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(+*__p); } @@ -3283,7 +3286,7 @@ valarray<_Tp>::operator-() const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(-*__p); } @@ -3301,7 +3304,7 @@ valarray<_Tp>::operator~() const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(~*__p); } @@ -3318,7 +3321,7 @@ valarray<_Tp>::operator!() const { __r.__begin_ = __r.__end_ = - static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), __alignof(bool))); + static_cast<bool*>(_VSTD::__libcpp_allocate(__n * sizeof(bool), _LIBCPP_ALIGNOF(bool))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) bool(!*__p); } @@ -3639,7 +3642,7 @@ valarray<_Tp>::shift(int __i) const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); const value_type* __sb; value_type* __tb; value_type* __te; @@ -3678,7 +3681,7 @@ valarray<_Tp>::cshift(int __i) const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); __i %= static_cast<int>(__n); const value_type* __m = __i >= 0 ? __begin_ + __i : __end_ + __i; for (const value_type* __s = __m; __s != __end_; ++__r.__end_, ++__s) @@ -3700,7 +3703,7 @@ valarray<_Tp>::apply(value_type __f(value_type)) const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(__f(*__p)); } @@ -3718,7 +3721,7 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const __r.__begin_ = __r.__end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); for (const value_type* __p = __begin_; __n; ++__r.__end_, ++__p, --__n) ::new (__r.__end_) value_type(__f(*__p)); } @@ -3726,38 +3729,38 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const } template <class _Tp> -void -valarray<_Tp>::__clear() +inline +void valarray<_Tp>::__clear(size_t __capacity) { - if (__begin_ != nullptr) - { - while (__end_ != __begin_) - (--__end_)->~value_type(); - _VSTD::__libcpp_deallocate(__begin_, __alignof(value_type)); - __begin_ = __end_ = nullptr; - } + if (__begin_ != nullptr) + { + while (__end_ != __begin_) + (--__end_)->~value_type(); + _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), _LIBCPP_ALIGNOF(value_type)); + __begin_ = __end_ = nullptr; + } } template <class _Tp> void valarray<_Tp>::resize(size_t __n, value_type __x) { - __clear(); + __clear(size()); if (__n) { __begin_ = __end_ = static_cast<value_type*>( - _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); + _VSTD::__libcpp_allocate(__n * sizeof(value_type), _LIBCPP_ALIGNOF(value_type))); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; --__n, ++__end_) + for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) ::new (__end_) value_type(__x); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS diff --git a/include/variant b/include/variant index f9098f42249a..a4339de6cde4 100644 --- a/include/variant +++ b/include/variant @@ -23,8 +23,8 @@ namespace std { // 20.7.2.1, constructors constexpr variant() noexcept(see below); - variant(const variant&); - variant(variant&&) noexcept(see below); + variant(const variant&); // constexpr in C++20 + variant(variant&&) noexcept(see below); // constexpr in C++20 template <class T> constexpr variant(T&&) noexcept(see below); @@ -46,8 +46,8 @@ namespace std { ~variant(); // 20.7.2.3, assignment - variant& operator=(const variant&); - variant& operator=(variant&&) noexcept(see below); + variant& operator=(const variant&); // constexpr in C++20 + variant& operator=(variant&&) noexcept(see below); // constexpr in C++20 template <class T> variant& operator=(T&&) noexcept(see below); @@ -208,6 +208,7 @@ namespace std { #include <type_traits> #include <utility> #include <limits> +#include <version> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -218,7 +219,7 @@ _LIBCPP_PUSH_MACROS namespace std { // explicitly not using versioning namespace -class _LIBCPP_EXCEPTION_ABI bad_variant_access : public exception { +class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { public: virtual const char* what() const _NOEXCEPT; }; @@ -231,6 +232,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS void __throw_bad_variant_access() { #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_variant_access(); @@ -1064,7 +1066,7 @@ public: #ifndef _LIBCPP_NO_EXCEPTIONS // EXTENSION: When the move construction of `__lhs` into `__rhs` throws // and `__tmp` is nothrow move constructible then we move `__tmp` back - // into `__rhs` and provide the strong exception safety guarentee. + // into `__rhs` and provide the strong exception safety guarantee. try { this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); } catch (...) { @@ -1320,7 +1322,8 @@ constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { template <size_t _Ip, class _Vp> inline _LIBCPP_INLINE_VISIBILITY -static constexpr auto&& __generic_get(_Vp&& __v) { +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +constexpr auto&& __generic_get(_Vp&& __v) { using __variant_detail::__access::__variant; if (!__holds_alternative<_Ip>(__v)) { __throw_bad_variant_access(); @@ -1330,6 +1333,7 @@ static constexpr auto&& __generic_get(_Vp&& __v) { template <size_t _Ip, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr variant_alternative_t<_Ip, variant<_Types...>>& get( variant<_Types...>& __v) { static_assert(_Ip < sizeof...(_Types)); @@ -1339,6 +1343,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>& get( template <size_t _Ip, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get( variant<_Types...>&& __v) { static_assert(_Ip < sizeof...(_Types)); @@ -1348,6 +1353,7 @@ constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get( template <size_t _Ip, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get( const variant<_Types...>& __v) { static_assert(_Ip < sizeof...(_Types)); @@ -1357,6 +1363,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get( template <size_t _Ip, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get( const variant<_Types...>&& __v) { static_assert(_Ip < sizeof...(_Types)); @@ -1366,6 +1373,7 @@ constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get( template <class _Tp, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Tp& get(variant<_Types...>& __v) { static_assert(!is_void_v<_Tp>); return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); @@ -1373,6 +1381,7 @@ constexpr _Tp& get(variant<_Types...>& __v) { template <class _Tp, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr _Tp&& get(variant<_Types...>&& __v) { static_assert(!is_void_v<_Tp>); return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( @@ -1381,6 +1390,7 @@ constexpr _Tp&& get(variant<_Types...>&& __v) { template <class _Tp, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const _Tp& get(const variant<_Types...>& __v) { static_assert(!is_void_v<_Tp>); return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); @@ -1388,6 +1398,7 @@ constexpr const _Tp& get(const variant<_Types...>& __v) { template <class _Tp, class... _Types> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr const _Tp&& get(const variant<_Types...>&& __v) { static_assert(!is_void_v<_Tp>); return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( @@ -1437,6 +1448,16 @@ get_if(const variant<_Types...>* __v) noexcept { return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); } +template <class _Operator> +struct __convert_to_bool { + template <class _T1, class _T2> + _LIBCPP_INLINE_VISIBILITY constexpr bool operator()(_T1 && __t1, _T2&& __t2) const { + static_assert(std::is_convertible<decltype(_Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2))), bool>::value, + "the relational operator does not return a type which is implicitly convertible to bool"); + return _Operator{}(_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); + } +}; + template <class... _Types> inline _LIBCPP_INLINE_VISIBILITY constexpr bool operator==(const variant<_Types...>& __lhs, @@ -1444,7 +1465,7 @@ constexpr bool operator==(const variant<_Types...>& __lhs, using __variant_detail::__visitation::__variant; if (__lhs.index() != __rhs.index()) return false; if (__lhs.valueless_by_exception()) return true; - return __variant::__visit_value_at(__lhs.index(), equal_to<>{}, __lhs, __rhs); + return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs); } template <class... _Types> @@ -1455,7 +1476,7 @@ constexpr bool operator!=(const variant<_Types...>& __lhs, if (__lhs.index() != __rhs.index()) return true; if (__lhs.valueless_by_exception()) return false; return __variant::__visit_value_at( - __lhs.index(), not_equal_to<>{}, __lhs, __rhs); + __lhs.index(), __convert_to_bool<not_equal_to<>>{}, __lhs, __rhs); } template <class... _Types> @@ -1467,7 +1488,7 @@ constexpr bool operator<(const variant<_Types...>& __lhs, if (__lhs.valueless_by_exception()) return true; if (__lhs.index() < __rhs.index()) return true; if (__lhs.index() > __rhs.index()) return false; - return __variant::__visit_value_at(__lhs.index(), less<>{}, __lhs, __rhs); + return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<less<>>{}, __lhs, __rhs); } template <class... _Types> @@ -1479,7 +1500,7 @@ constexpr bool operator>(const variant<_Types...>& __lhs, if (__rhs.valueless_by_exception()) return true; if (__lhs.index() > __rhs.index()) return true; if (__lhs.index() < __rhs.index()) return false; - return __variant::__visit_value_at(__lhs.index(), greater<>{}, __lhs, __rhs); + return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<greater<>>{}, __lhs, __rhs); } template <class... _Types> @@ -1492,7 +1513,7 @@ constexpr bool operator<=(const variant<_Types...>& __lhs, if (__lhs.index() < __rhs.index()) return true; if (__lhs.index() > __rhs.index()) return false; return __variant::__visit_value_at( - __lhs.index(), less_equal<>{}, __lhs, __rhs); + __lhs.index(), __convert_to_bool<less_equal<>>{}, __lhs, __rhs); } template <class... _Types> @@ -1505,11 +1526,12 @@ constexpr bool operator>=(const variant<_Types...>& __lhs, if (__lhs.index() > __rhs.index()) return true; if (__lhs.index() < __rhs.index()) return false; return __variant::__visit_value_at( - __lhs.index(), greater_equal<>{}, __lhs, __rhs); + __lhs.index(), __convert_to_bool<greater_equal<>>{}, __lhs, __rhs); } template <class _Visitor, class... _Vs> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) { using __variant_detail::__visitation::__variant; bool __results[] = {__vs.valueless_by_exception()...}; diff --git a/include/vector b/include/vector index 0f5006f37567..edb6d3e09f5f 100644 --- a/include/vector +++ b/include/vector @@ -261,6 +261,11 @@ template <class T, class Allocator> void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) noexcept(noexcept(x.swap(y))); +template <class T, class Allocator, class U> + void erase(vector<T, Allocator>& c, const U& value); // C++20 +template <class T, class Allocator, class Predicate> + void erase_if(vector<T, Allocator>& c, Predicate pred); // C++20 + } // std */ @@ -276,6 +281,7 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) #include <stdexcept> #include <algorithm> #include <cstring> +#include <version> #include <__split_buffer> #include <__functional_base> @@ -540,13 +546,14 @@ public: value_type, typename iterator_traits<_ForwardIterator>::reference>::value>::type* = 0); -#if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY ~vector() { + __annotate_delete(); +#if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__erase_c(this); - } #endif + } vector(const vector& __x); vector(const vector& __x, const allocator_type& __a); @@ -2453,7 +2460,7 @@ private: void __vdeallocate() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY static size_type __align_it(size_type __new_size) _NOEXCEPT - {return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);}; + {return __new_size + (__bits_per_word-1) & ~((size_type)__bits_per_word-1);} _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const; _LIBCPP_INLINE_VISIBILITY void __construct_at_end(size_type __n, bool __x); template <class _ForwardIterator> @@ -2604,6 +2611,13 @@ vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) { size_type __old_size = this->__size_; this->__size_ += __n; + if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) + { + if (this->__size_ <= __bits_per_word) + this->__begin_[0] = __storage_type(0); + else + this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0); + } _VSTD::fill_n(__make_iter(__old_size), __n, __x); } @@ -2618,6 +2632,13 @@ vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardI { size_type __old_size = this->__size_; this->__size_ += _VSTD::distance(__first, __last); + if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) + { + if (this->__size_ <= __bits_per_word) + this->__begin_[0] = __storage_type(0); + else + this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0); + } _VSTD::copy(__first, __last, __make_iter(__old_size)); } @@ -3392,6 +3413,18 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y) __x.swap(__y); } +#if _LIBCPP_STD_VER > 17 +template <class _Tp, class _Allocator, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +void erase(vector<_Tp, _Allocator>& __c, const _Up& __v) +{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); } + +template <class _Tp, class _Allocator, class _Predicate> +inline _LIBCPP_INLINE_VISIBILITY +void erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) +{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); } +#endif + _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/include/version b/include/version index 23a872ea85ac..e37afc448601 100644 --- a/include/version +++ b/include/version @@ -12,7 +12,105 @@ #define _LIBCPP_VERSIONH /* - version synopsis + version synopsis + +Macro name Value Headers +__cpp_lib_addressof_constexpr 201603L <memory> +__cpp_lib_allocator_traits_is_always_equal 201411L <memory> <scoped_allocator> <string> + <deque> <forward_list> <list> + <vector> <map> <set> + <unordered_map> <unordered_set> +__cpp_lib_any 201606L <any> +__cpp_lib_apply 201603L <tuple> +__cpp_lib_array_constexpr 201603L <iterator> <array> +__cpp_lib_as_const 201510L <utility> +__cpp_lib_atomic_is_always_lock_free 201603L <atomic> +__cpp_lib_atomic_ref 201806L <atomic> +__cpp_lib_bind_front 201811L <functional> +__cpp_lib_bit_cast 201806L <bit> +__cpp_lib_bool_constant 201505L <type_traits> +__cpp_lib_boyer_moore_searcher 201603L <functional> +__cpp_lib_byte 201603L <cstddef> +__cpp_lib_char8_t 201811L <atomic> <filesystem> <istream> + <limits> <locale> <ostream> + <string> <string_view> +__cpp_lib_chrono 201611L <chrono> +__cpp_lib_chrono_udls 201304L <chrono> +__cpp_lib_clamp 201603L <algorithm> +__cpp_lib_complex_udls 201309L <complex> +__cpp_lib_concepts 201806L <concepts> +__cpp_lib_constexpr_misc 201811L <array> <functional> <iterator> + <string_view> <tuple> <utility> +__cpp_lib_constexpr_swap_algorithms 201806L <algorithm> +__cpp_lib_destroying_delete 201806L <new> +__cpp_lib_enable_shared_from_this 201603L <memory> +__cpp_lib_erase_if 201811L <string> <deque> <forward_list> + <list> <vector> <map> + <set> <unordered_map> <unordered_set> +__cpp_lib_exchange_function 201304L <utility> +__cpp_lib_execution 201603L <execution> +__cpp_lib_filesystem 201703L <filesystem> +__cpp_lib_gcd_lcm 201606L <numeric> +__cpp_lib_generic_associative_lookup 201304L <map> <set> +__cpp_lib_generic_unordered_lookup 201811L <unordered_map> <unordered_set> +__cpp_lib_hardware_interference_size 201703L <new> +__cpp_lib_has_unique_object_representations 201606L <type_traits> +__cpp_lib_hypot 201603L <cmath> +__cpp_lib_incomplete_container_elements 201505L <forward_list> <list> <vector> +__cpp_lib_integer_sequence 201304L <utility> +__cpp_lib_integral_constant_callable 201304L <type_traits> +__cpp_lib_invoke 201411L <functional> +__cpp_lib_is_aggregate 201703L <type_traits> +__cpp_lib_is_constant_evaluated 201811L <type_traits> +__cpp_lib_is_final 201402L <type_traits> +__cpp_lib_is_invocable 201703L <type_traits> +__cpp_lib_is_null_pointer 201309L <type_traits> +__cpp_lib_is_swappable 201603L <type_traits> +__cpp_lib_launder 201606L <new> +__cpp_lib_list_remove_return_type 201806L <forward_list> <list> +__cpp_lib_logical_traits 201510L <type_traits> +__cpp_lib_make_from_tuple 201606L <tuple> +__cpp_lib_make_reverse_iterator 201402L <iterator> +__cpp_lib_make_unique 201304L <memory> +__cpp_lib_map_try_emplace 201411L <map> +__cpp_lib_math_special_functions 201603L <cmath> +__cpp_lib_memory_resource 201603L <memory_resource> +__cpp_lib_node_extract 201606L <map> <set> <unordered_map> + <unordered_set> +__cpp_lib_nonmember_container_access 201411L <iterator> <array> <deque> + <forward_list> <list> <map> + <regex> <set> <string> + <unordered_map> <unordered_set> <vector> +__cpp_lib_not_fn 201603L <functional> +__cpp_lib_null_iterators 201304L <iterator> +__cpp_lib_optional 201606L <optional> +__cpp_lib_parallel_algorithm 201603L <algorithm> <numeric> +__cpp_lib_quoted_string_io 201304L <iomanip> +__cpp_lib_ranges 201811L <algorithm> <functional> <iterator> + <memory> <ranges> +__cpp_lib_raw_memory_algorithms 201606L <memory> +__cpp_lib_result_of_sfinae 201210L <functional> <type_traits> +__cpp_lib_robust_nonmodifying_seq_ops 201304L <algorithm> +__cpp_lib_sample 201603L <algorithm> +__cpp_lib_scoped_lock 201703L <mutex> +__cpp_lib_shared_mutex 201505L <shared_mutex> +__cpp_lib_shared_ptr_arrays 201611L <memory> +__cpp_lib_shared_ptr_weak_type 201606L <memory> +__cpp_lib_shared_timed_mutex 201402L <shared_mutex> +__cpp_lib_string_udls 201304L <string> +__cpp_lib_string_view 201606L <string> <string_view> +__cpp_lib_three_way_comparison 201711L <compare> +__cpp_lib_to_chars 201611L <utility> +__cpp_lib_transformation_trait_aliases 201304L <type_traits> +__cpp_lib_transparent_operators 201510L <functional> + 201210L // C++14 +__cpp_lib_tuple_element_t 201402L <tuple> +__cpp_lib_tuples_by_type 201304L <utility> <tuple> +__cpp_lib_type_trait_variable_templates 201510L <type_traits> +__cpp_lib_uncaught_exceptions 201411L <exception> +__cpp_lib_unordered_map_try_emplace 201411L <unordered_map> +__cpp_lib_variant 201606L <variant> +__cpp_lib_void_t 201411L <type_traits> */ @@ -22,4 +120,113 @@ #pragma GCC system_header #endif -#endif // _LIBCPP_VERSIONH +#if _LIBCPP_STD_VER > 11 +# define __cpp_lib_chrono_udls 201304L +# define __cpp_lib_complex_udls 201309L +# define __cpp_lib_exchange_function 201304L +# define __cpp_lib_generic_associative_lookup 201304L +# define __cpp_lib_integer_sequence 201304L +# define __cpp_lib_integral_constant_callable 201304L +# define __cpp_lib_is_final 201402L +# define __cpp_lib_is_null_pointer 201309L +# define __cpp_lib_make_reverse_iterator 201402L +# define __cpp_lib_make_unique 201304L +# define __cpp_lib_null_iterators 201304L +# define __cpp_lib_quoted_string_io 201304L +# define __cpp_lib_result_of_sfinae 201210L +# define __cpp_lib_robust_nonmodifying_seq_ops 201304L +# if !defined(_LIBCPP_HAS_NO_THREADS) +# define __cpp_lib_shared_timed_mutex 201402L +# endif +# define __cpp_lib_string_udls 201304L +# define __cpp_lib_transformation_trait_aliases 201304L +# define __cpp_lib_transparent_operators 201210L +# define __cpp_lib_tuple_element_t 201402L +# define __cpp_lib_tuples_by_type 201304L +#endif + +#if _LIBCPP_STD_VER > 14 +# if !defined(_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF) +# define __cpp_lib_addressof_constexpr 201603L +# endif +# define __cpp_lib_allocator_traits_is_always_equal 201411L +# define __cpp_lib_any 201606L +# define __cpp_lib_apply 201603L +# define __cpp_lib_array_constexpr 201603L +# define __cpp_lib_as_const 201510L +# if !defined(_LIBCPP_HAS_NO_THREADS) +# define __cpp_lib_atomic_is_always_lock_free 201603L +# endif +# define __cpp_lib_bool_constant 201505L +// # define __cpp_lib_boyer_moore_searcher 201603L +# define __cpp_lib_byte 201603L +# define __cpp_lib_chrono 201611L +# define __cpp_lib_clamp 201603L +# define __cpp_lib_enable_shared_from_this 201603L +// # define __cpp_lib_execution 201603L +# define __cpp_lib_filesystem 201703L +# define __cpp_lib_gcd_lcm 201606L +# define __cpp_lib_hardware_interference_size 201703L +# if defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS) +# define __cpp_lib_has_unique_object_representations 201606L +# endif +# define __cpp_lib_hypot 201603L +# define __cpp_lib_incomplete_container_elements 201505L +# define __cpp_lib_invoke 201411L +# if !defined(_LIBCPP_HAS_NO_IS_AGGREGATE) +# define __cpp_lib_is_aggregate 201703L +# endif +# define __cpp_lib_is_invocable 201703L +# define __cpp_lib_is_swappable 201603L +# define __cpp_lib_launder 201606L +# define __cpp_lib_logical_traits 201510L +# define __cpp_lib_make_from_tuple 201606L +# define __cpp_lib_map_try_emplace 201411L +// # define __cpp_lib_math_special_functions 201603L +// # define __cpp_lib_memory_resource 201603L +# define __cpp_lib_node_extract 201606L +# define __cpp_lib_nonmember_container_access 201411L +# define __cpp_lib_not_fn 201603L +# define __cpp_lib_optional 201606L +// # define __cpp_lib_parallel_algorithm 201603L +# define __cpp_lib_raw_memory_algorithms 201606L +# define __cpp_lib_sample 201603L +# define __cpp_lib_scoped_lock 201703L +# if !defined(_LIBCPP_HAS_NO_THREADS) +# define __cpp_lib_shared_mutex 201505L +# endif +// # define __cpp_lib_shared_ptr_arrays 201611L +# define __cpp_lib_shared_ptr_weak_type 201606L +# define __cpp_lib_string_view 201606L +// # define __cpp_lib_to_chars 201611L +# undef __cpp_lib_transparent_operators +# define __cpp_lib_transparent_operators 201510L +# define __cpp_lib_type_trait_variable_templates 201510L +# define __cpp_lib_uncaught_exceptions 201411L +# define __cpp_lib_unordered_map_try_emplace 201411L +# define __cpp_lib_variant 201606L +# define __cpp_lib_void_t 201411L +#endif + +#if _LIBCPP_STD_VER > 17 +# if !defined(_LIBCPP_HAS_NO_THREADS) +// # define __cpp_lib_atomic_ref 201806L +# endif +// # define __cpp_lib_bind_front 201811L +// # define __cpp_lib_bit_cast 201806L +# if !defined(_LIBCPP_NO_HAS_CHAR8_T) +# define __cpp_lib_char8_t 201811L +# endif +// # define __cpp_lib_concepts 201806L +// # define __cpp_lib_constexpr_misc 201811L +// # define __cpp_lib_constexpr_swap_algorithms 201806L +// # define __cpp_lib_destroying_delete 201806L +# define __cpp_lib_erase_if 201811L +// # define __cpp_lib_generic_unordered_lookup 201811L +// # define __cpp_lib_is_constant_evaluated 201811L +// # define __cpp_lib_list_remove_return_type 201806L +// # define __cpp_lib_ranges 201811L +// # define __cpp_lib_three_way_comparison 201711L +#endif + +#endif // _LIBCPP_VERSIONH |