libcxx: update from LLVM 10 to 11rc1

This commit is contained in:
Andrew Kelley
2020-08-04 17:26:02 -07:00
parent 16513fee6c
commit 54b67c2025
68 changed files with 4217 additions and 1567 deletions
+15
View File
@@ -1122,6 +1122,21 @@ public:
__bit_iterator(const __type_for_copy_to_const& __it) _NOEXCEPT
: __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
// The non-const __bit_iterator has historically had a non-trivial
// copy constructor (as a quirk of its construction). We need to maintain
// this for ABI purposes.
using __type_for_abi_non_trivial_copy_ctor =
_If<!_IsConst, __bit_iterator, struct __private_nat>;
_LIBCPP_INLINE_VISIBILITY
__bit_iterator(__type_for_abi_non_trivial_copy_ctor const& __it) _NOEXCEPT
: __seg_(__it.__seg_), __ctz_(__it.__ctz_) {}
// Always declare the copy assignment operator since the implicit declaration
// is deprecated.
_LIBCPP_INLINE_VISIBILITY
__bit_iterator& operator=(__bit_iterator const&) = default;
_LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT
{return reference(__seg_, __storage_type(1) << __ctz_);}
+71 -42
View File
@@ -32,7 +32,7 @@
# define _GNUC_VER_NEW 0
#endif
#define _LIBCPP_VERSION 10000
#define _LIBCPP_VERSION 11000
#ifndef _LIBCPP_ABI_VERSION
# define _LIBCPP_ABI_VERSION 1
@@ -102,6 +102,9 @@
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
// All the regex constants must be distinct and nonzero.
# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
// Re-worked external template instantiations for std::string with a focus on
// performance and fast-path inlining.
# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
#elif _LIBCPP_ABI_VERSION == 1
# if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
// Enable compiling copies of now inline methods into the dylib to support
@@ -395,12 +398,12 @@
#if defined(_LIBCPP_COMPILER_CLANG)
// _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for
// _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT left here for backward compatibility.
#if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \
(!defined(__arm__) || __ARM_ARCH_7K__ >= 2)) || \
defined(_LIBCPP_ALTERNATE_STRING_LAYOUT)
#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
#if defined(_LIBCPP_ALTERNATE_STRING_LAYOUT)
# error _LIBCPP_ALTERNATE_STRING_LAYOUT is deprecated, please use _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT instead
#endif
#if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \
(!defined(__arm__) || __ARM_ARCH_7K__ >= 2)
# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
#endif
#if __has_feature(cxx_alignas)
@@ -416,12 +419,8 @@ typedef __char16_t char16_t;
typedef __char32_t char32_t;
#endif
#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS)
#define _LIBCPP_NO_EXCEPTIONS
#endif
#if !(__has_feature(cxx_rtti)) && !defined(_LIBCPP_NO_RTTI)
#define _LIBCPP_NO_RTTI
#if !__has_feature(cxx_exceptions)
# define _LIBCPP_NO_EXCEPTIONS
#endif
#if !(__has_feature(cxx_strong_enums))
@@ -467,6 +466,14 @@ typedef __char32_t char32_t;
#define _LIBCPP_HAS_OBJC_ARC_WEAK
#endif
#if __has_extension(blocks)
# define _LIBCPP_HAS_EXTENSION_BLOCKS
#endif
#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__)
# define _LIBCPP_HAS_BLOCKS_RUNTIME
#endif
#if !(__has_feature(cxx_relaxed_constexpr))
#define _LIBCPP_HAS_NO_CXX14_CONSTEXPR
#endif
@@ -492,6 +499,10 @@ typedef __char32_t char32_t;
#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
#endif
#if __has_builtin(__builtin_constant_p)
#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
#endif
#if !__is_identifier(__has_unique_object_representations)
#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS
#endif
@@ -513,8 +524,8 @@ typedef __char32_t char32_t;
#define _LIBCPP_NORETURN __attribute__((noreturn))
#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS)
#define _LIBCPP_NO_EXCEPTIONS
#if !__EXCEPTIONS
# define _LIBCPP_NO_EXCEPTIONS
#endif
// Determine if GCC supports relaxed constexpr
@@ -533,9 +544,7 @@ typedef __char32_t char32_t;
#if _GNUC_VER >= 700
#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
#endif
#if _GNUC_VER >= 700
#define _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
#define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS
#endif
@@ -745,14 +754,14 @@ typedef __char32_t char32_t;
# endif
#endif
#ifndef _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT
# ifdef _LIBCPP_OBJECT_FORMAT_COFF // Windows binaries can't merge typeinfos.
# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 0
#else
// TODO: This isn't strictly correct on ELF platforms due to llvm.org/PR37398
// And we should consider defaulting to OFF.
# define _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT 1
#endif
#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION
# ifdef _LIBCPP_OBJECT_FORMAT_COFF // Windows binaries can't merge typeinfos.
# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2
# else
// TODO: This isn't strictly correct on ELF platforms due to llvm.org/PR37398
// And we should consider defaulting to OFF.
# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1
# endif
#endif
#ifndef _LIBCPP_HIDE_FROM_ABI
@@ -901,6 +910,10 @@ typedef unsigned int char32_t;
#define _LIBCPP_EXTERN_TEMPLATE2(...) extern template __VA_ARGS__;
#endif
#ifndef _LIBCPP_EXTERN_TEMPLATE_DEFINE
#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__;
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \
defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__)
#define _LIBCPP_LOCALE__L_EXTENSIONS 1
@@ -1092,17 +1105,12 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
#endif
// Try to find out if RTTI is disabled.
// g++ and cl.exe have RTTI on by default and define a macro when it is.
// g++ only defines the macro in 4.3.2 and onwards.
#if !defined(_LIBCPP_NO_RTTI)
# if defined(__GNUC__) && \
((__GNUC__ >= 5) || \
(__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && \
!defined(__GXX_RTTI)
# define _LIBCPP_NO_RTTI
# elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI)
# define _LIBCPP_NO_RTTI
# endif
#if defined(_LIBCPP_COMPILER_CLANG) && !__has_feature(cxx_rtti)
# define _LIBCPP_NO_RTTI
#elif defined(__GNUC__) && !defined(__GXX_RTTI)
# define _LIBCPP_NO_RTTI
#elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI)
# define _LIBCPP_NO_RTTI
#endif
#ifndef _LIBCPP_WEAK
@@ -1125,7 +1133,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
(defined(__MINGW32__) && __has_include(<pthread.h>))
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(__Fuchsia__)
# define _LIBCPP_HAS_THREAD_API_C11
// TODO(44575): Switch to C11 thread API when possible.
# define _LIBCPP_HAS_THREAD_API_PTHREAD
# elif defined(_LIBCPP_WIN32API)
# define _LIBCPP_HAS_THREAD_API_WIN32
# else
@@ -1360,6 +1369,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
// Decide whether to use availability macros.
#if !defined(_LIBCPP_BUILDING_LIBRARY) && \
!defined(_LIBCXXABI_BUILDING_LIBRARY) && \
!defined(_LIBCPP_DISABLE_AVAILABILITY) && \
__has_feature(attribute_availability_with_strict) && \
__has_feature(attribute_availability_in_templates) && \
@@ -1377,10 +1387,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \
__attribute__((availability(macosx,strict,introduced=10.14))) \
__attribute__((availability(ios,strict,introduced=12.0))) \
__attribute__((availability(tvos,strict,introduced=12.0))) \
__attribute__((availability(watchos,strict,introduced=5.0)))
__attribute__((availability(macosx,strict,introduced=10.13))) \
__attribute__((availability(ios,strict,introduced=11.0))) \
__attribute__((availability(tvos,strict,introduced=11.0))) \
__attribute__((availability(watchos,strict,introduced=4.0)))
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \
@@ -1421,6 +1431,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
_Pragma("clang attribute pop") \
_Pragma("clang attribute pop") \
_Pragma("clang attribute pop")
# define _LIBCPP_AVAILABILITY_TO_CHARS \
_LIBCPP_AVAILABILITY_FILESYSTEM
# define _LIBCPP_AVAILABILITY_SYNC \
__attribute__((unavailable))
#else
# define _LIBCPP_AVAILABILITY_SHARED_MUTEX
# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
@@ -1435,6 +1449,8 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_AVAILABILITY_FILESYSTEM
# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH
# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP
# define _LIBCPP_AVAILABILITY_TO_CHARS
# define _LIBCPP_AVAILABILITY_SYNC
#endif
// Define availability that depends on _LIBCPP_NO_EXCEPTIONS.
@@ -1518,6 +1534,19 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_FOPEN_CLOEXEC_MODE
#endif
#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_CONSTANT_P
#define _LIBCPP_BUILTIN_CONSTANT_P(x) __builtin_constant_p(x)
#else
#define _LIBCPP_BUILTIN_CONSTANT_P(x) false
#endif
// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set
// of functions used in cstdio may not be available for low API levels when
// using 64-bit file offsets on LP32.
#if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24
#define _LIBCPP_HAS_NO_FGETPOS_FSETPOS
#endif
#endif // __cplusplus
#endif // _LIBCPP_CONFIG
+3 -1
View File
@@ -27,7 +27,9 @@
#cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
#cmakedefine _LIBCPP_NO_VCRUNTIME
#cmakedefine01 _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT
#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION
#cmakedefine _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION @_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION@
#endif
#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@
#cmakedefine _LIBCPP_HAS_PARALLEL_ALGORITHMS
+2 -2
View File
@@ -522,7 +522,7 @@ inline _LIBCPP_INLINE_VISIBILITY
reference_wrapper<_Tp>
ref(reference_wrapper<_Tp> __t) _NOEXCEPT
{
return ref(__t.get());
return _VSTD::ref(__t.get());
}
template <class _Tp>
@@ -538,7 +538,7 @@ inline _LIBCPP_INLINE_VISIBILITY
reference_wrapper<const _Tp>
cref(reference_wrapper<_Tp> __t) _NOEXCEPT
{
return cref(__t.get());
return _VSTD::cref(__t.get());
}
#ifndef _LIBCPP_CXX03_LANG
+1 -1
View File
@@ -1 +1 @@
10000
11000
+6
View File
@@ -496,7 +496,13 @@ public:
static const mask punct = 1<<7;
static const mask xdigit = 1<<8;
static const mask blank = 1<<9;
#if defined(__BIONIC__)
// Historically this was a part of regex_traits rather than ctype_base. The
// historical value of the constant is preserved for ABI compatibility.
static const mask __regex_word = 0x8000;
#else
static const mask __regex_word = 1<<10;
#endif // defined(__BIONIC__)
#endif
static const mask alnum = alpha | digit;
static const mask graph = alnum | punct;
+117
View File
@@ -70,6 +70,123 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
// The the extern template ABI lists are kept outside of <string> to improve the
// readability of that header.
// The extern template ABI lists are kept outside of <string> to improve the
// readability of that header. We maintain 2 ABI lists:
// - _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST
// - _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST
// As the name implies, the ABI lists define the V1 (Stable) and unstable ABI.
//
// For unstable, we may explicitly remove function that are external in V1,
// and add (new) external functions to better control inlining and compiler
// optimization opportunities.
//
// For stable, the ABI list should rarely change, except for adding new
// functions supporting new c++ version / API changes. Typically entries
// must never be removed from the stable list.
#define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, std::allocator<_CharType> const&)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, std::allocator<_CharType> const&)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
_Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
#define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, std::allocator<_CharType> const&)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \
_Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \
_Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \
_Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \
_Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type))
// char_traits
template <class _CharT>
+111
View File
@@ -26,6 +26,12 @@
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
# include <pthread.h>
# include <sched.h>
# ifdef __APPLE__
# define _LIBCPP_NO_NATIVE_SEMAPHORES
# endif
# ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
# include <semaphore.h>
# endif
#elif defined(_LIBCPP_HAS_THREAD_API_C11)
# include <threads.h>
#endif
@@ -65,6 +71,12 @@ typedef pthread_mutex_t __libcpp_recursive_mutex_t;
typedef pthread_cond_t __libcpp_condvar_t;
#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
// Semaphore
typedef sem_t __libcpp_semaphore_t;
# define _LIBCPP_SEMAPHORE_MAX SEM_VALUE_MAX
#endif
// Execute once
typedef pthread_once_t __libcpp_exec_once_flag;
#define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT
@@ -127,6 +139,9 @@ typedef void* __libcpp_recursive_mutex_t[5];
typedef void* __libcpp_condvar_t;
#define _LIBCPP_CONDVAR_INITIALIZER 0
// Semaphore
typedef void* __libcpp_semaphore_t;
// Execute Once
typedef void* __libcpp_exec_once_flag;
#define _LIBCPP_EXEC_ONCE_INITIALIZER 0
@@ -191,6 +206,26 @@ int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
// Semaphore
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init);
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem);
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem);
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem);
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns);
#endif // _LIBCPP_NO_NATIVE_SEMAPHORES
// Execute once
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
@@ -242,9 +277,52 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
struct __libcpp_timed_backoff_policy {
_LIBCPP_THREAD_ABI_VISIBILITY
bool operator()(chrono::nanoseconds __elapsed) const;
};
inline _LIBCPP_INLINE_VISIBILITY
bool __libcpp_timed_backoff_policy::operator()(chrono::nanoseconds __elapsed) const
{
if(__elapsed > chrono::milliseconds(128))
__libcpp_thread_sleep_for(chrono::milliseconds(8));
else if(__elapsed > chrono::microseconds(64))
__libcpp_thread_sleep_for(__elapsed / 2);
else if(__elapsed > chrono::microseconds(4))
__libcpp_thread_yield();
else
; // poll
return false;
}
static _LIBCPP_CONSTEXPR const int __libcpp_polling_count = 64;
template<class _Fn, class _BFn>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool __libcpp_thread_poll_with_backoff(
_Fn && __f, _BFn && __bf, chrono::nanoseconds __max_elapsed = chrono::nanoseconds::zero())
{
auto const __start = chrono::high_resolution_clock::now();
for(int __count = 0;;) {
if(__f())
return true; // _Fn completion means success
if(__count < __libcpp_polling_count) {
__count += 1;
continue;
}
chrono::nanoseconds const __elapsed = chrono::high_resolution_clock::now() - __start;
if(__max_elapsed != chrono::nanoseconds::zero() && __max_elapsed < __elapsed)
return false; // timeout failure
if(__bf(__elapsed))
return false; // _BFn completion means failure
}
}
#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL))
namespace __thread_detail {
inline __libcpp_timespec_t __convert_to_timespec(const chrono::nanoseconds& __ns)
@@ -364,6 +442,38 @@ int __libcpp_condvar_destroy(__libcpp_condvar_t *__cv)
return pthread_cond_destroy(__cv);
}
#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
// Semaphore
bool __libcpp_semaphore_init(__libcpp_semaphore_t* __sem, int __init)
{
return sem_init(__sem, 0, __init) == 0;
}
bool __libcpp_semaphore_destroy(__libcpp_semaphore_t* __sem)
{
return sem_destroy(__sem) == 0;
}
bool __libcpp_semaphore_post(__libcpp_semaphore_t* __sem)
{
return sem_post(__sem) == 0;
}
bool __libcpp_semaphore_wait(__libcpp_semaphore_t* __sem)
{
return sem_wait(__sem) == 0;
}
bool __libcpp_semaphore_wait_timed(__libcpp_semaphore_t* __sem, chrono::nanoseconds const& __ns)
{
auto const __abs_time = chrono::system_clock::now().time_since_epoch() + __ns;
__libcpp_timespec_t __ts = __thread_detail::__convert_to_timespec(__abs_time);
return sem_timedwait(__sem, &__ts) == 0;
}
#endif //_LIBCPP_NO_NATIVE_SEMAPHORES
// Execute once
int __libcpp_execute_once(__libcpp_exec_once_flag *flag,
void (*init_routine)()) {
@@ -600,6 +710,7 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
#endif
#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
class _LIBCPP_TYPE_VIS thread;
+142 -99
View File
@@ -32,24 +32,24 @@ struct array
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// No explicit construct/copy/destroy for aggregate type
void fill(const T& u);
void swap(array& a) noexcept(is_nothrow_swappable_v<T>);
void fill(const T& u); // constexpr in C++20
void swap(array& a) noexcept(is_nothrow_swappable_v<T>); // constexpr in C++20
// iterators:
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
iterator begin() noexcept; // constexpr in C++17
const_iterator begin() const noexcept; // constexpr in C++17
iterator end() noexcept; // constexpr in C++17
const_iterator end() const noexcept; // constexpr in C++17
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
reverse_iterator rbegin() noexcept; // constexpr in C++17
const_reverse_iterator rbegin() const noexcept; // constexpr in C++17
reverse_iterator rend() noexcept; // constexpr in C++17
const_reverse_iterator rend() const noexcept; // constexpr in C++17
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
const_iterator cbegin() const noexcept; // constexpr in C++17
const_iterator cend() const noexcept; // constexpr in C++17
const_reverse_iterator crbegin() const noexcept; // constexpr in C++17
const_reverse_iterator crend() const noexcept; // constexpr in C++17
// capacity:
constexpr size_type size() const noexcept;
@@ -57,46 +57,51 @@ struct array
constexpr bool empty() const noexcept;
// element access:
reference operator[](size_type n);
const_reference operator[](size_type n) const; // constexpr in C++14
const_reference at(size_type n) const; // constexpr in C++14
reference at(size_type n);
reference operator[](size_type n); // constexpr in C++17
const_reference operator[](size_type n) const; // constexpr in C++14
reference at(size_type n); // constexpr in C++17
const_reference at(size_type n) const; // constexpr in C++14
reference front();
const_reference front() const; // constexpr in C++14
reference back();
const_reference back() const; // constexpr in C++14
reference front(); // constexpr in C++17
const_reference front() const; // constexpr in C++14
reference back(); // constexpr in C++17
const_reference back() const; // constexpr in C++14
T* data() noexcept;
const T* data() const noexcept;
T* data() noexcept; // constexpr in C++17
const T* data() const noexcept; // constexpr in C++17
};
template <class T, class... U>
array(T, U...) -> array<T, 1 + sizeof...(U)>;
template <class T, class... U>
array(T, U...) -> array<T, 1 + sizeof...(U)>; // C++17
template <class T, size_t N>
bool operator==(const array<T,N>& x, const array<T,N>& y);
bool operator==(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
bool operator!=(const array<T,N>& x, const array<T,N>& y);
bool operator!=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
bool operator<(const array<T,N>& x, const array<T,N>& y);
bool operator<(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
bool operator>(const array<T,N>& x, const array<T,N>& y);
bool operator>(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
bool operator<=(const array<T,N>& x, const array<T,N>& y);
bool operator<=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
bool operator>=(const array<T,N>& x, const array<T,N>& y);
bool operator>=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N >
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17
void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
template <class T, size_t N>
constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]); // C++20
template <class T, size_t N>
constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20
template <class T> struct tuple_size;
template <size_t I, class T> struct tuple_element;
template <class T, size_t N> struct tuple_size<array<T, N>>;
template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
} // std
@@ -143,13 +148,14 @@ struct _LIBCPP_TEMPLATE_VIS array
_Tp __elems_[_Size];
// No explicit construct/copy/destroy for aggregate type
_LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) {
_VSTD::fill_n(__elems_, _Size, __u);
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void fill(const value_type& __u) {
_VSTD::fill_n(data(), _Size, __u);
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
std::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);
std::swap_ranges(data(), data() + _Size, __a.data());
}
// iterators:
@@ -186,21 +192,38 @@ struct _LIBCPP_TEMPLATE_VIS array
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return false; }
_LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
// element access:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator[](size_type __n) _NOEXCEPT {return __elems_[__n];}
reference operator[](size_type __n) _NOEXCEPT {
_LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
return __elems_[__n];
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference operator[](size_type __n) const _NOEXCEPT {return __elems_[__n];}
const_reference operator[](size_type __n) const _NOEXCEPT {
_LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
return __elems_[__n];
}
_LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type __n);
_LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
_LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type __n)
{
if (__n >= _Size)
__throw_out_of_range("array::at");
return __elems_[__n];
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() _NOEXCEPT {return __elems_[0];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT {return __elems_[0];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() _NOEXCEPT {return __elems_[_Size - 1];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const _NOEXCEPT {return __elems_[_Size - 1];}
_LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const
{
if (__n >= _Size)
__throw_out_of_range("array::at");
return __elems_[__n];
}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front() _NOEXCEPT {return (*this)[0];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT {return (*this)[0];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back() _NOEXCEPT {return (*this)[_Size - 1];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const _NOEXCEPT {return (*this)[_Size - 1];}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
value_type* data() _NOEXCEPT {return __elems_;}
@@ -208,28 +231,6 @@ struct _LIBCPP_TEMPLATE_VIS array
const value_type* data() const _NOEXCEPT {return __elems_;}
};
template <class _Tp, size_t _Size>
_LIBCPP_CONSTEXPR_AFTER_CXX14
typename array<_Tp, _Size>::reference
array<_Tp, _Size>::at(size_type __n)
{
if (__n >= _Size)
__throw_out_of_range("array::at");
return __elems_[__n];
}
template <class _Tp, size_t _Size>
_LIBCPP_CONSTEXPR_AFTER_CXX11
typename array<_Tp, _Size>::const_reference
array<_Tp, _Size>::at(size_type __n) const
{
if (__n >= _Size)
__throw_out_of_range("array::at");
return __elems_[__n];
}
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
{
@@ -253,44 +254,50 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
struct _ArrayInStructT { _Tp __data_[1]; };
_ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
value_type* data() _NOEXCEPT {return nullptr;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const value_type* data() const _NOEXCEPT {return nullptr;}
// No explicit construct/copy/destroy for aggregate type
_LIBCPP_INLINE_VISIBILITY void fill(const value_type&) {
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void fill(const value_type&) {
static_assert(!is_const<_Tp>::value,
"cannot fill zero-sized array of type 'const T'");
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(array&) _NOEXCEPT {
static_assert(!is_const<_Tp>::value,
"cannot swap zero-sized array of type 'const T'");
}
// iterators:
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
iterator begin() _NOEXCEPT {return iterator(data());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
iterator end() _NOEXCEPT {return iterator(data());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_iterator end() const _NOEXCEPT {return const_iterator(data());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_iterator cbegin() const _NOEXCEPT {return begin();}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_iterator cend() const _NOEXCEPT {return end();}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
const_reverse_iterator crend() const _NOEXCEPT {return rend();}
// capacity:
@@ -302,7 +309,7 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;}
// element access:
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference operator[](size_type) _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
_LIBCPP_UNREACHABLE();
@@ -314,52 +321,47 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference at(size_type) {
__throw_out_of_range("array<T, 0>::at");
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference at(size_type) const {
__throw_out_of_range("array<T, 0>::at");
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference front() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference front() const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference back() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference back() const _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
_LIBCPP_UNREACHABLE();
}
_LIBCPP_INLINE_VISIBILITY
value_type* data() _NOEXCEPT {return reinterpret_cast<value_type*>(__elems_);}
_LIBCPP_INLINE_VISIBILITY
const value_type* data() const _NOEXCEPT {return reinterpret_cast<const value_type*>(__elems_);}
};
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template<class _Tp, class... _Args,
class = typename enable_if<(is_same_v<_Tp, _Args> && ...), void>::type
class = _EnableIf<__all<_IsSame<_Tp, _Args>::value...>::value>
>
array(_Tp, _Args...)
-> array<_Tp, 1 + sizeof...(_Args)>;
@@ -415,7 +417,7 @@ operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
}
template <class _Tp, size_t _Size>
inline _LIBCPP_INLINE_VISIBILITY
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename enable_if
<
_Size == 0 ||
@@ -479,6 +481,47 @@ get(const array<_Tp, _Size>&& __a) _NOEXCEPT
#endif // !_LIBCPP_CXX03_LANG
#if _LIBCPP_STD_VER > 17
template <typename _Tp, size_t _Size, size_t... _Index>
_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) {
return {{__arr[_Index]...}};
}
template <typename _Tp, size_t _Size, size_t... _Index>
_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
__to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) {
return {{_VSTD::move(__arr[_Index])...}};
}
template <typename _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
static_assert(
!is_array_v<_Tp>,
"[array.creation]/1: to_array does not accept multidimensional arrays.");
static_assert(
is_constructible_v<_Tp, _Tp&>,
"[array.creation]/1: to_array requires copy constructible elements.");
return __to_array_lvalue_impl(__arr, make_index_sequence<_Size>());
}
template <typename _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
static_assert(
!is_array_v<_Tp>,
"[array.creation]/4: to_array does not accept multidimensional arrays.");
static_assert(
is_move_constructible_v<_Tp>,
"[array.creation]/4: to_array requires move constructible elements.");
return __to_array_rvalue_impl(_VSTD::move(__arr),
make_index_sequence<_Size>());
}
#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_ARRAY
+559 -213
View File
@@ -54,60 +54,30 @@ template <class T> T kill_dependency(T y) noexcept;
#define ATOMIC_LLONG_LOCK_FREE unspecified
#define ATOMIC_POINTER_LOCK_FREE unspecified
// flag type and operations
typedef struct atomic_flag
{
bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
void clear(memory_order m = memory_order_seq_cst) noexcept;
atomic_flag() noexcept = default;
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete;
} atomic_flag;
bool
atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
bool
atomic_flag_test_and_set(atomic_flag* obj) noexcept;
bool
atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
memory_order m) noexcept;
bool
atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
void
atomic_flag_clear(volatile atomic_flag* obj) noexcept;
void
atomic_flag_clear(atomic_flag* obj) noexcept;
void
atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
void
atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
#define ATOMIC_FLAG_INIT see below
#define ATOMIC_VAR_INIT(value) see below
template <class T>
struct atomic
{
using value_type = T;
static constexpr bool is_always_lock_free;
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
atomic() noexcept = default;
constexpr atomic(T desr) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
T load(memory_order m = memory_order_seq_cst) const noexcept;
operator T() const volatile noexcept;
operator T() const noexcept;
void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
T operator=(T) volatile noexcept;
T operator=(T) noexcept;
T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
bool compare_exchange_weak(T& expc, T desr,
@@ -126,27 +96,38 @@ struct atomic
bool compare_exchange_strong(T& expc, T desr,
memory_order m = memory_order_seq_cst) noexcept;
atomic() noexcept = default;
constexpr atomic(T desr) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T operator=(T) volatile noexcept;
T operator=(T) noexcept;
void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
void wait(T, memory_order = memory_order::seq_cst) const noexcept;
void notify_one() volatile noexcept;
void notify_one() noexcept;
void notify_all() volatile noexcept;
void notify_all() noexcept;
};
template <>
struct atomic<integral>
{
using value_type = integral;
static constexpr bool is_always_lock_free;
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
atomic() noexcept = default;
constexpr atomic(integral desr) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
integral load(memory_order m = memory_order_seq_cst) const noexcept;
operator integral() const volatile noexcept;
operator integral() const noexcept;
void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
integral operator=(integral desr) volatile noexcept;
integral operator=(integral desr) noexcept;
integral exchange(integral desr,
memory_order m = memory_order_seq_cst) volatile noexcept;
integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
@@ -167,30 +148,17 @@ struct atomic<integral>
bool compare_exchange_strong(integral& expc, integral desr,
memory_order m = memory_order_seq_cst) noexcept;
integral
fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
integral
fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
integral
fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
integral
fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
integral
fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
atomic() noexcept = default;
constexpr atomic(integral desr) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
integral operator=(integral desr) volatile noexcept;
integral operator=(integral desr) noexcept;
integral operator++(int) volatile noexcept;
integral operator++(int) noexcept;
integral operator--(int) volatile noexcept;
@@ -209,20 +177,39 @@ struct atomic<integral>
integral operator|=(integral op) noexcept;
integral operator^=(integral op) volatile noexcept;
integral operator^=(integral op) noexcept;
void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
void notify_one() volatile noexcept;
void notify_one() noexcept;
void notify_all() volatile noexcept;
void notify_all() noexcept;
};
template <class T>
struct atomic<T*>
{
using value_type = T*;
static constexpr bool is_always_lock_free;
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
atomic() noexcept = default;
constexpr atomic(T* desr) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
T* load(memory_order m = memory_order_seq_cst) const noexcept;
operator T*() const volatile noexcept;
operator T*() const noexcept;
void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
T* operator=(T*) volatile noexcept;
T* operator=(T*) noexcept;
T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
bool compare_exchange_weak(T*& expc, T* desr,
@@ -246,14 +233,6 @@ struct atomic<T*>
T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
atomic() noexcept = default;
constexpr atomic(T* desr) noexcept;
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
T* operator=(T*) volatile noexcept;
T* operator=(T*) noexcept;
T* operator++(int) volatile noexcept;
T* operator++(int) noexcept;
T* operator--(int) volatile noexcept;
@@ -266,224 +245,206 @@ struct atomic<T*>
T* operator+=(ptrdiff_t op) noexcept;
T* operator-=(ptrdiff_t op) volatile noexcept;
T* operator-=(ptrdiff_t op) noexcept;
void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
void notify_one() volatile noexcept;
void notify_one() noexcept;
void notify_all() volatile noexcept;
void notify_all() noexcept;
};
template <class T>
bool
atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
template <class T>
bool
atomic_is_lock_free(const atomic<T>* obj) noexcept;
bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
template <class T>
void
atomic_init(volatile atomic<T>* obj, T desr) noexcept;
void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
template <class T>
void
atomic_init(atomic<T>* obj, T desr) noexcept;
void atomic_store(atomic<T>* obj, T desr) noexcept;
template <class T>
void
atomic_store(volatile atomic<T>* obj, T desr) noexcept;
void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
template <class T>
void
atomic_store(atomic<T>* obj, T desr) noexcept;
void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
template <class T>
void
atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
T atomic_load(const volatile atomic<T>* obj) noexcept;
template <class T>
void
atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
T atomic_load(const atomic<T>* obj) noexcept;
template <class T>
T
atomic_load(const volatile atomic<T>* obj) noexcept;
T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
template <class T>
T
atomic_load(const atomic<T>* obj) noexcept;
T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
template <class T>
T
atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
template <class T>
T
atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
T atomic_exchange(atomic<T>* obj, T desr) noexcept;
template <class T>
T
atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
template <class T>
T
atomic_exchange(atomic<T>* obj, T desr) noexcept;
T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
template <class T>
T
atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
template <class T>
T
atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
template <class T>
bool
atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
template <class T>
bool
atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
template <class T>
bool
atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
T desr,
memory_order s, memory_order f) noexcept;
template <class T>
bool
atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
memory_order s, memory_order f) noexcept;
template <class T>
bool
atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
T desr,
memory_order s, memory_order f) noexcept;
bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
T* expc, T desr,
memory_order s, memory_order f) noexcept;
template <class T>
bool
atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
memory_order s, memory_order f) noexcept;
bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
T desr,
memory_order s, memory_order f) noexcept;
template <class T>
bool
atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
T* expc, T desr,
memory_order s, memory_order f) noexcept;
void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
template <class T>
bool
atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
T desr,
memory_order s, memory_order f) noexcept;
void atomic_wait(const atomic<T>* obj, T old) noexcept;
template <class T>
void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;
template <class T>
void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;
template <class T>
void atomic_one(volatile atomic<T>* obj) noexcept;
template <class T>
void atomic_one(atomic<T>* obj) noexcept;
template <class T>
void atomic_all(volatile atomic<T>* obj) noexcept;
template <class T>
void atomic_all(atomic<T>* obj) noexcept;
template <class Integral>
Integral
atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral
atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
template <class Integral>
Integral
atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class Integral>
Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
memory_order m) noexcept;
template <class T>
T*
atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
template <class T>
T*
atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
template <class T>
T*
atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
memory_order m) noexcept;
template <class T>
T*
atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
memory_order m) noexcept;
template <class T>
T*
atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
template <class T>
T*
atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
template <class T>
T*
atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
memory_order m) noexcept;
T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
template <class T>
T*
atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
memory_order m) noexcept;
template <class T>
T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
// Atomics for standard typedef types
@@ -516,7 +477,7 @@ typedef atomic<int_fast8_t> atomic_int_fast8_t;
typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
typedef atomic<int_fast16_t> atomic_int_fast16_t;
typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
typedef atomic<int_fast32_t> atomic_int_fast32_t;
typedef atomic<int_fast32_t> atomic_int_fast32_t;
typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
typedef atomic<int_fast64_t> atomic_int_fast64_t;
typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
@@ -537,18 +498,80 @@ typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
typedef atomic<intmax_t> atomic_intmax_t;
typedef atomic<uintmax_t> atomic_uintmax_t;
// flag type and operations
typedef struct atomic_flag
{
atomic_flag() noexcept = default;
atomic_flag(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) = delete;
atomic_flag& operator=(const atomic_flag&) volatile = delete;
bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
bool test(memory_order m = memory_order_seq_cst) noexcept;
bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
void clear(memory_order m = memory_order_seq_cst) noexcept;
void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
void notify_one() volatile noexcept;
void notify_one() noexcept;
void notify_all() volatile noexcept;
void notify_all() noexcept;
} atomic_flag;
bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
bool atomic_flag_test(atomic_flag* obj) noexcept;
bool atomic_flag_test_explicit(volatile atomic_flag* obj,
memory_order m) noexcept;
bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
memory_order m) noexcept;
bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
void atomic_flag_clear(atomic_flag* obj) noexcept;
void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
void atomic_wait(const atomic_flag* obj, T old) noexcept;
void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
void atomic_one(volatile atomic_flag* obj) noexcept;
void atomic_one(atomic_flag* obj) noexcept;
void atomic_all(volatile atomic_flag* obj) noexcept;
void atomic_all(atomic_flag* obj) noexcept;
// fences
void atomic_thread_fence(memory_order m) noexcept;
void atomic_signal_fence(memory_order m) noexcept;
// deprecated
template <class T>
void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
template <class T>
void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
#define ATOMIC_VAR_INIT(value) see below
#define ATOMIC_FLAG_INIT see below
} // std
*/
#include <__config>
#include <__threading_support>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <type_traits>
#include <version>
@@ -629,6 +652,11 @@ typedef enum memory_order {
#endif // _LIBCPP_STD_VER > 17
template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
return memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
}
static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
"unexpected underlying type for std::memory_order");
@@ -1218,9 +1246,9 @@ _LIBCPP_INLINE_VISIBILITY
bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
_Tp* __expected, _Tp __value, memory_order, memory_order) {
__a->__lock();
_Tp temp;
__cxx_atomic_assign_volatile(temp, __a->__a_value);
bool __ret = temp == *__expected;
_Tp __temp;
__cxx_atomic_assign_volatile(__temp, __a->__a_value);
bool __ret = __temp == *__expected;
if(__ret)
__cxx_atomic_assign_volatile(__a->__a_value, __value);
else
@@ -1247,9 +1275,9 @@ _LIBCPP_INLINE_VISIBILITY
bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
_Tp* __expected, _Tp __value, memory_order, memory_order) {
__a->__lock();
_Tp temp;
__cxx_atomic_assign_volatile(temp, __a->__a_value);
bool __ret = temp == *__expected;
_Tp __temp;
__cxx_atomic_assign_volatile(__temp, __a->__a_value);
bool __ret = __temp == *__expected;
if(__ret)
__cxx_atomic_assign_volatile(__a->__a_value, __value);
else
@@ -1452,6 +1480,93 @@ struct __cxx_atomic_impl : public _Base {
: _Base(value) {}
};
#ifdef __linux__
using __cxx_contention_t = int32_t;
#else
using __cxx_contention_t = int64_t;
#endif //__linux__
#if _LIBCPP_STD_VER >= 11
using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
template <class _Atp, class _Fn>
struct __libcpp_atomic_wait_backoff_impl {
_Atp* __a;
_Fn __test_fn;
_LIBCPP_AVAILABILITY_SYNC
_LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
{
if(__elapsed > chrono::microseconds(64))
{
auto const __monitor = __libcpp_atomic_monitor(__a);
if(__test_fn())
return true;
__libcpp_atomic_wait(__a, __monitor);
}
else if(__elapsed > chrono::microseconds(4))
__libcpp_thread_yield();
else
; // poll
return false;
}
};
template <class _Atp, class _Fn>
_LIBCPP_AVAILABILITY_SYNC
_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
{
__libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
}
#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
template <class _Atp, class _Fn>
_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
{
return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
}
#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
template <class _Atp, class _Tp>
struct __cxx_atomic_wait_test_fn_impl {
_Atp* __a;
_Tp __val;
memory_order __order;
_LIBCPP_INLINE_VISIBILITY bool operator()() const
{
return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
}
};
template <class _Atp, class _Tp>
_LIBCPP_AVAILABILITY_SYNC
_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
{
__cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
return __cxx_atomic_wait(__a, __test_fn);
}
#endif //_LIBCPP_STD_VER >= 11
// general atomic<T>
template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
@@ -1532,6 +1647,19 @@ struct __atomic_base // false
memory_order __m = memory_order_seq_cst) _NOEXCEPT
{return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
{__cxx_atomic_wait(&__a_, __v, __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
{__cxx_atomic_wait(&__a_, __v, __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
{__cxx_atomic_notify_one(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
{__cxx_atomic_notify_one(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
{__cxx_atomic_notify_all(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
{__cxx_atomic_notify_all(&__a_);}
_LIBCPP_INLINE_VISIBILITY
__atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
@@ -1544,8 +1672,11 @@ struct __atomic_base // false
__atomic_base& operator=(const __atomic_base&) volatile = delete;
#else
private:
_LIBCPP_INLINE_VISIBILITY
__atomic_base(const __atomic_base&);
_LIBCPP_INLINE_VISIBILITY
__atomic_base& operator=(const __atomic_base&);
_LIBCPP_INLINE_VISIBILITY
__atomic_base& operator=(const __atomic_base&) volatile;
#endif
};
@@ -1643,6 +1774,7 @@ struct atomic
: public __atomic_base<_Tp>
{
typedef __atomic_base<_Tp> __base;
typedef _Tp value_type;
_LIBCPP_INLINE_VISIBILITY
atomic() _NOEXCEPT _LIBCPP_DEFAULT
_LIBCPP_INLINE_VISIBILITY
@@ -1663,6 +1795,7 @@ struct atomic<_Tp*>
: public __atomic_base<_Tp*>
{
typedef __atomic_base<_Tp*> __base;
typedef _Tp* value_type;
_LIBCPP_INLINE_VISIBILITY
atomic() _NOEXCEPT _LIBCPP_DEFAULT
_LIBCPP_INLINE_VISIBILITY
@@ -1947,6 +2080,76 @@ atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
return __o->compare_exchange_strong(*__e, __d, __s, __f);
}
// atomic_wait
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_wait(const volatile atomic<_Tp>* __o,
typename atomic<_Tp>::value_type __v) _NOEXCEPT
{
return __o->wait(__v);
}
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_wait(const atomic<_Tp>* __o,
typename atomic<_Tp>::value_type __v) _NOEXCEPT
{
return __o->wait(__v);
}
// atomic_wait_explicit
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
typename atomic<_Tp>::value_type __v,
memory_order __m) _NOEXCEPT
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
{
return __o->wait(__v, __m);
}
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_wait_explicit(const atomic<_Tp>* __o,
typename atomic<_Tp>::value_type __v,
memory_order __m) _NOEXCEPT
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
{
return __o->wait(__v, __m);
}
// atomic_notify_one
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
{
__o->notify_one();
}
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
{
__o->notify_one();
}
// atomic_notify_one
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
{
__o->notify_all();
}
template <class _Tp>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
{
__o->notify_all();
}
// atomic_fetch_add
template <class _Tp>
@@ -2279,6 +2482,13 @@ typedef struct atomic_flag
{
__cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
_LIBCPP_INLINE_VISIBILITY
bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
{return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
_LIBCPP_INLINE_VISIBILITY
bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
{return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
_LIBCPP_INLINE_VISIBILITY
bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
{return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
@@ -2292,6 +2502,25 @@ typedef struct atomic_flag
void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
{__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
{__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
{__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void notify_one() volatile _NOEXCEPT
{__cxx_atomic_notify_one(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void notify_one() _NOEXCEPT
{__cxx_atomic_notify_one(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void notify_all() volatile _NOEXCEPT
{__cxx_atomic_notify_all(&__a_);}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void notify_all() _NOEXCEPT
{__cxx_atomic_notify_all(&__a_);}
_LIBCPP_INLINE_VISIBILITY
atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
@@ -2304,12 +2533,44 @@ typedef struct atomic_flag
atomic_flag& operator=(const atomic_flag&) volatile = delete;
#else
private:
_LIBCPP_INLINE_VISIBILITY
atomic_flag(const atomic_flag&);
_LIBCPP_INLINE_VISIBILITY
atomic_flag& operator=(const atomic_flag&);
_LIBCPP_INLINE_VISIBILITY
atomic_flag& operator=(const atomic_flag&) volatile;
#endif
} atomic_flag;
inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
{
return __o->test();
}
inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
{
return __o->test();
}
inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
{
return __o->test(__m);
}
inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
{
return __o->test(__m);
}
inline _LIBCPP_INLINE_VISIBILITY
bool
atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
@@ -2366,6 +2627,64 @@ atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
__o->clear(__m);
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
{
__o->wait(__v);
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
{
__o->wait(__v);
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_wait_explicit(const volatile atomic_flag* __o,
bool __v, memory_order __m) _NOEXCEPT
{
__o->wait(__v, __m);
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_wait_explicit(const atomic_flag* __o,
bool __v, memory_order __m) _NOEXCEPT
{
__o->wait(__v, __m);
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
{
__o->notify_one();
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
{
__o->notify_one();
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
{
__o->notify_all();
}
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
void
atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
{
__o->notify_all();
}
// fences
inline _LIBCPP_INLINE_VISIBILITY
@@ -2434,6 +2753,33 @@ typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
typedef atomic<intmax_t> atomic_intmax_t;
typedef atomic<uintmax_t> atomic_uintmax_t;
// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
#ifdef __cpp_lib_atomic_is_always_lock_free
# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
#else
# define _LIBCPP_CONTENTION_LOCK_FREE false
#endif
#if ATOMIC_LLONG_LOCK_FREE == 2
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
#elif ATOMIC_INT_LOCK_FREE == 2
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
#elif ATOMIC_SHORT_LOCK_FREE == 2
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
#elif ATOMIC_CHAR_LOCK_FREE == 2
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
#else
// No signed/unsigned lock-free types
#endif
typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
#define ATOMIC_FLAG_INIT {false}
#define ATOMIC_VAR_INIT(__v) {__v}
+322
View File
@@ -0,0 +1,322 @@
// -*- C++ -*-
//===--------------------------- barrier ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_BARRIER
#define _LIBCPP_BARRIER
/*
barrier synopsis
namespace std
{
template<class CompletionFunction = see below>
class barrier
{
public:
using arrival_token = see below;
constexpr explicit barrier(ptrdiff_t phase_count,
CompletionFunction f = CompletionFunction());
~barrier();
barrier(const barrier&) = delete;
barrier& operator=(const barrier&) = delete;
[[nodiscard]] arrival_token arrive(ptrdiff_t update = 1);
void wait(arrival_token&& arrival) const;
void arrive_and_wait();
void arrive_and_drop();
private:
CompletionFunction completion; // exposition only
};
}
*/
#include <__config>
#include <atomic>
#ifndef _LIBCPP_HAS_NO_TREE_BARRIER
# include <memory>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
# error <barrier> is not supported on this single threaded system
#endif
#if _LIBCPP_STD_VER >= 14
_LIBCPP_BEGIN_NAMESPACE_STD
struct __empty_completion
{
inline _LIBCPP_INLINE_VISIBILITY
void operator()() noexcept
{
}
};
#ifndef _LIBCPP_HAS_NO_TREE_BARRIER
/*
The default implementation of __barrier_base is a classic tree barrier.
It looks different from literature pseudocode for two main reasons:
1. Threads that call into std::barrier functions do not provide indices,
so a numbering step is added before the actual barrier algorithm,
appearing as an N+1 round to the N rounds of the tree barrier.
2. A great deal of attention has been paid to avoid cache line thrashing
by flattening the tree structure into cache-line sized arrays, that
are indexed in an efficient way.
*/
using __barrier_phase_t = uint8_t;
class __barrier_algorithm_base;
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI
__barrier_algorithm_base* __construct_barrier_algorithm_base(ptrdiff_t& __expected);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI
bool __arrive_barrier_algorithm_base(__barrier_algorithm_base* __barrier,
__barrier_phase_t __old_phase);
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI
void __destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier);
template<class _CompletionF>
class __barrier_base {
ptrdiff_t __expected;
unique_ptr<__barrier_algorithm_base,
void (*)(__barrier_algorithm_base*)> __base;
__atomic_base<ptrdiff_t> __expected_adjustment;
_CompletionF __completion;
__atomic_base<__barrier_phase_t> __phase;
public:
using arrival_token = __barrier_phase_t;
static constexpr ptrdiff_t max() noexcept {
return numeric_limits<ptrdiff_t>::max();
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
__barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
: __expected(__expected), __base(__construct_barrier_algorithm_base(this->__expected),
&__destroy_barrier_algorithm_base),
__expected_adjustment(0), __completion(move(__completion)), __phase(0)
{
}
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
arrival_token arrive(ptrdiff_t update)
{
auto const __old_phase = __phase.load(memory_order_relaxed);
for(; update; --update)
if(__arrive_barrier_algorithm_base(__base.get(), __old_phase)) {
__completion();
__expected += __expected_adjustment.load(memory_order_relaxed);
__expected_adjustment.store(0, memory_order_relaxed);
__phase.store(__old_phase + 2, memory_order_release);
__phase.notify_all();
}
return __old_phase;
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(arrival_token&& __old_phase) const
{
auto const __test_fn = [=]() -> bool {
return __phase.load(memory_order_acquire) != __old_phase;
};
__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_drop()
{
__expected_adjustment.fetch_sub(1, memory_order_relaxed);
(void)arrive(1);
}
};
#else
/*
The alternative implementation of __barrier_base is a central barrier.
Two versions of this algorithm are provided:
1. A fairly straightforward implementation of the litterature for the
general case where the completion function is not empty.
2. An optimized implementation that exploits 2's complement arithmetic
and well-defined overflow in atomic arithmetic, to handle the phase
roll-over for free.
*/
template<class _CompletionF>
class __barrier_base {
__atomic_base<ptrdiff_t> __expected;
__atomic_base<ptrdiff_t> __arrived;
_CompletionF __completion;
__atomic_base<bool> __phase;
public:
using arrival_token = bool;
static constexpr ptrdiff_t max() noexcept {
return numeric_limits<ptrdiff_t>::max();
}
_LIBCPP_INLINE_VISIBILITY
__barrier_base(ptrdiff_t __expected, _CompletionF __completion = _CompletionF())
: __expected(__expected), __arrived(__expected), __completion(move(__completion)), __phase(false)
{
}
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
arrival_token arrive(ptrdiff_t update)
{
auto const __old_phase = __phase.load(memory_order_relaxed);
auto const __result = __arrived.fetch_sub(update, memory_order_acq_rel) - update;
auto const new_expected = __expected.load(memory_order_relaxed);
if(0 == __result) {
__completion();
__arrived.store(new_expected, memory_order_relaxed);
__phase.store(!__old_phase, memory_order_release);
__phase.notify_all();
}
return __old_phase;
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(arrival_token&& __old_phase) const
{
__phase.wait(__old_phase, memory_order_acquire);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_drop()
{
__expected.fetch_sub(1, memory_order_relaxed);
(void)arrive(1);
}
};
template<>
class __barrier_base<__empty_completion> {
static constexpr uint64_t __expected_unit = 1ull;
static constexpr uint64_t __arrived_unit = 1ull << 32;
static constexpr uint64_t __expected_mask = __arrived_unit - 1;
static constexpr uint64_t __phase_bit = 1ull << 63;
static constexpr uint64_t __arrived_mask = (__phase_bit - 1) & ~__expected_mask;
__atomic_base<uint64_t> __phase_arrived_expected;
static _LIBCPP_INLINE_VISIBILITY
constexpr uint64_t __init(ptrdiff_t __count) _NOEXCEPT
{
return ((uint64_t(1u << 31) - __count) << 32)
| (uint64_t(1u << 31) - __count);
}
public:
using arrival_token = uint64_t;
static constexpr ptrdiff_t max() noexcept {
return ptrdiff_t(1u << 31) - 1;
}
_LIBCPP_INLINE_VISIBILITY
explicit inline __barrier_base(ptrdiff_t __count, __empty_completion = __empty_completion())
: __phase_arrived_expected(__init(__count))
{
}
[[nodiscard]] inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
arrival_token arrive(ptrdiff_t update)
{
auto const __inc = __arrived_unit * update;
auto const __old = __phase_arrived_expected.fetch_add(__inc, memory_order_acq_rel);
if((__old ^ (__old + __inc)) & __phase_bit) {
__phase_arrived_expected.fetch_add((__old & __expected_mask) << 32, memory_order_relaxed);
__phase_arrived_expected.notify_all();
}
return __old & __phase_bit;
}
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(arrival_token&& __phase) const
{
auto const __test_fn = [=]() -> bool {
uint64_t const __current = __phase_arrived_expected.load(memory_order_acquire);
return ((__current & __phase_bit) != __phase);
};
__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
}
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_drop()
{
__phase_arrived_expected.fetch_add(__expected_unit, memory_order_relaxed);
(void)arrive(1);
}
};
#endif //_LIBCPP_HAS_NO_TREE_BARRIER
template<class _CompletionF = __empty_completion>
class barrier {
__barrier_base<_CompletionF> __b;
public:
using arrival_token = typename __barrier_base<_CompletionF>::arrival_token;
static constexpr ptrdiff_t max() noexcept {
return __barrier_base<_CompletionF>::max();
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
: __b(__count, std::move(__completion)) {
}
barrier(barrier const&) = delete;
barrier& operator=(barrier const&) = delete;
[[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
arrival_token arrive(ptrdiff_t update = 1)
{
return __b.arrive(update);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait(arrival_token&& __phase) const
{
__b.wait(std::move(__phase));
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_wait()
{
wait(arrive());
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_drop()
{
__b.arrive_and_drop();
}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 14
#endif //_LIBCPP_BARRIER
+5 -4
View File
@@ -15,6 +15,7 @@
namespace std {
// [bit.pow.two], integral powers of 2
template <class T>
constexpr bool ispow2(T x) noexcept; // C++20
template <class T>
@@ -24,13 +25,13 @@ namespace std {
template <class T>
constexpr T log2p1(T x) noexcept; // C++20
// 23.20.2, rotating
// [bit.rotate], rotating
template<class T>
constexpr T rotl(T x, unsigned int s) noexcept; // C++20
template<class T>
constexpr T rotr(T x, unsigned int s) noexcept; // C++20
// 23.20.3, counting
// [bit.count], counting
template<class T>
constexpr int countl_zero(T x) noexcept; // C++20
template<class T>
@@ -42,7 +43,7 @@ namespace std {
template<class T>
constexpr int popcount(T x) noexcept; // C++20
// 20.15.9, endian
// [bit.endian], endian
enum class endian {
little = see below, // C++20
big = see below, // C++20
@@ -350,7 +351,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
bool __ispow2(_Tp __t) _NOEXCEPT
{
static_assert(__bitop_unsigned_integer<_Tp>::value, "__ispow2 requires unsigned");
return __t != 0 && (((__t & (__t - 1)) == 0));
return __t != 0 && (((__t & (__t - 1)) == 0));
}
+11 -2
View File
@@ -73,6 +73,7 @@ namespace std {
*/
#include <__config>
#include <__errc>
#include <type_traits>
#include <limits>
@@ -92,8 +93,8 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __itoa {
_LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer);
_LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer);
_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u64toa(uint64_t __value, char* __buffer) _NOEXCEPT;
_LIBCPP_AVAILABILITY_TO_CHARS _LIBCPP_FUNC_VIS char* __u32toa(uint32_t __value, char* __buffer) _NOEXCEPT;
}
#ifndef _LIBCPP_CXX03_LANG
@@ -167,6 +168,7 @@ struct _LIBCPP_HIDDEN __traits_base
}
#endif
_LIBCPP_AVAILABILITY_TO_CHARS
static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
{
return __u64toa(__v, __p);
@@ -189,6 +191,7 @@ struct _LIBCPP_HIDDEN
}
#endif
_LIBCPP_AVAILABILITY_TO_CHARS
static _LIBCPP_INLINE_VISIBILITY char* __convert(_Tp __v, char* __p)
{
return __u32toa(__v, __p);
@@ -292,6 +295,7 @@ __to_unsigned(_Tp __x)
}
template <typename _Tp>
_LIBCPP_AVAILABILITY_TO_CHARS
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
{
@@ -306,6 +310,7 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type)
}
template <typename _Tp>
_LIBCPP_AVAILABILITY_TO_CHARS
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
{
@@ -337,6 +342,7 @@ __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type)
}
template <typename _Tp>
_LIBCPP_AVAILABILITY_TO_CHARS
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
true_type)
@@ -352,6 +358,7 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
}
template <typename _Tp>
_LIBCPP_AVAILABILITY_TO_CHARS
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
__to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
false_type)
@@ -380,6 +387,7 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base,
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
_LIBCPP_AVAILABILITY_TO_CHARS
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
to_chars(char* __first, char* __last, _Tp __value)
{
@@ -387,6 +395,7 @@ to_chars(char* __first, char* __last, _Tp __value)
}
template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0>
_LIBCPP_AVAILABILITY_TO_CHARS
inline _LIBCPP_INLINE_VISIBILITY to_chars_result
to_chars(char* __first, char* __last, _Tp __value, int __base)
{
+1 -1
View File
@@ -2454,7 +2454,7 @@ chrono::day year_month_day_last::day() const noexcept
chrono::day(31), chrono::day(31), chrono::day(30),
chrono::day(31), chrono::day(30), chrono::day(31)
};
return month() != February || !__y.is_leap() ?
return (month() != February || !__y.is_leap()) && month().ok() ?
__d[static_cast<unsigned>(month()) - 1] : chrono::day{29};
}
+4
View File
@@ -296,6 +296,10 @@ floating_point trunc (arithmetic x);
float truncf(float x);
long double truncl(long double x);
constexpr float lerp(float a, float b, float t) noexcept; // C++20
constexpr double lerp(double a, double b, double t) noexcept; // C++20
constexpr long double lerp(long double a, long double b, long double t) noexcept; // C++20
} // std
*/
+36 -36
View File
@@ -102,11 +102,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -137,11 +137,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -172,11 +172,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <class _Elem, unsigned long _Maxcode = 0x10ffff,
@@ -225,11 +225,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -260,11 +260,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -295,11 +295,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -330,11 +330,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -365,11 +365,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -400,11 +400,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <class _Elem, unsigned long _Maxcode = 0x10ffff,
@@ -453,11 +453,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -488,11 +488,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <>
@@ -523,11 +523,11 @@ protected:
virtual result
do_unshift(state_type& __st,
extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
virtual int do_encoding() const throw();
virtual bool do_always_noconv() const throw();
virtual int do_encoding() const _NOEXCEPT;
virtual bool do_always_noconv() const _NOEXCEPT;
virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end,
size_t __mx) const;
virtual int do_max_length() const throw();
virtual int do_max_length() const _NOEXCEPT;
};
template <class _Elem, unsigned long _Maxcode = 0x10ffff,
+84
View File
@@ -43,6 +43,84 @@ namespace std {
template<class T> constexpr partial_ordering partial_order(const T& a, const T& b);
template<class T> constexpr strong_equality strong_equal(const T& a, const T& b);
template<class T> constexpr weak_equality weak_equal(const T& a, const T& b);
// [cmp.partialord], Class partial_ordering
class partial_ordering {
public:
// valid values
static const partial_ordering less;
static const partial_ordering equivalent;
static const partial_ordering greater;
static const partial_ordering unordered;
// comparisons
friend constexpr bool operator==(partial_ordering v, unspecified) noexcept;
friend constexpr bool operator==(partial_ordering v, partial_ordering w) noexcept = default;
friend constexpr bool operator< (partial_ordering v, unspecified) noexcept;
friend constexpr bool operator> (partial_ordering v, unspecified) noexcept;
friend constexpr bool operator<=(partial_ordering v, unspecified) noexcept;
friend constexpr bool operator>=(partial_ordering v, unspecified) noexcept;
friend constexpr bool operator< (unspecified, partial_ordering v) noexcept;
friend constexpr bool operator> (unspecified, partial_ordering v) noexcept;
friend constexpr bool operator<=(unspecified, partial_ordering v) noexcept;
friend constexpr bool operator>=(unspecified, partial_ordering v) noexcept;
friend constexpr partial_ordering operator<=>(partial_ordering v, unspecified) noexcept;
friend constexpr partial_ordering operator<=>(unspecified, partial_ordering v) noexcept;
};
// [cmp.weakord], Class weak_ordering
class weak_ordering {
public:
// valid values
static const weak_ordering less;
static const weak_ordering equivalent;
static const weak_ordering greater;
// conversions
constexpr operator partial_ordering() const noexcept;
// comparisons
friend constexpr bool operator==(weak_ordering v, unspecified) noexcept;
friend constexpr bool operator==(weak_ordering v, weak_ordering w) noexcept = default;
friend constexpr bool operator< (weak_ordering v, unspecified) noexcept;
friend constexpr bool operator> (weak_ordering v, unspecified) noexcept;
friend constexpr bool operator<=(weak_ordering v, unspecified) noexcept;
friend constexpr bool operator>=(weak_ordering v, unspecified) noexcept;
friend constexpr bool operator< (unspecified, weak_ordering v) noexcept;
friend constexpr bool operator> (unspecified, weak_ordering v) noexcept;
friend constexpr bool operator<=(unspecified, weak_ordering v) noexcept;
friend constexpr bool operator>=(unspecified, weak_ordering v) noexcept;
friend constexpr weak_ordering operator<=>(weak_ordering v, unspecified) noexcept;
friend constexpr weak_ordering operator<=>(unspecified, weak_ordering v) noexcept;
};
// [cmp.strongord], Class strong_ordering
class strong_ordering {
public:
// valid values
static const strong_ordering less;
static const strong_ordering equal;
static const strong_ordering equivalent;
static const strong_ordering greater;
// conversions
constexpr operator partial_ordering() const noexcept;
constexpr operator weak_ordering() const noexcept;
// comparisons
friend constexpr bool operator==(strong_ordering v, unspecified) noexcept;
friend constexpr bool operator==(strong_ordering v, strong_ordering w) noexcept = default;
friend constexpr bool operator< (strong_ordering v, unspecified) noexcept;
friend constexpr bool operator> (strong_ordering v, unspecified) noexcept;
friend constexpr bool operator<=(strong_ordering v, unspecified) noexcept;
friend constexpr bool operator>=(strong_ordering v, unspecified) noexcept;
friend constexpr bool operator< (unspecified, strong_ordering v) noexcept;
friend constexpr bool operator> (unspecified, strong_ordering v) noexcept;
friend constexpr bool operator<=(unspecified, strong_ordering v) noexcept;
friend constexpr bool operator>=(unspecified, strong_ordering v) noexcept;
friend constexpr strong_ordering operator<=>(strong_ordering v, unspecified) noexcept;
friend constexpr strong_ordering operator<=>(unspecified, strong_ordering v) noexcept;
};
}
*/
@@ -248,6 +326,8 @@ public:
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default;
_LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept;
#endif
@@ -364,6 +444,8 @@ public:
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default;
_LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept;
#endif
@@ -490,6 +572,8 @@ public:
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
#ifndef _LIBCPP_HAS_NO_SPACESHIP_OPERATOR
_LIBCPP_INLINE_VISIBILITY friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default;
_LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept;
_LIBCPP_INLINE_VISIBILITY friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept;
#endif
+7 -6
View File
@@ -243,6 +243,7 @@ template<class T, class charT, class traits>
#include <type_traits>
#include <stdexcept>
#include <cmath>
#include <iosfwd>
#include <sstream>
#include <version>
@@ -1406,10 +1407,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
__x = complex<_Tp>(__r, __i);
}
else
__is.setstate(ios_base::failbit);
__is.setstate(__is.failbit);
}
else
__is.setstate(ios_base::failbit);
__is.setstate(__is.failbit);
}
else if (__c == _CharT(')'))
{
@@ -1417,10 +1418,10 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
__x = complex<_Tp>(__r, _Tp(0));
}
else
__is.setstate(ios_base::failbit);
__is.setstate(__is.failbit);
}
else
__is.setstate(ios_base::failbit);
__is.setstate(__is.failbit);
}
else
{
@@ -1429,11 +1430,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x)
if (!__is.fail())
__x = complex<_Tp>(__r, _Tp(0));
else
__is.setstate(ios_base::failbit);
__is.setstate(__is.failbit);
}
}
else
__is.setstate(ios_base::failbit);
__is.setstate(__is.failbit);
return __is;
}
+166
View File
@@ -0,0 +1,166 @@
// -*- C++ -*-
//===-------------------------- concepts ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_CONCEPTS
#define _LIBCPP_CONCEPTS
/*
concepts synopsis
namespace std {
// [concepts.lang], language-related concepts
// [concept.same], concept same_as
template<class T, class U>
concept same_as = see below;
// [concept.derived], concept derived_from
template<class Derived, class Base>
concept derived_from = see below;
// [concept.convertible], concept convertible_to
template<class From, class To>
concept convertible_to = see below;
// [concept.commonref], concept common_reference_with
template<class T, class U>
concept common_reference_with = see below;
// [concept.common], concept common_with
template<class T, class U>
concept common_with = see below;
// [concepts.arithmetic], arithmetic concepts
template<class T>
concept integral = see below;
template<class T>
concept signed_integral = see below;
template<class T>
concept unsigned_integral = see below;
template<class T>
concept floating_point = see below;
// [concept.assignable], concept assignable_from
template<class LHS, class RHS>
concept assignable_from = see below;
// [concept.swappable], concept swappable
namespace ranges {
inline namespace unspecified {
inline constexpr unspecified swap = unspecified;
}
}
template<class T>
concept swappable = see below;
template<class T, class U>
concept swappable_with = see below;
// [concept.destructible], concept destructible
template<class T>
concept destructible = see below;
// [concept.constructible], concept constructible_from
template<class T, class... Args>
concept constructible_from = see below;
// [concept.defaultconstructible], concept default_constructible
template<class T>
concept default_constructible = see below;
// [concept.moveconstructible], concept move_constructible
template<class T>
concept move_constructible = see below;
// [concept.copyconstructible], concept copy_constructible
template<class T>
concept copy_constructible = see below;
// [concepts.compare], comparison concepts
// [concept.boolean], concept boolean
template<class B>
concept boolean = see below;
// [concept.equalitycomparable], concept equality_comparable
template<class T>
concept equality_comparable = see below;
template<class T, class U>
concept equality_comparable_with = see below;
// [concept.totallyordered], concept totally_ordered
template<class T>
concept totally_ordered = see below;
template<class T, class U>
concept totally_ordered_with = see below;
// [concepts.object], object concepts
template<class T>
concept movable = see below;
template<class T>
concept copyable = see below;
template<class T>
concept semiregular = see below;
template<class T>
concept regular = see below;
// [concepts.callable], callable concepts
// [concept.invocable], concept invocable
template<class F, class... Args>
concept invocable = see below;
// [concept.regularinvocable], concept regular_invocable
template<class F, class... Args>
concept regular_invocable = see below;
// [concept.predicate], concept predicate
template<class F, class... Args>
concept predicate = see below;
// [concept.relation], concept relation
template<class R, class T, class U>
concept relation = see below;
// [concept.equiv], concept equivalence_relation
template<class R, class T, class U>
concept equivalence_relation = see below;
// [concept.strictweakorder], concept strict_weak_order
template<class R, class T, class U>
concept strict_weak_order = see below;
}
*/
#include <__config>
#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
// [concept.same]
template<class _Tp, class _Up>
concept __same_as_impl = _VSTD::_IsSame<_Tp, _Up>::value;
template<class _Tp, class _Up>
concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>;
#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP_CONCEPTS
+55 -7
View File
@@ -25,7 +25,7 @@ Types:
ptrdiff_t
size_t
max_align_t
max_align_t // C++11
nullptr_t
byte // C++17
@@ -49,12 +49,34 @@ _LIBCPP_BEGIN_NAMESPACE_STD
using ::ptrdiff_t;
using ::size_t;
#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \
defined(__DEFINED_max_align_t) || defined(__NetBSD__)
// Re-use the compiler's <stddef.h> max_align_t where possible.
#if !defined(_LIBCPP_CXX03_LANG)
using ::max_align_t;
#else
typedef long double max_align_t;
#endif
template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; };
template <> struct __libcpp_is_integral<bool> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<char> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<signed char> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<unsigned char> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<wchar_t> { enum { value = 1 }; };
#ifndef _LIBCPP_NO_HAS_CHAR8_T
template <> struct __libcpp_is_integral<char8_t> { enum { value = 1 }; };
#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <> struct __libcpp_is_integral<char16_t> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<char32_t> { enum { value = 1 }; };
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
template <> struct __libcpp_is_integral<short> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<unsigned short> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<int> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<unsigned int> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<long> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<unsigned long> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<long long> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<unsigned long long> { enum { value = 1 }; };
#ifndef _LIBCPP_HAS_NO_INT128
template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; };
template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; };
#endif
_LIBCPP_END_NAMESPACE_STD
@@ -64,6 +86,11 @@ namespace std // purposefully not versioned
{
enum class byte : unsigned char {};
template <bool> struct __enable_if_integral_imp {};
template <> struct __enable_if_integral_imp<true> { using type = byte; };
template <class _Tp> using _EnableByteOverload = typename __enable_if_integral_imp<__libcpp_is_integral<_Tp>::value>::type;
constexpr byte operator| (byte __lhs, byte __rhs) noexcept
{
return static_cast<byte>(
@@ -104,10 +131,31 @@ constexpr byte operator~ (byte __b) noexcept
~static_cast<unsigned int>(__b)
));
}
template <class _Integer>
constexpr _EnableByteOverload<_Integer> &
operator<<=(byte& __lhs, _Integer __shift) noexcept
{ return __lhs = __lhs << __shift; }
template <class _Integer>
constexpr _EnableByteOverload<_Integer>
operator<< (byte __lhs, _Integer __shift) noexcept
{ return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) << __shift)); }
template <class _Integer>
constexpr _EnableByteOverload<_Integer> &
operator>>=(byte& __lhs, _Integer __shift) noexcept
{ return __lhs = __lhs >> __shift; }
template <class _Integer>
constexpr _EnableByteOverload<_Integer>
operator>> (byte __lhs, _Integer __shift) noexcept
{ return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); }
template <class _Integer, class = _EnableByteOverload<_Integer> >
constexpr _Integer
to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); }
}
#include <type_traits> // rest of byte
#endif
#endif // _LIBCPP_CSTDDEF
+4
View File
@@ -131,9 +131,13 @@ using ::putc;
using ::ungetc;
using ::fread;
using ::fwrite;
#ifndef _LIBCPP_HAS_NO_FGETPOS_FSETPOS
using ::fgetpos;
#endif
using ::fseek;
#ifndef _LIBCPP_HAS_NO_FGETPOS_FSETPOS
using ::fsetpos;
#endif
using ::ftell;
using ::rewind;
using ::clearerr;
+16 -8
View File
@@ -150,9 +150,11 @@ template <class T, class Allocator>
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(deque<T, Allocator>& c, const U& value); // C++20
typename deque<T, Allocator>::size_type
erase(deque<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
typename deque<T, Allocator>::size_type
erase_if(deque<T, Allocator>& c, Predicate pred); // C++20
} // std
@@ -3021,14 +3023,20 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y)
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(deque<_Tp, _Allocator>& __c, const _Up& __v)
{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
erase(deque<_Tp, _Allocator>& __c, const _Up& __v) {
auto __old_size = __c.size();
__c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
return __old_size - __c.size();
}
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
inline _LIBCPP_INLINE_VISIBILITY typename deque<_Tp, _Allocator>::size_type
erase_if(deque<_Tp, _Allocator>& __c, _Predicate __pred) {
auto __old_size = __c.size();
__c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
return __old_size - __c.size();
}
#endif
+2
View File
@@ -98,6 +98,8 @@ class _LIBCPP_EXCEPTION_ABI exception
{
public:
_LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default;
virtual ~exception() _NOEXCEPT;
virtual const char* what() const _NOEXCEPT;
};
+1
View File
@@ -1346,6 +1346,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
const path& path2() const noexcept { return __storage_->__p2_; }
filesystem_error(const filesystem_error&) = default;
~filesystem_error() override; // key function
_LIBCPP_INLINE_VISIBILITY
+12 -6
View File
@@ -169,9 +169,11 @@ template <class T, class Allocator>
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(forward_list<T, Allocator>& c, const U& value); // C++20
typename forward_list<T, Allocator>::size_type
erase(forward_list<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
typename forward_list<T, Allocator>::size_type
erase_if(forward_list<T, Allocator>& c, Predicate pred); // C++20
} // std
@@ -1765,13 +1767,17 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y)
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.remove_if(__pred); }
typename forward_list<_Tp, _Allocator>::size_type
erase_if(forward_list<_Tp, _Allocator>& __c, _Predicate __pred) {
return __c.remove_if(__pred);
}
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v)
{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
typename forward_list<_Tp, _Allocator>::size_type
erase(forward_list<_Tp, _Allocator>& __c, const _Up& __v) {
return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
}
#endif
_LIBCPP_END_NAMESPACE_STD
+112 -25
View File
@@ -508,6 +508,10 @@ POLICY: For non-variadic implementations, the number of arguments is limited
#include <__functional_base>
#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC)
#include <Block.h>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
@@ -1434,7 +1438,14 @@ void __throw_bad_function_call()
#endif
}
template<class _Fp> class _LIBCPP_TEMPLATE_VIS function; // undefined
#if defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) && __has_attribute(deprecated)
# define _LIBCPP_DEPRECATED_CXX03_FUNCTION \
__attribute__((deprecated("Using std::function in C++03 is not supported anymore. Please upgrade to C++11 or later, or use a different type")))
#else
# define _LIBCPP_DEPRECATED_CXX03_FUNCTION /* nothing */
#endif
template<class _Fp> class _LIBCPP_DEPRECATED_CXX03_FUNCTION _LIBCPP_TEMPLATE_VIS function; // undefined
namespace __function
{
@@ -1477,6 +1488,12 @@ template <class _Fp>
_LIBCPP_INLINE_VISIBILITY
bool __not_null(function<_Fp> const& __f) { return !!__f; }
#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS
template <class _Rp, class ..._Args>
_LIBCPP_INLINE_VISIBILITY
bool __not_null(_Rp (^__p)(_Args...)) { return __p; }
#endif
} // namespace __function
#ifndef _LIBCPP_CXX03_LANG
@@ -1611,7 +1628,7 @@ public:
// __base provides an abstract interface for copyable functors.
template<class _Fp> class __base;
template<class _Fp> class _LIBCPP_TEMPLATE_VIS __base;
template<class _Rp, class ..._ArgTypes>
class __base<_Rp(_ArgTypes...)>
@@ -2238,6 +2255,72 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)>
#endif // _LIBCPP_NO_RTTI
};
#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) && !defined(_LIBCPP_HAS_OBJC_ARC)
template<class _Rp1, class ..._ArgTypes1, class _Alloc, class _Rp, class ..._ArgTypes>
class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)>
: public __base<_Rp(_ArgTypes...)>
{
typedef _Rp1(^__block_type)(_ArgTypes1...);
__block_type __f_;
public:
_LIBCPP_INLINE_VISIBILITY
explicit __func(__block_type const& __f)
: __f_(__f ? Block_copy(__f) : (__block_type)0)
{ }
// [TODO] add && to save on a retain
_LIBCPP_INLINE_VISIBILITY
explicit __func(__block_type __f, const _Alloc& /* unused */)
: __f_(__f ? Block_copy(__f) : (__block_type)0)
{ }
virtual __base<_Rp(_ArgTypes...)>* __clone() const {
_LIBCPP_ASSERT(false,
"Block pointers are just pointers, so they should always fit into "
"std::function's small buffer optimization. This function should "
"never be invoked.");
return nullptr;
}
virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const {
::new (__p) __func(__f_);
}
virtual void destroy() _NOEXCEPT {
if (__f_)
Block_release(__f_);
__f_ = 0;
}
virtual void destroy_deallocate() _NOEXCEPT {
_LIBCPP_ASSERT(false,
"Block pointers are just pointers, so they should always fit into "
"std::function's small buffer optimization. This function should "
"never be invoked.");
}
virtual _Rp operator()(_ArgTypes&& ... __arg) {
return __invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
}
#ifndef _LIBCPP_NO_RTTI
virtual const void* target(type_info const& __ti) const _NOEXCEPT {
if (__ti == typeid(__func::__block_type))
return &__f_;
return (const void*)nullptr;
}
virtual const std::type_info& target_type() const _NOEXCEPT {
return typeid(__func::__block_type);
}
#endif // _LIBCPP_NO_RTTI
};
#endif // _LIBCPP_HAS_EXTENSION_BLOCKS && !_LIBCPP_HAS_OBJC_ARC
} // __function
template<class _Rp, class ..._ArgTypes>
@@ -2255,14 +2338,14 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
template <class _Fp, bool = _And<
_IsNotSame<__uncvref_t<_Fp>, function>,
__invokable<_Fp&, _ArgTypes...>
__invokable<_Fp, _ArgTypes...>
>::value>
struct __callable;
template <class _Fp>
struct __callable<_Fp, true>
{
static const bool value = is_same<void, _Rp>::value ||
is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,
is_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
_Rp>::value;
};
template <class _Fp>
@@ -2272,7 +2355,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
};
template <class _Fp>
using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type;
using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
public:
typedef _Rp result_type;
@@ -2283,7 +2366,7 @@ public:
function(nullptr_t) _NOEXCEPT {}
function(const function&);
function(function&&) _NOEXCEPT;
template<class _Fp, class = _EnableIfCallable<_Fp>>
template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
function(_Fp);
#if _LIBCPP_STD_VER <= 14
@@ -2297,14 +2380,14 @@ public:
function(allocator_arg_t, const _Alloc&, const function&);
template<class _Alloc>
function(allocator_arg_t, const _Alloc&, function&&);
template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>>
template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
function(allocator_arg_t, const _Alloc& __a, _Fp __f);
#endif
function& operator=(const function&);
function& operator=(function&&) _NOEXCEPT;
function& operator=(nullptr_t) _NOEXCEPT;
template<class _Fp, class = _EnableIfCallable<_Fp>>
template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
function& operator=(_Fp&&);
~function();
@@ -2967,14 +3050,14 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
forward_iterator_tag, forward_iterator_tag)
{
if (__first2 == __last2)
return make_pair(__first1, __first1); // Everything matches an empty sequence
return _VSTD::make_pair(__first1, __first1); // Everything matches an empty sequence
while (true)
{
// Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks
while (true)
{
if (__first1 == __last1) // return __last1 if no element matches *__first2
return make_pair(__last1, __last1);
return _VSTD::make_pair(__last1, __last1);
if (__pred(*__first1, *__first2))
break;
++__first1;
@@ -2985,9 +3068,9 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
while (true)
{
if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern)
return make_pair(__first1, __m1);
return _VSTD::make_pair(__first1, __m1);
if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found
return make_pair(__last1, __last1);
return _VSTD::make_pair(__last1, __last1);
if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1
{
++__first1;
@@ -3009,10 +3092,10 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
// Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern
const _D2 __len2 = __last2 - __first2;
if (__len2 == 0)
return make_pair(__first1, __first1);
return _VSTD::make_pair(__first1, __first1);
const _D1 __len1 = __last1 - __first1;
if (__len1 < __len2)
return make_pair(__last1, __last1);
return _VSTD::make_pair(__last1, __last1);
const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here
while (true)
@@ -3020,7 +3103,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
while (true)
{
if (__first1 == __s)
return make_pair(__last1, __last1);
return _VSTD::make_pair(__last1, __last1);
if (__pred(*__first1, *__first2))
break;
++__first1;
@@ -3031,7 +3114,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
while (true)
{
if (++__m2 == __last2)
return make_pair(__first1, __first1 + __len2);
return _VSTD::make_pair(__first1, __first1 + __len2);
++__m1; // no need to check range on __m1 because __s guarantees we have enough source
if (!__pred(*__m1, *__m2))
{
@@ -3080,15 +3163,19 @@ using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type;
#endif // > C++17
template <class _Container, class _Predicate>
inline void __libcpp_erase_if_container( _Container& __c, _Predicate __pred)
{
for (typename _Container::iterator __iter = __c.begin(), __last = __c.end(); __iter != __last;)
{
if (__pred(*__iter))
__iter = __c.erase(__iter);
else
++__iter;
}
inline typename _Container::size_type
__libcpp_erase_if_container(_Container& __c, _Predicate __pred) {
typename _Container::size_type __old_size = __c.size();
const typename _Container::iterator __last = __c.end();
for (typename _Container::iterator __iter = __c.begin(); __iter != __last;) {
if (__pred(*__iter))
__iter = __c.erase(__iter);
else
++__iter;
}
return __old_size - __c.size();
}
_LIBCPP_END_NAMESPACE_STD
+1
View File
@@ -506,6 +506,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
const error_code& code() const _NOEXCEPT {return __ec_;}
future_error(const future_error&) _NOEXCEPT = default;
virtual ~future_error() _NOEXCEPT;
};
+26 -25
View File
@@ -431,7 +431,8 @@ class _LIBCPP_EXCEPTION_ABI ios_base::failure
public:
explicit failure(const string& __msg, const error_code& __ec = io_errc::stream);
explicit failure(const char* __msg, const error_code& __ec = io_errc::stream);
virtual ~failure() throw();
failure(const failure&) _NOEXCEPT = default;
virtual ~failure() _NOEXCEPT;
};
_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
@@ -842,7 +843,7 @@ basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf<char_type, traits_type>* _
ios_base::set_rdbuf(__sb);
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
boolalpha(ios_base& __str)
{
@@ -850,7 +851,7 @@ boolalpha(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
noboolalpha(ios_base& __str)
{
@@ -858,7 +859,7 @@ noboolalpha(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
showbase(ios_base& __str)
{
@@ -866,7 +867,7 @@ showbase(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
noshowbase(ios_base& __str)
{
@@ -874,7 +875,7 @@ noshowbase(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
showpoint(ios_base& __str)
{
@@ -882,7 +883,7 @@ showpoint(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
noshowpoint(ios_base& __str)
{
@@ -890,7 +891,7 @@ noshowpoint(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
showpos(ios_base& __str)
{
@@ -898,7 +899,7 @@ showpos(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
noshowpos(ios_base& __str)
{
@@ -906,7 +907,7 @@ noshowpos(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
skipws(ios_base& __str)
{
@@ -914,7 +915,7 @@ skipws(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
noskipws(ios_base& __str)
{
@@ -922,7 +923,7 @@ noskipws(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
uppercase(ios_base& __str)
{
@@ -930,7 +931,7 @@ uppercase(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
nouppercase(ios_base& __str)
{
@@ -938,7 +939,7 @@ nouppercase(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
unitbuf(ios_base& __str)
{
@@ -946,7 +947,7 @@ unitbuf(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
nounitbuf(ios_base& __str)
{
@@ -954,7 +955,7 @@ nounitbuf(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
internal(ios_base& __str)
{
@@ -962,7 +963,7 @@ internal(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
left(ios_base& __str)
{
@@ -970,7 +971,7 @@ left(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
right(ios_base& __str)
{
@@ -978,7 +979,7 @@ right(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
dec(ios_base& __str)
{
@@ -986,7 +987,7 @@ dec(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
hex(ios_base& __str)
{
@@ -994,7 +995,7 @@ hex(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
oct(ios_base& __str)
{
@@ -1002,7 +1003,7 @@ oct(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
fixed(ios_base& __str)
{
@@ -1010,7 +1011,7 @@ fixed(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
scientific(ios_base& __str)
{
@@ -1018,7 +1019,7 @@ scientific(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
hexfloat(ios_base& __str)
{
@@ -1026,7 +1027,7 @@ hexfloat(ios_base& __str)
return __str;
}
inline _LIBCPP_INLINE_VISIBILITY
inline
ios_base&
defaultfloat(ios_base& __str)
{
+10 -11
View File
@@ -54,10 +54,8 @@ struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
// 27.4.3, iterator operations
// extension: second argument not conforming to C++03
template <class InputIterator> // constexpr in C++17
constexpr void advance(InputIterator& i,
typename iterator_traits<InputIterator>::difference_type n);
template <class InputIterator, class Distance> // constexpr in C++17
constexpr void advance(InputIterator& i, Distance n);
template <class InputIterator> // constexpr in C++17
constexpr typename iterator_traits<InputIterator>::difference_type
@@ -663,13 +661,14 @@ void __advance(_RandIter& __i,
__i += __n;
}
template <class _InputIter>
template <class _InputIter, class _Distance>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
void advance(_InputIter& __i,
typename iterator_traits<_InputIter>::difference_type __n)
void advance(_InputIter& __i, _Distance __orig_n)
{
_LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
"Attempt to advance(it, -n) on a non-bidi iterator");
_LIBCPP_ASSERT(__orig_n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
"Attempt to advance(it, n) with negative n on a non-bidirectional iterator");
typedef decltype(__convert_to_integral(__orig_n)) _IntegralSize;
_IntegralSize __n = __orig_n;
__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category());
}
@@ -711,7 +710,7 @@ next(_InputIter __x,
typename iterator_traits<_InputIter>::difference_type __n = 1)
{
_LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
"Attempt to next(it, -n) on a non-bidi iterator");
"Attempt to next(it, n) with negative n on a non-bidirectional iterator");
_VSTD::advance(__x, __n);
return __x;
@@ -728,7 +727,7 @@ prev(_InputIter __x,
typename iterator_traits<_InputIter>::difference_type __n = 1)
{
_LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value,
"Attempt to prev(it, +n) on a non-bidi iterator");
"Attempt to prev(it, n) with a positive n on a non-bidirectional iterator");
_VSTD::advance(__x, -__n);
return __x;
}
+104
View File
@@ -0,0 +1,104 @@
// -*- C++ -*-
//===--------------------------- latch -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_LATCH
#define _LIBCPP_LATCH
/*
latch synopsis
namespace std
{
class latch
{
public:
constexpr explicit latch(ptrdiff_t __expected);
~latch();
latch(const latch&) = delete;
latch& operator=(const latch&) = delete;
void count_down(ptrdiff_t __update = 1);
bool try_wait() const noexcept;
void wait() const;
void arrive_and_wait(ptrdiff_t __update = 1);
private:
ptrdiff_t __counter; // exposition only
};
}
*/
#include <__config>
#include <atomic>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
# error <latch> is not supported on this single threaded system
#endif
#if _LIBCPP_STD_VER >= 14
_LIBCPP_BEGIN_NAMESPACE_STD
class latch
{
__atomic_base<ptrdiff_t> __a;
public:
static constexpr ptrdiff_t max() noexcept {
return numeric_limits<ptrdiff_t>::max();
}
inline _LIBCPP_INLINE_VISIBILITY
constexpr explicit latch(ptrdiff_t __expected) : __a(__expected) { }
~latch() = default;
latch(const latch&) = delete;
latch& operator=(const latch&) = delete;
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void count_down(ptrdiff_t __update = 1)
{
auto const __old = __a.fetch_sub(__update, memory_order_release);
if(__old == __update)
__a.notify_all();
}
inline _LIBCPP_INLINE_VISIBILITY
bool try_wait() const noexcept
{
return 0 == __a.load(memory_order_acquire);
}
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void wait() const
{
auto const __test_fn = [=]() -> bool {
return try_wait();
};
__cxx_atomic_wait(&__a.__a_, __test_fn);
}
inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void arrive_and_wait(ptrdiff_t __update = 1)
{
count_down(__update);
wait();
}
};
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 14
#endif //_LIBCPP_LATCH
+12 -8
View File
@@ -170,9 +170,11 @@ template <class T, class Alloc>
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(list<T, Allocator>& c, const U& value); // C++20
typename list<T, Allocator>::size_type
erase(list<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(list<T, Allocator>& c, Predicate pred); // C++20
typename list<T, Allocator>::size_type
erase_if(list<T, Allocator>& c, Predicate pred); // C++20
} // std
@@ -2471,14 +2473,16 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.remove_if(__pred); }
inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) {
return __c.remove_if(__pred);
}
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(list<_Tp, _Allocator>& __c, const _Up& __v)
{ _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; }); }
inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type
erase(list<_Tp, _Allocator>& __c, const _Up& __v) {
return _VSTD::erase_if(__c, [&](auto& __elem) { return __elem == __v; });
}
#endif
_LIBCPP_END_NAMESPACE_STD
+17 -8
View File
@@ -254,7 +254,8 @@ swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class T, class Compare, class Allocator, class Predicate>
void erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
typename map<Key, T, Compare, Allocator>::size_type
erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
template <class Key, class T, class Compare = less<Key>,
@@ -469,7 +470,8 @@ swap(multimap<Key, T, Compare, Allocator>& x,
noexcept(noexcept(x.swap(y)));
template <class Key, class T, class Compare, class Allocator, class Predicate>
void erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
typename multimap<Key, T, Compare, Allocator>::size_type
erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20
} // std
@@ -1653,10 +1655,13 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x,
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
template <class _Key, class _Tp, class _Compare, class _Allocator,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename map<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
@@ -2235,10 +2240,14 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x,
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>
template <class _Key, class _Tp, class _Compare, class _Allocator,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type
erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
_LIBCPP_END_NAMESPACE_STD
+5 -56
View File
@@ -297,9 +297,6 @@ long double truncl(long double x);
#pragma GCC system_header
#endif
#define _LIBCPP_STDLIB_INCLUDE_NEXT
#include <stdlib.h>
#include_next <math.h>
#ifdef __cplusplus
@@ -308,6 +305,7 @@ long double truncl(long double x);
// back to C++ linkage before including these C++ headers.
extern "C++" {
#include <stdlib.h>
#include <type_traits>
#include <limits>
@@ -760,61 +758,12 @@ isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
#endif // isunordered
// abs
#undef abs
#undef labs
#ifndef _LIBCPP_HAS_NO_LONG_LONG
#undef llabs
#endif
// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
return ::labs(__x);
}
#ifndef _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
return ::llabs(__x);
}
#endif // _LIBCPP_HAS_NO_LONG_LONG
#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
#if !(defined(_AIX) || defined(__sun__))
inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
return ::fabsf(__lcpp_x);
}
inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
return ::fabs(__lcpp_x);
}
inline _LIBCPP_INLINE_VISIBILITY long double
abs(long double __lcpp_x) _NOEXCEPT {
return ::fabsl(__lcpp_x);
}
#endif // !(defined(_AIX) || defined(__sun__))
//
// handled in stdlib.h
// div
#undef div
#undef ldiv
#ifndef _LIBCPP_HAS_NO_LONG_LONG
#undef lldiv
#endif
// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
return ::ldiv(__x, __y);
}
#ifndef _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
long long __y) _NOEXCEPT {
return ::lldiv(__x, __y);
}
#endif // _LIBCPP_HAS_NO_LONG_LONG
#endif // _LIBCPP_MSVCRT / __sun__ / _AIX
//
// handled in stdlib.h
// acos
+290 -382
View File
@@ -80,7 +80,7 @@ struct allocator_traits
typedef Alloc::is_always_equal
| is_empty is_always_equal;
template <class T> using rebind_alloc = Alloc::rebind<U>::other | Alloc<T, Args...>;
template <class T> using rebind_alloc = Alloc::rebind<T>::other | Alloc<T, Args...>;
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
static pointer allocate(allocator_type& a, size_type n); // [[nodiscard]] in C++20
@@ -101,7 +101,7 @@ struct allocator_traits
};
template <>
class allocator<void>
class allocator<void> // deprecated in C++17, removed in C++20
{
public:
typedef void* pointer;
@@ -115,30 +115,37 @@ template <class T>
class allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef typename add_lvalue_reference<T>::type reference;
typedef typename add_lvalue_reference<const T>::type const_reference;
typedef T value_type;
typedef size_t size_type; // deprecated in C++17, removed in C++20
typedef ptrdiff_t difference_type; // deprecated in C++17, removed in C++20
typedef T* pointer; // deprecated in C++17, removed in C++20
typedef const T* const_pointer; // deprecated in C++17, removed in C++20
typedef typename add_lvalue_reference<T>::type
reference; // deprecated in C++17, removed in C++20
typedef typename add_lvalue_reference<const T>::type
const_reference; // deprecated in C++17, removed in C++20
template <class U> struct rebind {typedef allocator<U> other;};
typedef T value_type;
template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
constexpr allocator() noexcept; // constexpr in C++20
constexpr allocator(const allocator&) noexcept; // constexpr in C++20
template <class U>
constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
~allocator();
pointer address(reference x) const noexcept;
const_pointer address(const_reference x) const noexcept;
pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
void deallocate(pointer p, size_type n) noexcept;
size_type max_size() const noexcept;
pointer address(reference x) const noexcept; // deprecated in C++17, removed in C++20
const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
T* allocate(size_t n, const void* hint); // deprecated in C++17, removed in C++20
T* allocate(size_t n);
void deallocate(T* p, size_t n) noexcept;
size_type max_size() const noexcept; // deprecated in C++17, removed in C++20
template<class U, class... Args>
void construct(U* p, Args&&... args);
void construct(U* p, Args&&... args); // deprecated in C++17, removed in C++20
template <class U>
void destroy(U* p);
void destroy(U* p); // deprecated in C++17, removed in C++20
};
template <class T, class U>
@@ -443,6 +450,11 @@ public:
template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
};
template<class T>
shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
template<class T, class D>
shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
// shared_ptr comparisons:
template<class T, class U>
bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
@@ -541,6 +553,9 @@ public:
template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
};
template<class T>
weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
// weak_ptr specialized algorithms:
template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
@@ -705,8 +720,9 @@ _ValueType __libcpp_acquire_load(_ValueType const* __value) {
template <class _Tp> class allocator;
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
template <>
class _LIBCPP_TEMPLATE_VIS allocator<void>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void>
{
public:
typedef void* pointer;
@@ -717,7 +733,7 @@ public:
};
template <>
class _LIBCPP_TEMPLATE_VIS allocator<const void>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<const void>
{
public:
typedef const void* pointer;
@@ -726,6 +742,7 @@ public:
template <class _Up> struct rebind {typedef allocator<_Up> other;};
};
#endif
// pointer_traits
@@ -838,7 +855,9 @@ struct __has_rebind
private:
struct __two {char __lx; char __lxx;};
template <class _Xp> static __two __test(...);
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
@@ -1266,7 +1285,9 @@ struct __has_rebind_other
private:
struct __two {char __lx; char __lxx;};
template <class _Xp> static __two __test(...);
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Xp> static char __test(typename _Xp::template rebind<_Up>::other* = 0);
_LIBCPP_SUPPRESS_DEPRECATED_POP
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
@@ -1280,15 +1301,17 @@ struct __has_rebind_other<_Tp, _Up, false>
template <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
struct __allocator_traits_rebind
{
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
_LIBCPP_SUPPRESS_DEPRECATED_POP
};
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
{
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
typedef _LIBCPP_NODEBUG_TYPE typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
_LIBCPP_SUPPRESS_DEPRECATED_POP
};
template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
@@ -1297,68 +1320,14 @@ struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
typedef _LIBCPP_NODEBUG_TYPE _Alloc<_Up, _Args...> type;
};
#else // _LIBCPP_HAS_NO_VARIADICS
template <template <class> class _Alloc, class _Tp, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true>
{
typedef typename _Alloc<_Tp>::template rebind<_Up>::other type;
};
template <template <class> class _Alloc, class _Tp, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false>
{
typedef _Alloc<_Up> type;
};
template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true>
{
typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type;
};
template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false>
{
typedef _Alloc<_Up, _A0> type;
};
template <template <class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true>
{
typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type;
};
template <template <class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false>
{
typedef _Alloc<_Up, _A0, _A1> type;
};
template <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _A2, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true>
{
typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
};
template <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _A2, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false>
{
typedef _Alloc<_Up, _A0, _A1, _A2> type;
};
#endif // _LIBCPP_HAS_NO_VARIADICS
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Alloc, class _SizeType, class _ConstVoidPtr>
auto
__has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
-> decltype((void)__a.allocate(__sz, __p), true_type());
_LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Alloc, class _SizeType, class _ConstVoidPtr>
auto
@@ -1367,12 +1336,9 @@ __has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __
template <class _Alloc, class _SizeType, class _ConstVoidPtr>
struct __has_allocate_hint
: integral_constant<bool,
is_same<
decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(),
declval<_SizeType>(),
declval<_ConstVoidPtr>())),
true_type>::value>
: decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(),
declval<_SizeType>(),
declval<_ConstVoidPtr>()))
{
};
@@ -1386,33 +1352,26 @@ struct __has_allocate_hint
#endif // _LIBCPP_CXX03_LANG
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Alloc, class ..._Args,
class = decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Args>()...))>
static true_type __test_has_construct(int);
_LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Alloc, class...>
static false_type __test_has_construct(...);
template <class _Alloc, class ..._Args>
struct __has_construct : decltype(__test_has_construct<_Alloc, _Args...>(0)) {};
#if !defined(_LIBCPP_CXX03_LANG)
template <class _Alloc, class _Tp, class ..._Args>
decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(),
_VSTD::declval<_Args>()...),
true_type())
__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args);
template <class _Alloc, class _Pointer, class ..._Args>
false_type
__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args);
template <class _Alloc, class _Pointer, class ..._Args>
struct __has_construct
: integral_constant<bool,
is_same<
decltype(_VSTD::__has_construct_test(declval<_Alloc>(),
declval<_Pointer>(),
declval<_Args>()...)),
true_type>::value>
{
};
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Alloc, class _Pointer>
auto
__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
-> decltype(__a.destroy(__p), true_type());
_LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Alloc, class _Pointer>
auto
@@ -1421,18 +1380,17 @@ __has_destroy_test(const _Alloc& __a, _Pointer&& __p)
template <class _Alloc, class _Pointer>
struct __has_destroy
: integral_constant<bool,
is_same<
decltype(_VSTD::__has_destroy_test(declval<_Alloc>(),
declval<_Pointer>())),
true_type>::value>
: decltype(_VSTD::__has_destroy_test(declval<_Alloc>(),
declval<_Pointer>()))
{
};
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
template <class _Alloc>
auto
__has_max_size_test(_Alloc&& __a)
-> decltype(__a.max_size(), true_type());
_LIBCPP_SUPPRESS_DEPRECATED_POP
template <class _Alloc>
auto
@@ -1441,10 +1399,7 @@ __has_max_size_test(const volatile _Alloc& __a)
template <class _Alloc>
struct __has_max_size
: integral_constant<bool,
is_same<
decltype(_VSTD::__has_max_size_test(declval<_Alloc&>())),
true_type>::value>
: decltype(_VSTD::__has_max_size_test(declval<_Alloc&>()))
{
};
@@ -1460,23 +1415,12 @@ __has_select_on_container_copy_construction_test(const volatile _Alloc& __a)
template <class _Alloc>
struct __has_select_on_container_copy_construction
: integral_constant<bool,
is_same<
decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>())),
true_type>::value>
: decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>()))
{
};
#else // _LIBCPP_CXX03_LANG
template <class _Alloc, class _Pointer, class _Tp, class = void>
struct __has_construct : std::false_type {};
template <class _Alloc, class _Pointer, class _Tp>
struct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t<
decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>()))
>::type> : std::true_type {};
template <class _Alloc, class _Pointer, class = void>
struct __has_destroy : false_type {};
@@ -1588,41 +1532,11 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT
{__a.deallocate(__p, __n);}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class... _Args>
_LIBCPP_INLINE_VISIBILITY
static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
{__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
__a, __p, _VSTD::forward<_Args>(__args)...);}
#else // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
static void construct(allocator_type&, _Tp* __p)
{
::new ((void*)__p) _Tp();
}
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
{
__construct(__has_construct<allocator_type, _Tp*, const _A0&>(),
__a, __p, __a0);
}
template <class _Tp, class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
const _A1& __a1)
{
::new ((void*)__p) _Tp(__a0, __a1);
}
template <class _Tp, class _A0, class _A1, class _A2>
_LIBCPP_INLINE_VISIBILITY
static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
const _A1& __a1, const _A2& __a2)
{
::new ((void*)__p) _Tp(__a0, __a1, __a2);
}
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
@@ -1695,7 +1609,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
static
typename enable_if
<
is_trivially_move_constructible<_DestTp>::value &&
is_trivially_copy_constructible<_DestTp>::value &&
is_same<_RawSourceTp, _RawDestTp>::value &&
(__is_default_allocator<allocator_type>::value ||
!__has_construct<allocator_type, _DestTp*, _SourceTp&>::value),
@@ -1755,42 +1669,40 @@ private:
_LIBCPP_INLINE_VISIBILITY
static pointer __allocate(allocator_type& __a, size_type __n,
const_void_pointer __hint, true_type)
{return __a.allocate(__n, __hint);}
{
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
return __a.allocate(__n, __hint);
_LIBCPP_SUPPRESS_DEPRECATED_POP
}
_LIBCPP_INLINE_VISIBILITY
static pointer __allocate(allocator_type& __a, size_type __n,
const_void_pointer, false_type)
{return __a.allocate(__n);}
#ifndef _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class... _Args>
_LIBCPP_INLINE_VISIBILITY
static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)
{__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
{
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
__a.construct(__p, _VSTD::forward<_Args>(__args)...);
_LIBCPP_SUPPRESS_DEPRECATED_POP
}
template <class _Tp, class... _Args>
_LIBCPP_INLINE_VISIBILITY
static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)
{
::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
}
#else // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
static void __construct(true_type, allocator_type& __a, _Tp* __p,
const _A0& __a0)
{__a.construct(__p, __a0);}
template <class _Tp, class _A0>
_LIBCPP_INLINE_VISIBILITY
static void __construct(false_type, allocator_type&, _Tp* __p,
const _A0& __a0)
{
::new ((void*)__p) _Tp(__a0);
}
#endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
static void __destroy(true_type, allocator_type& __a, _Tp* __p)
{__a.destroy(__p);}
{
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
__a.destroy(__p);
_LIBCPP_SUPPRESS_DEPRECATED_POP
}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
static void __destroy(false_type, allocator_type&, _Tp* __p)
@@ -1800,7 +1712,12 @@ private:
_LIBCPP_INLINE_VISIBILITY
static size_type __max_size(true_type, const allocator_type& __a) _NOEXCEPT
{return __a.max_size();}
{
_LIBCPP_SUPPRESS_DEPRECATED_PUSH
return __a.max_size();
_LIBCPP_SUPPRESS_DEPRECATED_POP
}
_LIBCPP_INLINE_VISIBILITY
static size_type __max_size(false_type, const allocator_type&) _NOEXCEPT
{return numeric_limits<size_type>::max() / sizeof(value_type);}
@@ -1831,19 +1748,22 @@ template <class _Tp>
class _LIBCPP_TEMPLATE_VIS allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t size_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef ptrdiff_t difference_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp& reference;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
#endif
typedef _Tp value_type;
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
template <class _Up> struct rebind {typedef allocator<_Up> other;};
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator() _NOEXCEPT {}
@@ -1851,103 +1771,67 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up>&) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
pointer address(reference __x) const _NOEXCEPT
{return _VSTD::addressof(__x);}
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
const_pointer address(const_reference __x) const _NOEXCEPT
{return _VSTD::addressof(__x);}
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
#endif
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _Tp* allocate(size_t __n)
{
if (__n > max_size())
// TODO(mpark): Replace with `allocator_traits<allocator>::max_size(*this)`.
if (__n > (size_t(~0) / sizeof(_Tp)))
__throw_length_error("allocator<T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
_Tp* allocate(size_t __n, const void*) { return allocate(__n); }
#endif
_LIBCPP_INLINE_VISIBILITY void deallocate(_Tp* __p, size_t __n) _NOEXCEPT
{_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
template <class _Up, class... _Args>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
void
construct(_Up* __p, _Args&&... __args)
{
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
}
#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p)
{
::new((void*)__p) _Tp();
}
# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <class _A0>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0)
{
::new((void*)__p) _Tp(__a0);
}
template <class _A0>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0)
{
::new((void*)__p) _Tp(__a0);
}
# endif // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0, _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0, _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0, const _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0, const _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
#endif
};
template <class _Tp>
class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp* const_pointer;
typedef const _Tp& reference;
typedef const _Tp& const_reference;
typedef const _Tp value_type;
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t size_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef ptrdiff_t difference_type;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
_LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
#endif
typedef const _Tp value_type;
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
template <class _Up> struct rebind {typedef allocator<_Up> other;};
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator() _NOEXCEPT {}
@@ -1955,22 +1839,36 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
allocator(const allocator<_Up>&) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
const_pointer address(const_reference __x) const _NOEXCEPT
{return _VSTD::addressof(__x);}
_LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
#endif
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY const _Tp* allocate(size_t __n)
{
if (__n > max_size())
// TODO(mpark): Replace with `allocator_traits<allocator>::max_size(*this)`.
if (__n > (size_t(~0) / sizeof(_Tp)))
__throw_length_error("allocator<const T>::allocate(size_t n)"
" 'n' exceeds maximum supported size");
return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
}
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
const _Tp* allocate(size_t __n, const void*) { return allocate(__n); }
#endif
_LIBCPP_INLINE_VISIBILITY void deallocate(const _Tp* __p, size_t __n)
{_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
template <class _Up, class... _Args>
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
void
construct(_Up* __p, _Args&&... __args)
{
@@ -2029,7 +1927,8 @@ public:
::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
}
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
#endif
};
template <class _Tp, class _Up>
@@ -2134,39 +2033,39 @@ private:
public:
typedef _Tp element_type;
_LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) throw() : __ptr_(__p) {}
_LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) throw() : __ptr_(__p.release()) {}
template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) throw()
_LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
_LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
: __ptr_(__p.release()) {}
_LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) throw()
_LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
{reset(__p.release()); return *this;}
template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) throw()
template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
{reset(__p.release()); return *this;}
_LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) throw()
_LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
{reset(__p.__ptr_); return *this;}
_LIBCPP_INLINE_VISIBILITY ~auto_ptr() throw() {delete __ptr_;}
_LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
_LIBCPP_INLINE_VISIBILITY _Tp& operator*() const throw()
_LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
{return *__ptr_;}
_LIBCPP_INLINE_VISIBILITY _Tp* operator->() const throw() {return __ptr_;}
_LIBCPP_INLINE_VISIBILITY _Tp* get() const throw() {return __ptr_;}
_LIBCPP_INLINE_VISIBILITY _Tp* release() throw()
_LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
_LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
_LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
{
_Tp* __t = __ptr_;
__ptr_ = 0;
return __t;
}
_LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) throw()
_LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
{
if (__ptr_ != __p)
delete __ptr_;
__ptr_ = __p;
}
_LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) throw() : __ptr_(__p.__ptr_) {}
template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() throw()
_LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
{auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() throw()
template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
{return auto_ptr<_Up>(release());}
};
@@ -3393,6 +3292,8 @@ class _LIBCPP_EXCEPTION_ABI bad_weak_ptr
: public std::exception
{
public:
bad_weak_ptr() _NOEXCEPT = default;
bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
virtual ~bad_weak_ptr() _NOEXCEPT;
virtual const char* what() const _NOEXCEPT;
};
@@ -3628,15 +3529,25 @@ public:
template<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
template<class _Tp, class _Up>
struct __compatible_with
#if _LIBCPP_STD_VER > 14
: is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
#else
: is_convertible<_Tp*, _Up*> {};
#endif // _LIBCPP_STD_VER > 14
template<class _Tp>
class _LIBCPP_TEMPLATE_VIS shared_ptr
{
public:
typedef _Tp element_type;
#if _LIBCPP_STD_VER > 14
typedef weak_ptr<_Tp> weak_type;
typedef remove_extent_t<_Tp> element_type;
#else
typedef _Tp element_type;
#endif
private:
element_type* __ptr_;
__shared_weak_count* __cntrl_;
@@ -3649,13 +3560,13 @@ public:
_LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
template<class _Yp>
explicit shared_ptr(_Yp* __p,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
template<class _Yp, class _Dp>
shared_ptr(_Yp* __p, _Dp __d,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
template<class _Yp, class _Dp, class _Alloc>
shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
@@ -3664,13 +3575,13 @@ public:
template<class _Yp>
_LIBCPP_INLINE_VISIBILITY
shared_ptr(const shared_ptr<_Yp>& __r,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat())
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
_NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
shared_ptr(shared_ptr&& __r) _NOEXCEPT;
template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(shared_ptr<_Yp>&& __r,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat())
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
_NOEXCEPT;
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
@@ -3686,7 +3597,6 @@ public:
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
#endif
#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Yp, class _Dp>
shared_ptr(unique_ptr<_Yp, _Dp>&&,
typename enable_if
@@ -3705,26 +3615,6 @@ public:
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
__nat
>::type = __nat());
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Yp, class _Dp>
shared_ptr(unique_ptr<_Yp, _Dp>,
typename enable_if
<
!is_lvalue_reference<_Dp>::value &&
!is_array<_Yp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
__nat
>::type = __nat());
template <class _Yp, class _Dp>
shared_ptr(unique_ptr<_Yp, _Dp>,
typename enable_if
<
is_lvalue_reference<_Dp>::value &&
!is_array<_Yp>::value &&
is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
__nat
>::type = __nat());
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
~shared_ptr();
@@ -3733,7 +3623,7 @@ public:
template<class _Yp>
typename enable_if
<
is_convertible<_Yp*, element_type*>::value,
__compatible_with<_Yp, element_type>::value,
shared_ptr&
>::type
_LIBCPP_INLINE_VISIBILITY
@@ -3744,8 +3634,8 @@ public:
template<class _Yp>
typename enable_if
<
is_convertible<_Yp*, element_type*>::value,
shared_ptr<_Tp>&
__compatible_with<_Yp, element_type>::value,
shared_ptr&
>::type
_LIBCPP_INLINE_VISIBILITY
operator=(shared_ptr<_Yp>&& __r);
@@ -3795,7 +3685,7 @@ public:
template<class _Yp>
typename enable_if
<
is_convertible<_Yp*, element_type*>::value,
__compatible_with<_Yp, element_type>::value,
void
>::type
_LIBCPP_INLINE_VISIBILITY
@@ -3803,7 +3693,7 @@ public:
template<class _Yp, class _Dp>
typename enable_if
<
is_convertible<_Yp*, element_type*>::value,
__compatible_with<_Yp, element_type>::value,
void
>::type
_LIBCPP_INLINE_VISIBILITY
@@ -3811,7 +3701,7 @@ public:
template<class _Yp, class _Dp, class _Alloc>
typename enable_if
<
is_convertible<_Yp*, element_type*>::value,
__compatible_with<_Yp, element_type>::value,
void
>::type
_LIBCPP_INLINE_VISIBILITY
@@ -3823,7 +3713,12 @@ public:
typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
{return *__ptr_;}
_LIBCPP_INLINE_VISIBILITY
element_type* operator->() const _NOEXCEPT {return __ptr_;}
element_type* operator->() const _NOEXCEPT
{
static_assert(!_VSTD::is_array<_Tp>::value,
"std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
return __ptr_;
}
_LIBCPP_INLINE_VISIBILITY
long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
_LIBCPP_INLINE_VISIBILITY
@@ -3843,6 +3738,17 @@ public:
__owner_equivalent(const shared_ptr& __p) const
{return __cntrl_ == __p.__cntrl_;}
#if _LIBCPP_STD_VER > 14
typename add_lvalue_reference<element_type>::type
_LIBCPP_INLINE_VISIBILITY
operator[](ptrdiff_t __i) const
{
static_assert(_VSTD::is_array<_Tp>::value,
"std::shared_ptr<T>::operator[] is only valid when T is an array type.");
return __ptr_[__i];
}
#endif
#ifndef _LIBCPP_NO_RTTI
template <class _Dp>
_LIBCPP_INLINE_VISIBILITY
@@ -3854,7 +3760,7 @@ public:
template<class _Yp, class _CntrlBlk>
static shared_ptr<_Tp>
__create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl)
__create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
{
shared_ptr<_Tp> __r;
__r.__ptr_ = __p;
@@ -3863,11 +3769,6 @@ public:
return __r;
}
template<class _Alloc, class ..._Args>
static
shared_ptr<_Tp>
allocate_shared(const _Alloc& __a, _Args&& ...__args);
private:
template <class _Yp, bool = is_function<_Yp>::value>
struct __shared_ptr_default_allocator
@@ -3900,10 +3801,28 @@ private:
_LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
template <class, class _Yp>
struct __shared_ptr_default_delete
: default_delete<_Yp> {};
template <class _Yp, class _Un, size_t _Sz>
struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
: default_delete<_Yp[]> {};
template <class _Yp, class _Un>
struct __shared_ptr_default_delete<_Yp[], _Un>
: default_delete<_Yp[]> {};
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
};
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template<class _Tp>
shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
template<class _Tp, class _Dp>
shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
#endif
template<class _Tp>
inline
@@ -3926,13 +3845,13 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
template<class _Tp>
template<class _Yp>
shared_ptr<_Tp>::shared_ptr(_Yp* __p,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
: __ptr_(__p)
{
unique_ptr<_Yp> __hold(__p);
typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk;
__cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT());
typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
__cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
__hold.release();
__enable_weak_this(__p, __p);
}
@@ -3940,7 +3859,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p,
template<class _Tp>
template<class _Yp, class _Dp>
shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
: __ptr_(__p)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -3986,7 +3905,7 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
template<class _Tp>
template<class _Yp, class _Dp, class _Alloc>
shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
: __ptr_(__p)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@@ -4064,7 +3983,7 @@ template<class _Tp>
template<class _Yp>
inline
shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
_NOEXCEPT
: __ptr_(__r.__ptr_),
__cntrl_(__r.__cntrl_)
@@ -4089,7 +4008,7 @@ template<class _Tp>
template<class _Yp>
inline
shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
_NOEXCEPT
: __ptr_(__r.__ptr_),
__cntrl_(__r.__cntrl_)
@@ -4120,11 +4039,7 @@ shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r,
template<class _Tp>
template <class _Yp, class _Dp>
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
#else
shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
#endif
typename enable_if
<
!is_lvalue_reference<_Dp>::value &&
@@ -4150,11 +4065,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
template<class _Tp>
template <class _Yp, class _Dp>
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
#else
shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
#endif
typename enable_if
<
is_lvalue_reference<_Dp>::value &&
@@ -4174,32 +4085,12 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
typedef __shared_ptr_pointer<_Yp*,
reference_wrapper<typename remove_reference<_Dp>::type>,
_AllocT > _CntrlBlk;
__cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), _AllocT());
__cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
__enable_weak_this(__r.get(), __r.get());
}
__r.release();
}
template<class _Tp>
template<class _Alloc, class ..._Args>
shared_ptr<_Tp>
shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)
{
static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared" );
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
_A2 __a2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
_CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
shared_ptr<_Tp> __r;
__r.__ptr_ = __hold2.get()->get();
__r.__cntrl_ = _VSTD::addressof(*__hold2.release());
__r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
return __r;
}
template<class _Tp>
shared_ptr<_Tp>::~shared_ptr()
{
@@ -4221,7 +4112,7 @@ template<class _Yp>
inline
typename enable_if
<
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
__compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
shared_ptr<_Tp>&
>::type
shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
@@ -4246,7 +4137,7 @@ template<class _Yp>
inline
typename enable_if
<
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
__compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
shared_ptr<_Tp>&
>::type
shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
@@ -4347,7 +4238,7 @@ template<class _Yp>
inline
typename enable_if
<
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
__compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
void
>::type
shared_ptr<_Tp>::reset(_Yp* __p)
@@ -4360,7 +4251,7 @@ template<class _Yp, class _Dp>
inline
typename enable_if
<
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
__compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
void
>::type
shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
@@ -4373,7 +4264,7 @@ template<class _Yp, class _Dp, class _Alloc>
inline
typename enable_if
<
is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
__compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
void
>::type
shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
@@ -4412,7 +4303,19 @@ typename enable_if
>::type
allocate_shared(const _Alloc& __a, _Args&& ...__args)
{
return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...);
static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared");
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
typedef __allocator_destructor<_A2> _D2;
_A2 __a2(__a);
unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
_CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
typename shared_ptr<_Tp>::element_type *__p = __hold2.get()->get();
return shared_ptr<_Tp>::__create_with_control_block(__p, _VSTD::addressof(*__hold2.release()));
}
template<class _Tp, class _Up>
@@ -4575,41 +4478,41 @@ swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
template<class _Tp, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
!is_array<_Tp>::value && !is_array<_Up>::value,
shared_ptr<_Tp>
>::type
shared_ptr<_Tp>
static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
{
return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
return shared_ptr<_Tp>(__r,
static_cast<
typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
template<class _Tp, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
!is_array<_Tp>::value && !is_array<_Up>::value,
shared_ptr<_Tp>
>::type
shared_ptr<_Tp>
dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
{
_Tp* __p = dynamic_cast<_Tp*>(__r.get());
typedef typename shared_ptr<_Tp>::element_type _ET;
_ET* __p = dynamic_cast<_ET*>(__r.get());
return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
}
template<class _Tp, class _Up>
typename enable_if
<
is_array<_Tp>::value == is_array<_Up>::value,
shared_ptr<_Tp>
>::type
shared_ptr<_Tp>
const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
{
typedef typename remove_extent<_Tp>::type _RTp;
typedef typename shared_ptr<_Tp>::element_type _RTp;
return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
}
template<class _Tp, class _Up>
shared_ptr<_Tp>
reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
{
return shared_ptr<_Tp>(__r,
reinterpret_cast<
typename shared_ptr<_Tp>::element_type*>(__r.get()));
}
#ifndef _LIBCPP_NO_RTTI
template<class _Dp, class _Tp>
@@ -4712,6 +4615,11 @@ public:
template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
};
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template<class _Tp>
weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
#endif
template<class _Tp>
inline
_LIBCPP_CONSTEXPR
@@ -5008,7 +4916,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
_LIBCPP_INLINE_VISIBILITY
result_type operator()(const argument_type& __ptr) const _NOEXCEPT
{
return hash<_Tp*>()(__ptr.get());
return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
}
};
+23
View File
@@ -231,6 +231,11 @@ module std [system] {
header "atomic"
export *
}
module barrier {
requires cplusplus14
header "barrier"
export *
}
module bit {
header "bit"
export *
@@ -262,6 +267,10 @@ module std [system] {
header "complex"
export *
}
module concepts {
header "concepts"
export *
}
module condition_variable {
header "condition_variable"
export *
@@ -334,6 +343,11 @@ module std [system] {
header "iterator"
export *
}
module latch {
requires cplusplus14
header "latch"
export *
}
module limits {
header "limits"
export *
@@ -364,6 +378,10 @@ module std [system] {
header "new"
export *
}
module numbers {
header "numbers"
export *
}
module numeric {
header "numeric"
export *
@@ -400,6 +418,11 @@ module std [system] {
header "scoped_allocator"
export *
}
module semaphore {
requires cplusplus14
header "semaphore"
export *
}
module set {
header "set"
export initializer_list
+141
View File
@@ -0,0 +1,141 @@
// -*- C++ -*-
//===---------------------------- numbers ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_NUMBERS
#define _LIBCPP_NUMBERS
/*
numbers synopsis
namespace std::numbers {
template<class T> inline constexpr T e_v = unspecified;
template<class T> inline constexpr T log2e_v = unspecified;
template<class T> inline constexpr T log10e_v = unspecified;
template<class T> inline constexpr T pi_v = unspecified;
template<class T> inline constexpr T inv_pi_v = unspecified;
template<class T> inline constexpr T inv_sqrtpi_v = unspecified;
template<class T> inline constexpr T ln2_v = unspecified;
template<class T> inline constexpr T ln10_v = unspecified;
template<class T> inline constexpr T sqrt2_v = unspecified;
template<class T> inline constexpr T sqrt3_v = unspecified;
template<class T> inline constexpr T inv_sqrt3_v = unspecified;
template<class T> inline constexpr T egamma_v = unspecified;
template<class T> inline constexpr T phi_v = unspecified;
template<floating_point T> inline constexpr T e_v<T> = see below;
template<floating_point T> inline constexpr T log2e_v<T> = see below;
template<floating_point T> inline constexpr T log10e_v<T> = see below;
template<floating_point T> inline constexpr T pi_v<T> = see below;
template<floating_point T> inline constexpr T inv_pi_v<T> = see below;
template<floating_point T> inline constexpr T inv_sqrtpi_v<T> = see below;
template<floating_point T> inline constexpr T ln2_v<T> = see below;
template<floating_point T> inline constexpr T ln10_v<T> = see below;
template<floating_point T> inline constexpr T sqrt2_v<T> = see below;
template<floating_point T> inline constexpr T sqrt3_v<T> = see below;
template<floating_point T> inline constexpr T inv_sqrt3_v<T> = see below;
template<floating_point T> inline constexpr T egamma_v<T> = see below;
template<floating_point T> inline constexpr T phi_v<T> = see below;
inline constexpr double e = e_v<double>;
inline constexpr double log2e = log2e_v<double>;
inline constexpr double log10e = log10e_v<double>;
inline constexpr double pi = pi_v<double>;
inline constexpr double inv_pi = inv_pi_v<double>;
inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
inline constexpr double ln2 = ln2_v<double>;
inline constexpr double ln10 = ln10_v<double>;
inline constexpr double sqrt2 = sqrt2_v<double>;
inline constexpr double sqrt3 = sqrt3_v<double>;
inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
inline constexpr double egamma = egamma_v<double>;
inline constexpr double phi = phi_v<double>;
}
*/
#include <__config>
#if _LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
#include <type_traits>
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
namespace numbers {
template <class T>
inline constexpr bool __false = false;
template <class T>
struct __illformed
{
static_assert(__false<T>, "A program that instantiates a primary template of a mathematical constant variable template is ill-formed.");
};
template <class T> inline constexpr T e_v = __illformed<T>{};
template <class T> inline constexpr T log2e_v = __illformed<T>{};
template <class T> inline constexpr T log10e_v = __illformed<T>{};
template <class T> inline constexpr T pi_v = __illformed<T>{};
template <class T> inline constexpr T inv_pi_v = __illformed<T>{};
template <class T> inline constexpr T inv_sqrtpi_v = __illformed<T>{};
template <class T> inline constexpr T ln2_v = __illformed<T>{};
template <class T> inline constexpr T ln10_v = __illformed<T>{};
template <class T> inline constexpr T sqrt2_v = __illformed<T>{};
template <class T> inline constexpr T sqrt3_v = __illformed<T>{};
template <class T> inline constexpr T inv_sqrt3_v = __illformed<T>{};
template <class T> inline constexpr T egamma_v = __illformed<T>{};
template <class T> inline constexpr T phi_v = __illformed<T>{};
template <class T>
concept __floating_point = std::is_floating_point_v<T>;
template <__floating_point T> inline constexpr T e_v<T> = 2.718281828459045235360287471352662;
template <__floating_point T> inline constexpr T log2e_v<T> = 1.442695040888963407359924681001892;
template <__floating_point T> inline constexpr T log10e_v<T> = 0.434294481903251827651128918916605;
template <__floating_point T> inline constexpr T pi_v<T> = 3.141592653589793238462643383279502;
template <__floating_point T> inline constexpr T inv_pi_v<T> = 0.318309886183790671537767526745028;
template <__floating_point T> inline constexpr T inv_sqrtpi_v<T> = 0.564189583547756286948079451560772;
template <__floating_point T> inline constexpr T ln2_v<T> = 0.693147180559945309417232121458176;
template <__floating_point T> inline constexpr T ln10_v<T> = 2.302585092994045684017991454684364;
template <__floating_point T> inline constexpr T sqrt2_v<T> = 1.414213562373095048801688724209698;
template <__floating_point T> inline constexpr T sqrt3_v<T> = 1.732050807568877293527446341505872;
template <__floating_point T> inline constexpr T inv_sqrt3_v<T> = 0.577350269189625764509148780501957;
template <__floating_point T> inline constexpr T egamma_v<T> = 0.577215664901532860606512090082402;
template <__floating_point T> inline constexpr T phi_v<T> = 1.618033988749894848204586834365638;
inline constexpr double e = e_v<double>;
inline constexpr double log2e = log2e_v<double>;
inline constexpr double log10e = log10e_v<double>;
inline constexpr double pi = pi_v<double>;
inline constexpr double inv_pi = inv_pi_v<double>;
inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
inline constexpr double ln2 = ln2_v<double>;
inline constexpr double ln10 = ln10_v<double>;
inline constexpr double sqrt2 = sqrt2_v<double>;
inline constexpr double sqrt3 = sqrt3_v<double>;
inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
inline constexpr double egamma = egamma_v<double>;
inline constexpr double phi = phi_v<double>;
} // namespace numbers
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif //_LIBCPP_STD_VER > 17 && defined(__cpp_concepts) && __cpp_concepts >= 201811L
#endif // _LIBCPP_NUMBERS
+3 -3
View File
@@ -999,7 +999,7 @@ basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir)
}
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
inline
basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{
@@ -1009,7 +1009,7 @@ endl(basic_ostream<_CharT, _Traits>& __os)
}
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
inline
basic_ostream<_CharT, _Traits>&
ends(basic_ostream<_CharT, _Traits>& __os)
{
@@ -1018,7 +1018,7 @@ ends(basic_ostream<_CharT, _Traits>& __os)
}
template <class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
inline
basic_ostream<_CharT, _Traits>&
flush(basic_ostream<_CharT, _Traits>& __os)
{
+5
View File
@@ -4048,10 +4048,12 @@ binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)
result_type __rd = __ru;
while (true)
{
bool __break = true;
if (__rd >= 1)
{
__pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1));
__u -= __pd;
__break = false;
if (__u < 0)
return __rd - 1;
}
@@ -4062,9 +4064,12 @@ binomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)
{
__pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru;
__u -= __pu;
__break = false;
if (__u < 0)
return __ru;
}
if (__break)
return 0;
}
}
+47 -21
View File
@@ -21,7 +21,7 @@ namespace std
namespace regex_constants
{
emum syntax_option_type
enum syntax_option_type
{
icase = unspecified,
nosubs = unspecified,
@@ -631,7 +631,7 @@ template <class OutputIterator, class BidirectionalIterator,
const basic_regex<charT, traits>& e, const charT* fmt,
regex_constants::match_flag_type flags = regex_constants::match_default);
template <class traits, class charT, class ST, class SA, class FST, class FSA>>
template <class traits, class charT, class ST, class SA, class FST, class FSA>
basic_string<charT, ST, SA>
regex_replace(const basic_string<charT, ST, SA>& s,
const basic_regex<charT, traits>& e,
@@ -675,9 +675,9 @@ public:
regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type& re,
regex_constants::match_flag_type m = regex_constants::match_default);
regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
const regex_type&& __re,
regex_constants::match_flag_type __m
regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type&& re,
regex_constants::match_flag_type m
= regex_constants::match_default) = delete; // C++14
regex_iterator(const regex_iterator&);
regex_iterator& operator=(const regex_iterator&);
@@ -698,7 +698,7 @@ typedef regex_iterator<string::const_iterator> sregex_iterator;
typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
template <class BidirectionalIterator,
class charT = typename iterator_traits< BidirectionalIterator>::value_type,
class charT = typename iterator_traits<BidirectionalIterator>::value_type,
class traits = regex_traits<charT>>
class regex_token_iterator
{
@@ -735,8 +735,8 @@ public:
regex_constants::match_flag_type m = regex_constants::match_default);
template <size_t N>
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type& re, const int (&submatches)[N],
regex_constants::match_flag_type m = regex_constants::match_default) = delete // C++14;
const regex_type&& re, const int (&submatches)[N],
regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
regex_token_iterator(const regex_token_iterator&);
regex_token_iterator& operator=(const regex_token_iterator&);
@@ -977,7 +977,8 @@ class _LIBCPP_EXCEPTION_ABI regex_error
regex_constants::error_type __code_;
public:
explicit regex_error(regex_constants::error_type __ecode);
virtual ~regex_error() throw();
regex_error(const regex_error&) _NOEXCEPT = default;
virtual ~regex_error() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
regex_constants::error_type code() const {return __code_;}
};
@@ -1000,7 +1001,19 @@ public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
typedef locale locale_type;
#ifdef __BIONIC__
// Originally bionic's ctype_base used its own ctype masks because the
// builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
// was only 8 bits wide and already saturated, so it used a wider type here
// to make room for __regex_word (then a part of this class rather than
// ctype_base). Bionic has since moved to the builtin ctype_base
// implementation, but this was not updated to match. Since then Android has
// needed to maintain a stable libc++ ABI, and this can't be changed without
// an ABI break.
typedef uint16_t char_class_type;
#else
typedef ctype_base::mask char_class_type;
#endif
static const char_class_type __regex_word = ctype_base::__regex_word;
private:
@@ -2837,6 +2850,8 @@ private:
__parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,
basic_string<_CharT>* __str = nullptr);
bool __test_back_ref(_CharT c);
_LIBCPP_INLINE_VISIBILITY
void __push_l_anchor();
void __push_r_anchor();
@@ -3408,18 +3423,8 @@ basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,
if (__first != __last)
{
_ForwardIterator __temp = _VSTD::next(__first);
if (__temp != __last)
{
if (*__first == '\\')
{
int __val = __traits_.value(*__temp, 10);
if (__val >= 1 && __val <= 9)
{
__push_back_ref(__val);
__first = ++__temp;
}
}
}
if (__temp != __last && *__first == '\\' && __test_back_ref(*__temp))
__first = ++__temp;
}
return __first;
}
@@ -3547,6 +3552,8 @@ basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,
default:
if (__get_grammar(__flags_) == awk)
__first = __parse_awk_escape(++__first, __last);
else if(__test_back_ref(*__temp))
__first = ++__temp;
break;
}
}
@@ -4660,6 +4667,22 @@ basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first,
return __first;
}
template <class _CharT, class _Traits>
bool
basic_regex<_CharT, _Traits>::__test_back_ref(_CharT c)
{
unsigned __val = __traits_.value(c, 10);
if (__val >= 1 && __val <= 9)
{
if (__val > mark_count())
__throw_regex_error<regex_constants::error_backref>();
__push_back_ref(__val);
return true;
}
return false;
}
template <class _CharT, class _Traits>
void
basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,
@@ -5917,6 +5940,9 @@ basic_regex<_CharT, _Traits>::__search(
match_results<const _CharT*, _Allocator>& __m,
regex_constants::match_flag_type __flags) const
{
if (__flags & regex_constants::match_prev_avail)
__flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow);
__m.__init(1 + mark_count(), __first, __last,
__flags & regex_constants::__no_update_pos);
if (__match_at_start(__first, __last, __m, __flags,
+235
View File
@@ -0,0 +1,235 @@
// -*- C++ -*-
//===--------------------------- semaphore --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_SEMAPHORE
#define _LIBCPP_SEMAPHORE
/*
semaphore synopsis
namespace std {
template<ptrdiff_t least_max_value = implementation-defined>
class counting_semaphore
{
public:
static constexpr ptrdiff_t max() noexcept;
constexpr explicit counting_semaphore(ptrdiff_t desired);
~counting_semaphore();
counting_semaphore(const counting_semaphore&) = delete;
counting_semaphore& operator=(const counting_semaphore&) = delete;
void release(ptrdiff_t update = 1);
void acquire();
bool try_acquire() noexcept;
template<class Rep, class Period>
bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
template<class Clock, class Duration>
bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
private:
ptrdiff_t counter; // exposition only
};
using binary_semaphore = counting_semaphore<1>;
}
*/
#include <__config>
#include <__threading_support>
#include <atomic>
#include <cassert>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#ifdef _LIBCPP_HAS_NO_THREADS
# error <semaphore> is not supported on this single threaded system
#endif
#if _LIBCPP_STD_VER >= 14
_LIBCPP_BEGIN_NAMESPACE_STD
/*
__atomic_semaphore_base is the general-case implementation, to be used for
user-requested least-max values that exceed the OS implementation support
(incl. when the OS has no support of its own) and for binary semaphores.
It is a typical Dijsktra semaphore algorithm over atomics, wait and notify
functions. It avoids contention against users' own use of those facilities.
*/
class __atomic_semaphore_base
{
__atomic_base<ptrdiff_t> __a;
public:
_LIBCPP_INLINE_VISIBILITY
__atomic_semaphore_base(ptrdiff_t __count) : __a(__count)
{
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void release(ptrdiff_t __update = 1)
{
if(0 < __a.fetch_add(__update, memory_order_release))
;
else if(__update > 1)
__a.notify_all();
else
__a.notify_one();
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void acquire()
{
auto const __test_fn = [=]() -> bool {
auto __old = __a.load(memory_order_relaxed);
return (__old != 0) && __a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed);
};
__cxx_atomic_wait(&__a.__a_, __test_fn);
}
template <class Rep, class Period>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
{
auto const __test_fn = [=]() -> bool {
auto __old = __a.load(memory_order_acquire);
while(1) {
if (__old == 0)
return false;
if(__a.compare_exchange_strong(__old, __old - 1, memory_order_acquire, memory_order_relaxed))
return true;
}
};
return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time);
}
};
#ifndef _LIBCPP_NO_NATIVE_SEMAPHORES
/*
__platform_semaphore_base a simple wrapper for the OS semaphore type. That
is, every call is routed to the OS in the most direct manner possible.
*/
class __platform_semaphore_base
{
__libcpp_semaphore_t __semaphore;
public:
_LIBCPP_INLINE_VISIBILITY
__platform_semaphore_base(ptrdiff_t __count) :
__semaphore()
{
__libcpp_semaphore_init(&__semaphore, __count);
}
_LIBCPP_INLINE_VISIBILITY
~__platform_semaphore_base() {
__libcpp_semaphore_destroy(&__semaphore);
}
_LIBCPP_INLINE_VISIBILITY
void release(ptrdiff_t __update)
{
for(; __update; --__update)
__libcpp_semaphore_post(&__semaphore);
}
_LIBCPP_INLINE_VISIBILITY
void acquire()
{
__libcpp_semaphore_wait(&__semaphore);
}
_LIBCPP_INLINE_VISIBILITY
bool try_acquire_for(chrono::nanoseconds __rel_time)
{
return __libcpp_semaphore_wait_timed(&__semaphore, __rel_time);
}
};
template<ptrdiff_t __least_max_value>
using __semaphore_base =
typename conditional<(__least_max_value > 1 && __least_max_value <= _LIBCPP_SEMAPHORE_MAX),
__platform_semaphore_base,
__atomic_semaphore_base>::type;
#else
template<ptrdiff_t __least_max_value>
using __semaphore_base =
__atomic_semaphore_base;
#define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max())
#endif //_LIBCPP_NO_NATIVE_SEMAPHORES
template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX>
class counting_semaphore
{
__semaphore_base<__least_max_value> __semaphore;
public:
static constexpr ptrdiff_t max() noexcept {
return __least_max_value;
}
_LIBCPP_INLINE_VISIBILITY
counting_semaphore(ptrdiff_t __count = 0) : __semaphore(__count) { }
~counting_semaphore() = default;
counting_semaphore(const counting_semaphore&) = delete;
counting_semaphore& operator=(const counting_semaphore&) = delete;
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void release(ptrdiff_t __update = 1)
{
__semaphore.release(__update);
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
void acquire()
{
__semaphore.acquire();
}
template<class Rep, class Period>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time)
{
return __semaphore.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time));
}
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire()
{
return try_acquire_for(chrono::nanoseconds::zero());
}
template <class Clock, class Duration>
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time)
{
auto const current = Clock::now();
if(current >= __abs_time)
return try_acquire();
else
return try_acquire_for(__abs_time - current);
}
};
using binary_semaphore = counting_semaphore<1>;
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_STD_VER >= 14
#endif //_LIBCPP_SEMAPHORE
+12 -6
View File
@@ -216,7 +216,8 @@ swap(set<Key, Compare, Allocator>& x, set<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class Compare, class Allocator, class Predicate>
void erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
typename set<Key, Compare, Allocator>::size_type
erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // C++20
template <class Key, class Compare = less<Key>,
class Allocator = allocator<Key>>
@@ -417,7 +418,8 @@ swap(multiset<Key, Compare, Allocator>& x, multiset<Key, Compare, Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class Key, class Compare, class Allocator, class Predicate>
void erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
typename multiset<Key, Compare, Allocator>::size_type
erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20
} // std
@@ -960,8 +962,10 @@ swap(set<_Key, _Compare, _Allocator>& __x,
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename set<_Key, _Compare, _Allocator>::size_type
erase_if(set<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
template <class _Key, class _Compare = less<_Key>,
@@ -1484,8 +1488,10 @@ swap(multiset<_Key, _Compare, _Allocator>& __x,
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Compare, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename multiset<_Key, _Compare, _Allocator>::size_type
erase_if(multiset<_Key, _Compare, _Allocator>& __c, _Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
_LIBCPP_END_NAMESPACE_STD
+64 -106
View File
@@ -46,15 +46,13 @@ public:
using reference = element_type&;
using const_reference = const element_type&;
using iterator = implementation-defined;
using const_iterator = implementation-defined;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
static constexpr size_type extent = Extent;
// [span.cons], span constructors, copy, assignment, and destructor
constexpr span() noexcept;
constexpr span(pointer ptr, size_type count);
constexpr span(pointer firstElem, pointer lastElem);
constexpr explicit(Extent != dynamic_extent) span(pointer ptr, size_type count);
constexpr explicit(Extent != dynamic_extent) span(pointer firstElem, pointer lastElem);
template <size_t N>
constexpr span(element_type (&arr)[N]) noexcept;
template <size_t N>
@@ -62,12 +60,12 @@ public:
template <size_t N>
constexpr span(const array<value_type, N>& arr) noexcept;
template <class Container>
constexpr span(Container& cont);
constexpr explicit(Extent != dynamic_extent) span(Container& cont);
template <class Container>
constexpr span(const Container& cont);
constexpr explicit(Extent != dynamic_extent) span(const Container& cont);
constexpr span(const span& other) noexcept = default;
template <class OtherElementType, size_t OtherExtent>
constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;
~span() noexcept = default;
constexpr span& operator=(const span& other) noexcept = default;
@@ -97,12 +95,8 @@ public:
// [span.iterators], span iterator support
constexpr iterator begin() const noexcept;
constexpr iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr reverse_iterator rbegin() const noexcept;
constexpr reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
private:
pointer data_; // exposition only
@@ -129,11 +123,10 @@ template<class Container>
*/
#include <__config>
#include <cstddef> // for ptrdiff_t
#include <iterator> // for iterators
#include <array> // for array
#include <type_traits> // for remove_cv, etc
#include <cstddef> // for byte
#include <iterator> // for iterators
#include <type_traits> // for remove_cv, etc
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
@@ -143,7 +136,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
inline constexpr size_t dynamic_extent = (numeric_limits<size_t>::max)();
template <typename _Tp, size_t _Extent = dynamic_extent> class span;
@@ -202,27 +195,49 @@ public:
using reference = _Tp &;
using const_reference = const _Tp &;
using iterator = __wrap_iter<pointer>;
using const_iterator = __wrap_iter<const_pointer>;
using reverse_iterator = _VSTD::reverse_iterator<iterator>;
using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
static constexpr size_type extent = _Extent;
// [span.cons], span constructors, copy, assignment, and destructor
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}
{ static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); }
template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {}
constexpr span (const span&) noexcept = default;
constexpr span& operator=(const span&) noexcept = default;
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}
_LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, size_type __count) : __data{__ptr}
{ (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); }
_LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}
_LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) : __data{__f}
{ (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
_LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {}
_LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
_LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
template <class _OtherElementType,
enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY
constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
template <class _OtherElementType,
enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY
constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {}
template <class _Container>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span( _Container& __c,
enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)} {
_LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)");
}
template <class _Container>
_LIBCPP_INLINE_VISIBILITY
constexpr explicit span(const _Container& __c,
enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)} {
_LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)");
}
template <class _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
@@ -234,7 +249,7 @@ public:
template <class _OtherElementType>
_LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, dynamic_extent>& __other,
constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other,
enable_if_t<
is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
nullptr_t> = nullptr) noexcept
@@ -248,7 +263,7 @@ public:
constexpr span<element_type, _Count> first() const noexcept
{
static_assert(_Count <= _Extent, "Count out of range in span::first()");
return {data(), _Count};
return span<element_type, _Count>{data(), _Count};
}
template <size_t _Count>
@@ -256,7 +271,7 @@ public:
constexpr span<element_type, _Count> last() const noexcept
{
static_assert(_Count <= _Extent, "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
@@ -279,7 +294,10 @@ public:
-> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
{
static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()");
return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()");
using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>;
return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
@@ -291,7 +309,7 @@ public:
_LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
_LIBCPP_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
@@ -301,19 +319,19 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds");
_LIBCPP_ASSERT(__idx < size(), "span<T,N>[] index out of bounds");
return __data[__idx];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
{
static_assert(_Extent > 0, "span<T,N>[].front() on empty span");
_LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");
return __data[0];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
{
static_assert(_Extent > 0, "span<T,N>[].back() on empty span");
_LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");
return __data[size()-1];
}
@@ -322,25 +340,14 @@ public:
// [span.iter], span iterator support
_LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
_LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
{
pointer __p = __data;
__data = __other.__data;
__other.__data = __p;
}
_LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept
{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
{ return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; }
_LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept
{ return {reinterpret_cast<byte *>(data()), size_bytes()}; }
{ return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; }
private:
pointer __data;
@@ -363,9 +370,7 @@ public:
using reference = _Tp &;
using const_reference = const _Tp &;
using iterator = __wrap_iter<pointer>;
using const_iterator = __wrap_iter<const_pointer>;
using reverse_iterator = _VSTD::reverse_iterator<iterator>;
using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
static constexpr size_type extent = dynamic_extent;
@@ -382,13 +387,15 @@ public:
_LIBCPP_INLINE_VISIBILITY
constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
template <size_t _Sz>
template <class _OtherElementType, size_t _Sz,
enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY
constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <size_t _Sz>
template <class _OtherElementType, size_t _Sz,
enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr>
_LIBCPP_INLINE_VISIBILITY
constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
template <class _Container>
_LIBCPP_INLINE_VISIBILITY
@@ -418,7 +425,7 @@ public:
constexpr span<element_type, _Count> first() const noexcept
{
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
return {data(), _Count};
return span<element_type, _Count>{data(), _Count};
}
template <size_t _Count>
@@ -426,7 +433,7 @@ public:
constexpr span<element_type, _Count> last() const noexcept
{
_LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
return {data() + size() - _Count, _Count};
return span<element_type, _Count>{data() + size() - _Count, _Count};
}
_LIBCPP_INLINE_VISIBILITY
@@ -445,11 +452,11 @@ public:
template <size_t _Offset, size_t _Count = dynamic_extent>
_LIBCPP_INLINE_VISIBILITY
constexpr span<_Tp, dynamic_extent> subspan() const noexcept
constexpr span<element_type, _Count> subspan() const noexcept
{
_LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()");
_LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()");
return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
_LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "Offset + count out of range in span::subspan()");
return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
}
constexpr span<element_type, dynamic_extent>
@@ -460,7 +467,7 @@ public:
_LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");
if (__count == dynamic_extent)
return {data() + __offset, size() - __offset};
_LIBCPP_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)");
_LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)");
return {data() + __offset, __count};
}
@@ -470,7 +477,7 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept
{
_LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds");
_LIBCPP_ASSERT(__idx < size(), "span<T>[] index out of bounds");
return __data[__idx];
}
@@ -492,23 +499,8 @@ public:
// [span.iter], span iterator support
_LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
_LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
_LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
_LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
{
pointer __p = __data;
__data = __other.__data;
__other.__data = __p;
size_type __sz = __size;
__size = __other.__size;
__other.__size = __sz;
}
_LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept
{ return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
@@ -521,34 +513,6 @@ private:
size_type __size;
};
// tuple interface
template <class _Tp, size_t _Size>
struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, _Size>>
: public integral_constant<size_t, _Size> {};
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, dynamic_extent>>; // declared but not defined
template <size_t _Ip, class _Tp, size_t _Size>
struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>>
{
static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span<T, dynamic_extent>");
static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)");
typedef _Tp type;
};
template <size_t _Ip, class _Tp, size_t _Size>
_LIBCPP_INLINE_VISIBILITY constexpr
_Tp&
get(span<_Tp, _Size> __s) noexcept
{
static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span<T, dynamic_extent>");
static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)");
return __s[_Ip];
}
// as_bytes & as_writable_bytes
template <class _Tp, size_t _Extent>
_LIBCPP_INLINE_VISIBILITY
@@ -562,12 +526,6 @@ auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
-> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())>
{ return __s.__as_writable_bytes(); }
template <class _Tp, size_t _Extent>
_LIBCPP_INLINE_VISIBILITY
constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept
{ __lhs.swap(__rhs); }
// Deduction guides
template<class _Tp, size_t _Sz>
span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
+1 -7
View File
@@ -31,7 +31,7 @@ Types:
ptrdiff_t
size_t
max_align_t
max_align_t // C++11
nullptr_t
*/
@@ -51,12 +51,6 @@ extern "C++" {
using std::nullptr_t;
}
// Re-use the compiler's <stddef.h> max_align_t where possible.
#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \
!defined(__DEFINED_max_align_t) && !defined(__NetBSD__)
typedef long double max_align_t;
#endif
#endif
#endif // _LIBCPP_STDDEF_H
+7
View File
@@ -129,6 +129,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s) : logic_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
domain_error(const domain_error&) _NOEXCEPT = default;
virtual ~domain_error() _NOEXCEPT;
#endif
};
@@ -141,6 +142,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s) : logic_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
invalid_argument(const invalid_argument&) _NOEXCEPT = default;
virtual ~invalid_argument() _NOEXCEPT;
#endif
};
@@ -152,6 +154,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {}
_LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s) : logic_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
length_error(const length_error&) _NOEXCEPT = default;
virtual ~length_error() _NOEXCEPT;
#endif
};
@@ -164,6 +167,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s) : logic_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
out_of_range(const out_of_range&) _NOEXCEPT = default;
virtual ~out_of_range() _NOEXCEPT;
#endif
};
@@ -176,6 +180,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s) : runtime_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
range_error(const range_error&) _NOEXCEPT = default;
virtual ~range_error() _NOEXCEPT;
#endif
};
@@ -188,6 +193,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s) : runtime_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
overflow_error(const overflow_error&) _NOEXCEPT = default;
virtual ~overflow_error() _NOEXCEPT;
#endif
};
@@ -200,6 +206,7 @@ public:
_LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s) : runtime_error(__s) {}
#ifndef _LIBCPP_ABI_VCRUNTIME
underflow_error(const underflow_error&) _NOEXCEPT = default;
virtual ~underflow_error() _NOEXCEPT;
#endif
};
+58 -6
View File
@@ -7,16 +7,12 @@
//
//===----------------------------------------------------------------------===//
#if defined(__need_malloc_and_calloc) || defined(_LIBCPP_STDLIB_INCLUDE_NEXT)
#if defined(__need_malloc_and_calloc)
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#if defined(_LIBCPP_STDLIB_INCLUDE_NEXT)
#undef _LIBCPP_STDLIB_INCLUDE_NEXT
#endif
#include_next <stdlib.h>
#elif !defined(_LIBCPP_STDLIB_H)
@@ -97,7 +93,63 @@ void *aligned_alloc(size_t alignment, size_t size); // C11
#include_next <stdlib.h>
#ifdef __cplusplus
#include <math.h>
extern "C++" {
// abs
#undef abs
#undef labs
#ifndef _LIBCPP_HAS_NO_LONG_LONG
#undef llabs
#endif
// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT {
return __builtin_labs(__x);
}
#ifndef _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {
return __builtin_llabs(__x);
}
#endif // _LIBCPP_HAS_NO_LONG_LONG
#endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
#if !(defined(_AIX) || defined(__sun__))
inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {
return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h
}
inline _LIBCPP_INLINE_VISIBILITY double abs(double __lcpp_x) _NOEXCEPT {
return __builtin_fabs(__lcpp_x);
}
inline _LIBCPP_INLINE_VISIBILITY long double
abs(long double __lcpp_x) _NOEXCEPT {
return __builtin_fabsl(__lcpp_x);
}
#endif // !(defined(_AIX) || defined(__sun__))
// div
#undef div
#undef ldiv
#ifndef _LIBCPP_HAS_NO_LONG_LONG
#undef lldiv
#endif
// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT {
return ::ldiv(__x, __y);
}
#ifndef _LIBCPP_HAS_NO_LONG_LONG
inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x,
long long __y) _NOEXCEPT {
return ::lldiv(__x, __y);
}
#endif // _LIBCPP_HAS_NO_LONG_LONG
#endif // _LIBCPP_MSVCRT / __sun__ / _AIX
} // extern "C++"
#endif // __cplusplus
#endif // _LIBCPP_STDLIB_H
+313 -185
View File
@@ -437,9 +437,11 @@ basic_istream<charT, traits>&
getline(basic_istream<charT, traits>& is, basic_string<charT, traits, Allocator>& str);
template<class charT, class traits, class Allocator, class U>
void erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
typename basic_string<charT, traits, Allocator>::size_type
erase(basic_string<charT, traits, Allocator>& c, const U& value); // C++20
template<class charT, class traits, class Allocator, class Predicate>
void erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
typename basic_string<charT, traits, Allocator>::size_type
erase_if(basic_string<charT, traits, Allocator>& c, Predicate pred); // C++20
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
@@ -643,9 +645,10 @@ struct __libcpp_string_gets_noexcept_iterator
: public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value || __libcpp_string_gets_noexcept_iterator_impl<_Iter>::value) {};
template <class _CharT, class _Traits, class _Tp>
struct __can_be_converted_to_string_view : public _LIBCPP_BOOL_CONSTANT(
( is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
!is_convertible<const _Tp&, const _CharT*>::value)) {};
struct __can_be_converted_to_string_view : public _BoolConstant<
is_convertible<const _Tp&, basic_string_view<_CharT, _Traits> >::value &&
!is_convertible<const _Tp&, const _CharT*>::value
> {};
#ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
@@ -688,13 +691,8 @@ public:
static_assert(( is_same<typename allocator_type::value_type, value_type>::value),
"Allocator::value_type must be same type as value_type");
#if defined(_LIBCPP_RAW_ITERATORS)
typedef pointer iterator;
typedef const_pointer const_iterator;
#else // defined(_LIBCPP_RAW_ITERATORS)
typedef __wrap_iter<pointer> iterator;
typedef __wrap_iter<const_pointer> const_iterator;
#endif // defined(_LIBCPP_RAW_ITERATORS)
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -784,6 +782,7 @@ private:
__compressed_pair<__rep, allocator_type> __r_;
public:
_LIBCPP_FUNC_VIS
static const size_type npos = -1;
_LIBCPP_INLINE_VISIBILITY basic_string()
@@ -812,7 +811,7 @@ public:
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_CXX03_LANG
template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
_LIBCPP_INLINE_VISIBILITY
basic_string(const _CharT* __s) : __r_(__default_init_tag(), __default_init_tag()) {
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
@@ -822,7 +821,7 @@ public:
# endif
}
template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
_LIBCPP_INLINE_VISIBILITY
basic_string(const _CharT* __s, const _Allocator& __a);
@@ -833,7 +832,7 @@ public:
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, _CharT __c);
template <class = typename enable_if<__is_allocator<_Allocator>::value, nullptr_t>::type>
template <class = _EnableIf<__is_allocator<_Allocator>::value, nullptr_t> >
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, _CharT __c, const _Allocator& __a);
@@ -843,23 +842,24 @@ public:
basic_string(const basic_string& __str, size_type __pos,
const _Allocator& __a = _Allocator());
template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
basic_string(const _Tp& __t, size_type __pos, size_type __n,
const allocator_type& __a = allocator_type());
const allocator_type& __a = allocator_type());
template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
!__is_same_uncvref<_Tp, basic_string>::value> >
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
explicit basic_string(const _Tp& __t);
template<class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
template<class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
explicit basic_string(const _Tp& __t, const allocator_type& __a);
template<class _InputIterator, class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value>::type>
template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> >
_LIBCPP_INLINE_VISIBILITY
basic_string(_InputIterator __first, _InputIterator __last);
template<class _InputIterator, class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value>::type>
template<class _InputIterator, class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value> >
_LIBCPP_INLINE_VISIBILITY
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
#ifndef _LIBCPP_CXX03_LANG
@@ -876,7 +876,7 @@ public:
basic_string& operator=(const basic_string& __str);
template <class _Tp, class = typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type>
template <class _Tp, class = _EnableIf<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value> >
basic_string& operator=(const _Tp& __t)
{__self_view __sv = __t; return assign(__sv);}
@@ -976,11 +976,12 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string >::value,
basic_string&
>::type
>
operator+=(const _Tp& __t) {__self_view __sv = __t; return append(__sv);}
_LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);}
_LIBCPP_INLINE_VISIBILITY basic_string& operator+=(value_type __c) {push_back(__c); return *this;}
@@ -993,21 +994,22 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
_EnableIf<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>::type
>
append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); }
basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>::type
>
append(const _Tp& __t, size_type __pos, size_type __n=npos);
basic_string& append(const value_type* __s, size_type __n);
basic_string& append(const value_type* __s);
@@ -1021,12 +1023,12 @@ public:
basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator);
template<class _InputIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
basic_string&
>::type
>
_LIBCPP_INLINE_VISIBILITY
append(_InputIterator __first, _InputIterator __last) {
const basic_string __temp (__first, __last, __alloc());
@@ -1035,12 +1037,12 @@ public:
}
template<class _ForwardIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
basic_string&
>::type
>
_LIBCPP_INLINE_VISIBILITY
append(_ForwardIterator __first, _ForwardIterator __last) {
return __append_forward_unsafe(__first, __last);
@@ -1061,11 +1063,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>::type
>
assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); }
_LIBCPP_INLINE_VISIBILITY
basic_string& assign(const basic_string& __str) { return *this = __str; }
@@ -1078,32 +1080,33 @@ public:
basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos);
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>::type
>
assign(const _Tp & __t, size_type __pos, size_type __n=npos);
basic_string& assign(const value_type* __s, size_type __n);
basic_string& assign(const value_type* __s);
basic_string& assign(size_type __n, value_type __c);
template<class _InputIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
basic_string&
>::type
>
assign(_InputIterator __first, _InputIterator __last);
template<class _ForwardIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
basic_string&
>::type
>
assign(_ForwardIterator __first, _ForwardIterator __last);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
@@ -1115,21 +1118,21 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>::type
>
insert(size_type __pos1, const _Tp& __t)
{ __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); }
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>::type
>
insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos);
basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos);
basic_string& insert(size_type __pos, const value_type* __s, size_type __n);
@@ -1140,21 +1143,21 @@ public:
iterator insert(const_iterator __pos, size_type __n, value_type __c);
template<class _InputIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
iterator
>::type
>
insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
template<class _ForwardIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
iterator
>::type
>
insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
@@ -1173,20 +1176,20 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>::type
>
replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); }
basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos);
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
basic_string&
>::type
>
replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos);
basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
basic_string& replace(size_type __pos, size_type __n1, const value_type* __s);
@@ -1196,11 +1199,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
basic_string&
>::type
>
replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); }
_LIBCPP_INLINE_VISIBILITY
@@ -1211,11 +1214,11 @@ public:
basic_string& replace(const_iterator __i1, const_iterator __i2, size_type __n, value_type __c);
template<class _InputIterator>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__is_cpp17_input_iterator<_InputIterator>::value,
basic_string&
>::type
>
replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
@@ -1253,11 +1256,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>::type
>
find(const _Tp& __t, size_type __pos = 0) const;
size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -1269,11 +1272,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>::type
>
rfind(const _Tp& __t, size_type __pos = npos) const;
size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -1285,11 +1288,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>::type
>
find_first_of(const _Tp& __t, size_type __pos = 0) const;
size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -1302,11 +1305,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>::type
>
find_last_of(const _Tp& __t, size_type __pos = npos) const;
size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -1319,11 +1322,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>::type
>
find_first_not_of(const _Tp &__t, size_type __pos = 0) const;
size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -1336,11 +1339,11 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
size_type
>::type
>
find_last_not_of(const _Tp& __t, size_type __pos = npos) const;
size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
@@ -1353,20 +1356,20 @@ public:
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
int
>::type
>
compare(const _Tp &__t) const;
template <class _Tp>
_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
int
>::type
>
compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
_LIBCPP_INLINE_VISIBILITY
@@ -1375,11 +1378,11 @@ public:
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value,
int
>::type
>
compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const;
int compare(const value_type* __s) const _NOEXCEPT;
int compare(size_type __pos1, size_type __n1, const value_type* __s) const;
@@ -1543,22 +1546,30 @@ private:
inline
void __init(size_type __n, value_type __c);
// Slow path for the (inlined) copy constructor for 'long' strings.
// Always externally instantiated and not inlined.
// Requires that __s is zero terminated.
// The main reason for this function to exist is because for unstable, we
// want to allow inlining of the copy constructor. However, we don't want
// to call the __init() functions as those are marked as inline which may
// result in over-aggressive inlining by the compiler, where our aim is
// to only inline the fast path code directly in the ctor.
void __init_copy_ctor_external(const value_type* __s, size_type __sz);
template <class _InputIterator>
inline
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
void
>::type
__is_exactly_cpp17_input_iterator<_InputIterator>::value
>
__init(_InputIterator __first, _InputIterator __last);
template <class _ForwardIterator>
inline
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
void
>::type
__is_cpp17_forward_iterator<_ForwardIterator>::value
>
__init(_ForwardIterator __first, _ForwardIterator __last);
void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz,
@@ -1567,9 +1578,19 @@ private:
size_type __n_copy, size_type __n_del,
size_type __n_add, const value_type* __p_new_stuff);
// __assign_no_alias is invoked for assignment operations where we
// have proof that the input does not alias the current instance.
// For example, operator=(basic_string) performs a 'self' check.
template <bool __is_short>
basic_string& __assign_no_alias(const value_type* __s, size_type __n);
_LIBCPP_INLINE_VISIBILITY
void __erase_to_end(size_type __pos);
// __erase_external_with_move is invoked for erase() invocations where
// `n ~= npos`, likely requiring memory moves on the string data.
void __erase_external_with_move(size_type __pos, size_type __n);
_LIBCPP_INLINE_VISIBILITY
void __copy_assign_alloc(const basic_string& __str)
{__copy_assign_alloc(__str, integral_constant<bool,
@@ -1638,6 +1659,19 @@ private:
_NOEXCEPT
{}
basic_string& __assign_external(const value_type* __s);
basic_string& __assign_external(const value_type* __s, size_type __n);
// Assigns the value in __s, guaranteed to be __n < __min_cap in length.
inline basic_string& __assign_short(const value_type* __s, size_type __n) {
pointer __p = __is_long()
? (__set_long_size(__n), __get_long_pointer())
: (__set_short_size(__n), __get_short_pointer());
traits_type::move(_VSTD::__to_address(__p), __s, __n);
traits_type::assign(__p[__n], value_type());
return *this;
}
_LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators();
_LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(size_type);
@@ -1648,12 +1682,23 @@ private:
friend basic_string operator+<>(const basic_string&, value_type);
};
// These declarations must appear before any functions are implicitly used
// so that they have the correct visibility specifier.
#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char)
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
#else
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, char)
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE, wchar_t)
#endif
#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
template<class _InputIterator,
class _CharT = typename iterator_traits<_InputIterator>::value_type,
class _Allocator = allocator<_CharT>,
class = typename enable_if<__is_cpp17_input_iterator<_InputIterator>::value, void>::type,
class = typename enable_if<__is_allocator<_Allocator>::value, void>::type
class = _EnableIf<__is_cpp17_input_iterator<_InputIterator>::value>,
class = _EnableIf<__is_allocator<_Allocator>::value>
>
basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
-> basic_string<_CharT, char_traits<_CharT>, _Allocator>;
@@ -1661,7 +1706,7 @@ basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator())
template<class _CharT,
class _Traits,
class _Allocator = allocator<_CharT>,
class = typename enable_if<__is_allocator<_Allocator>::value, void>::type
class = _EnableIf<__is_allocator<_Allocator>::value>
>
explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
-> basic_string<_CharT, _Traits, _Allocator>;
@@ -1669,14 +1714,13 @@ explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _A
template<class _CharT,
class _Traits,
class _Allocator = allocator<_CharT>,
class = typename enable_if<__is_allocator<_Allocator>::value, void>::type,
class = _EnableIf<__is_allocator<_Allocator>::value>,
class _Sz = typename allocator_traits<_Allocator>::size_type
>
basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _Allocator())
-> basic_string<_CharT, _Traits, _Allocator>;
#endif
template <class _CharT, class _Traits, class _Allocator>
inline
void
@@ -1837,7 +1881,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
if (!__str.__is_long())
__r_.first().__r = __str.__r_.first().__r;
else
__init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
__init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()),
__str.__get_long_size());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
@@ -1851,12 +1897,32 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
if (!__str.__is_long())
__r_.first().__r = __str.__r_.first().__r;
else
__init(_VSTD::__to_address(__str.__get_long_pointer()), __str.__get_long_size());
__init_copy_ctor_external(_VSTD::__to_address(__str.__get_long_pointer()),
__str.__get_long_size());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
}
template <class _CharT, class _Traits, class _Allocator>
void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external(
const value_type* __s, size_type __sz) {
pointer __p;
if (__sz < __min_cap) {
__p = __get_short_pointer();
__set_short_size(__sz);
} else {
if (__sz > max_size())
this->__throw_length_error();
size_t __cap = __recommend(__sz);
__p = __alloc_traits::allocate(__alloc(), __cap + 1);
__set_long_pointer(__p);
__set_long_cap(__cap + 1);
__set_long_size(__sz);
}
traits_type::copy(_VSTD::__to_address(__p), __s, __sz + 1);
}
#ifndef _LIBCPP_CXX03_LANG
template <class _CharT, class _Traits, class _Allocator>
@@ -2014,11 +2080,10 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _
template <class _CharT, class _Traits, class _Allocator>
template <class _InputIterator>
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value,
void
>::type
__is_exactly_cpp17_input_iterator<_InputIterator>::value
>
basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last)
{
__zero();
@@ -2041,11 +2106,10 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input
template <class _CharT, class _Traits, class _Allocator>
template <class _ForwardIterator>
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value,
void
>::type
__is_cpp17_forward_iterator<_ForwardIterator>::value
>
basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last)
{
size_type __sz = static_cast<size_type>(_VSTD::distance(__first, __last));
@@ -2197,26 +2261,51 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t
// assign
template <class _CharT, class _Traits, class _Allocator>
template <bool __is_short>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias(
const value_type* __s, size_type __n) {
size_type __cap = __is_short ? __min_cap : __get_long_cap();
if (__n < __cap) {
pointer __p = __is_short ? __get_short_pointer() : __get_long_pointer();
__is_short ? __set_short_size(__n) : __set_long_size(__n);
traits_type::copy(_VSTD::__to_address(__p), __s, __n);
traits_type::assign(__p[__n], value_type());
__invalidate_iterators_past(__n);
} else {
size_type __sz = __is_short ? __get_short_size() : __get_long_size();
__grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s);
}
return *this;
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::__assign_external(
const value_type* __s, size_type __n) {
size_type __cap = capacity();
if (__cap >= __n) {
value_type* __p = _VSTD::__to_address(__get_pointer());
traits_type::move(__p, __s, __n);
traits_type::assign(__p[__n], value_type());
__set_size(__n);
__invalidate_iterators_past(__n);
} else {
size_type __sz = size();
__grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
}
return *this;
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr");
size_type __cap = capacity();
if (__cap >= __n)
{
value_type* __p = _VSTD::__to_address(__get_pointer());
traits_type::move(__p, __s, __n);
traits_type::assign(__p[__n], value_type());
__set_size(__n);
__invalidate_iterators_past(__n);
}
else
{
size_type __sz = size();
__grow_by_and_replace(__cap, __n - __cap, __sz, 0, __sz, __n, __s);
}
return *this;
return (_LIBCPP_BUILTIN_CONSTANT_P(__n) && __n < __min_cap)
? __assign_short(__s, __n)
: __assign_external(__s, __n);
}
template <class _CharT, class _Traits, class _Allocator>
@@ -2263,12 +2352,19 @@ template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str)
{
if (this != &__str)
{
__copy_assign_alloc(__str);
return assign(__str.data(), __str.size());
if (this != &__str) {
__copy_assign_alloc(__str);
if (!__is_long()) {
if (!__str.__is_long()) {
__r_.first().__r = __str.__r_.first().__r;
} else {
return __assign_no_alias<true>(__str.data(), __str.size());
}
} else {
return __assign_no_alias<false>(__str.data(), __str.size());
}
return *this;
}
return *this;
}
#ifndef _LIBCPP_CXX03_LANG
@@ -2326,12 +2422,12 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(basic_string&& __str)
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator <_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last)
{
const basic_string __temp(__first, __last, __alloc());
@@ -2341,12 +2437,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _Input
template <class _CharT, class _Traits, class _Allocator>
template<class _ForwardIterator>
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last)
{
size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last));
@@ -2378,11 +2474,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n)
{
__self_view __sv = __t;
@@ -2393,14 +2490,23 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
return __assign_external(__s, traits_type::length(__s));
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s)
{
_LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr");
return assign(__s, traits_type::length(__s));
return _LIBCPP_BUILTIN_CONSTANT_P(*__s)
? (traits_type::length(__s) < __min_cap
? __assign_short(__s, traits_type::length(__s))
: __assign_external(__s, traits_type::length(__s)))
: __assign_external(__s);
}
// append
template <class _CharT, class _Traits, class _Allocator>
@@ -2565,11 +2671,11 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n)
{
__self_view __sv = __t;
@@ -2654,12 +2760,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
typename enable_if
_EnableIf
<
__is_exactly_cpp17_input_iterator<_InputIterator>::value
|| !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value,
typename basic_string<_CharT, _Traits, _Allocator>::iterator
>::type
>
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -2673,12 +2779,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt
template <class _CharT, class _Traits, class _Allocator>
template<class _ForwardIterator>
typename enable_if
_EnableIf
<
__is_cpp17_forward_iterator<_ForwardIterator>::value
&& __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value,
typename basic_string<_CharT, _Traits, _Allocator>::iterator
>::type
>
basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -2743,11 +2849,11 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t,
size_type __pos2, size_type __n)
{
@@ -2852,8 +2958,8 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
}
traits_type::move(__p + __pos, __s, __n2);
__finish:
// __sz += __n2 - __n1; in this and the below function below can cause unsigned integer overflow,
// but this is a safe operation, so we disable the check.
// __sz += __n2 - __n1; in this and the below function below can cause unsigned
// integer overflow, but this is a safe operation, so we disable the check.
__sz += __n2 - __n1;
__set_size(__sz);
__invalidate_iterators_past(__sz);
@@ -2900,11 +3006,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
template <class _CharT, class _Traits, class _Allocator>
template<class _InputIterator>
typename enable_if
_EnableIf
<
__is_cpp17_input_iterator<_InputIterator>::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2,
_InputIterator __j1, _InputIterator __j2)
{
@@ -2933,11 +3039,11 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
basic_string<_CharT, _Traits, _Allocator>&
>::type
>
basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t,
size_type __pos2, size_type __n2)
{
@@ -2991,15 +3097,16 @@ basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_it
// erase
// 'externally instantiated' erase() implementation, called when __n != npos.
// Does not check __pos against size()
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
void
basic_string<_CharT, _Traits, _Allocator>::__erase_external_with_move(
size_type __pos, size_type __n)
{
size_type __sz = size();
if (__pos > __sz)
this->__throw_out_of_range();
if (__n)
{
size_type __sz = size();
value_type* __p = _VSTD::__to_address(__get_pointer());
__n = _VSTD::min(__n, __sz - __pos);
size_type __n_move = __sz - __pos - __n;
@@ -3010,7 +3117,19 @@ basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos, size_type __n)
__invalidate_iterators_past(__sz);
traits_type::assign(__p[__sz], value_type());
}
return *this;
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::erase(size_type __pos,
size_type __n) {
if (__pos > size()) this->__throw_out_of_range();
if (__n == npos) {
__erase_to_end(__pos);
} else {
__erase_external_with_move(__pos, __n);
}
return *this;
}
template <class _CharT, class _Traits, class _Allocator>
@@ -3356,11 +3475,11 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str,
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
typename basic_string<_CharT, _Traits, _Allocator>::size_type
>::type
>
basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t,
size_type __pos) const
{
@@ -3414,11 +3533,11 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str,
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
typename basic_string<_CharT, _Traits, _Allocator>::size_type
>::type
>
basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t,
size_type __pos) const
{
@@ -3472,11 +3591,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
typename basic_string<_CharT, _Traits, _Allocator>::size_type
>::type
>
basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t,
size_type __pos) const
{
@@ -3530,11 +3649,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
typename basic_string<_CharT, _Traits, _Allocator>::size_type
>::type
>
basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t,
size_type __pos) const
{
@@ -3588,11 +3707,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string&
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
typename basic_string<_CharT, _Traits, _Allocator>::size_type
>::type
>
basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t,
size_type __pos) const
{
@@ -3647,11 +3766,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string&
template<class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
typename basic_string<_CharT, _Traits, _Allocator>::size_type
>::type
>
basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t,
size_type __pos) const
{
@@ -3685,11 +3804,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c,
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
int
>::type
>
basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const
{
__self_view __sv = __t;
@@ -3739,11 +3858,11 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
int
>::type
>
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
const _Tp& __t) const
@@ -3764,11 +3883,12 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
template <class _CharT, class _Traits, class _Allocator>
template <class _Tp>
typename enable_if
_EnableIf
<
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value,
__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value
&& !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
int
>::type
>
basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1,
size_type __n1,
const _Tp& __t,
@@ -4230,8 +4350,9 @@ _LIBCPP_FUNC_VIS wstring to_wstring(double __val);
_LIBCPP_FUNC_VIS wstring to_wstring(long double __val);
template<class _CharT, class _Traits, class _Allocator>
const typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::npos;
_LIBCPP_FUNC_VIS
const typename basic_string<_CharT, _Traits, _Allocator>::size_type
basic_string<_CharT, _Traits, _Allocator>::npos;
template <class _CharT, class _Allocator>
struct _LIBCPP_TEMPLATE_VIS
@@ -4283,15 +4404,25 @@ getline(basic_istream<_CharT, _Traits>&& __is,
#endif // _LIBCPP_CXX03_LANG
#if _LIBCPP_STD_VER > 17
template<class _CharT, class _Traits, class _Allocator, class _Up>
template <class _CharT, class _Traits, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v)
{ __str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end()); }
typename basic_string<_CharT, _Traits, _Allocator>::size_type
erase(basic_string<_CharT, _Traits, _Allocator>& __str, const _Up& __v) {
auto __old_size = __str.size();
__str.erase(_VSTD::remove(__str.begin(), __str.end(), __v), __str.end());
return __old_size - __str.size();
}
template<class _CharT, class _Traits, class _Allocator, class _Predicate>
template <class _CharT, class _Traits, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(basic_string<_CharT, _Traits, _Allocator>& __str, _Predicate __pred)
{ __str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred), __str.end()); }
typename basic_string<_CharT, _Traits, _Allocator>::size_type
erase_if(basic_string<_CharT, _Traits, _Allocator>& __str,
_Predicate __pred) {
auto __old_size = __str.size();
__str.erase(_VSTD::remove_if(__str.begin(), __str.end(), __pred),
__str.end());
return __old_size - __str.size();
}
#endif
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -4330,9 +4461,6 @@ basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator*
#endif // _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_string<wchar_t>)
#if _LIBCPP_STD_VER > 11
// Literal suffixes for basic_string [basic.string.literals]
inline namespace literals
+1
View File
@@ -469,6 +469,7 @@ public:
system_error(int __ev, const error_category& __ecat, const string& __what_arg);
system_error(int __ev, const error_category& __ecat, const char* __what_arg);
system_error(int __ev, const error_category& __ecat);
system_error(const system_error&) _NOEXCEPT = default;
~system_error() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
+13 -17
View File
@@ -241,12 +241,19 @@ public:
#endif
~thread();
#ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {__t.__t_ = _LIBCPP_NULL_THREAD;}
thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) {
__t.__t_ = _LIBCPP_NULL_THREAD;
}
_LIBCPP_INLINE_VISIBILITY
thread& operator=(thread&& __t) _NOEXCEPT;
#endif // _LIBCPP_CXX03_LANG
thread& operator=(thread&& __t) _NOEXCEPT {
if (!__libcpp_thread_isnull(&__t_))
terminate();
__t_ = __t.__t_;
__t.__t_ = _LIBCPP_NULL_THREAD;
return *this;
}
_LIBCPP_INLINE_VISIBILITY
void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);}
@@ -304,17 +311,6 @@ thread::thread(_Fp&& __f, _Args&&... __args)
__throw_system_error(__ec, "thread constructor failed");
}
inline
thread&
thread::operator=(thread&& __t) _NOEXCEPT
{
if (!__libcpp_thread_isnull(&__t_))
terminate();
__t_ = __t.__t_;
__t.__t_ = _LIBCPP_NULL_THREAD;
return *this;
}
#else // _LIBCPP_CXX03_LANG
template <class _Fp>
@@ -369,9 +365,9 @@ sleep_for(const chrono::duration<_Rep, _Period>& __d)
{
#if defined(_LIBCPP_COMPILER_GCC) && (__powerpc__ || __POWERPC__)
// GCC's long double const folding is incomplete for IBM128 long doubles.
_LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
#else
_LIBCPP_CONSTEXPR duration<long double> _Max = duration<long double>(ULLONG_MAX/1000000000ULL) ;
#else
_LIBCPP_CONSTEXPR duration<long double> _Max = nanoseconds::max();
#endif
nanoseconds __ns;
if (__d < _Max)
+390 -55
View File
@@ -544,6 +544,18 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp
// is_same
#if __has_keyword(__is_same)
template <class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Up>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v = __is_same(_Tp, _Up);
#endif
#else
template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {};
@@ -553,6 +565,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_same_v
= is_same<_Tp, _Up>::value;
#endif
#endif // __is_same
template <class _Tp, class _Up>
using _IsSame = _BoolConstant<
#ifdef __clang__
@@ -656,6 +670,18 @@ struct __two {char __lx[2];};
// is_const
#if __has_keyword(__is_const)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v = __is_const(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {};
@@ -665,8 +691,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_const_v
= is_const<_Tp>::value;
#endif
#endif // __has_keyword(__is_const)
// is_volatile
#if __has_keyword(__is_volatile)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v = __is_volatile(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {};
@@ -676,37 +716,87 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_volatile_v
= is_volatile<_Tp>::value;
#endif
#endif // __has_keyword(__is_volatile)
// remove_const
#if __has_keyword(__remove_const)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_const {typedef __remove_const(_Tp) type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_const_t = __remove_const(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_const_t = typename remove_const<_Tp>::type;
#endif
#endif // __has_keyword(__remove_const)
// remove_volatile
#if __has_keyword(__remove_volatile)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef __remove_volatile(_Tp) type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_volatile_t = __remove_volatile(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_volatile_t = typename remove_volatile<_Tp>::type;
#endif
#endif // __has_keyword(__remove_volatile)
// remove_cv
#if __has_keyword(__remove_cv)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_cv {typedef __remove_cv(_Tp) type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_cv_t = __remove_cv(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
{typedef typename remove_volatile<typename remove_const<_Tp>::type>::type type;};
#if _LIBCPP_STD_VER > 11
template <class _Tp> using remove_cv_t = typename remove_cv<_Tp>::type;
#endif
#endif // __has_keyword(__remove_cv)
// is_void
template <class _Tp> struct __libcpp_is_void : public false_type {};
template <> struct __libcpp_is_void<void> : public true_type {};
#if __has_keyword(__is_void)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v = __is_void(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void
: public __libcpp_is_void<typename remove_cv<_Tp>::type> {};
: public is_same<typename remove_cv<_Tp>::type, void> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
@@ -714,6 +804,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_void_v
= is_void<_Tp>::value;
#endif
#endif // __has_keyword(__is_void)
// __is_nullptr_t
template <class _Tp> struct __is_nullptr_t_impl : public false_type {};
@@ -735,34 +827,20 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_null_pointer_v
// is_integral
template <class _Tp> struct __libcpp_is_integral : public false_type {};
template <> struct __libcpp_is_integral<bool> : public true_type {};
template <> struct __libcpp_is_integral<char> : public true_type {};
template <> struct __libcpp_is_integral<signed char> : public true_type {};
template <> struct __libcpp_is_integral<unsigned char> : public true_type {};
template <> struct __libcpp_is_integral<wchar_t> : public true_type {};
#ifndef _LIBCPP_NO_HAS_CHAR8_T
template <> struct __libcpp_is_integral<char8_t> : public true_type {};
#endif
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <> struct __libcpp_is_integral<char16_t> : public true_type {};
template <> struct __libcpp_is_integral<char32_t> : public true_type {};
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
template <> struct __libcpp_is_integral<short> : public true_type {};
template <> struct __libcpp_is_integral<unsigned short> : public true_type {};
template <> struct __libcpp_is_integral<int> : public true_type {};
template <> struct __libcpp_is_integral<unsigned int> : public true_type {};
template <> struct __libcpp_is_integral<long> : public true_type {};
template <> struct __libcpp_is_integral<unsigned long> : public true_type {};
template <> struct __libcpp_is_integral<long long> : public true_type {};
template <> struct __libcpp_is_integral<unsigned long long> : public true_type {};
#ifndef _LIBCPP_HAS_NO_INT128
template <> struct __libcpp_is_integral<__int128_t> : public true_type {};
template <> struct __libcpp_is_integral<__uint128_t> : public true_type {};
#if __has_keyword(__is_integral)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { };
#if _LIBCPP_STD_VER > 14
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v = __is_integral(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral
: public __libcpp_is_integral<typename remove_cv<_Tp>::type> {};
: public _BoolConstant<__libcpp_is_integral<typename remove_cv<_Tp>::type>::value> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
@@ -770,6 +848,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v
= is_integral<_Tp>::value;
#endif
#endif // __has_keyword(__is_integral)
// is_floating_point
template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
@@ -788,6 +868,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_floating_point_v
// is_array
#if __has_keyword(__is_array)
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v = __is_array(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array
: public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]>
@@ -801,8 +893,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_array_v
= is_array<_Tp>::value;
#endif
#endif // __has_keyword(__is_array)
// is_pointer
// In clang 10.0.0 and earlier __is_pointer didn't work with Objective-C types.
#if __has_keyword(__is_pointer) && _LIBCPP_CLANG_VER > 1000
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v = __is_pointer(_Tp);
#endif
#else // __has_keyword(__is_pointer)
template <class _Tp> struct __libcpp_is_pointer : public false_type {};
template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {};
@@ -823,8 +930,36 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pointer_v
= is_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_pointer)
// is_reference
#if __has_keyword(__is_lvalue_reference) && \
__has_keyword(__is_rvalue_reference) && \
__has_keyword(__is_reference)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { };
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { };
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_reference_v = __is_reference(_Tp);
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_lvalue_reference_v = __is_lvalue_reference(_Tp);
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v = __is_rvalue_reference(_Tp);
#endif
#else // __has_keyword(__is_lvalue_reference) && etc...
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {};
@@ -848,6 +983,9 @@ template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_rvalue_reference_v
= is_rvalue_reference<_Tp>::value;
#endif
#endif // __has_keyword(__is_lvalue_reference) && etc...
// is_union
#if __has_feature(is_union) || defined(_LIBCPP_COMPILER_GCC)
@@ -928,6 +1066,19 @@ template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> {
};
};
#if __has_keyword(__is_member_function_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
: _BoolConstant<__is_member_function_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
= __is_member_function_pointer(_Tp);
#endif
#else // __has_keyword(__is_member_function_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_func > {};
@@ -938,8 +1089,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_function_pointer_v
= is_member_function_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_member_function_pointer)
// is_member_pointer
#if __has_keyword(__is_member_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v = __is_member_pointer(_Tp);
#endif
#else // __has_keyword(__is_member_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_member > {};
@@ -949,8 +1114,24 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_pointer_v
= is_member_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_member_pointer)
// is_member_object_pointer
#if __has_keyword(__is_member_object_pointer)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
: _BoolConstant<__is_member_object_pointer(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
= __is_member_object_pointer(_Tp);
#endif
#else // __has_keyword(__is_member_object_pointer)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer
: public _BoolConstant< __libcpp_is_member_pointer<typename remove_cv<_Tp>::type>::__is_obj > {};
@@ -960,6 +1141,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
= is_member_object_pointer<_Tp>::value;
#endif
#endif // __has_keyword(__is_member_object_pointer)
// is_enum
#if __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
@@ -967,6 +1150,11 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_member_object_pointer_v
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
: public integral_constant<bool, __is_enum(_Tp)> {};
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_enum_v = __is_enum(_Tp);
#endif
#else
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
@@ -981,16 +1169,17 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum
!is_class<_Tp>::value &&
!is_function<_Tp>::value > {};
#endif
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_enum_v
= is_enum<_Tp>::value;
#endif
#endif // __has_feature(is_enum) || defined(_LIBCPP_COMPILER_GCC)
// is_arithmetic
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic
: public integral_constant<bool, is_integral<_Tp>::value ||
is_floating_point<_Tp>::value> {};
@@ -1003,6 +1192,20 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_arithmetic_v
// is_fundamental
// In clang 9 and lower, this builtin did not work for nullptr_t. Additionally, in C++03 mode,
// nullptr isn't defined by the compiler so, this builtin won't work.
#if __has_keyword(__is_fundamental) && _LIBCPP_CLANG_VER > 900 && !defined(_LIBCPP_CXX03_LANG)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v = __is_fundamental(_Tp);
#endif
#else // __has_keyword(__is_fundamental)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental
: public integral_constant<bool, is_void<_Tp>::value ||
__is_nullptr_t<_Tp>::value ||
@@ -1014,13 +1217,34 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_fundamental_v
= is_fundamental<_Tp>::value;
#endif
#endif // __has_keyword(__is_fundamental)
// is_scalar
// >= 11 because in C++03 nullptr isn't actually nullptr
#if __has_keyword(__is_scalar) && !defined(_LIBCPP_CXX03_LANG)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v = __is_scalar(_Tp);
#endif
#else // __has_keyword(__is_scalar)
template <class _Tp> struct __is_block : false_type {};
#if defined(_LIBCPP_HAS_EXTENSION_BLOCKS)
template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {};
#endif
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar
: public integral_constant<bool, is_arithmetic<_Tp>::value ||
is_member_pointer<_Tp>::value ||
is_pointer<_Tp>::value ||
__is_nullptr_t<_Tp>::value ||
__is_block<_Tp>::value ||
is_enum<_Tp>::value > {};
template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {};
@@ -1031,8 +1255,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_scalar_v
= is_scalar<_Tp>::value;
#endif
#endif // __has_keyword(__is_scalar)
// is_object
#if __has_keyword(__is_object)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v = __is_object(_Tp);
#endif
#else // __has_keyword(__is_object)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object
: public integral_constant<bool, is_scalar<_Tp>::value ||
is_array<_Tp>::value ||
@@ -1045,8 +1283,23 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_object_v
= is_object<_Tp>::value;
#endif
#endif // __has_keyword(__is_object)
// is_compound
// >= 11 because in C++03 nullptr isn't actually nullptr
#if __has_keyword(__is_compound) && !defined(_LIBCPP_CXX03_LANG)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v = __is_compound(_Tp);
#endif
#else // __has_keyword(__is_compound)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound
: public integral_constant<bool, !is_fundamental<_Tp>::value> {};
@@ -1056,6 +1309,7 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_compound_v
= is_compound<_Tp>::value;
#endif
#endif // __has_keyword(__is_compound)
// __is_referenceable [defns.referenceable]
@@ -1100,6 +1354,13 @@ template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type;
// remove_reference
#if __has_keyword(__remove_reference)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS remove_reference { typedef __remove_reference(_Tp) type; };
#else // __has_keyword(__remove_reference)
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG_TYPE _Tp type;};
@@ -1108,6 +1369,8 @@ template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typede
template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>::type;
#endif
#endif // __has_keyword(__remove_reference)
// add_lvalue_reference
template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
@@ -1215,6 +1478,19 @@ template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type;
// is_signed
// In clang 9 and earlier, this builtin did not work for floating points or enums
#if __has_keyword(__is_signed) && _LIBCPP_CLANG_VER > 900
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v = __is_signed(_Tp);
#endif
#else // __has_keyword(__is_signed)
template <class _Tp, bool = is_integral<_Tp>::value>
struct __libcpp_is_signed_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {};
@@ -1234,8 +1510,22 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_signed_v
= is_signed<_Tp>::value;
#endif
#endif // __has_keyword(__is_signed)
// is_unsigned
#if __has_keyword(__is_unsigned)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v = __is_unsigned(_Tp);
#endif
#else // __has_keyword(__is_unsigned)
template <class _Tp, bool = is_integral<_Tp>::value>
struct __libcpp_is_unsigned_impl : public _LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {};
@@ -1255,6 +1545,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_unsigned_v
= is_unsigned<_Tp>::value;
#endif
#endif // __has_keyword(__is_unsigned)
// rank
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank
@@ -1272,6 +1564,19 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t rank_v
// extent
#if __has_keyword(__array_extent)
template<class _Tp, size_t _Dim = 0>
struct _LIBCPP_TEMPLATE_VIS extent
: integral_constant<size_t, __array_extent(_Tp, _Dim)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, unsigned _Ip = 0>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v = __array_extent(_Tp, _Ip);
#endif
#else // __has_keyword(__array_extent)
template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent
: public integral_constant<size_t, 0> {};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0>
@@ -1289,6 +1594,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR size_t extent_v
= extent<_Tp, _Ip>::value;
#endif
#endif // __has_keyword(__array_extent)
// remove_extent
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent
@@ -2041,9 +2348,33 @@ struct _LIBCPP_TEMPLATE_VIS make_unsigned
template <class _Tp> using make_unsigned_t = typename make_unsigned<_Tp>::type;
#endif
#if _LIBCPP_STD_VER > 14
template <class...> using void_t = void;
#endif
#if _LIBCPP_STD_VER > 17
// Let COND_RES(X, Y) be:
template <class _Tp, class _Up>
using __cond_type = decltype(false ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>());
template <class _Tp, class _Up, class = void>
struct __common_type3 {};
// sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..."
template <class _Tp, class _Up>
struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>>
{
using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>;
};
template <class _Tp, class _Up, class = void>
struct __common_type2_imp : __common_type3<_Tp, _Up> {};
#else
template <class _Tp, class _Up, class = void>
struct __common_type2_imp {};
#endif
// sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..."
template <class _Tp, class _Up>
struct __common_type2_imp<_Tp, _Up,
typename __void_t<decltype(
@@ -2107,6 +2438,7 @@ struct _LIBCPP_TEMPLATE_VIS common_type<_Tp>
// bullet 3 - sizeof...(Tp) == 2
// sub-bullet 1 - "If is_same_v<T1, D1> is false or ..."
template <class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up>
: conditional<
@@ -2134,6 +2466,18 @@ template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type
template<typename, typename _Tp> struct __select_2nd { typedef _LIBCPP_NODEBUG_TYPE _Tp type; };
#if __has_keyword(__is_assignable)
template<class _Tp, class _Up>
struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp, class _Arg>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v = __is_assignable(_Tp, _Arg);
#endif
#else // __has_keyword(__is_assignable)
template <class _Tp, class _Arg>
typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type
__is_assignable_test(int);
@@ -2162,6 +2506,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_assignable_v
= is_assignable<_Tp, _Arg>::value;
#endif
#endif // __has_keyword(__is_assignable)
// is_copy_assignable
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_copy_assignable
@@ -2188,6 +2534,18 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_move_assignable_v
// is_destructible
#if __has_keyword(__is_destructible)
template<class _Tp>
struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { };
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
template <class _Tp>
_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v = __is_destructible(_Tp);
#endif
#else // __has_keyword(__is_destructible)
// if it's a reference, return true
// if it's a function, return false
// if it's void, return false
@@ -2250,6 +2608,8 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_destructible_v
= is_destructible<_Tp>::value;
#endif
#endif // __has_keyword(__is_destructible)
// move
template <class _Tp>
@@ -3879,7 +4239,6 @@ struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {};
template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type;
#endif
template <class _Tp, bool = is_enum<_Tp>::value>
struct __sfinae_underlying_type
{
@@ -3962,8 +4321,6 @@ struct __has_operator_addressof
#if _LIBCPP_STD_VER > 14
template <class...> using void_t = void;
template <class... _Args>
struct conjunction : _And<_Args...> {};
template<class... _Args>
@@ -4040,29 +4397,7 @@ _LIBCPP_END_NAMESPACE_STD
// std::byte
namespace std // purposefully not versioned
{
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
operator<<=(byte& __lhs, _Integer __shift) noexcept
{ return __lhs = __lhs << __shift; }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type
operator<< (byte __lhs, _Integer __shift) noexcept
{ return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) << __shift)); }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
operator>>=(byte& __lhs, _Integer __shift) noexcept
{ return __lhs = __lhs >> __shift; }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type
operator>> (byte __lhs, _Integer __shift) noexcept
{ return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, _Integer>::type
to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); }
}
#endif
+9 -4
View File
@@ -60,6 +60,7 @@ public:
#include <exception>
#include <cstddef>
#include <cstdint>
#include <type_traits>
#ifdef _LIBCPP_NO_EXCEPTIONS
#include <cstdlib>
#endif
@@ -120,6 +121,7 @@ public:
// ========================================================================== //
// ------------------------------------------------------------------------- //
// Unique
// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1)
// ------------------------------------------------------------------------- //
// This implementation of type_info assumes a unique copy of the RTTI for a
// given type inside a program. This is a valid assumption when abiding to
@@ -129,6 +131,7 @@ public:
// a deep string comparison.
// -------------------------------------------------------------------------- //
// NonUnique
// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 2)
// -------------------------------------------------------------------------- //
// This implementation of type_info does not assume there is always a unique
// copy of the RTTI for a given type inside a program. For various reasons
@@ -138,6 +141,7 @@ public:
// comparison is equal.
// -------------------------------------------------------------------------- //
// NonUniqueARMRTTIBit
// (selected on ARM64 regardless of _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION)
// -------------------------------------------------------------------------- //
// This implementation of type_info does not assume always a unique copy of
// the RTTI for a given type inside a program. It packs the pointer to the
@@ -255,12 +259,12 @@ struct __type_info_implementations {
typedef
#if defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__)
__non_unique_arm_rtti_bit_impl
#elif _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT == 0
__non_unique_impl
#elif _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT == 1
#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1
__unique_impl
#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2
__non_unique_impl
#else
# error invalid configuration for _LIBCPP_HAS_MERGED_TYPEINFO_NAMES_DEFAULT
# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION
#endif
__impl;
};
@@ -318,6 +322,7 @@ class _LIBCPP_EXCEPTION_ABI bad_cast
{
public:
bad_cast() _NOEXCEPT;
bad_cast(const bad_cast&) _NOEXCEPT = default;
virtual ~bad_cast() _NOEXCEPT;
virtual const char* what() const _NOEXCEPT;
};
+18 -8
View File
@@ -386,10 +386,12 @@ template <class Key, class T, class Hash, class Pred, class Alloc>
noexcept(noexcept(x.swap(y)));
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20
typename unordered_map<K, T, H, P, A>::size_type
erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred); // C++20
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20
typename unordered_multimap<K, T, H, P, A>::size_type
erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred); // C++20
template <class Key, class T, class Hash, class Pred, class Alloc>
bool
@@ -1704,10 +1706,14 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate>
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type
erase_if(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
@@ -2402,10 +2408,14 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
}
#if _LIBCPP_STD_VER > 17
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, class _Predicate>
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type
erase_if(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
+18 -8
View File
@@ -341,10 +341,12 @@ template <class Value, class Hash, class Pred, class Alloc>
noexcept(noexcept(x.swap(y)));
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20
typename unordered_set<K, T, H, P, A>::size_type
erase_if(unordered_set<K, T, H, P, A>& c, Predicate pred); // C++20
template <class K, class T, class H, class P, class A, class Predicate>
void erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20
typename unordered_multiset<K, T, H, P, A>::size_type
erase_if(unordered_multiset<K, T, H, P, A>& c, Predicate pred); // C++20
template <class Value, class Hash, class Pred, class Alloc>
@@ -1006,10 +1008,14 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
}
#if _LIBCPP_STD_VER > 17
template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate>
template <class _Value, class _Hash, class _Pred, class _Alloc,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename unordered_set<_Value, _Hash, _Pred, _Alloc>::size_type
erase_if(unordered_set<_Value, _Hash, _Pred, _Alloc>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
template <class _Value, class _Hash, class _Pred, class _Alloc>
@@ -1637,10 +1643,14 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
}
#if _LIBCPP_STD_VER > 17
template <class _Value, class _Hash, class _Pred, class _Alloc, class _Predicate>
template <class _Value, class _Hash, class _Pred, class _Alloc,
class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c, _Predicate __pred)
{ __libcpp_erase_if_container(__c, __pred); }
typename unordered_multiset<_Value, _Hash, _Pred, _Alloc>::size_type
erase_if(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __c,
_Predicate __pred) {
return __libcpp_erase_if_container(__c, __pred);
}
#endif
template <class _Value, class _Hash, class _Pred, class _Alloc>
+14 -8
View File
@@ -1063,18 +1063,24 @@ public:
}
__impl __tmp(_VSTD::move(*__rhs));
#ifndef _LIBCPP_NO_EXCEPTIONS
// EXTENSION: When the move construction of `__lhs` into `__rhs` throws
// and `__tmp` is nothrow move constructible then we move `__tmp` back
// into `__rhs` and provide the strong exception safety guarantee.
try {
if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) {
this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
} catch (...) {
if (__tmp.__move_nothrow()) {
this->__generic_construct(*__rhs, _VSTD::move(__tmp));
} else {
// EXTENSION: When the move construction of `__lhs` into `__rhs` throws
// and `__tmp` is nothrow move constructible then we move `__tmp` back
// into `__rhs` and provide the strong exception safety guarantee.
try {
this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
} catch (...) {
if (__tmp.__move_nothrow()) {
this->__generic_construct(*__rhs, _VSTD::move(__tmp));
}
throw;
}
throw;
}
#else
// this isn't consolidated with the `if constexpr` branch above due to
// `throw` being ill-formed with exceptions disabled even when discarded.
this->__generic_construct(*__rhs, _VSTD::move(*__lhs));
#endif
this->__generic_construct(*__lhs, _VSTD::move(__tmp));
+27 -16
View File
@@ -261,9 +261,11 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y)
noexcept(noexcept(x.swap(y)));
template <class T, class Allocator, class U>
void erase(vector<T, Allocator>& c, const U& value); // C++20
typename vector<T, Allocator>::size_type
erase(vector<T, Allocator>& c, const U& value); // C++20
template <class T, class Allocator, class Predicate>
void erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
typename vector<T, Allocator>::size_type
erase_if(vector<T, Allocator>& c, Predicate pred); // C++20
} // std
@@ -1041,8 +1043,9 @@ void
vector<_Tp, _Allocator>::__construct_at_end(size_type __n)
{
_ConstructTransaction __tx(*this, __n);
for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) {
__alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_));
const_pointer __new_end = __tx.__new_end_;
for (pointer __pos = __tx.__pos_; __pos != __new_end; ++__pos, __tx.__pos_ = __pos) {
__alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__pos));
}
}
@@ -1058,8 +1061,9 @@ void
vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
{
_ConstructTransaction __tx(*this, __n);
for (; __tx.__pos_ != __tx.__new_end_; ++__tx.__pos_) {
__alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_), __x);
const_pointer __new_end = __tx.__new_end_;
for (pointer __pos = __tx.__pos_; __pos != __new_end; ++__pos, __tx.__pos_ = __pos) {
__alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__pos), __x);
}
}
@@ -1751,9 +1755,10 @@ vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointe
{
pointer __i = __from_s + __n;
_ConstructTransaction __tx(*this, __from_e - __i);
for (; __i < __from_e; ++__i, ++__tx.__pos_) {
for (pointer __pos = __tx.__pos_; __i < __from_e;
++__i, ++__pos, __tx.__pos_ = __pos) {
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_address(__tx.__pos_),
_VSTD::__to_address(__pos),
_VSTD::move(*__i));
}
}
@@ -1956,8 +1961,8 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs
#endif // _LIBCPP_NO_EXCEPTIONS
}
__p = _VSTD::rotate(__p, __old_last, this->__end_);
insert(__make_iter(__p), make_move_iterator(__v.begin()),
make_move_iterator(__v.end()));
insert(__make_iter(__p), _VSTD::make_move_iterator(__v.begin()),
_VSTD::make_move_iterator(__v.end()));
return begin() + __off;
}
@@ -3389,14 +3394,20 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y)
#if _LIBCPP_STD_VER > 17
template <class _Tp, class _Allocator, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
void erase(vector<_Tp, _Allocator>& __c, const _Up& __v)
{ __c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end()); }
inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::size_type
erase(vector<_Tp, _Allocator>& __c, const _Up& __v) {
auto __old_size = __c.size();
__c.erase(_VSTD::remove(__c.begin(), __c.end(), __v), __c.end());
return __old_size - __c.size();
}
template <class _Tp, class _Allocator, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred)
{ __c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end()); }
inline _LIBCPP_INLINE_VISIBILITY typename vector<_Tp, _Allocator>::size_type
erase_if(vector<_Tp, _Allocator>& __c, _Predicate __pred) {
auto __old_size = __c.size();
__c.erase(_VSTD::remove_if(__c.begin(), __c.end(), __pred), __c.end());
return __old_size - __c.size();
}
#endif
_LIBCPP_END_NAMESPACE_STD
+16 -5
View File
@@ -21,7 +21,8 @@ __cpp_lib_allocator_traits_is_always_equal 201411L <memory> <scoped
<unordered_map> <unordered_set>
__cpp_lib_any 201606L <any>
__cpp_lib_apply 201603L <tuple>
__cpp_lib_array_constexpr 201603L <iterator> <array>
__cpp_lib_array_constexpr 201811L <iterator> <array>
201603L // C++17
__cpp_lib_as_const 201510L <utility>
__cpp_lib_atomic_is_always_lock_free 201603L <atomic>
__cpp_lib_atomic_ref 201806L <atomic>
@@ -44,7 +45,7 @@ __cpp_lib_constexpr_swap_algorithms 201806L <algorithm>
__cpp_lib_destroying_delete 201806L <new>
__cpp_lib_enable_shared_from_this 201603L <memory>
__cpp_lib_endian 201907L <bit>
__cpp_lib_erase_if 201811L <string> <deque> <forward_list>
__cpp_lib_erase_if 202002L <string> <deque> <forward_list>
<list> <vector> <map>
<set> <unordered_map> <unordered_set>
__cpp_lib_exchange_function 201304L <utility>
@@ -74,6 +75,7 @@ __cpp_lib_make_from_tuple 201606L <tuple>
__cpp_lib_make_reverse_iterator 201402L <iterator>
__cpp_lib_make_unique 201304L <memory>
__cpp_lib_map_try_emplace 201411L <map>
__cpp_lib_math_constants 201907L <numbers>
__cpp_lib_math_special_functions 201603L <cmath>
__cpp_lib_memory_resource 201603L <memory_resource>
__cpp_lib_node_extract 201606L <map> <set> <unordered_map>
@@ -98,9 +100,11 @@ __cpp_lib_shared_mutex 201505L <shared_mutex>
__cpp_lib_shared_ptr_arrays 201611L <memory>
__cpp_lib_shared_ptr_weak_type 201606L <memory>
__cpp_lib_shared_timed_mutex 201402L <shared_mutex>
__cpp_lib_span 202002L <span>
__cpp_lib_string_udls 201304L <string>
__cpp_lib_string_view 201606L <string> <string_view>
__cpp_lib_three_way_comparison 201711L <compare>
__cpp_lib_to_array 201907L <array>
__cpp_lib_to_chars 201611L <utility>
__cpp_lib_transformation_trait_aliases 201304L <type_traits>
__cpp_lib_transparent_operators 201510L <functional>
@@ -167,7 +171,7 @@ __cpp_lib_void_t 201411L <type_traits>
// # define __cpp_lib_execution 201603L
# define __cpp_lib_filesystem 201703L
# define __cpp_lib_gcd_lcm 201606L
# define __cpp_lib_hardware_interference_size 201703L
// # define __cpp_lib_hardware_interference_size 201703L
# if defined(_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS)
# define __cpp_lib_has_unique_object_representations 201606L
# endif
@@ -210,6 +214,8 @@ __cpp_lib_void_t 201411L <type_traits>
#endif
#if _LIBCPP_STD_VER > 17
# undef __cpp_lib_array_constexpr
# define __cpp_lib_array_constexpr 201811L
# if !defined(_LIBCPP_HAS_NO_THREADS)
// # define __cpp_lib_atomic_ref 201806L
# endif
@@ -225,15 +231,20 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_destroying_delete 201806L
# endif
# define __cpp_lib_endian 201907L
# define __cpp_lib_erase_if 201811L
# define __cpp_lib_erase_if 202002L
// # define __cpp_lib_generic_unordered_lookup 201811L
# define __cpp_lib_interpolate 201902L
# if !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)
# define __cpp_lib_is_constant_evaluated 201811L
# endif
// # define __cpp_lib_list_remove_return_type 201806L
# define __cpp_lib_list_remove_return_type 201806L
# if defined(__cpp_concepts) && __cpp_concepts >= 201811L
# define __cpp_lib_math_constants 201907L
# endif
// # define __cpp_lib_ranges 201811L
# define __cpp_lib_span 202002L
// # define __cpp_lib_three_way_comparison 201711L
# define __cpp_lib_to_array 201907L
#endif
#endif // _LIBCPP_VERSIONH
+1
View File
@@ -106,6 +106,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
*/
#include <__config>
#include <stddef.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
-48
View File
@@ -7,13 +7,6 @@
//===----------------------------------------------------------------------===//
#include "algorithm"
#include "random"
#ifndef _LIBCPP_HAS_NO_THREADS
#include "mutex"
#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
#pragma comment(lib, "pthread")
#endif
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -51,45 +44,4 @@ template bool __insertion_sort_incomplete<__less<long double>&, long double*>(lo
template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
#ifndef _LIBCPP_HAS_NO_THREADS
_LIBCPP_SAFE_STATIC static __libcpp_mutex_t __rs_mut = _LIBCPP_MUTEX_INITIALIZER;
#endif
unsigned __rs_default::__c_ = 0;
__rs_default::__rs_default()
{
#ifndef _LIBCPP_HAS_NO_THREADS
__libcpp_mutex_lock(&__rs_mut);
#endif
__c_ = 1;
}
__rs_default::__rs_default(const __rs_default&)
{
++__c_;
}
__rs_default::~__rs_default()
{
#ifndef _LIBCPP_HAS_NO_THREADS
if (--__c_ == 0)
__libcpp_mutex_unlock(&__rs_mut);
#else
--__c_;
#endif
}
__rs_default::result_type
__rs_default::operator()()
{
static mt19937 __rs_g;
return __rs_g();
}
__rs_default
__rs_get()
{
return __rs_default();
}
_LIBCPP_END_NAMESPACE_STD
+189
View File
@@ -0,0 +1,189 @@
//===------------------------- atomic.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <__config>
#ifndef _LIBCPP_HAS_NO_THREADS
#include <climits>
#include <atomic>
#include <functional>
#include <iostream>
#ifdef __linux__
#include <unistd.h>
#include <linux/futex.h>
#include <sys/syscall.h>
#else // <- Add other operating systems here
// Baseline needs no new headers
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#ifdef __linux__
static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
__cxx_contention_t __val)
{
static constexpr timespec __timeout = { 2, 0 };
syscall(SYS_futex, __ptr, FUTEX_WAIT_PRIVATE, __val, &__timeout, 0, 0);
}
static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
bool __notify_one)
{
syscall(SYS_futex, __ptr, FUTEX_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, 0, 0, 0);
}
#elif defined(__APPLE__) && defined(_LIBCPP_USE_ULOCK)
extern "C" int __ulock_wait(uint32_t operation, void *addr, uint64_t value,
uint32_t timeout); /* timeout is specified in microseconds */
extern "C" int __ulock_wake(uint32_t operation, void *addr, uint64_t wake_value);
#define UL_COMPARE_AND_WAIT 1
#define ULF_WAKE_ALL 0x00000100
static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
__cxx_contention_t __val)
{
__ulock_wait(UL_COMPARE_AND_WAIT,
const_cast<__cxx_atomic_contention_t*>(__ptr), __val, 0);
}
static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr,
bool __notify_one)
{
__ulock_wake(UL_COMPARE_AND_WAIT | (__notify_one ? 0 : ULF_WAKE_ALL),
const_cast<__cxx_atomic_contention_t*>(__ptr), 0);
}
#else // <- Add other operating systems here
// Baseline is just a timed backoff
static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr,
__cxx_contention_t __val)
{
__libcpp_thread_poll_with_backoff([=]() -> bool {
return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__ptr, memory_order_relaxed), __val);
}, __libcpp_timed_backoff_policy());
}
static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile*, bool) { }
#endif // __linux__
static constexpr size_t __libcpp_contention_table_size = (1 << 8); /* < there's no magic in this number */
struct alignas(64) /* aim to avoid false sharing */ __libcpp_contention_table_entry
{
__cxx_atomic_contention_t __contention_state;
__cxx_atomic_contention_t __platform_state;
inline constexpr __libcpp_contention_table_entry() :
__contention_state(0), __platform_state(0) { }
};
static __libcpp_contention_table_entry __libcpp_contention_table[ __libcpp_contention_table_size ];
static hash<void const volatile*> __libcpp_contention_hasher;
static __libcpp_contention_table_entry* __libcpp_contention_state(void const volatile * p)
{
return &__libcpp_contention_table[__libcpp_contention_hasher(p) & (__libcpp_contention_table_size - 1)];
}
/* Given an atomic to track contention and an atomic to actually wait on, which may be
the same atomic, we try to detect contention to avoid spuriously calling the platform. */
static void __libcpp_contention_notify(__cxx_atomic_contention_t volatile* __contention_state,
__cxx_atomic_contention_t const volatile* __platform_state,
bool __notify_one)
{
if(0 != __cxx_atomic_load(__contention_state, memory_order_seq_cst))
// We only call 'wake' if we consumed a contention bit here.
__libcpp_platform_wake_by_address(__platform_state, __notify_one);
}
static __cxx_contention_t __libcpp_contention_monitor_for_wait(__cxx_atomic_contention_t volatile* __contention_state,
__cxx_atomic_contention_t const volatile* __platform_state)
{
// We will monitor this value.
return __cxx_atomic_load(__platform_state, memory_order_acquire);
}
static void __libcpp_contention_wait(__cxx_atomic_contention_t volatile* __contention_state,
__cxx_atomic_contention_t const volatile* __platform_state,
__cxx_contention_t __old_value)
{
__cxx_atomic_fetch_add(__contention_state, __cxx_contention_t(1), memory_order_seq_cst);
// We sleep as long as the monitored value hasn't changed.
__libcpp_platform_wait_on_address(__platform_state, __old_value);
__cxx_atomic_fetch_sub(__contention_state, __cxx_contention_t(1), memory_order_release);
}
/* When the incoming atomic is the wrong size for the platform wait size, need to
launder the value sequence through an atomic from our table. */
static void __libcpp_atomic_notify(void const volatile* __location)
{
auto const __entry = __libcpp_contention_state(__location);
// The value sequence laundering happens on the next line below.
__cxx_atomic_fetch_add(&__entry->__platform_state, __cxx_contention_t(1), memory_order_release);
__libcpp_contention_notify(&__entry->__contention_state,
&__entry->__platform_state,
false /* when laundering, we can't handle notify_one */);
}
_LIBCPP_EXPORTED_FROM_ABI
void __cxx_atomic_notify_one(void const volatile* __location)
{ __libcpp_atomic_notify(__location); }
_LIBCPP_EXPORTED_FROM_ABI
void __cxx_atomic_notify_all(void const volatile* __location)
{ __libcpp_atomic_notify(__location); }
_LIBCPP_EXPORTED_FROM_ABI
__cxx_contention_t __libcpp_atomic_monitor(void const volatile* __location)
{
auto const __entry = __libcpp_contention_state(__location);
return __libcpp_contention_monitor_for_wait(&__entry->__contention_state, &__entry->__platform_state);
}
_LIBCPP_EXPORTED_FROM_ABI
void __libcpp_atomic_wait(void const volatile* __location, __cxx_contention_t __old_value)
{
auto const __entry = __libcpp_contention_state(__location);
__libcpp_contention_wait(&__entry->__contention_state, &__entry->__platform_state, __old_value);
}
/* When the incoming atomic happens to be the platform wait size, we still need to use the
table for the contention detection, but we can use the atomic directly for the wait. */
_LIBCPP_EXPORTED_FROM_ABI
void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile* __location)
{
__libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, true);
}
_LIBCPP_EXPORTED_FROM_ABI
void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile* __location)
{
__libcpp_contention_notify(&__libcpp_contention_state(__location)->__contention_state, __location, false);
}
_LIBCPP_EXPORTED_FROM_ABI
__cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile* __location)
{
return __libcpp_contention_monitor_for_wait(&__libcpp_contention_state(__location)->__contention_state, __location);
}
_LIBCPP_EXPORTED_FROM_ABI
void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile* __location, __cxx_contention_t __old_value)
{
__libcpp_contention_wait(&__libcpp_contention_state(__location)->__contention_state, __location, __old_value);
}
_LIBCPP_END_NAMESPACE_STD
#endif //_LIBCPP_HAS_NO_THREADS
+103
View File
@@ -0,0 +1,103 @@
//===------------------------- barrier.cpp ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include <__config>
#ifndef _LIBCPP_HAS_NO_THREADS
#include <barrier>
#include <thread>
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_TREE_BARRIER) && (_LIBCPP_STD_VER > 11)
class __barrier_algorithm_base {
public:
struct alignas(64) /* naturally-align the heap state */ __state_t
{
struct {
__atomic_base<__barrier_phase_t> __phase = ATOMIC_VAR_INIT(0);
} __tickets[64];
};
ptrdiff_t& __expected;
unique_ptr<char[]> __state_allocation;
__state_t* __state;
_LIBCPP_HIDDEN
__barrier_algorithm_base(ptrdiff_t& __expected)
: __expected(__expected)
{
size_t const __count = (__expected + 1) >> 1;
size_t const __size = sizeof(__state_t) * __count;
size_t __allocation_size = __size + alignof(__state_t);
__state_allocation = unique_ptr<char[]>(new char[__allocation_size]);
void* __allocation = __state_allocation.get();
void* const __state_ = align(alignof(__state_t), __size, __allocation, __allocation_size);
__state = new (__state_) __barrier_algorithm_base::__state_t[__count];
}
_LIBCPP_HIDDEN
bool __arrive(__barrier_phase_t __old_phase)
{
__barrier_phase_t const __half_step = __old_phase + 1,
__full_step = __old_phase + 2;
size_t __current_expected = __expected,
__current = hash<thread::id>()(this_thread::get_id()) % ((__expected + 1) >> 1);
for(int __round = 0;; ++__round) {
if(__current_expected <= 1)
return true;
size_t const __end_node = ((__current_expected + 1) >> 1),
__last_node = __end_node - 1;
for(;;++__current) {
if(__current == __end_node)
__current = 0;
__barrier_phase_t expect = __old_phase;
if(__current == __last_node && (__current_expected & 1))
{
if(__state[__current].__tickets[__round].__phase.compare_exchange_strong(expect, __full_step, memory_order_acq_rel))
break; // I'm 1 in 1, go to next __round
}
else if(__state[__current].__tickets[__round].__phase.compare_exchange_strong(expect, __half_step, memory_order_acq_rel))
{
return false; // I'm 1 in 2, done with arrival
}
else if(expect == __half_step)
{
if(__state[__current].__tickets[__round].__phase.compare_exchange_strong(expect, __full_step, memory_order_acq_rel))
break; // I'm 2 in 2, go to next __round
}
}
__current_expected = __last_node + 1;
__current >>= 1;
}
}
};
_LIBCPP_EXPORTED_FROM_ABI
__barrier_algorithm_base * __construct_barrier_algorithm_base(ptrdiff_t& __expected)
{
return new __barrier_algorithm_base(__expected);
}
_LIBCPP_EXPORTED_FROM_ABI
bool __arrive_barrier_algorithm_base(__barrier_algorithm_base* __barrier,
__barrier_phase_t __old_phase)
{
return __barrier->__arrive(__old_phase);
}
_LIBCPP_EXPORTED_FROM_ABI
void __destroy_barrier_algorithm_base(__barrier_algorithm_base* __barrier)
{
delete __barrier;
}
#endif //!defined(_LIBCPP_HAS_NO_TREE_BARRIER) && (_LIBCPP_STD_VER >= 11)
_LIBCPP_END_NAMESPACE_STD
#endif //_LIBCPP_HAS_NO_THREADS
+9 -9
View File
@@ -32,7 +32,7 @@ static constexpr char cDigitsLut[200] = {
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append1(char* buffer, T i)
append1(char* buffer, T i) noexcept
{
*buffer = '0' + static_cast<char>(i);
return buffer + 1;
@@ -40,7 +40,7 @@ append1(char* buffer, T i)
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append2(char* buffer, T i)
append2(char* buffer, T i) noexcept
{
memcpy(buffer, &cDigitsLut[(i)*2], 2);
return buffer + 2;
@@ -48,21 +48,21 @@ append2(char* buffer, T i)
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append3(char* buffer, T i)
append3(char* buffer, T i) noexcept
{
return append2(append1(buffer, (i) / 100), (i) % 100);
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append4(char* buffer, T i)
append4(char* buffer, T i) noexcept
{
return append2(append2(buffer, (i) / 100), (i) % 100);
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append2_no_zeros(char* buffer, T v)
append2_no_zeros(char* buffer, T v) noexcept
{
if (v < 10)
return append1(buffer, v);
@@ -72,7 +72,7 @@ append2_no_zeros(char* buffer, T v)
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append4_no_zeros(char* buffer, T v)
append4_no_zeros(char* buffer, T v) noexcept
{
if (v < 100)
return append2_no_zeros(buffer, v);
@@ -84,7 +84,7 @@ append4_no_zeros(char* buffer, T v)
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append8_no_zeros(char* buffer, T v)
append8_no_zeros(char* buffer, T v) noexcept
{
if (v < 10000)
{
@@ -99,7 +99,7 @@ append8_no_zeros(char* buffer, T v)
}
char*
__u32toa(uint32_t value, char* buffer)
__u32toa(uint32_t value, char* buffer) _NOEXCEPT
{
if (value < 100000000)
{
@@ -120,7 +120,7 @@ __u32toa(uint32_t value, char* buffer)
}
char*
__u64toa(uint64_t value, char* buffer)
__u64toa(uint64_t value, char* buffer) _NOEXCEPT
{
if (value < 100000000)
{
+31 -89
View File
@@ -9,36 +9,32 @@
#include "chrono"
#include "cerrno" // errno
#include "system_error" // __throw_system_error
#include <time.h> // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
#include <time.h> // clock_gettime and CLOCK_{MONOTONIC,REALTIME,MONOTONIC_RAW}
#include "include/apple_availability.h"
#if !defined(__APPLE__)
#if __has_include(<unistd.h>)
#include <unistd.h>
#endif
#if !defined(__APPLE__) && _POSIX_TIMERS > 0
#define _LIBCPP_USE_CLOCK_GETTIME
#endif // __APPLE__
#endif
#if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#include <windows.h>
#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#include <winapifamily.h>
#endif
# define WIN32_LEAN_AND_MEAN
# define VC_EXTRA_LEAN
# include <windows.h>
# if _WIN32_WINNT >= _WIN32_WINNT_WIN8
# include <winapifamily.h>
# endif
#else
#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
#include <sys/time.h> // for gettimeofday and timeval
#endif // !defined(CLOCK_REALTIME)
# if !defined(CLOCK_REALTIME)
# include <sys/time.h> // for gettimeofday and timeval
# endif // !defined(CLOCK_REALTIME)
#endif // defined(_LIBCPP_WIN32API)
#if !defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK)
#if __APPLE__
#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
#elif !defined(_LIBCPP_WIN32API) && !defined(CLOCK_MONOTONIC)
#error "Monotonic clock not implemented"
#endif
#endif
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
#pragma comment(lib, "rt")
# pragma comment(lib, "rt")
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -78,7 +74,7 @@ system_clock::now() _NOEXCEPT
static_cast<__int64>(ft.dwLowDateTime)};
return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
#else
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
#if defined(CLOCK_REALTIME)
struct timespec tp;
if (0 != clock_gettime(CLOCK_REALTIME, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
@@ -87,7 +83,7 @@ system_clock::now() _NOEXCEPT
timeval tv;
gettimeofday(&tv, 0);
return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif // CLOCK_REALTIME
#endif
}
@@ -114,71 +110,24 @@ const bool steady_clock::is_steady;
#if defined(__APPLE__)
// Darwin libc versions >= 1133 provide ns precision via CLOCK_UPTIME_RAW
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
#if !defined(CLOCK_MONOTONIC_RAW)
# error "Building libc++ on Apple platforms requires CLOCK_MONOTONIC_RAW"
#endif
// On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
// mach_absolute_time are able to time functions in the nanosecond range.
// Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
// also counts cycles when the system is asleep. Thus, it is the only
// acceptable implementation of steady_clock.
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
struct timespec tp;
if (0 != clock_gettime(CLOCK_UPTIME_RAW, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_UPTIME_RAW) failed");
if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC_RAW) failed");
return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}
#else
// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
// are run time constants supplied by the OS. This clock has no relationship
// to the Gregorian calendar. It's main use is as a high resolution timer.
// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
// for that case as an optimization.
static
steady_clock::rep
steady_simplified()
{
return static_cast<steady_clock::rep>(mach_absolute_time());
}
static
double
compute_steady_factor()
{
mach_timebase_info_data_t MachInfo;
mach_timebase_info(&MachInfo);
return static_cast<double>(MachInfo.numer) / MachInfo.denom;
}
static
steady_clock::rep
steady_full()
{
static const double factor = compute_steady_factor();
return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
}
typedef steady_clock::rep (*FP)();
static
FP
init_steady_clock()
{
mach_timebase_info_data_t MachInfo;
mach_timebase_info(&MachInfo);
if (MachInfo.numer == MachInfo.denom)
return &steady_simplified;
return &steady_full;
}
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
static FP fp = init_steady_clock();
return time_point(duration(fp()));
}
#endif // defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
#elif defined(_LIBCPP_WIN32API)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
@@ -206,13 +155,6 @@ steady_clock::now() _NOEXCEPT
#elif defined(CLOCK_MONOTONIC)
// On Apple platforms only CLOCK_UPTIME_RAW or mach_absolute_time are able to
// time functions in the nanosecond range. Thus, they are the only acceptable
// implementations of steady_clock.
#ifdef __APPLE__
#error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms"
#endif
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
@@ -223,7 +165,7 @@ steady_clock::now() _NOEXCEPT
}
#else
#error "Monotonic clock not implemented"
# error "Monotonic clock not implemented"
#endif
#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK
@@ -0,0 +1,54 @@
/*===-- int128_builtins.cpp - Implement __muloti4 --------------------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* ===----------------------------------------------------------------------===
*
* This file implements __muloti4, and is stolen from the compiler_rt library.
*
* FIXME: we steal and re-compile it into filesystem, which uses __int128_t,
* and requires this builtin when sanitized. See llvm.org/PR30643
*
* ===----------------------------------------------------------------------===
*/
#include "__config"
#include "climits"
#if !defined(_LIBCPP_HAS_NO_INT128)
extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS
__int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) {
const int N = (int)(sizeof(__int128_t) * CHAR_BIT);
const __int128_t MIN = (__int128_t)1 << (N - 1);
const __int128_t MAX = ~MIN;
*overflow = 0;
__int128_t result = a * b;
if (a == MIN) {
if (b != 0 && b != 1)
*overflow = 1;
return result;
}
if (b == MIN) {
if (a != 0 && a != 1)
*overflow = 1;
return result;
}
__int128_t sa = a >> (N - 1);
__int128_t abs_a = (a ^ sa) - sa;
__int128_t sb = b >> (N - 1);
__int128_t abs_b = (b ^ sb) - sb;
if (abs_a < 2 || abs_b < 2)
return result;
if (sa == sb) {
if (abs_a > MAX / abs_b)
*overflow = 1;
} else {
if (abs_a > MIN / -abs_b)
*overflow = 1;
}
return result;
}
#endif
+4 -8
View File
@@ -36,13 +36,9 @@
#define _LIBCPP_USE_COPYFILE
#endif
#if !defined(__APPLE__)
#define _LIBCPP_USE_CLOCK_GETTIME
#endif
#if !defined(CLOCK_REALTIME) || !defined(_LIBCPP_USE_CLOCK_GETTIME)
#if !defined(CLOCK_REALTIME)
#include <sys/time.h> // for gettimeofday and timeval
#endif // !defined(CLOCK_REALTIME)
#endif // !defined(CLOCK_REALTIME)
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
#pragma comment(lib, "rt")
@@ -490,7 +486,7 @@ const bool _FilesystemClock::is_steady;
_FilesystemClock::time_point _FilesystemClock::now() noexcept {
typedef chrono::duration<rep> __secs;
#if defined(_LIBCPP_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
#if defined(CLOCK_REALTIME)
typedef chrono::duration<rep, nano> __nsecs;
struct timespec tp;
if (0 != clock_gettime(CLOCK_REALTIME, &tp))
@@ -502,7 +498,7 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept {
timeval tv;
gettimeofday(&tv, 0);
return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec));
#endif // _LIBCPP_USE_CLOCK_GETTIME && CLOCK_REALTIME
#endif // CLOCK_REALTIME
}
filesystem_error::~filesystem_error() {}
+8 -8
View File
@@ -29,20 +29,20 @@
#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
#define _LIBCPP_USE_CLOCK_GETTIME
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500
#define _LIBCPP_USE_ULOCK
#endif
#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 100000
#define _LIBCPP_USE_CLOCK_GETTIME
#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 130000
#define _LIBCPP_USE_ULOCK
#endif
#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 100000
#define _LIBCPP_USE_CLOCK_GETTIME
#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 130000
#define _LIBCPP_USE_ULOCK
#endif
#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 30000
#define _LIBCPP_USE_CLOCK_GETTIME
#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 60000
#define _LIBCPP_USE_ULOCK
#endif
#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
+2 -2
View File
@@ -536,7 +536,7 @@ locale::operator=(const locale& other) _NOEXCEPT
locale::locale(const char* name)
: __locale_(name ? new __imp(name)
: (__throw_runtime_error("locale constructed with null"), (__imp*)0))
: (__throw_runtime_error("locale constructed with null"), nullptr))
{
__locale_->__add_shared();
}
@@ -549,7 +549,7 @@ locale::locale(const string& name)
locale::locale(const locale& other, const char* name, category c)
: __locale_(name ? new __imp(*other.__locale_, name, c)
: (__throw_runtime_error("locale constructed with null"), (__imp*)0))
: (__throw_runtime_error("locale constructed with null"), nullptr))
{
__locale_->__add_shared();
}
+61
View File
@@ -0,0 +1,61 @@
//===----------------------- random_shuffle.cpp ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "algorithm"
#include "random"
#ifndef _LIBCPP_HAS_NO_THREADS
# include "mutex"
# if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
# pragma comment(lib, "pthread")
# endif
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_HAS_NO_THREADS
_LIBCPP_SAFE_STATIC static __libcpp_mutex_t __rs_mut = _LIBCPP_MUTEX_INITIALIZER;
#endif
unsigned __rs_default::__c_ = 0;
__rs_default::__rs_default()
{
#ifndef _LIBCPP_HAS_NO_THREADS
__libcpp_mutex_lock(&__rs_mut);
#endif
__c_ = 1;
}
__rs_default::__rs_default(const __rs_default&)
{
++__c_;
}
__rs_default::~__rs_default()
{
#ifndef _LIBCPP_HAS_NO_THREADS
if (--__c_ == 0)
__libcpp_mutex_unlock(&__rs_mut);
#else
--__c_;
#endif
}
__rs_default::result_type
__rs_default::operator()()
{
static mt19937 __rs_g;
return __rs_g();
}
__rs_default
__rs_get()
{
return __rs_default();
}
_LIBCPP_END_NAMESPACE_STD
+7 -2
View File
@@ -20,8 +20,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common<true>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<char>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_string<wchar_t>;
#ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
_LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
#else
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char)
_LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t)
#endif
template
string
+3 -3
View File
@@ -23,9 +23,9 @@
# endif
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) || defined(__Fuchsia__) || defined(__wasi__)
# include <unistd.h>
#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) || defined(__Fuchsia__) || defined(__wasi__)
#if __has_include(<unistd.h>)
#include <unistd.h>
#endif
#if defined(__NetBSD__)
#pragma weak pthread_create // Do not create libpthread dependency