diff options
Diffstat (limited to 'include')
91 files changed, 9885 insertions, 3988 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 219d1b730839..7b574353193d 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -10,16 +10,18 @@ set(LIBCXX_HEADER_PATTERN ${LIBCXX_SUPPORT_HEADER_PATTERN} ) -file(COPY . - DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1" - FILES_MATCHING - ${LIBCXX_HEADER_PATTERN} - ) +if(NOT LIBCXX_USING_INSTALLED_LLVM AND LLVM_BINARY_DIR) + file(COPY . + DESTINATION "${LLVM_BINARY_DIR}/include/c++/v1" + FILES_MATCHING + ${LIBCXX_HEADER_PATTERN} + ) +endif() if (LIBCXX_INSTALL_HEADERS) install(DIRECTORY . DESTINATION include/c++/v1 - COMPONENT libcxx-headers + COMPONENT cxx-headers FILES_MATCHING ${LIBCXX_HEADER_PATTERN} PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ @@ -27,7 +29,7 @@ if (LIBCXX_INSTALL_HEADERS) if (LIBCXX_NEEDS_SITE_CONFIG) set(UNIX_CAT cat) - if (WIN32) + if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") set(UNIX_CAT type) endif() # Generate and install a custom __config header. The new header is created @@ -47,17 +49,20 @@ if (LIBCXX_INSTALL_HEADERS) DESTINATION include/c++/v1 PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ RENAME __config - COMPONENT libcxx-headers) + COMPONENT cxx-headers) endif() if (NOT CMAKE_CONFIGURATION_TYPES) # this target is just needed as a placeholder for the distribution target - add_custom_target(libcxx-headers) - add_custom_target(install-libcxx-headers - DEPENDS libcxx-headers ${generated_config_deps} + add_custom_target(cxx-headers) + add_custom_target(install-cxx-headers + DEPENDS cxx-headers ${generated_config_deps} COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=libcxx-headers + -DCMAKE_INSTALL_COMPONENT=cxx-headers -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + + add_custom_target(libcxx-headers) + add_custom_target(install-libcxx-headers DEPENDS install-cxx-headers) endif() endif() diff --git a/include/__bit_reference b/include/__bit_reference index 5659ed068246..8f245463c91d 100644 --- a/include/__bit_reference +++ b/include/__bit_reference @@ -163,7 +163,7 @@ __find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type { typedef __bit_iterator<_Cp, _IsConst> _It; typedef typename _It::__storage_type __storage_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + static const int __bits_per_word = _It::__bits_per_word; // do first partial word if (__first.__ctz_ != 0) { @@ -199,7 +199,7 @@ __find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type { typedef __bit_iterator<_Cp, _IsConst> _It; typedef typename _It::__storage_type __storage_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; // do first partial word if (__first.__ctz_ != 0) { @@ -251,7 +251,7 @@ __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type typedef __bit_iterator<_Cp, _IsConst> _It; typedef typename _It::__storage_type __storage_type; typedef typename _It::difference_type difference_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; difference_type __r = 0; // do first partial word if (__first.__ctz_ != 0) @@ -282,7 +282,7 @@ __count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_typ typedef __bit_iterator<_Cp, _IsConst> _It; typedef typename _It::__storage_type __storage_type; typedef typename _It::difference_type difference_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; difference_type __r = 0; // do first partial word if (__first.__ctz_ != 0) @@ -324,7 +324,7 @@ __fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, false> _It; typedef typename _It::__storage_type __storage_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; // do first partial word if (__first.__ctz_ != 0) { @@ -354,7 +354,7 @@ __fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) { typedef __bit_iterator<_Cp, false> _It; typedef typename _It::__storage_type __storage_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + const int __bits_per_word = _It::__bits_per_word; // do first partial word if (__first.__ctz_ != 0) { @@ -412,7 +412,7 @@ __copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCon typedef __bit_iterator<_Cp, _IsConst> _In; typedef typename _In::difference_type difference_type; typedef typename _In::__storage_type __storage_type; - static const unsigned __bits_per_word = _In::__bits_per_word; + const int __bits_per_word = _In::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -461,7 +461,7 @@ __copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsC typedef __bit_iterator<_Cp, _IsConst> _In; typedef typename _In::difference_type difference_type; typedef typename _In::__storage_type __storage_type; - static const unsigned __bits_per_word = _In::__bits_per_word; + static const int __bits_per_word = _In::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -551,7 +551,7 @@ __copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_C typedef __bit_iterator<_Cp, _IsConst> _In; typedef typename _In::difference_type difference_type; typedef typename _In::__storage_type __storage_type; - static const unsigned __bits_per_word = _In::__bits_per_word; + const int __bits_per_word = _In::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -600,7 +600,7 @@ __copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator< typedef __bit_iterator<_Cp, _IsConst> _In; typedef typename _In::difference_type difference_type; typedef typename _In::__storage_type __storage_type; - static const unsigned __bits_per_word = _In::__bits_per_word; + const int __bits_per_word = _In::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -718,7 +718,7 @@ __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, typedef __bit_iterator<__C1, false> _I1; typedef typename _I1::difference_type difference_type; typedef typename _I1::__storage_type __storage_type; - static const unsigned __bits_per_word = _I1::__bits_per_word; + const int __bits_per_word = _I1::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -768,7 +768,7 @@ __swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1 typedef __bit_iterator<__C1, false> _I1; typedef typename _I1::difference_type difference_type; typedef typename _I1::__storage_type __storage_type; - static const unsigned __bits_per_word = _I1::__bits_per_word; + const int __bits_per_word = _I1::__bits_per_word; difference_type __n = __last - __first; if (__n > 0) { @@ -959,7 +959,7 @@ __equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> typedef __bit_iterator<_Cp, _IC1> _It; typedef typename _It::difference_type difference_type; typedef typename _It::__storage_type __storage_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + static const int __bits_per_word = _It::__bits_per_word; difference_type __n = __last1 - __first1; if (__n > 0) { @@ -1041,7 +1041,7 @@ __equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __ typedef __bit_iterator<_Cp, _IC1> _It; typedef typename _It::difference_type difference_type; typedef typename _It::__storage_type __storage_type; - static const unsigned __bits_per_word = _It::__bits_per_word; + static const int __bits_per_word = _It::__bits_per_word; difference_type __n = __last1 - __first1; if (__n > 0) { diff --git a/include/__config b/include/__config index 3edb9de017ab..321e71778228 100644 --- a/include/__config +++ b/include/__config @@ -27,14 +27,14 @@ #define _GNUC_VER 0 #endif -#define _LIBCPP_VERSION 3900 +#define _LIBCPP_VERSION 4000 #ifndef _LIBCPP_ABI_VERSION #define _LIBCPP_ABI_VERSION 1 #endif #if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 -// Change short string represention so that string data starts at offset 0, +// Change short string representation so that string data starts at offset 0, // improving its alignment in some cases. #define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT // Fix deque iterator type in order to support incomplete types. @@ -43,9 +43,15 @@ #define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB // Fix undefined behavior in how __tree stores its end and parent nodes. #define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __hash_table stores it's pointer types +#define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB #define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB #define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +// Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr +// provided under the alternate keyword __nullptr, which changes the mangling +// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode. +#define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR #elif _LIBCPP_ABI_VERSION == 1 // Feature macros for disabling pre ABI v1 features. All of these options // are deprecated. @@ -64,6 +70,9 @@ #define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) +#if __cplusplus < 201103L +#define _LIBCPP_CXX03_LANG +#endif #ifndef __has_attribute #define __has_attribute(__x) 0 @@ -83,6 +92,13 @@ #define __is_identifier(__x) 1 #endif +// Need to detect which libc we're using if we're on Linux. +#if defined(__linux__) +#include <features.h> +#if !defined(__GLIBC_PREREQ) +#define __GLIBC_PREREQ(a, b) 0 +#endif // !defined(__GLIBC_PREREQ) +#endif // defined(__linux__) #ifdef __LITTLE_ENDIAN__ #if __LITTLE_ENDIAN__ @@ -200,90 +216,6 @@ #define _LIBCPP_NO_CFI #endif -#ifdef _WIN32 - -// only really useful for a DLL -#ifdef _LIBCPP_DLL // this should be a compiler builtin define ideally... -# ifdef cxx_EXPORTS -# define _LIBCPP_HIDDEN -# define _LIBCPP_FUNC_VIS __declspec(dllexport) -# define _LIBCPP_TYPE_VIS __declspec(dllexport) -# else -# define _LIBCPP_HIDDEN -# define _LIBCPP_FUNC_VIS __declspec(dllimport) -# define _LIBCPP_TYPE_VIS __declspec(dllimport) -# endif -#else -# define _LIBCPP_HIDDEN -# define _LIBCPP_FUNC_VIS -# define _LIBCPP_TYPE_VIS -#endif - -#define _LIBCPP_TYPE_VIS_ONLY -#define _LIBCPP_FUNC_VIS_ONLY - -#ifndef _LIBCPP_INLINE_VISIBILITY -# ifdef _LIBCPP_MSVC -# define _LIBCPP_INLINE_VISIBILITY __forceinline -# else // MinGW GCC and Clang -# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) -# endif -#endif - -#ifndef _LIBCPP_EXCEPTION_ABI -#define _LIBCPP_EXCEPTION_ABI _LIBCPP_TYPE_VIS -#endif - -#ifndef _LIBCPP_ALWAYS_INLINE -# ifdef _LIBCPP_MSVC -# define _LIBCPP_ALWAYS_INLINE __forceinline -# endif -#endif - -#endif // _WIN32 - -#ifndef _LIBCPP_HIDDEN -#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) -#endif - -#ifndef _LIBCPP_FUNC_VIS -#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) -#endif - -#ifndef _LIBCPP_TYPE_VIS -# if __has_attribute(__type_visibility__) -# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default"))) -# else -# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default"))) -# endif -#endif - -#ifndef _LIBCPP_PREFERRED_OVERLOAD -# if __has_attribute(__enable_if__) -# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) -# endif -#endif - -#ifndef _LIBCPP_TYPE_VIS_ONLY -# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS -#endif - -#ifndef _LIBCPP_FUNC_VIS_ONLY -# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS -#endif - -#ifndef _LIBCPP_INLINE_VISIBILITY -#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) -#endif - -#ifndef _LIBCPP_EXCEPTION_ABI -#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) -#endif - -#ifndef _LIBCPP_ALWAYS_INLINE -#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__)) -#endif - #if defined(__clang__) // _LIBCPP_ALTERNATE_STRING_LAYOUT is an old name for @@ -302,10 +234,6 @@ # define _ALIGNAS(x) __attribute__((__aligned__(x))) #endif -#if !__has_feature(cxx_alias_templates) -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES -#endif - #if __cplusplus < 201103L typedef __char16_t char16_t; typedef __char32_t char32_t; @@ -333,14 +261,6 @@ typedef __char32_t char32_t; # define _LIBCPP_NORETURN __attribute__ ((noreturn)) #endif -#if !(__has_feature(cxx_default_function_template_args)) -#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS -#endif - -#if !(__has_feature(cxx_defaulted_functions)) -#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS -#endif // !(__has_feature(cxx_defaulted_functions)) - #if !(__has_feature(cxx_deleted_functions)) #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS #endif // !(__has_feature(cxx_deleted_functions)) @@ -350,33 +270,25 @@ typedef __char32_t char32_t; #endif #if !(__has_feature(cxx_nullptr)) -#define _LIBCPP_HAS_NO_NULLPTR +# if __has_extension(cxx_nullptr) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR) +# define nullptr __nullptr +# else +# define _LIBCPP_HAS_NO_NULLPTR +# endif #endif #if !(__has_feature(cxx_rvalue_references)) #define _LIBCPP_HAS_NO_RVALUE_REFERENCES #endif -#if !(__has_feature(cxx_static_assert)) -#define _LIBCPP_HAS_NO_STATIC_ASSERT -#endif - #if !(__has_feature(cxx_auto_type)) #define _LIBCPP_HAS_NO_AUTO_TYPE #endif -#if !(__has_feature(cxx_access_control_sfinae)) || !__has_feature(cxx_trailing_return) -#define _LIBCPP_HAS_NO_ADVANCED_SFINAE -#endif - #if !(__has_feature(cxx_variadic_templates)) #define _LIBCPP_HAS_NO_VARIADICS #endif -#if !(__has_feature(cxx_trailing_return)) -#define _LIBCPP_HAS_NO_TRAILING_RETURN -#endif - #if !(__has_feature(cxx_generalized_initializers)) #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #endif @@ -415,12 +327,12 @@ typedef __char32_t char32_t; #if defined(__FreeBSD__) #define _LIBCPP_HAS_QUICK_EXIT #define _LIBCPP_HAS_C11_FEATURES -#elif defined(__ANDROID__) +#elif defined(__Fuchsia__) #define _LIBCPP_HAS_QUICK_EXIT +#define _LIBCPP_HAS_C11_FEATURES #elif defined(__linux__) #if !defined(_LIBCPP_HAS_MUSL_LIBC) -# include <features.h> -#if __GLIBC_PREREQ(2, 15) +#if __GLIBC_PREREQ(2, 15) || defined(__BIONIC__) #define _LIBCPP_HAS_QUICK_EXIT #endif #if __GLIBC_PREREQ(2, 17) @@ -504,34 +416,25 @@ namespace std { #endif #ifndef __GXX_EXPERIMENTAL_CXX0X__ - -#define _LIBCPP_HAS_NO_ADVANCED_SFINAE #define _LIBCPP_HAS_NO_DECLTYPE -#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS -#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS #define _LIBCPP_HAS_NO_NULLPTR -#define _LIBCPP_HAS_NO_STATIC_ASSERT #define _LIBCPP_HAS_NO_UNICODE_CHARS #define _LIBCPP_HAS_NO_VARIADICS #define _LIBCPP_HAS_NO_RVALUE_REFERENCES #define _LIBCPP_HAS_NO_STRONG_ENUMS -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #define _LIBCPP_HAS_NO_NOEXCEPT #else // __GXX_EXPERIMENTAL_CXX0X__ #if _GNUC_VER < 403 -#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #define _LIBCPP_HAS_NO_RVALUE_REFERENCES -#define _LIBCPP_HAS_NO_STATIC_ASSERT #endif #if _GNUC_VER < 404 #define _LIBCPP_HAS_NO_DECLTYPE #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS -#define _LIBCPP_HAS_NO_TRAILING_RETURN #define _LIBCPP_HAS_NO_UNICODE_CHARS #define _LIBCPP_HAS_NO_VARIADICS #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -540,12 +443,6 @@ namespace std { #if _GNUC_VER < 406 #define _LIBCPP_HAS_NO_NOEXCEPT #define _LIBCPP_HAS_NO_NULLPTR -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES -#endif - -#if _GNUC_VER < 407 -#define _LIBCPP_HAS_NO_ADVANCED_SFINAE -#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS #endif #endif // __GXX_EXPERIMENTAL_CXX0X__ @@ -566,21 +463,17 @@ using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); #elif defined(_LIBCPP_MSVC) -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES #define _LIBCPP_HAS_NO_CONSTEXPR #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES #define _LIBCPP_HAS_NO_UNICODE_CHARS #define _LIBCPP_HAS_NO_DELETED_FUNCTIONS -#define _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS #define _LIBCPP_HAS_NO_NOEXCEPT #define __alignof__ __alignof #define _LIBCPP_NORETURN __declspec(noreturn) #define _ALIGNAS(x) __declspec(align(x)) #define _LIBCPP_HAS_NO_VARIADICS - - #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { #define _LIBCPP_END_NAMESPACE_STD } #define _VSTD std @@ -598,9 +491,6 @@ namespace std { #define _ATTRIBUTE(x) __attribute__((x)) #define _LIBCPP_NORETURN __attribute__((noreturn)) -#define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES -#define _LIBCPP_HAS_NO_ADVANCED_SFINAE #define _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #define _LIBCPP_HAS_NO_NOEXCEPT #define _LIBCPP_HAS_NO_NULLPTR @@ -626,6 +516,141 @@ namespace std { #endif // __clang__ || __GNUC__ || _MSC_VER || __IBMCPP__ + +#ifdef _WIN32 +#if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_DLL_VIS +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS +#elif defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_DLL_VIS __declspec(dllexport) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS +#else +# define _LIBCPP_DLL_VIS __declspec(dllimport) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS +#endif + +#define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS +#define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS +#define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS +#define _LIBCPP_HIDDEN +#define _LIBCPP_TYPE_VIS_ONLY +#define _LIBCPP_FUNC_VIS_ONLY +#define _LIBCPP_ENUM_VIS +#if defined(_LIBCPP_MSVC) +# define _LIBCPP_INLINE_VISIBILITY __forceinline +# define _LIBCPP_ALWAYS_INLINE __forceinline +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline +#else +# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) +# define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__)) +#endif +#endif // _WIN32 + +#ifndef _LIBCPP_HIDDEN +#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) +#else +#define _LIBCPP_HIDDEN +#endif +#endif + +#ifndef _LIBCPP_FUNC_VIS +#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) +#else +#define _LIBCPP_FUNC_VIS +#endif +#endif + +#ifndef _LIBCPP_TYPE_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# if __has_attribute(__type_visibility__) +# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default"))) +# endif +# else +# define _LIBCPP_TYPE_VIS +# endif +#endif + +#ifndef _LIBCPP_TYPE_VIS_ONLY +# define _LIBCPP_TYPE_VIS_ONLY _LIBCPP_TYPE_VIS +#endif + +#ifndef _LIBCPP_FUNC_VIS_ONLY +# define _LIBCPP_FUNC_VIS_ONLY _LIBCPP_FUNC_VIS +#endif + +#ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_FUNC_VIS +#endif + +#ifndef _LIBCPP_EXCEPTION_ABI +#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) +#else +#define _LIBCPP_EXCEPTION_ABI +#endif +#endif + +#ifndef _LIBCPP_ENUM_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) +# define _LIBCPP_ENUM_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define _LIBCPP_ENUM_VIS +# endif +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# endif +#endif + +#ifndef _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +#endif + +#ifndef _LIBCPP_INLINE_VISIBILITY +#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) +#else +#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) +#endif +#endif + +#ifndef _LIBCPP_ALWAYS_INLINE +#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__)) +#else +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) +#endif +#endif + +#ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__)) +# else +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__)) +# endif +#endif + +#ifndef _LIBCPP_PREFERRED_OVERLOAD +# if __has_attribute(__enable_if__) +# define _LIBCPP_PREFERRED_OVERLOAD __attribute__ ((__enable_if__(true, ""))) +# endif +#endif + #ifndef _LIBCPP_HAS_NO_NOEXCEPT # define _NOEXCEPT noexcept # define _NOEXCEPT_(x) noexcept(x) @@ -634,6 +659,17 @@ namespace std { # define _NOEXCEPT_(x) #endif +#if defined(_LIBCPP_DEBUG_USE_EXCEPTIONS) +# if !defined(_LIBCPP_DEBUG) +# error cannot use _LIBCPP_DEBUG_USE_EXCEPTIONS unless _LIBCPP_DEBUG is defined +# endif +# define _NOEXCEPT_DEBUG noexcept(false) +# define _NOEXCEPT_DEBUG_(x) noexcept(false) +#else +# define _NOEXCEPT_DEBUG _NOEXCEPT +# define _NOEXCEPT_DEBUG_(x) _NOEXCEPT_(x) +#endif + #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS typedef unsigned short char16_t; typedef unsigned int char32_t; @@ -643,8 +679,10 @@ typedef unsigned int char32_t; #define _LIBCPP_HAS_NO_INT128 #endif -#ifdef _LIBCPP_HAS_NO_STATIC_ASSERT - +#ifdef _LIBCPP_CXX03_LANG +# if __has_extension(c_static_assert) +# define static_assert(__b, __m) _Static_assert(__b, __m) +# else extern "C++" { template <bool> struct __static_assert_test; template <> struct __static_assert_test<true> {}; @@ -653,8 +691,8 @@ template <unsigned> struct __static_assert_check {}; #define static_assert(__b, __m) \ typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \ _LIBCPP_CONCAT(__t, __LINE__) - -#endif // _LIBCPP_HAS_NO_STATIC_ASSERT +# endif // __has_extension(c_static_assert) +#endif // _LIBCPP_CXX03_LANG #ifdef _LIBCPP_HAS_NO_DECLTYPE // GCC 4.6 provides __decltype in all standard modes. @@ -671,7 +709,7 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_CONSTEXPR constexpr #endif -#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifdef _LIBCPP_CXX03_LANG #define _LIBCPP_DEFAULT {} #else #define _LIBCPP_DEFAULT = default; @@ -689,7 +727,8 @@ template <unsigned> struct __static_assert_check {}; #define _NOALIAS #endif -#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) +#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \ + (!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions # define _LIBCPP_EXPLICIT explicit #else # define _LIBCPP_EXPLICIT @@ -708,7 +747,7 @@ template <unsigned> struct __static_assert_check {}; _LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \ }; #else // _LIBCPP_HAS_NO_STRONG_ENUMS -#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_TYPE_VIS x +#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x #define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) #endif // _LIBCPP_HAS_NO_STRONG_ENUMS @@ -742,7 +781,7 @@ template <unsigned> struct __static_assert_check {}; #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) +#if !defined(_WIN32) && !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) #define _LIBCPP_HAS_CATOPEN 1 #endif #endif @@ -795,6 +834,11 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_CONSTEXPR_AFTER_CXX14 #endif +// FIXME: Remove all usages of this macro once compilers catch up. +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606L) +# define _LIBCPP_HAS_NO_INLINE_VARIABLES +#endif + #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES # define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) #else @@ -802,7 +846,7 @@ template <unsigned> struct __static_assert_check {}; #endif #ifndef _LIBCPP_HAS_NO_ASAN -extern "C" void __sanitizer_annotate_contiguous_container( +_LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( const void *, const void *, const void *, const void *); #endif @@ -823,8 +867,11 @@ extern "C" void __sanitizer_annotate_contiguous_container( #endif // Thread API -#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#if !defined(_LIBCPP_HAS_NO_THREADS) && \ + !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \ + !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) # if defined(__FreeBSD__) || \ + defined(__Fuchsia__) || \ defined(__NetBSD__) || \ defined(__linux__) || \ defined(__APPLE__) || \ @@ -841,6 +888,11 @@ extern "C" void __sanitizer_annotate_contiguous_container( _LIBCPP_HAS_NO_THREADS is not defined. #endif +#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +# error _LIBCPP_HAS_EXTERNAL_THREAD_API may not be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. +#endif + #if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) # error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ _LIBCPP_HAS_NO_THREADS is defined. @@ -861,11 +913,12 @@ extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_HAS_NO_STDOUT #endif -#if defined(__ANDROID__) || defined(__CloudABI__) || defined(_LIBCPP_HAS_MUSL_LIBC) +#if defined(__BIONIC__) || defined(__CloudABI__) || \ + defined(_LIBCPP_HAS_MUSL_LIBC) #define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE #endif -// Thread-unsafe functions such as strtok(), mbtowc() and localtime() +// Thread-unsafe functions such as strtok() and localtime() // are not available. #ifdef __CloudABI__ #define _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS @@ -886,17 +939,25 @@ extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK #endif -#if __cplusplus < 201103L -#define _LIBCPP_CXX03_LANG +#if (defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && defined(__clang__) \ + && __has_attribute(acquire_capability)) +#define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +#endif + +#if __has_attribute(require_constant_initialization) +#define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__)) #else -#if defined(_LIBCPP_HAS_NO_VARIADIC_TEMPLATES) || defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) -#error Libc++ requires a feature complete C++11 compiler in C++11 or greater. +#define _LIBCPP_SAFE_STATIC #endif + +#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700 +#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF #endif -#if (defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && defined(__clang__) \ - && __has_attribute(acquire_capability)) -#define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +#if !defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) +#if defined(_WIN32) || defined(_NEWLIB_VERSION) +#define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS +#endif #endif #endif // __cplusplus diff --git a/include/__config_site.in b/include/__config_site.in index 6c2b7bb446d7..f2a1986888ba 100644 --- a/include/__config_site.in +++ b/include/__config_site.in @@ -20,5 +20,7 @@ #cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS #cmakedefine _LIBCPP_HAS_MUSL_LIBC #cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD +#cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL +#cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #endif // _LIBCPP_CONFIG_SITE diff --git a/include/__debug b/include/__debug index a21f9a89884b..f8c1129a3694 100644 --- a/include/__debug +++ b/include/__debug @@ -17,23 +17,103 @@ #pragma GCC system_header #endif -#if _LIBCPP_DEBUG_LEVEL >= 1 +#if defined(_LIBCPP_HAS_NO_NULLPTR) +# include <cstddef> +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) # include <cstdlib> # include <cstdio> # include <cstddef> -# ifndef _LIBCPP_ASSERT -# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::fprintf(stderr, "%s\n", m), _VSTD::abort())) -# endif +# include <exception> +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_ASSERT) +# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : \ + _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 2 +#ifndef _LIBCPP_DEBUG_ASSERT +#define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) +#endif +#define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__ #endif #ifndef _LIBCPP_ASSERT # define _LIBCPP_ASSERT(x, m) ((void)0) #endif +#ifndef _LIBCPP_DEBUG_ASSERT +# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) +#endif +#ifndef _LIBCPP_DEBUG_MODE +#define _LIBCPP_DEBUG_MODE(...) ((void)0) +#endif -#if _LIBCPP_DEBUG_LEVEL >= 2 +#if _LIBCPP_DEBUG_LEVEL < 1 +class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception; +#endif _LIBCPP_BEGIN_NAMESPACE_STD +struct _LIBCPP_TYPE_VIS_ONLY __libcpp_debug_info { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __libcpp_debug_info() + : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m) + : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {} + const char* __file_; + int __line_; + const char* __pred_; + const char* __msg_; +}; + +/// __libcpp_debug_function_type - The type of the assertion failure handler. +typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); + +/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT +/// fails. +extern __libcpp_debug_function_type __libcpp_debug_function; + +/// __libcpp_abort_debug_function - A debug handler that aborts when called. +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS +void __libcpp_abort_debug_function(__libcpp_debug_info const&); + +/// __libcpp_throw_debug_function - A debug handler that throws +/// an instance of __libcpp_debug_exception when called. + _LIBCPP_NORETURN _LIBCPP_FUNC_VIS +void __libcpp_throw_debug_function(__libcpp_debug_info const&); + +/// __libcpp_set_debug_function - Set the debug handler to the specified +/// function. +_LIBCPP_FUNC_VIS +bool __libcpp_set_debug_function(__libcpp_debug_function_type __func); + +// Setup the throwing debug handler during dynamic initialization. +#if _LIBCPP_DEBUG_LEVEL >= 1 && defined(_LIBCPP_DEBUG_USE_EXCEPTIONS) +# if defined(_LIBCPP_NO_EXCEPTIONS) +# error _LIBCPP_DEBUG_USE_EXCEPTIONS cannot be used when exceptions are disabled. +# endif +static bool __init_dummy = __libcpp_set_debug_function(__libcpp_throw_debug_function); +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) +class _LIBCPP_EXCEPTION_ABI __libcpp_debug_exception : public exception { +public: + __libcpp_debug_exception() _NOEXCEPT; + explicit __libcpp_debug_exception(__libcpp_debug_info const& __i); + __libcpp_debug_exception(__libcpp_debug_exception const&); + ~__libcpp_debug_exception() _NOEXCEPT; + const char* what() const _NOEXCEPT; +private: + struct __libcpp_debug_exception_imp; + __libcpp_debug_exception_imp *__imp_; +}; +#endif + +#if _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) + struct _LIBCPP_TYPE_VIS __c_node; struct _LIBCPP_TYPE_VIS __i_node @@ -102,7 +182,7 @@ struct _C_node }; template <class _Cont> -bool +inline bool _C_node<_Cont>::__dereferenceable(const void* __i) const { typedef typename _Cont::const_iterator iterator; @@ -112,7 +192,7 @@ _C_node<_Cont>::__dereferenceable(const void* __i) const } template <class _Cont> -bool +inline bool _C_node<_Cont>::__decrementable(const void* __i) const { typedef typename _Cont::const_iterator iterator; @@ -122,7 +202,7 @@ _C_node<_Cont>::__decrementable(const void* __i) const } template <class _Cont> -bool +inline bool _C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const { typedef typename _Cont::const_iterator iterator; @@ -132,7 +212,7 @@ _C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const } template <class _Cont> -bool +inline bool _C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const { typedef typename _Cont::const_iterator iterator; @@ -214,9 +294,9 @@ _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); -_LIBCPP_END_NAMESPACE_STD +#endif // _LIBCPP_DEBUG_LEVEL >= 2 || defined(_LIBCPP_BUILDING_LIBRARY) -#endif +_LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_DEBUG_H diff --git a/include/__functional_03 b/include/__functional_03 index 4edbb0996ca0..a1cec8bcac95 100644 --- a/include/__functional_03 +++ b/include/__functional_03 @@ -642,6 +642,8 @@ template<class _Rp> void function<_Rp()>::swap(function& __f) { + if (_VSTD::addressof(__f) == this) + return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; @@ -679,10 +681,8 @@ template<class _Rp> _Rp function<_Rp()>::operator()() const { -#ifndef _LIBCPP_NO_EXCEPTIONS if (__f_ == 0) - throw bad_function_call(); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_bad_function_call(); return (*__f_)(); } @@ -918,6 +918,8 @@ template<class _Rp, class _A0> void function<_Rp(_A0)>::swap(function& __f) { + if (_VSTD::addressof(__f) == this) + return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; @@ -955,10 +957,8 @@ template<class _Rp, class _A0> _Rp function<_Rp(_A0)>::operator()(_A0 __a0) const { -#ifndef _LIBCPP_NO_EXCEPTIONS if (__f_ == 0) - throw bad_function_call(); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_bad_function_call(); return (*__f_)(__a0); } @@ -1194,6 +1194,8 @@ template<class _Rp, class _A0, class _A1> void function<_Rp(_A0, _A1)>::swap(function& __f) { + if (_VSTD::addressof(__f) == this) + return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; @@ -1231,10 +1233,8 @@ template<class _Rp, class _A0, class _A1> _Rp function<_Rp(_A0, _A1)>::operator()(_A0 __a0, _A1 __a1) const { -#ifndef _LIBCPP_NO_EXCEPTIONS if (__f_ == 0) - throw bad_function_call(); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_bad_function_call(); return (*__f_)(__a0, __a1); } @@ -1470,6 +1470,8 @@ template<class _Rp, class _A0, class _A1, class _A2> void function<_Rp(_A0, _A1, _A2)>::swap(function& __f) { + if (_VSTD::addressof(__f) == this) + return; if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; @@ -1507,10 +1509,8 @@ template<class _Rp, class _A0, class _A1, class _A2> _Rp function<_Rp(_A0, _A1, _A2)>::operator()(_A0 __a0, _A1 __a1, _A2 __a2) const { -#ifndef _LIBCPP_NO_EXCEPTIONS if (__f_ == 0) - throw bad_function_call(); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_bad_function_call(); return (*__f_)(__a0, __a1, __a2); } diff --git a/include/__functional_base b/include/__functional_base index 1a08ea29deea..6e2cfefc5972 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -625,6 +625,11 @@ struct _LIBCPP_TYPE_VIS_ONLY uses_allocator { }; +#if _LIBCPP_STD_VER > 14 +template <class _Tp, class _Alloc> +constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; +#endif + #ifndef _LIBCPP_HAS_NO_VARIADICS // allocator construction @@ -632,7 +637,8 @@ struct _LIBCPP_TYPE_VIS_ONLY uses_allocator template <class _Tp, class _Alloc, class ..._Args> struct __uses_alloc_ctor_imp { - static const bool __ua = uses_allocator<_Tp, _Alloc>::value; + typedef typename __uncvref<_Alloc>::type _RawAlloc; + static const bool __ua = uses_allocator<_Tp, _RawAlloc>::value; static const bool __ic = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; static const int value = __ua ? 2 - __ic : 0; @@ -650,6 +656,7 @@ void __user_alloc_construct_impl (integral_constant<int, 0>, _Tp *__storage, con new (__storage) _Tp (_VSTD::forward<_Args>(__args)...); } +// FIXME: This should have a version which takes a non-const alloc. template <class _Tp, class _Allocator, class... _Args> inline _LIBCPP_INLINE_VISIBILITY void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) @@ -657,6 +664,7 @@ void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, con new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); } +// FIXME: This should have a version which takes a non-const alloc. template <class _Tp, class _Allocator, class... _Args> inline _LIBCPP_INLINE_VISIBILITY void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) @@ -664,6 +672,7 @@ void __user_alloc_construct_impl (integral_constant<int, 2>, _Tp *__storage, con new (__storage) _Tp (_VSTD::forward<_Args>(__args)..., __a); } +// FIXME: Theis should have a version which takes a non-const alloc. template <class _Tp, class _Allocator, class... _Args> inline _LIBCPP_INLINE_VISIBILITY void __user_alloc_construct (_Tp *__storage, const _Allocator &__a, _Args &&... __args) diff --git a/include/__hash_table b/include/__hash_table index 08bc519ae17f..9a0d441b37b8 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -59,9 +59,38 @@ size_t __next_prime(size_t __n); template <class _NodePtr> struct __hash_node_base { + typedef typename pointer_traits<_NodePtr>::element_type __node_type; typedef __hash_node_base __first_node; + typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer; + typedef _NodePtr __node_pointer; + +#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) + typedef __node_base_pointer __next_pointer; +#else + typedef typename conditional< + is_pointer<__node_pointer>::value, + __node_base_pointer, + __node_pointer>::type __next_pointer; +#endif + + __next_pointer __next_; + + _LIBCPP_INLINE_VISIBILITY + __next_pointer __ptr() _NOEXCEPT { + return static_cast<__next_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(*this)); + } - _NodePtr __next_; + _LIBCPP_INLINE_VISIBILITY + __node_pointer __upcast() _NOEXCEPT { + return static_cast<__node_pointer>( + pointer_traits<__node_base_pointer>::pointer_to(*this)); + } + + _LIBCPP_INLINE_VISIBILITY + size_t __hash() const _NOEXCEPT { + return static_cast<__node_type const&>(*this).__hash_; + } _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} }; @@ -75,7 +104,7 @@ struct __hash_node { typedef _Tp __node_value_type; - size_t __hash_; + size_t __hash_; __node_value_type __value_; }; @@ -219,11 +248,14 @@ public: typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type __node_base_pointer; + typedef typename __node_base_type::__next_pointer __next_pointer; + typedef _Tp __node_value_type; typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type __node_value_type_pointer; typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type __const_node_value_type_pointer; + private: static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const"); @@ -233,8 +265,6 @@ private: _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); }; - - template <class _HashIterator> struct __hash_node_types_from_iterator; template <class _NodePtr> @@ -258,9 +288,10 @@ template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator { typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __node_pointer __node_; + __next_pointer __node_; public: typedef forward_iterator_tag iterator_category; @@ -269,18 +300,11 @@ public: typedef value_type& reference; typedef typename _NodeTypes::__node_value_type_pointer pointer; - _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT -#if _LIBCPP_STD_VER > 11 - : __node_(nullptr) -#endif - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_i(this); -#endif + _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY __hash_iterator(const __hash_iterator& __i) : __node_(__i.__node_) @@ -304,35 +328,26 @@ public: } return *this; } - #endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container iterator"); -#endif - return __node_->__value_; - } + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container iterator"); + return __node_->__upcast()->__value_; + } + _LIBCPP_INLINE_VISIBILITY - pointer operator->() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable unordered container iterator"); -#endif - return pointer_traits<pointer>::pointer_to(__node_->__value_); - } + return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); + } _LIBCPP_INLINE_VISIBILITY - __hash_iterator& operator++() - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + __hash_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to increment non-incrementable unordered container iterator"); -#endif __node_ = __node_->__next_; return *this; } @@ -357,18 +372,17 @@ public: private: #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__node_pointer __node, const void* __c) _NOEXCEPT + __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT : __node_(__node) { __get_db()->__insert_ic(this, __c); } #else _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__node_pointer __node) _NOEXCEPT + __hash_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {} #endif - template <class, class, class, class> friend class __hash_table; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator; @@ -381,9 +395,10 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator { static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, ""); typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __node_pointer __node_; + __next_pointer __node_; public: typedef __hash_iterator<_NodePtr> __non_const_iterator; @@ -395,26 +410,18 @@ public: typedef typename _NodeTypes::__const_node_value_type_pointer pointer; - _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT -#if _LIBCPP_STD_VER > 11 - : __node_(nullptr) -#endif - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_i(this); -#endif + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__iterator_copy(this, &__x); -#endif + _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); } #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY __hash_const_iterator(const __hash_const_iterator& __i) : __node_(__i.__node_) @@ -438,35 +445,25 @@ public: } return *this; } - #endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable unordered container const_iterator"); -#endif - return __node_->__value_; - } + return __node_->__upcast()->__value_; + } _LIBCPP_INLINE_VISIBILITY - pointer operator->() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable unordered container const_iterator"); -#endif - return pointer_traits<pointer>::pointer_to(__node_->__value_); - } + return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); + } _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator& operator++() - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment non-incrementable unordered container const_iterator"); -#endif + __hash_const_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable unordered container const_iterator"); __node_ = __node_->__next_; return *this; } @@ -491,18 +488,17 @@ public: private: #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__node_pointer __node, const void* __c) _NOEXCEPT + __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT : __node_(__node) { __get_db()->__insert_ic(this, __c); } #else _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__node_pointer __node) _NOEXCEPT + __hash_const_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {} #endif - template <class, class, class, class> friend class __hash_table; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; @@ -513,9 +509,10 @@ template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator { typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __node_pointer __node_; + __next_pointer __node_; size_t __bucket_; size_t __bucket_count_; @@ -526,15 +523,11 @@ public: typedef value_type& reference; typedef typename _NodeTypes::__node_value_type_pointer pointer; - _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_i(this); -#endif + _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY __hash_local_iterator(const __hash_local_iterator& __i) : __node_(__i.__node_), @@ -562,37 +555,28 @@ public: } return *this; } - #endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable unordered container local_iterator"); -#endif - return __node_->__value_; - } + return __node_->__upcast()->__value_; + } + _LIBCPP_INLINE_VISIBILITY - pointer operator->() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container local_iterator"); -#endif - return pointer_traits<pointer>::pointer_to(__node_->__value_); - } + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); + } _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator& operator++() - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + __hash_local_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to increment non-incrementable unordered container local_iterator"); -#endif __node_ = __node_->__next_; - if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_) + if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; return *this; } @@ -617,7 +601,7 @@ public: private: #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(__node_pointer __node, size_t __bucket, + __hash_local_iterator(__next_pointer __node, size_t __bucket, size_t __bucket_count, const void* __c) _NOEXCEPT : __node_(__node), __bucket_(__bucket), @@ -629,7 +613,7 @@ private: } #else _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(__node_pointer __node, size_t __bucket, + __hash_local_iterator(__next_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT : __node_(__node), __bucket_(__bucket), @@ -648,9 +632,10 @@ template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator { typedef __hash_node_types<_ConstNodePtr> _NodeTypes; - typedef _ConstNodePtr __node_pointer; + typedef _ConstNodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __node_pointer __node_; + __next_pointer __node_; size_t __bucket_; size_t __bucket_count_; @@ -670,11 +655,8 @@ public: typedef typename _NodeTypes::__const_node_value_type_pointer pointer; - _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__insert_i(this); -#endif + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { + _LIBCPP_DEBUG_MODE(__get_db()->__insert_i(this)); } _LIBCPP_INLINE_VISIBILITY @@ -683,13 +665,10 @@ public: __bucket_(__x.__bucket_), __bucket_count_(__x.__bucket_count_) { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __get_db()->__iterator_copy(this, &__x); -#endif + _LIBCPP_DEBUG_MODE(__get_db()->__iterator_copy(this, &__x)); } #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(const __hash_const_local_iterator& __i) : __node_(__i.__node_), @@ -717,37 +696,28 @@ public: } return *this; } - #endif // _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - reference operator*() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + reference operator*() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); -#endif - return __node_->__value_; - } + return __node_->__upcast()->__value_; + } + _LIBCPP_INLINE_VISIBILITY - pointer operator->() const - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + pointer operator->() const { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); -#endif - return pointer_traits<pointer>::pointer_to(__node_->__value_); - } + return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); + } _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator& operator++() - { -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + __hash_const_local_iterator& operator++() { + _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to increment non-incrementable unordered container const_local_iterator"); -#endif __node_ = __node_->__next_; - if (__node_ != nullptr && __constrain_hash(__node_->__hash_, __bucket_count_) != __bucket_) + if (__node_ != nullptr && __constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) __node_ = nullptr; return *this; } @@ -772,7 +742,7 @@ public: private: #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__node_pointer __node, size_t __bucket, + __hash_const_local_iterator(__next_pointer __node, size_t __bucket, size_t __bucket_count, const void* __c) _NOEXCEPT : __node_(__node), __bucket_(__bucket), @@ -784,7 +754,7 @@ private: } #else _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(__node_pointer __node, size_t __bucket, + __hash_const_local_iterator(__next_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT : __node_(__node), __bucket_(__bucket), @@ -927,6 +897,7 @@ public: typedef typename _NodeTypes::__node_pointer __node_const_pointer; typedef typename _NodeTypes::__node_base_type __first_node; typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; private: // check for sane allocator pointer rebinding semantics. Rebinding the @@ -942,11 +913,11 @@ private: private: - typedef typename __rebind_alloc_helper<__node_traits, __node_pointer>::type __pointer_allocator; + typedef typename __rebind_alloc_helper<__node_traits, __next_pointer>::type __pointer_allocator; typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; - typedef unique_ptr<__node_pointer[], __bucket_list_deleter> __bucket_list; + typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; - typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; + typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; // --- Member data begin --- __bucket_list __bucket_list_; @@ -1033,8 +1004,10 @@ public: _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { - return allocator_traits<__pointer_allocator>::max_size( - __bucket_list_.get_deleter().__alloc()); + return std::min<size_type>( + __node_traits::max_size(__node_alloc()), + numeric_limits<difference_type >::max() + ); } pair<iterator, bool> __node_insert_unique(__node_pointer __nd); @@ -1129,6 +1102,7 @@ public: #else // !defined(_LIBCPP_CXX03_LANG) template <class _Key, class _Args> + _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); iterator __insert_multi(const __container_value_type& __x); @@ -1207,7 +1181,7 @@ public: void swap(__hash_table& __u) #if _LIBCPP_STD_VER <= 11 - _NOEXCEPT_( + _NOEXCEPT_DEBUG_( __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || __is_nothrow_swappable<__pointer_allocator>::value) @@ -1215,12 +1189,12 @@ public: || __is_nothrow_swappable<__node_allocator>::value) ); #else - _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value); + _NOEXCEPT_DEBUG_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value); #endif _LIBCPP_INLINE_VISIBILITY size_type max_bucket_count() const _NOEXCEPT - {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());} + {return max_size(); } size_type bucket_size(size_type __n) const; _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT { @@ -1347,8 +1321,8 @@ private: void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} #endif // _LIBCPP_CXX03_LANG - void __deallocate(__node_pointer __np) _NOEXCEPT; - __node_pointer __detach() _NOEXCEPT; + void __deallocate(__next_pointer __np) _NOEXCEPT; + __next_pointer __detach() _NOEXCEPT; template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_map; template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; @@ -1439,8 +1413,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) { if (size() > 0) { - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = - static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); __u.__p1_.first().__next_ = nullptr; __u.size() = 0; } @@ -1463,8 +1437,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, { __p1_.first().__next_ = __u.__p1_.first().__next_; __u.__p1_.first().__next_ = nullptr; - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = - static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); size() = __u.size(); __u.size() = 0; } @@ -1518,13 +1492,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) template <class _Tp, class _Hash, class _Equal, class _Alloc> void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__next_pointer __np) _NOEXCEPT { __node_allocator& __na = __node_alloc(); while (__np != nullptr) { - __node_pointer __next = __np->__next_; + __next_pointer __next = __np->__next_; #if _LIBCPP_DEBUG_LEVEL >= 2 __c_node* __c = __get_db()->__find_c_and_lock(this); for (__i_node** __p = __c->end_; __p != __c->beg_; ) @@ -1540,21 +1514,22 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) } __get_db()->unlock(); #endif - __node_traits::destroy(__na, _NodeTypes::__get_ptr(__np->__value_)); - __node_traits::deallocate(__na, __np, 1); + __node_pointer __real_np = __np->__upcast(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); + __node_traits::deallocate(__na, __real_np, 1); __np = __next; } } template <class _Tp, class _Hash, class _Equal, class _Alloc> -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT { size_type __bc = bucket_count(); for (size_type __i = 0; __i < __bc; ++__i) __bucket_list_[__i] = nullptr; size() = 0; - __node_pointer __cache = __p1_.first().__next_; + __next_pointer __cache = __p1_.first().__next_; __p1_.first().__next_ = nullptr; return __cache; } @@ -1582,8 +1557,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __p1_.first().__next_ = __u.__p1_.first().__next_; if (size() > 0) { - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = - static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); __u.__p1_.first().__next_ = nullptr; __u.size() = 0; } @@ -1606,7 +1581,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( max_load_factor() = __u.max_load_factor(); if (bucket_count() != 0) { - __node_pointer __cache = __detach(); + __next_pointer __cache = __detach(); #ifndef _LIBCPP_NO_EXCEPTIONS try { @@ -1614,9 +1589,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( const_iterator __i = __u.begin(); while (__cache != nullptr && __u.size() != 0) { - __cache->__value_ = _VSTD::move(__u.remove(__i++)->__value_); - __node_pointer __next = __cache->__next_; - __node_insert_multi(__cache); + __cache->__upcast()->__value_ = + _VSTD::move(__u.remove(__i++)->__value_); + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); __cache = __next; } #ifndef _LIBCPP_NO_EXCEPTIONS @@ -1669,16 +1645,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first if (bucket_count() != 0) { - __node_pointer __cache = __detach(); + __next_pointer __cache = __detach(); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (; __cache != nullptr && __first != __last; ++__first) { - __cache->__value_ = *__first; - __node_pointer __next = __cache->__next_; - __node_insert_unique(__cache); + __cache->__upcast()->__value_ = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_unique(__cache->__upcast()); __cache = __next; } #ifndef _LIBCPP_NO_EXCEPTIONS @@ -1709,16 +1685,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, " or the nodes value type"); if (bucket_count() != 0) { - __node_pointer __cache = __detach(); + __next_pointer __cache = __detach(); #ifndef _LIBCPP_NO_EXCEPTIONS try { #endif // _LIBCPP_NO_EXCEPTIONS for (; __cache != nullptr && __first != __last; ++__first) { - __cache->__value_ = *__first; - __node_pointer __next = __cache->__next_; - __node_insert_multi(__cache); + __cache->__upcast()->__value_ = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); __cache = __next; } #ifndef _LIBCPP_NO_EXCEPTIONS @@ -1805,7 +1781,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ __nd->__hash_ = hash_function()(__nd->__value_); size_type __bc = bucket_count(); bool __inserted = false; - __node_pointer __ndptr; + __next_pointer __ndptr; size_t __chash; if (__bc != 0) { @@ -1814,10 +1790,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ if (__ndptr != nullptr) { for (__ndptr = __ndptr->__next_; __ndptr != nullptr && - __constrain_hash(__ndptr->__hash_, __bc) == __chash; + __constrain_hash(__ndptr->__hash(), __bc) == __chash; __ndptr = __ndptr->__next_) { - if (key_eq()(__ndptr->__value_, __nd->__value_)) + if (key_eq()(__ndptr->__upcast()->__value_, __nd->__value_)) goto __done; } } @@ -1831,23 +1807,23 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ __chash = __constrain_hash(__nd->__hash_, __bc); } // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __node_pointer __pn = __bucket_list_[__chash]; + __next_pointer __pn = __bucket_list_[__chash]; if (__pn == nullptr) { - __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __pn =__p1_.first().__ptr(); __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd; + __pn->__next_ = __nd->__ptr(); // fix up __bucket_list_ __bucket_list_[__chash] = __pn; if (__nd->__next_ != nullptr) - __bucket_list_[__constrain_hash(__nd->__next_->__hash_, __bc)] = __nd; + __bucket_list_[__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); } else { __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd; + __pn->__next_ = __nd->__ptr(); } - __ndptr = __nd; + __ndptr = __nd->__ptr(); // increment size ++size(); __inserted = true; @@ -1873,21 +1849,22 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c __bc = bucket_count(); } size_t __chash = __constrain_hash(__cp->__hash_, __bc); - __node_pointer __pn = __bucket_list_[__chash]; + __next_pointer __pn = __bucket_list_[__chash]; if (__pn == nullptr) { - __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __pn =__p1_.first().__ptr(); __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp; + __pn->__next_ = __cp->__ptr(); // fix up __bucket_list_ __bucket_list_[__chash] = __pn; if (__cp->__next_ != nullptr) - __bucket_list_[__constrain_hash(__cp->__next_->__hash_, __bc)] = __cp; + __bucket_list_[__constrain_hash(__cp->__next_->__hash(), __bc)] + = __cp->__ptr(); } else { for (bool __found = false; __pn->__next_ != nullptr && - __constrain_hash(__pn->__next_->__hash_, __bc) == __chash; + __constrain_hash(__pn->__next_->__hash(), __bc) == __chash; __pn = __pn->__next_) { // __found key_eq() action @@ -1895,8 +1872,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c // true true loop // false true set __found to true // true false break - if (__found != (__pn->__next_->__hash_ == __cp->__hash_ && - key_eq()(__pn->__next_->__value_, __cp->__value_))) + if (__found != (__pn->__next_->__hash() == __cp->__hash_ && + key_eq()(__pn->__next_->__upcast()->__value_, __cp->__value_))) { if (!__found) __found = true; @@ -1905,19 +1882,19 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c } } __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp; + __pn->__next_ = __cp->__ptr(); if (__cp->__next_ != nullptr) { - size_t __nhash = __constrain_hash(__cp->__next_->__hash_, __bc); + size_t __nhash = __constrain_hash(__cp->__next_->__hash(), __bc); if (__nhash != __chash) - __bucket_list_[__nhash] = __cp; + __bucket_list_[__nhash] = __cp->__ptr(); } } ++size(); #if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(__cp, this); + return iterator(__cp->__ptr(), this); #else - return iterator(__cp); + return iterator(__cp->__ptr()); #endif } @@ -1933,8 +1910,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( #endif if (__p != end() && key_eq()(*__p, __cp->__value_)) { - __node_pointer __np = __p.__node_; - __cp->__hash_ = __np->__hash_; + __next_pointer __np = __p.__node_; + __cp->__hash_ = __np->__hash(); size_type __bc = bucket_count(); if (size()+1 > __bc * max_load_factor() || __bc == 0) { @@ -1943,16 +1920,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( __bc = bucket_count(); } size_t __chash = __constrain_hash(__cp->__hash_, __bc); - __node_pointer __pp = __bucket_list_[__chash]; + __next_pointer __pp = __bucket_list_[__chash]; while (__pp->__next_ != __np) __pp = __pp->__next_; __cp->__next_ = __np; - __pp->__next_ = __cp; + __pp->__next_ = static_cast<__next_pointer>(__cp); ++size(); #if _LIBCPP_DEBUG_LEVEL >= 2 - return iterator(__cp, this); + return iterator(static_cast<__next_pointer>(__cp), this); #else - return iterator(__cp); + return iterator(static_cast<__next_pointer>(__cp)); #endif } return __node_insert_multi(__cp); @@ -1963,13 +1940,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( #ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class _Key, class ..._Args> -_LIBCPP_INLINE_VISIBILITY pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) #else template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class _Key, class _Args> -_LIBCPP_INLINE_VISIBILITY pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args& __args) #endif @@ -1978,7 +1953,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& size_t __hash = hash_function()(__k); size_type __bc = bucket_count(); bool __inserted = false; - __node_pointer __nd; + __next_pointer __nd; size_t __chash; if (__bc != 0) { @@ -1987,10 +1962,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - __constrain_hash(__nd->__hash_, __bc) == __chash; + (__nd->__hash() == __hash || __constrain_hash(__nd->__hash(), __bc) == __chash); __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __k)) + if (key_eq()(__nd->__upcast()->__value_, __k)) goto __done; } } @@ -2009,23 +1984,24 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __chash = __constrain_hash(__hash, __bc); } // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __node_pointer __pn = __bucket_list_[__chash]; + __next_pointer __pn = __bucket_list_[__chash]; if (__pn == nullptr) { - __pn = static_cast<__node_pointer>(static_cast<__void_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))); + __pn = __p1_.first().__ptr(); __h->__next_ = __pn->__next_; - __pn->__next_ = __h.get(); + __pn->__next_ = __h.get()->__ptr(); // fix up __bucket_list_ __bucket_list_[__chash] = __pn; if (__h->__next_ != nullptr) - __bucket_list_[__constrain_hash(__h->__next_->__hash_, __bc)] = __h.get(); + __bucket_list_[__constrain_hash(__h->__next_->__hash(), __bc)] + = __h.get()->__ptr(); } else { __h->__next_ = __pn->__next_; - __pn->__next_ = __h.get(); + __pn->__next_ = static_cast<__next_pointer>(__h.get()); } - __nd = __h.release(); + __nd = static_cast<__next_pointer>(__h.release()); // increment size ++size(); __inserted = true; @@ -2149,17 +2125,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) { for (size_type __i = 0; __i < __nbc; ++__i) __bucket_list_[__i] = nullptr; - __node_pointer __pp(static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))); - __node_pointer __cp = __pp->__next_; + __next_pointer __pp = __p1_.first().__ptr(); + __next_pointer __cp = __pp->__next_; if (__cp != nullptr) { - size_type __chash = __constrain_hash(__cp->__hash_, __nbc); + size_type __chash = __constrain_hash(__cp->__hash(), __nbc); __bucket_list_[__chash] = __pp; size_type __phash = __chash; for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { - __chash = __constrain_hash(__cp->__hash_, __nbc); + __chash = __constrain_hash(__cp->__hash(), __nbc); if (__chash == __phash) __pp = __cp; else @@ -2172,9 +2148,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc) } else { - __node_pointer __np = __cp; + __next_pointer __np = __cp; for (; __np->__next_ != nullptr && - key_eq()(__cp->__value_, __np->__next_->__value_); + key_eq()(__cp->__upcast()->__value_, + __np->__next_->__upcast()->__value_); __np = __np->__next_) ; __pp->__next_ = __np->__next_; @@ -2198,15 +2175,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) if (__bc != 0) { size_t __chash = __constrain_hash(__hash, __bc); - __node_pointer __nd = __bucket_list_[__chash]; + __next_pointer __nd = __bucket_list_[__chash]; if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - (__nd->__hash_ == __hash - || __constrain_hash(__nd->__hash_, __bc) == __chash); + (__nd->__hash() == __hash + || __constrain_hash(__nd->__hash(), __bc) == __chash); __nd = __nd->__next_) { - if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) + if ((__nd->__hash() == __hash) + && key_eq()(__nd->__upcast()->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__nd, this); #else @@ -2228,14 +2206,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const if (__bc != 0) { size_t __chash = __constrain_hash(__hash, __bc); - __node_const_pointer __nd = __bucket_list_[__chash]; + __next_pointer __nd = __bucket_list_[__chash]; if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - (__hash == __nd->__hash_ || __constrain_hash(__nd->__hash_, __bc) == __chash); + (__hash == __nd->__hash() + || __constrain_hash(__nd->__hash(), __bc) == __chash); __nd = __nd->__next_) { - if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) + if ((__nd->__hash() == __hash) + && key_eq()(__nd->__upcast()->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return const_iterator(__nd, this); #else @@ -2320,7 +2300,7 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { - __node_pointer __np = __p.__node_; + __next_pointer __np = __p.__node_; #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered container erase(iterator) called with an iterator not" @@ -2354,7 +2334,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, ++__first; erase(__p); } - __node_pointer __np = __last.__node_; + __next_pointer __np = __last.__node_; #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator (__np, this); #else @@ -2398,26 +2378,27 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT { // current node - __node_pointer __cn = __p.__node_; + __next_pointer __cn = __p.__node_; size_type __bc = bucket_count(); - size_t __chash = __constrain_hash(__cn->__hash_, __bc); + size_t __chash = __constrain_hash(__cn->__hash(), __bc); // find previous node - __node_pointer __pn = __bucket_list_[__chash]; + __next_pointer __pn = __bucket_list_[__chash]; for (; __pn->__next_ != __cn; __pn = __pn->__next_) ; // Fix up __bucket_list_ // if __pn is not in same bucket (before begin is not in same bucket) && // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) - if (__pn == static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())) - || __constrain_hash(__pn->__hash_, __bc) != __chash) + if (__pn == __p1_.first().__ptr() + || __constrain_hash(__pn->__hash(), __bc) != __chash) { - if (__cn->__next_ == nullptr || __constrain_hash(__cn->__next_->__hash_, __bc) != __chash) + if (__cn->__next_ == nullptr + || __constrain_hash(__cn->__next_->__hash(), __bc) != __chash) __bucket_list_[__chash] = nullptr; } // if __cn->__next_ is not in same bucket (nullptr is in same bucket) if (__cn->__next_ != nullptr) { - size_t __nhash = __constrain_hash(__cn->__next_->__hash_, __bc); + size_t __nhash = __constrain_hash(__cn->__next_->__hash(), __bc); if (__nhash != __chash) __bucket_list_[__nhash] = __pn; } @@ -2427,20 +2408,20 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT --size(); #if _LIBCPP_DEBUG_LEVEL >= 2 __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) + for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); + --__dp; + iterator* __i = static_cast<iterator*>((*__dp)->__i_); if (__i->__node_ == __cn) { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + (*__dp)->__c_ = nullptr; + if (--__c->end_ != __dp) + memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); } } __get_db()->unlock(); #endif - return __node_holder(__cn, _Dp(__node_alloc(), true)); + return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); } template <class _Tp, class _Hash, class _Equal, class _Alloc> @@ -2543,7 +2524,7 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc> void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) #if _LIBCPP_STD_VER <= 11 - _NOEXCEPT_( + _NOEXCEPT_DEBUG_( __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || __is_nothrow_swappable<__pointer_allocator>::value) @@ -2551,9 +2532,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) || __is_nothrow_swappable<__node_allocator>::value) ) #else - _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value) + _NOEXCEPT_DEBUG_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value) #endif { + _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || + this->__node_alloc() == __u.__node_alloc(), + "list::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); { __node_pointer_pointer __npp = __bucket_list_.release(); __bucket_list_.reset(__u.__bucket_list_.release()); @@ -2567,11 +2552,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) __p2_.swap(__u.__p2_); __p3_.swap(__u.__p3_); if (size() > 0) - __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash_, bucket_count())] = - static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __bucket_list_[__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = + __p1_.first().__ptr(); if (__u.size() > 0) - __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash_, __u.bucket_count())] = - static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__u.__p1_.first())); + __u.__bucket_list_[__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = + __u.__p1_.first().__ptr(); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->swap(this, &__u); #endif @@ -2583,13 +2568,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const { _LIBCPP_ASSERT(__n < bucket_count(), "unordered container::bucket_size(n) called with n >= bucket_count()"); - __node_const_pointer __np = __bucket_list_[__n]; + __next_pointer __np = __bucket_list_[__n]; size_type __bc = bucket_count(); size_type __r = 0; if (__np != nullptr) { for (__np = __np->__next_; __np != nullptr && - __constrain_hash(__np->__hash_, __bc) == __n; + __constrain_hash(__np->__hash(), __bc) == __n; __np = __np->__next_, ++__r) ; } diff --git a/include/__libcpp_version b/include/__libcpp_version new file mode 100644 index 000000000000..a2113715a3e8 --- /dev/null +++ b/include/__libcpp_version @@ -0,0 +1 @@ +4000
\ No newline at end of file diff --git a/include/__locale b/include/__locale index 7bc701dda6e3..535ee165f652 100644 --- a/include/__locale +++ b/include/__locale @@ -165,10 +165,9 @@ template <class _Facet> locale locale::combine(const locale& __other) const { -#ifndef _LIBCPP_NO_EXCEPTIONS if (!_VSTD::has_facet<_Facet>(__other)) - throw runtime_error("locale::combine: locale missing facet"); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_runtime_error("locale::combine: locale missing facet"); + return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other))); } @@ -270,8 +269,8 @@ collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const return static_cast<long>(__h); } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>) // template <class CharT> class collate_byname; @@ -1179,12 +1178,12 @@ codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() { } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char, char, mbstate_t>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>) -_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); template <size_t _Np> struct __narrow_to_utf8 diff --git a/include/__mutex_base b/include/__mutex_base index 38a76ac6f2ec..59458ecdf7b8 100644 --- a/include/__mutex_base +++ b/include/__mutex_base @@ -43,7 +43,7 @@ class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mut public: _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_HAS_NO_CONSTEXPR - constexpr mutex() _NOEXCEPT _LIBCPP_DEFAULT + constexpr mutex() _NOEXCEPT = default; #else mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;} #endif @@ -300,7 +300,7 @@ class _LIBCPP_TYPE_VIS condition_variable public: _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_HAS_NO_CONSTEXPR - constexpr condition_variable() _NOEXCEPT _LIBCPP_DEFAULT + constexpr condition_variable() _NOEXCEPT = default; #else condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;} #endif diff --git a/include/__nullptr b/include/__nullptr index 95415a6325a3..38ee379eff9d 100644 --- a/include/__nullptr +++ b/include/__nullptr @@ -42,10 +42,6 @@ struct _LIBCPP_TYPE_VIS_ONLY nullptr_t friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;} friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;} - friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<(nullptr_t, nullptr_t) {return false;} - friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator<=(nullptr_t, nullptr_t) {return true;} - friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>(nullptr_t, nullptr_t) {return false;} - friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator>=(nullptr_t, nullptr_t) {return true;} }; inline _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);} diff --git a/include/__refstring b/include/__refstring index 61ccc75122a5..7f417a03c491 100644 --- a/include/__refstring +++ b/include/__refstring @@ -11,6 +11,7 @@ #define _LIBCPP___REFSTRING #include <__config> +#include <stdexcept> #include <cstddef> #include <cstring> #ifdef __APPLE__ @@ -20,119 +21,106 @@ _LIBCPP_BEGIN_NAMESPACE_STD -class _LIBCPP_HIDDEN __libcpp_refstring -{ -private: - const char* str_; +namespace __refstring_imp { namespace { +typedef int count_t; - typedef int count_t; +struct _Rep_base { + std::size_t len; + std::size_t cap; + count_t count; +}; - struct _Rep_base - { - std::size_t len; - std::size_t cap; - count_t count; - }; - - static - _Rep_base* - rep_from_data(const char *data_) _NOEXCEPT - { - char *data = const_cast<char *>(data_); - return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base)); - } - static - char * - data_from_rep(_Rep_base *rep) _NOEXCEPT - { - char *data = reinterpret_cast<char *>(rep); - return data + sizeof(*rep); - } +inline _Rep_base* rep_from_data(const char *data_) noexcept { + char *data = const_cast<char *>(data_); + return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base)); +} -#ifdef __APPLE__ - static - const char* - compute_gcc_empty_string_storage() _NOEXCEPT - { - void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); - if (handle == nullptr) - return nullptr; - void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE"); - if (sym == nullptr) - return nullptr; - return data_from_rep(reinterpret_cast<_Rep_base *>(sym)); - } - - static - const char* - get_gcc_empty_string_storage() _NOEXCEPT - { - static const char* p = compute_gcc_empty_string_storage(); - return p; - } +inline char * data_from_rep(_Rep_base *rep) noexcept { + char *data = reinterpret_cast<char *>(rep); + return data + sizeof(*rep); +} - bool - uses_refcount() const - { - return str_ != get_gcc_empty_string_storage(); - } -#else - bool - uses_refcount() const - { - return true; - } +#if defined(__APPLE__) +inline +const char* compute_gcc_empty_string_storage() _NOEXCEPT +{ + void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); + if (handle == nullptr) + return nullptr; + void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE"); + if (sym == nullptr) + return nullptr; + return data_from_rep(reinterpret_cast<_Rep_base *>(sym)); +} + +inline +const char* +get_gcc_empty_string_storage() _NOEXCEPT +{ + static const char* p = compute_gcc_empty_string_storage(); + return p; +} #endif -public: - explicit __libcpp_refstring(const char* msg) { - std::size_t len = strlen(msg); - _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1)); - rep->len = len; - rep->cap = len; - rep->count = 0; - char *data = data_from_rep(rep); - std::memcpy(data, msg, len + 1); - str_ = data; - } - - __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT : str_(s.str_) - { - if (uses_refcount()) - __sync_add_and_fetch(&rep_from_data(str_)->count, 1); - } - - __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT +}} // namespace __refstring_imp + +using namespace __refstring_imp; + +inline +__libcpp_refstring::__libcpp_refstring(const char* msg) { + std::size_t len = strlen(msg); + _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1)); + rep->len = len; + rep->cap = len; + rep->count = 0; + char *data = data_from_rep(rep); + std::memcpy(data, msg, len + 1); + __imp_ = data; +} + +inline +__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT + : __imp_(s.__imp_) +{ + if (__uses_refcount()) + __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); +} + +inline +__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT { + bool adjust_old_count = __uses_refcount(); + struct _Rep_base *old_rep = rep_from_data(__imp_); + __imp_ = s.__imp_; + if (__uses_refcount()) + __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); + if (adjust_old_count) { - bool adjust_old_count = uses_refcount(); - struct _Rep_base *old_rep = rep_from_data(str_); - str_ = s.str_; - if (uses_refcount()) - __sync_add_and_fetch(&rep_from_data(str_)->count, 1); - if (adjust_old_count) + if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0) { - if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0) - { - ::operator delete(old_rep); - } + ::operator delete(old_rep); } - return *this; } - - ~__libcpp_refstring() - { - if (uses_refcount()) - { - _Rep_base* rep = rep_from_data(str_); - if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) - { - ::operator delete(rep); - } + return *this; +} + +inline +__libcpp_refstring::~__libcpp_refstring() { + if (__uses_refcount()) { + _Rep_base* rep = rep_from_data(__imp_); + if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) { + ::operator delete(rep); } } +} - const char* c_str() const _NOEXCEPT {return str_;} -}; +inline +bool __libcpp_refstring::__uses_refcount() const { +#ifdef __APPLE__ + return __imp_ != get_gcc_empty_string_storage(); +#else + return true; +#endif +} _LIBCPP_END_NAMESPACE_STD diff --git a/include/__std_stream b/include/__std_stream index f867cd23bdd5..fb5a346f10d8 100644 --- a/include/__std_stream +++ b/include/__std_stream @@ -297,7 +297,7 @@ __stdoutbuf<_CharT>::overflow(int_type __c) return traits_type::eof(); if (__r == codecvt_base::partial) { - pbase = (char_type*)__e; + pbase = const_cast<char_type*>(__e); } } else diff --git a/include/__string b/include/__string new file mode 100644 index 000000000000..b612d6ba627d --- /dev/null +++ b/include/__string @@ -0,0 +1,766 @@ +// -*- C++ -*- +//===-------------------------- __string ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___STRING +#define _LIBCPP___STRING + +/* + string synopsis + +namespace std +{ + +template <class charT> +struct char_traits +{ + typedef charT char_type; + typedef ... int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static void assign(char_type& c1, const char_type& c2) noexcept; + static constexpr bool eq(char_type c1, char_type c2) noexcept; + static constexpr bool lt(char_type c1, char_type c2) noexcept; + + static int compare(const char_type* s1, const char_type* s2, size_t n); + static size_t length(const char_type* s); + static const char_type* find(const char_type* s, size_t n, const char_type& a); + static char_type* move(char_type* s1, const char_type* s2, size_t n); + static char_type* copy(char_type* s1, const char_type* s2, size_t n); + static char_type* assign(char_type* s, size_t n, char_type a); + + static constexpr int_type not_eof(int_type c) noexcept; + static constexpr char_type to_char_type(int_type c) noexcept; + static constexpr int_type to_int_type(char_type c) noexcept; + static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept; + static constexpr int_type eof() noexcept; +}; + +template <> struct char_traits<char>; +template <> struct char_traits<wchar_t>; + +} // std + +*/ + +#include <__config> +#include <algorithm> // for search and min +#include <cstdio> // For EOF. +#include <memory> // for __murmur2_or_cityhash + +#include <__undef_min_max> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// char_traits + +template <class _CharT> +struct _LIBCPP_TYPE_VIS_ONLY char_traits +{ + typedef _CharT char_type; + typedef int int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT + {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + static int compare(const char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static size_t length(const char_type* __s); + _LIBCPP_INLINE_VISIBILITY + static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a); + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(EOF);} +}; + +template <class _CharT> +int +char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +template <class _CharT> +inline +size_t +char_traits<_CharT>::length(const char_type* __s) +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +template <class _CharT> +inline +const _CharT* +char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +template <class _CharT> +_CharT* +char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +template <class _CharT> +inline +_CharT* +char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +template <class _CharT> +inline +_CharT* +char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} + +// char_traits<char> + +template <> +struct _LIBCPP_TYPE_VIS_ONLY char_traits<char> +{ + typedef char char_type; + typedef int int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT + {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return (unsigned char)__c1 < (unsigned char)__c2;} + + static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);} + static inline size_t length(const char_type* __s) _NOEXCEPT {return strlen(__s);} + static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT + {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);} + static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} + static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); + } + static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type((unsigned char)__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(EOF);} +}; + +// char_traits<wchar_t> + +template <> +struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t> +{ + typedef wchar_t char_type; + typedef wint_t int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT + {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);} + static inline size_t length(const char_type* __s) _NOEXCEPT + {return wcslen(__s);} + static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT + {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);} + static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);} + static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n); + } + static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT + {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);} + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(WEOF);} +}; + +#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS + +template <> +struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t> +{ + typedef char16_t char_type; + typedef uint_least16_t int_type; + typedef streamoff off_type; + typedef u16streampos pos_type; + typedef mbstate_t state_type; + + static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT + {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + _LIBCPP_INLINE_VISIBILITY + static int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static size_t length(const char_type* __s) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(0xFFFF);} +}; + +inline +int +char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +inline +size_t +char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline +const char16_t* +char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +inline +char16_t* +char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +inline +char16_t* +char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +inline +char16_t* +char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} + +template <> +struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t> +{ + typedef char32_t char_type; + typedef uint_least32_t int_type; + typedef streamoff off_type; + typedef u32streampos pos_type; + typedef mbstate_t state_type; + + static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT + {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + _LIBCPP_INLINE_VISIBILITY + static int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static size_t length(const char_type* __s) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT; + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(0xFFFFFFFF);} +}; + +inline +int +char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +inline +size_t +char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +inline +const char32_t* +char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +inline +char32_t* +char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +inline +char32_t* +char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +inline +char32_t* +char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} + +#endif // _LIBCPP_HAS_NO_UNICODE_CHARS + +// helper fns for basic_string and string_view + +// __str_find +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__pos >= __sz) + return __npos; + const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c); + if (__r == 0) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + +template <class _CharT, class _Traits> +inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT * +__search_substring(const _CharT *__first1, const _CharT *__last1, + const _CharT *__first2, const _CharT *__last2) { + // Take advantage of knowing source and pattern lengths. + // Stop short when source is smaller than pattern. + const ptrdiff_t __len2 = __last2 - __first2; + if (__len2 == 0) + return __first1; + + ptrdiff_t __len1 = __last1 - __first1; + if (__len1 < __len2) + return __last1; + + // First element of __first2 is loop invariant. + _CharT __f2 = *__first2; + while (true) { + __len1 = __last1 - __first1; + // Check whether __first1 still has at least __len2 bytes. + if (__len1 < __len2) + return __last1; + + // Find __f2 the first byte matching in __first1. + __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2); + if (__first1 == 0) + return __last1; + + // It is faster to compare from the first byte of __first1 even if we + // already know that it matches the first byte of __first2: this is because + // __first2 is most likely aligned, as it is user's "pattern" string, and + // __first1 + 1 is most likely not aligned, as the match is in the middle of + // the string. + if (_Traits::compare(__first1, __first2, __len2) == 0) + return __first1; + + ++__first1; + } +} + +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos > __sz) + return __npos; + + if (__n == 0) // There is nothing to search, just return __pos. + return __pos; + + const _CharT *__r = __search_substring<_CharT, _Traits>( + __p + __pos, __p + __sz, __s, __s + __n); + + if (__r == __p + __sz) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + + +// __str_rfind + +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_rfind(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__sz < 1) + return __npos; + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + { + if (_Traits::eq(*--__ps, __c)) + return static_cast<_SizeT>(__ps - __p); + } + return __npos; +} + +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_rfind(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + __pos = _VSTD::min(__pos, __sz); + if (__n < __sz - __pos) + __pos += __n; + else + __pos = __sz; + const _CharT* __r = _VSTD::__find_end( + __p, __p + __pos, __s, __s + __n, _Traits::eq, + random_access_iterator_tag(), random_access_iterator_tag()); + if (__n > 0 && __r == __p + __pos) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + +// __str_find_first_of +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_first_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos >= __sz || __n == 0) + return __npos; + const _CharT* __r = _VSTD::__find_first_of_ce + (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq ); + if (__r == __p + __sz) + return __npos; + return static_cast<_SizeT>(__r - __p); +} + + +// __str_find_last_of +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_last_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT + { + if (__n != 0) + { + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + { + const _CharT* __r = _Traits::find(__s, __n, *--__ps); + if (__r) + return static_cast<_SizeT>(__ps - __p); + } + } + return __npos; +} + + +// __str_find_first_not_of +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_first_not_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos < __sz) + { + const _CharT* __pe = __p + __sz; + for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) + if (_Traits::find(__s, __n, *__ps) == 0) + return static_cast<_SizeT>(__ps - __p); + } + return __npos; +} + + +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_first_not_of(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__pos < __sz) + { + const _CharT* __pe = __p + __sz; + for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) + if (!_Traits::eq(*__ps, __c)) + return static_cast<_SizeT>(__ps - __p); + } + return __npos; +} + + +// __str_find_last_not_of +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_last_not_of(const _CharT *__p, _SizeT __sz, + const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT +{ + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + if (_Traits::find(__s, __n, *--__ps) == 0) + return static_cast<_SizeT>(__ps - __p); + return __npos; +} + + +template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +__str_find_last_not_of(const _CharT *__p, _SizeT __sz, + _CharT __c, _SizeT __pos) _NOEXCEPT +{ + if (__pos < __sz) + ++__pos; + else + __pos = __sz; + for (const _CharT* __ps = __p + __pos; __ps != __p;) + if (!_Traits::eq(*--__ps, __c)) + return static_cast<_SizeT>(__ps - __p); + return __npos; +} + +template<class _Ptr> +inline _LIBCPP_INLINE_VISIBILITY +size_t __do_string_hash(_Ptr __p, _Ptr __e) +{ + typedef typename iterator_traits<_Ptr>::value_type value_type; + return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type)); +} + +template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> > +struct __quoted_output_proxy +{ + _Iter __first; + _Iter __last; + _CharT __delim; + _CharT __escape; + + __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e) + : __first(__f), __last(__l), __delim(__d), __escape(__e) {} + // This would be a nice place for a string_ref +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___STRING diff --git a/include/__threading_support b/include/__threading_support index c9a4ea9d0947..36f1701f178c 100644 --- a/include/__threading_support +++ b/include/__threading_support @@ -19,20 +19,91 @@ #ifndef _LIBCPP_HAS_NO_THREADS -#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#ifndef __libcpp_has_include + #ifndef __has_include + #define __libcpp_has_include(x) 0 + #else + #define __libcpp_has_include(x) __has_include(x) + #endif +#endif + +#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \ + __libcpp_has_include(<__external_threading>) +#include <__external_threading> +#else #include <pthread.h> #include <sched.h> + +#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) +#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS +#else +#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) - // Mutex -#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER typedef pthread_mutex_t __libcpp_mutex_t; +#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER + +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_mutex_lock(__libcpp_mutex_t* __m); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_mutex_trylock(__libcpp_mutex_t* __m); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_mutex_unlock(__libcpp_mutex_t* __m); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_mutex_destroy(__libcpp_mutex_t* __m); + +// Condition variable +typedef pthread_cond_t __libcpp_condvar_t; +#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_signal(__libcpp_condvar_t* __cv); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv); + +// Thread id +typedef pthread_t __libcpp_thread_id; +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); +_LIBCPP_THREAD_ABI_VISIBILITY +bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); + +// Thread +typedef pthread_t __libcpp_thread_t; +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg); +_LIBCPP_THREAD_ABI_VISIBILITY +__libcpp_thread_id __libcpp_thread_get_current_id(); +_LIBCPP_THREAD_ABI_VISIBILITY +__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_join(__libcpp_thread_t* __t); +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_thread_detach(__libcpp_thread_t* __t); +_LIBCPP_THREAD_ABI_VISIBILITY +void __libcpp_thread_yield(); + +// Thread local storage +typedef pthread_key_t __libcpp_tls_key; +_LIBCPP_THREAD_ABI_VISIBILITY +int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)); +_LIBCPP_THREAD_ABI_VISIBILITY +void* __libcpp_tls_get(__libcpp_tls_key __key); +_LIBCPP_THREAD_ABI_VISIBILITY +void __libcpp_tls_set(__libcpp_tls_key __key, void* __p); + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS) -inline _LIBCPP_ALWAYS_INLINE int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m) { pthread_mutexattr_t attr; @@ -59,147 +130,117 @@ int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m) return 0; } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_mutex_lock(__libcpp_mutex_t* __m) { return pthread_mutex_lock(__m); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_mutex_trylock(__libcpp_mutex_t* __m) { return pthread_mutex_trylock(__m); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_mutex_unlock(__libcpp_mutex_t* __m) { return pthread_mutex_unlock(__m); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_mutex_destroy(__libcpp_mutex_t* __m) { return pthread_mutex_destroy(__m); } // Condition variable -#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER -typedef pthread_cond_t __libcpp_condvar_t; - -inline _LIBCPP_ALWAYS_INLINE int __libcpp_condvar_signal(__libcpp_condvar_t* __cv) { return pthread_cond_signal(__cv); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv) { return pthread_cond_broadcast(__cv); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m) { return pthread_cond_wait(__cv, __m); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts) { return pthread_cond_timedwait(__cv, __m, __ts); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv) { return pthread_cond_destroy(__cv); } -// Thread id -typedef pthread_t __libcpp_thread_id; - // Returns non-zero if the thread ids are equal, otherwise 0 -inline _LIBCPP_ALWAYS_INLINE bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) { return pthread_equal(t1, t2) != 0; } // Returns non-zero if t1 < t2, otherwise 0 -inline _LIBCPP_ALWAYS_INLINE bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2) { return t1 < t2; } // Thread -typedef pthread_t __libcpp_thread_t; - -inline _LIBCPP_ALWAYS_INLINE int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg) { return pthread_create(__t, 0, __func, __arg); } -inline _LIBCPP_ALWAYS_INLINE __libcpp_thread_id __libcpp_thread_get_current_id() { return pthread_self(); } -inline _LIBCPP_ALWAYS_INLINE __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t) { return *__t; } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_thread_join(__libcpp_thread_t* __t) { return pthread_join(*__t, 0); } -inline _LIBCPP_ALWAYS_INLINE int __libcpp_thread_detach(__libcpp_thread_t* __t) { return pthread_detach(*__t); } -inline _LIBCPP_ALWAYS_INLINE void __libcpp_thread_yield() { sched_yield(); } // Thread local storage -typedef pthread_key_t __libcpp_tl_key; - -inline _LIBCPP_ALWAYS_INLINE -int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*)) +int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*)) { return pthread_key_create(__key, __at_exit); } -inline _LIBCPP_ALWAYS_INLINE -void* __libcpp_tl_get(__libcpp_tl_key __key) +void* __libcpp_tls_get(__libcpp_tls_key __key) { return pthread_getspecific(__key); } -inline _LIBCPP_ALWAYS_INLINE -void __libcpp_tl_set(__libcpp_tl_key __key, void* __p) +void __libcpp_tls_set(__libcpp_tls_key __key, void* __p) { pthread_setspecific(__key, __p); } -#else // !_LIBCPP_HAS_THREAD_API_PTHREAD - #error "No thread API selected." -#endif +#endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS _LIBCPP_END_NAMESPACE_STD +#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>) + #endif // _LIBCPP_HAS_NO_THREADS #endif // _LIBCPP_THREADING_SUPPORT diff --git a/include/__tree b/include/__tree index b560bf071e81..485a6c13af40 100644 --- a/include/__tree +++ b/include/__tree @@ -1106,19 +1106,22 @@ public: _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT - {return __node_traits::max_size(__node_alloc());} + {return std::min<size_type>( + __node_traits::max_size(__node_alloc()), + numeric_limits<difference_type >::max());} void clear() _NOEXCEPT; void swap(__tree& __t) +#if _LIBCPP_STD_VER <= 11 _NOEXCEPT_( __is_nothrow_swappable<value_compare>::value -#if _LIBCPP_STD_VER <= 11 && (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value) -#endif ); - +#else + _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value); +#endif #ifndef _LIBCPP_CXX03_LANG template <class _Key, class ..._Args> @@ -1425,7 +1428,7 @@ private: __node_alloc() = __t.__node_alloc(); } _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __tree& __t, false_type) {} + void __copy_assign_alloc(const __tree&, false_type) {} void __move_assign(__tree& __t, false_type); void __move_assign(__tree& __t, true_type) @@ -1445,7 +1448,7 @@ private: _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value) {__node_alloc() = _VSTD::move(__t.__node_alloc());} _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__tree& __t, false_type) _NOEXCEPT {} + void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {} __node_pointer __detach(); static __node_pointer __detach(__node_pointer); @@ -1797,13 +1800,15 @@ __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT template <class _Tp, class _Compare, class _Allocator> void __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) +#if _LIBCPP_STD_VER <= 11 _NOEXCEPT_( __is_nothrow_swappable<value_compare>::value -#if _LIBCPP_STD_VER <= 11 && (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value) -#endif ) +#else + _NOEXCEPT_(__is_nothrow_swappable<value_compare>::value) +#endif { using _VSTD::swap; swap(__begin_node_, __t.__begin_node_); diff --git a/include/__tuple b/include/__tuple index cc9fbbebc096..775d7340b54d 100644 --- a/include/__tuple +++ b/include/__tuple @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size; +template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size {}; template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<const _Tp> @@ -146,6 +146,12 @@ template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple; template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; +template <class ..._Tp> +class _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> > + : public integral_constant<size_t, sizeof...(_Tp)> +{ +}; + template <size_t _Ip, class ..._Tp> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type& @@ -368,7 +374,7 @@ template <bool ..._Preds> struct __all_dummy; template <bool ..._Pred> -using __all = is_same<__all_dummy<_Pred...>, __all_dummy<(_Pred, true)...>>; +using __all = is_same<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>>; struct __tuple_sfinae_base { template <template <class, class...> class _Trait, @@ -431,8 +437,105 @@ struct __tuple_assignable<_Tp, _Up, true, true> > {}; + +template <size_t _Ip, class ..._Tp> +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> > +{ +public: + typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; +}; + +#if _LIBCPP_STD_VER > 11 +template <size_t _Ip, class ..._Tp> +using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; +#endif + #endif // _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG +template <bool _IsTuple, class _SizeTrait, size_t _Expected> +struct __tuple_like_with_size_imp : false_type {}; + +template <class _SizeTrait, size_t _Expected> +struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected> + : integral_constant<bool, _SizeTrait::value == _Expected> {}; + +template <class _Tuple, size_t _ExpectedSize, + class _RawTuple = typename __uncvref<_Tuple>::type> +using __tuple_like_with_size = __tuple_like_with_size_imp< + __tuple_like<_RawTuple>::value, + tuple_size<_RawTuple>, _ExpectedSize + >; + +struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { + template <class ...> + static constexpr bool __enable_default() { return false; } + template <class ...> + static constexpr bool __enable_explicit() { return false; } + template <class ...> + static constexpr bool __enable_implicit() { return false; } + template <class ...> + static constexpr bool __enable_assign() { return false; } +}; +#endif + +#if _LIBCPP_STD_VER > 14 + +template <bool _CanCopy, bool _CanMove> +struct __sfinae_ctor_base {}; +template <> +struct __sfinae_ctor_base<false, false> { + __sfinae_ctor_base() = default; + __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; + __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; + __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; + __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; +}; +template <> +struct __sfinae_ctor_base<true, false> { + __sfinae_ctor_base() = default; + __sfinae_ctor_base(__sfinae_ctor_base const&) = default; + __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; + __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; + __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; +}; +template <> +struct __sfinae_ctor_base<false, true> { + __sfinae_ctor_base() = default; + __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; + __sfinae_ctor_base(__sfinae_ctor_base &&) = default; + __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; + __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; +}; + +template <bool _CanCopy, bool _CanMove> +struct __sfinae_assign_base {}; +template <> +struct __sfinae_assign_base<false, false> { + __sfinae_assign_base() = default; + __sfinae_assign_base(__sfinae_assign_base const&) = default; + __sfinae_assign_base(__sfinae_assign_base &&) = default; + __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; + __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; +}; +template <> +struct __sfinae_assign_base<true, false> { + __sfinae_assign_base() = default; + __sfinae_assign_base(__sfinae_assign_base const&) = default; + __sfinae_assign_base(__sfinae_assign_base &&) = default; + __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default; + __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; +}; +template <> +struct __sfinae_assign_base<false, true> { + __sfinae_assign_base() = default; + __sfinae_assign_base(__sfinae_assign_base const&) = default; + __sfinae_assign_base(__sfinae_assign_base &&) = default; + __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; + __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default; +}; +#endif // _LIBCPP_STD_VER > 14 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___TUPLE diff --git a/include/algorithm b/include/algorithm index 7a6db7abd26d..189991efbee0 100644 --- a/include/algorithm +++ b/include/algorithm @@ -89,7 +89,7 @@ template <class InputIterator1, class InputIterator2> template <class InputIterator1, class InputIterator2> pair<InputIterator1, InputIterator2> - mismatch(InputIterator1 first1, InputIterator1 last1, + mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); // **C++14** template <class InputIterator1, class InputIterator2, class BinaryPredicate> @@ -109,7 +109,7 @@ template <class InputIterator1, class InputIterator2> template <class InputIterator1, class InputIterator2> bool - equal(InputIterator1 first1, InputIterator1 last1, + equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); // **C++14** template <class InputIterator1, class InputIterator2, class BinaryPredicate> @@ -288,6 +288,12 @@ template <class RandomAccessIterator, class RandomNumberGenerator> random_shuffle(RandomAccessIterator first, RandomAccessIterator last, RandomNumberGenerator& rand); // deprecated in C++14 +template<class PopulationIterator, class SampleIterator, + class Distance, class UniformRandomBitGenerator> + SampleIterator sample(PopulationIterator first, PopulationIterator last, + SampleIterator out, Distance n, + UniformRandomBitGenerator&& g); // C++17 + template<class RandomAccessIterator, class UniformRandomNumberGenerator> void shuffle(RandomAccessIterator first, RandomAccessIterator last, UniformRandomNumberGenerator&& g); @@ -688,7 +694,7 @@ struct __equal_to<_T1, const _T1> template <class _T1, class _T2 = _T1> struct __less { - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -749,14 +755,28 @@ struct __debug_less { _Compare __comp_; __debug_less(_Compare& __c) : __comp_(__c) {} + template <class _Tp, class _Up> bool operator()(const _Tp& __x, const _Up& __y) { bool __r = __comp_(__x, __y); if (__r) - _LIBCPP_ASSERT(!__comp_(__y, __x), "Comparator does not induce a strict weak ordering"); + __do_compare_assert(0, __y, __x); return __r; } + + template <class _LHS, class _RHS> + inline _LIBCPP_INLINE_VISIBILITY + decltype((void)_VSTD::declval<_Compare&>()( + _VSTD::declval<_LHS const&>(), _VSTD::declval<_RHS const&>())) + __do_compare_assert(int, _LHS const& __l, _RHS const& __r) { + _LIBCPP_ASSERT(!__comp_(__l, __r), + "Comparator does not induce a strict weak ordering"); + } + + template <class _LHS, class _RHS> + inline _LIBCPP_INLINE_VISIBILITY + void __do_compare_assert(long, _LHS const&, _RHS const&) {} }; #endif // _LIBCPP_DEBUG @@ -857,7 +877,7 @@ for_each(_InputIterator __first, _InputIterator __last, _Function __f) { for (; __first != __last; ++__first) __f(*__first); - return _LIBCPP_EXPLICIT_MOVE(__f); // explicitly moved for (emulated) C++03 + return __f; } // find @@ -1215,7 +1235,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> inline _LIBCPP_INLINE_VISIBILITY bool -__equal(_InputIterator1 __first1, _InputIterator1 __last1, +__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag ) { @@ -1228,8 +1248,8 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> inline _LIBCPP_INLINE_VISIBILITY bool -__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, +__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag ) { if ( _VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) @@ -1242,11 +1262,11 @@ __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> inline _LIBCPP_INLINE_VISIBILITY bool -equal(_InputIterator1 __first1, _InputIterator1 __last1, +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _BinaryPredicate __pred ) { return _VSTD::__equal<typename add_lvalue_reference<_BinaryPredicate>::type> - (__first1, __last1, __first2, __last2, __pred, + (__first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), typename iterator_traits<_InputIterator2>::iterator_category()); } @@ -1254,7 +1274,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, template <class _InputIterator1, class _InputIterator2> inline _LIBCPP_INLINE_VISIBILITY bool -equal(_InputIterator1 __first1, _InputIterator1 __last1, +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { typedef typename iterator_traits<_InputIterator1>::value_type __v1; @@ -1328,7 +1348,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, template<class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> bool __is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag ) { @@ -1379,7 +1399,7 @@ __next_iter:; template<class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> bool __is_permutation(_RandomAccessIterator1 __first1, _RandomAccessIterator2 __last1, - _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator1 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag ) { @@ -1458,7 +1478,7 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX11 +_LIBCPP_CONSTEXPR_AFTER_CXX11 pair<_RandomAccessIterator1, _RandomAccessIterator1> __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, @@ -1474,9 +1494,9 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, if (__len1 < __len2) return make_pair(__last1, __last1); const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here + while (true) { -#if !_LIBCPP_UNROLL_LOOPS while (true) { if (__first1 == __s) @@ -1485,40 +1505,9 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, break; ++__first1; } -#else // !_LIBCPP_UNROLL_LOOPS - for (_D1 __loop_unroll = (__s - __first1) / 4; __loop_unroll > 0; --__loop_unroll) - { - if (__pred(*__first1, *__first2)) - goto __phase2; - if (__pred(*++__first1, *__first2)) - goto __phase2; - if (__pred(*++__first1, *__first2)) - goto __phase2; - if (__pred(*++__first1, *__first2)) - goto __phase2; - ++__first1; - } - switch (__s - __first1) - { - case 3: - if (__pred(*__first1, *__first2)) - break; - ++__first1; - case 2: - if (__pred(*__first1, *__first2)) - break; - ++__first1; - case 1: - if (__pred(*__first1, *__first2)) - break; - case 0: - return make_pair(__last1, __last1); - } - __phase2: -#endif // !_LIBCPP_UNROLL_LOOPS + _RandomAccessIterator1 __m1 = __first1; _RandomAccessIterator2 __m2 = __first2; -#if !_LIBCPP_UNROLL_LOOPS while (true) { if (++__m2 == __last2) @@ -1530,43 +1519,6 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, break; } } -#else // !_LIBCPP_UNROLL_LOOPS - ++__m2; - ++__m1; - for (_D2 __loop_unroll = (__last2 - __m2) / 4; __loop_unroll > 0; --__loop_unroll) - { - if (!__pred(*__m1, *__m2)) - goto __continue; - if (!__pred(*++__m1, *++__m2)) - goto __continue; - if (!__pred(*++__m1, *++__m2)) - goto __continue; - if (!__pred(*++__m1, *++__m2)) - goto __continue; - ++__m1; - ++__m2; - } - switch (__last2 - __m2) - { - case 3: - if (!__pred(*__m1, *__m2)) - break; - ++__m1; - ++__m2; - case 2: - if (!__pred(*__m1, *__m2)) - break; - ++__m1; - ++__m2; - case 1: - if (!__pred(*__m1, *__m2)) - break; - case 0: - return make_pair(__first1, __first1 + __len2); - } - __continue: - ++__first1; -#endif // !_LIBCPP_UNROLL_LOOPS } } @@ -1729,6 +1681,20 @@ __unwrap_iter(__wrap_iter<_Tp*> __i) return __i.base(); } +#else + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_trivially_copy_assignable<_Tp>::value, + __wrap_iter<_Tp*> +>::type +__unwrap_iter(__wrap_iter<_Tp*> __i) +{ + return __i; +} + #endif // _LIBCPP_DEBUG_LEVEL < 2 template <class _InputIterator, class _OutputIterator> @@ -1802,7 +1768,9 @@ _BidirectionalIterator2 copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { - return _VSTD::__copy_backward(__unwrap_iter(__first), __unwrap_iter(__last), __unwrap_iter(__result)); + return _VSTD::__copy_backward(__unwrap_iter(__first), + __unwrap_iter(__last), + __unwrap_iter(__result)); } // copy_if @@ -2417,7 +2385,7 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt template<typename _Integral> inline _LIBCPP_INLINE_VISIBILITY _Integral -__gcd(_Integral __x, _Integral __y) +__algo_gcd(_Integral __x, _Integral __y) { do { @@ -2442,7 +2410,7 @@ __rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran _VSTD::swap_ranges(__first, __middle, __middle); return __middle; } - const difference_type __g = _VSTD::__gcd(__m1, __m2); + const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); for (_RandomAccessIterator __p = __first + __g; __p != __first;) { value_type __t(_VSTD::move(*--__p)); @@ -2785,7 +2753,7 @@ minmax(initializer_list<_Tp> __t, _Compare __comp) __result.second = *__first; ++__first; } - + while (__first != __last) { _Tp __prev = *__first++; @@ -2797,7 +2765,7 @@ minmax(initializer_list<_Tp> __t, _Compare __comp) if ( __comp(__prev, __result.first)) __result.first = __prev; if (!__comp(*__first, __result.second)) __result.second = *__first; } - + __first++; } return __result; @@ -3128,6 +3096,78 @@ random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, } } +template <class _PopulationIterator, class _SampleIterator, class _Distance, + class _UniformRandomNumberGenerator> +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, + _UniformRandomNumberGenerator & __g, + input_iterator_tag) { + + _Distance __k = 0; + for (; __first != __last && __k < __n; ++__first, (void)++__k) + __out[__k] = *__first; + _Distance __sz = __k; + for (; __first != __last; ++__first, (void)++__k) { + _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); + if (__r < __sz) + __out[__r] = *__first; + } + return __out + _VSTD::min(__n, __k); +} + +template <class _PopulationIterator, class _SampleIterator, class _Distance, + class _UniformRandomNumberGenerator> +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, + _UniformRandomNumberGenerator& __g, + forward_iterator_tag) { + _Distance __unsampled_sz = _VSTD::distance(__first, __last); + for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { + _Distance __r = + _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); + if (__r < __n) { + *__out++ = *__first; + --__n; + } + } + return __out; +} + +template <class _PopulationIterator, class _SampleIterator, class _Distance, + class _UniformRandomNumberGenerator> +_LIBCPP_INLINE_VISIBILITY +_SampleIterator __sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, _UniformRandomNumberGenerator& __g) { + typedef typename iterator_traits<_PopulationIterator>::iterator_category + _PopCategory; + typedef typename iterator_traits<_PopulationIterator>::difference_type + _Difference; + static_assert(__is_forward_iterator<_PopulationIterator>::value || + __is_random_access_iterator<_SampleIterator>::value, + "SampleIterator must meet the requirements of RandomAccessIterator"); + typedef typename common_type<_Distance, _Difference>::type _CommonType; + _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); + return _VSTD::__sample( + __first, __last, __out, _CommonType(__n), + __g, _PopCategory()); +} + +#if _LIBCPP_STD_VER > 14 +template <class _PopulationIterator, class _SampleIterator, class _Distance, + class _UniformRandomNumberGenerator> +inline _LIBCPP_INLINE_VISIBILITY +_SampleIterator sample(_PopulationIterator __first, + _PopulationIterator __last, _SampleIterator __out, + _Distance __n, _UniformRandomNumberGenerator&& __g) { + return _VSTD::__sample(__first, __last, __out, __n, __g); +} +#endif // _LIBCPP_STD_VER > 14 + template<class _RandomAccessIterator, class _UniformRandomNumberGenerator> void shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -4423,7 +4463,7 @@ __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator ::new(__p) value_type(_VSTD::move(*__i)); typedef reverse_iterator<_BidirectionalIterator> _RBi; typedef reverse_iterator<value_type*> _Rv; - __half_inplace_merge(_Rv(__p), _Rv(__buff), + __half_inplace_merge(_Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), __negate<_Compare>(__comp)); } @@ -4871,7 +4911,8 @@ push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) template <class _Compare, class _RandomAccessIterator> void -__sift_down(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, +__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/, + _Compare __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, _RandomAccessIterator __start) { diff --git a/include/any b/include/any new file mode 100644 index 000000000000..1f70c4ff9b8d --- /dev/null +++ b/include/any @@ -0,0 +1,663 @@ +// -*- C++ -*- +//===------------------------------ any -----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ANY +#define _LIBCPP_ANY + +/* + any synopsis + +namespace std { + + class bad_any_cast : public bad_cast + { + public: + virtual const char* what() const noexcept; + }; + + class any + { + public: + + // 6.3.1 any construct/destruct + any() noexcept; + + any(const any& other); + any(any&& other) noexcept; + + template <class ValueType> + any(ValueType&& value); + + ~any(); + + // 6.3.2 any assignments + any& operator=(const any& rhs); + any& operator=(any&& rhs) noexcept; + + template <class ValueType> + any& operator=(ValueType&& rhs); + + // 6.3.3 any modifiers + void reset() noexcept; + void swap(any& rhs) noexcept; + + // 6.3.4 any observers + bool has_value() const noexcept; + const type_info& type() const noexcept; + }; + + // 6.4 Non-member functions + void swap(any& x, any& y) noexcept; + + template <class T, class ...Args> + any make_any(Args&& ...args); + template <class T, class U, class ...Args> + any make_any(initializer_list<U>, Args&& ...args); + + template<class ValueType> + ValueType any_cast(const any& operand); + template<class ValueType> + ValueType any_cast(any& operand); + template<class ValueType> + ValueType any_cast(any&& operand); + + template<class ValueType> + const ValueType* any_cast(const any* operand) noexcept; + template<class ValueType> + ValueType* any_cast(any* operand) noexcept; + +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + +*/ + +#include <experimental/__config> +#include <memory> +#include <new> +#include <typeinfo> +#include <type_traits> +#include <cstdlib> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std { +class _LIBCPP_EXCEPTION_ABI bad_any_cast : public bad_cast +{ +public: + virtual const char* what() const _NOEXCEPT; +}; +} // namespace std + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_bad_any_cast() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_any_cast(); +#else + _VSTD::abort(); +#endif +} + +// Forward declarations +class _LIBCPP_TYPE_VIS_ONLY any; + +template <class _ValueType> +_LIBCPP_INLINE_VISIBILITY +add_pointer_t<add_const_t<_ValueType>> +any_cast(any const *) _NOEXCEPT; + +template <class _ValueType> +_LIBCPP_INLINE_VISIBILITY +add_pointer_t<_ValueType> any_cast(any *) _NOEXCEPT; + +namespace __any_imp +{ + using _Buffer = aligned_storage_t<3*sizeof(void*), alignment_of<void*>::value>; + + template <class _Tp> + using _IsSmallObject = integral_constant<bool + , sizeof(_Tp) <= sizeof(_Buffer) + && alignment_of<_Buffer>::value + % alignment_of<_Tp>::value == 0 + && is_nothrow_move_constructible<_Tp>::value + >; + + enum class _Action { + _Destroy, + _Copy, + _Move, + _Get, + _TypeInfo + }; + + template <class _Tp> struct _SmallHandler; + template <class _Tp> struct _LargeHandler; + + template <class _Tp> + struct _LIBCPP_TYPE_VIS_ONLY __unique_typeinfo { static constexpr int __id = 0; }; + template <class _Tp> constexpr int __unique_typeinfo<_Tp>::__id; + + template <class _Tp> + inline _LIBCPP_INLINE_VISIBILITY + constexpr const void* __get_fallback_typeid() { + return &__unique_typeinfo<decay_t<_Tp>>::__id; + } + + template <class _Tp> + inline _LIBCPP_INLINE_VISIBILITY + bool __compare_typeid(type_info const* __id, const void* __fallback_id) + { +#if !defined(_LIBCPP_NO_RTTI) + if (__id && *__id == typeid(_Tp)) + return true; +#endif + if (!__id && __fallback_id == __any_imp::__get_fallback_typeid<_Tp>()) + return true; + return false; + } + + template <class _Tp> + using _Handler = conditional_t< + _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>; + +} // namespace __any_imp + +class _LIBCPP_TYPE_VIS_ONLY any +{ +public: + // construct/destruct + _LIBCPP_INLINE_VISIBILITY + constexpr any() _NOEXCEPT : __h(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + any(any const & __other) : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Copy, this); + } + + _LIBCPP_INLINE_VISIBILITY + any(any && __other) _NOEXCEPT : __h(nullptr) + { + if (__other.__h) __other.__call(_Action::_Move, this); + } + + template < + class _ValueType + , class _Tp = decay_t<_ValueType> + , class = enable_if_t< + !is_same<_Tp, any>::value && + !__is_inplace_type<_ValueType>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + any(_ValueType && __value); + + template <class _ValueType, class ..._Args, + class _Tp = decay_t<_ValueType>, + class = enable_if_t< + is_constructible<_Tp, _Args...>::value && + is_copy_constructible<_Tp>::value + > + > + _LIBCPP_INLINE_VISIBILITY + explicit any(in_place_type_t<_ValueType>, _Args&&... __args); + + template <class _ValueType, class _Up, class ..._Args, + class _Tp = decay_t<_ValueType>, + class = enable_if_t< + is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + explicit any(in_place_type_t<_ValueType>, initializer_list<_Up>, _Args&&... __args); + + _LIBCPP_INLINE_VISIBILITY + ~any() { this->reset(); } + + // assignments + _LIBCPP_INLINE_VISIBILITY + any & operator=(any const & __rhs) { + any(__rhs).swap(*this); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + any & operator=(any && __rhs) _NOEXCEPT { + any(_VSTD::move(__rhs)).swap(*this); + return *this; + } + + template < + class _ValueType + , class _Tp = decay_t<_ValueType> + , class = enable_if_t< + !is_same<_Tp, any>::value + && is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + any & operator=(_ValueType && __rhs); + + template <class _ValueType, class ..._Args, + class _Tp = decay_t<_ValueType>, + class = enable_if_t< + is_constructible<_Tp, _Args...>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + void emplace(_Args&&... args); + + template <class _ValueType, class _Up, class ..._Args, + class _Tp = decay_t<_ValueType>, + class = enable_if_t< + is_constructible<_Tp, initializer_list<_Up>&, _Args...>::value && + is_copy_constructible<_Tp>::value> + > + _LIBCPP_INLINE_VISIBILITY + void emplace(initializer_list<_Up>, _Args&&...); + + // 6.3.3 any modifiers + _LIBCPP_INLINE_VISIBILITY + void reset() _NOEXCEPT { if (__h) this->__call(_Action::_Destroy); } + + _LIBCPP_INLINE_VISIBILITY + void swap(any & __rhs) _NOEXCEPT; + + // 6.3.4 any observers + _LIBCPP_INLINE_VISIBILITY + bool has_value() const _NOEXCEPT { return __h != nullptr; } + +#if !defined(_LIBCPP_NO_RTTI) + _LIBCPP_INLINE_VISIBILITY + const type_info & type() const _NOEXCEPT { + if (__h) { + return *static_cast<type_info const *>(this->__call(_Action::_TypeInfo)); + } else { + return typeid(void); + } + } +#endif + +private: + typedef __any_imp::_Action _Action; + using _HandleFuncPtr = void* (*)(_Action, any const *, any *, const type_info *, + const void* __fallback_info); + + union _Storage { + constexpr _Storage() : __ptr(nullptr) {} + void * __ptr; + __any_imp::_Buffer __buf; + }; + + _LIBCPP_ALWAYS_INLINE + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr, + const void* __fallback_info = nullptr) const + { + return __h(__a, this, __other, __info, __fallback_info); + } + + _LIBCPP_ALWAYS_INLINE + void * __call(_Action __a, any * __other = nullptr, + type_info const * __info = nullptr, + const void* __fallback_info = nullptr) + { + return __h(__a, this, __other, __info, __fallback_info); + } + + template <class> + friend struct __any_imp::_SmallHandler; + template <class> + friend struct __any_imp::_LargeHandler; + + template <class _ValueType> + friend add_pointer_t<add_const_t<_ValueType>> + any_cast(any const *) _NOEXCEPT; + + template <class _ValueType> + friend add_pointer_t<_ValueType> + any_cast(any *) _NOEXCEPT; + + _HandleFuncPtr __h = nullptr; + _Storage __s; +}; + +namespace __any_imp +{ + template <class _Tp> + struct _LIBCPP_TYPE_VIS_ONLY _SmallHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, any * __other, + type_info const * __info, const void* __fallback_info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast<any &>(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast<any &>(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast<any &>(*__this), __info, __fallback_info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + static void __create(any & __dest, _Args&&... __args) { + ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...); + __dest.__h = &_SmallHandler::__handle; + } + + private: + _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this) { + _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf)); + __value.~_Tp(); + __this.__h = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) { + _SmallHandler::__create(__dest, *static_cast<_Tp const *>( + static_cast<void const *>(&__this.__s.__buf))); + } + + _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) { + _SmallHandler::__create(__dest, _VSTD::move( + *static_cast<_Tp*>(static_cast<void*>(&__this.__s.__buf)))); + __destroy(__this); + } + + _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, + type_info const * __info, + const void* __fallback_id) + { + if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_id)) + return static_cast<void*>(&__this.__s.__buf); + return nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + + template <class _Tp> + struct _LIBCPP_TYPE_VIS_ONLY _LargeHandler + { + _LIBCPP_INLINE_VISIBILITY + static void* __handle(_Action __act, any const * __this, + any * __other, type_info const * __info, + void const* __fallback_info) + { + switch (__act) + { + case _Action::_Destroy: + __destroy(const_cast<any &>(*__this)); + return nullptr; + case _Action::_Copy: + __copy(*__this, *__other); + return nullptr; + case _Action::_Move: + __move(const_cast<any &>(*__this), *__other); + return nullptr; + case _Action::_Get: + return __get(const_cast<any &>(*__this), __info, __fallback_info); + case _Action::_TypeInfo: + return __type_info(); + } + } + + template <class ..._Args> + _LIBCPP_INLINE_VISIBILITY + static void __create(any & __dest, _Args&&... __args) { + typedef allocator<_Tp> _Alloc; + typedef __allocator_destructor<_Alloc> _Dp; + _Alloc __a; + unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...); + __dest.__s.__ptr = __hold.release(); + __dest.__h = &_LargeHandler::__handle; + } + + private: + + _LIBCPP_INLINE_VISIBILITY + static void __destroy(any & __this){ + delete static_cast<_Tp*>(__this.__s.__ptr); + __this.__h = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void __copy(any const & __this, any & __dest) { + _LargeHandler::__create(__dest, *static_cast<_Tp const *>(__this.__s.__ptr)); + } + + _LIBCPP_INLINE_VISIBILITY + static void __move(any & __this, any & __dest) { + __dest.__s.__ptr = __this.__s.__ptr; + __dest.__h = &_LargeHandler::__handle; + __this.__h = nullptr; + } + + _LIBCPP_INLINE_VISIBILITY + static void* __get(any & __this, type_info const * __info, + void const* __fallback_info) + { + if (__any_imp::__compare_typeid<_Tp>(__info, __fallback_info)) + return static_cast<void*>(__this.__s.__ptr); + return nullptr; + + } + + _LIBCPP_INLINE_VISIBILITY + static void* __type_info() + { +#if !defined(_LIBCPP_NO_RTTI) + return const_cast<void*>(static_cast<void const *>(&typeid(_Tp))); +#else + return nullptr; +#endif + } + }; + +} // namespace __any_imp + + +template <class _ValueType, class _Tp, class> +any::any(_ValueType && __v) : __h(nullptr) +{ + __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_ValueType>(__v)); +} + +template <class _ValueType, class ..._Args, class _Tp, class> +any::any(in_place_type_t<_ValueType>, _Args&&... __args) { + __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); +}; + +template <class _ValueType, class _Up, class ..._Args, class _Tp, class> +any::any(in_place_type_t<_ValueType>, initializer_list<_Up> __il, _Args&&... __args) { + __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); +} + +template <class _ValueType, class, class> +inline _LIBCPP_INLINE_VISIBILITY +any & any::operator=(_ValueType && __v) +{ + any(_VSTD::forward<_ValueType>(__v)).swap(*this); + return *this; +} + +template <class _ValueType, class ..._Args, class _Tp, class> +inline _LIBCPP_INLINE_VISIBILITY +void any::emplace(_Args&&... __args) { + reset(); + __any_imp::_Handler<_Tp>::__create(*this, _VSTD::forward<_Args>(__args)...); +} + +template <class _ValueType, class _Up, class ..._Args, class _Tp, class> +inline _LIBCPP_INLINE_VISIBILITY +void any::emplace(initializer_list<_Up> __il, _Args&&... __args) { + reset(); + __any_imp::_Handler<_Tp>::__create(*this, __il, _VSTD::forward<_Args>(__args)...); +} + +inline _LIBCPP_INLINE_VISIBILITY +void any::swap(any & __rhs) _NOEXCEPT +{ + if (this == &__rhs) + return; + if (__h && __rhs.__h) { + any __tmp; + __rhs.__call(_Action::_Move, &__tmp); + this->__call(_Action::_Move, &__rhs); + __tmp.__call(_Action::_Move, this); + } + else if (__h) { + this->__call(_Action::_Move, &__rhs); + } + else if (__rhs.__h) { + __rhs.__call(_Action::_Move, this); + } +} + +// 6.4 Non-member functions + +inline _LIBCPP_INLINE_VISIBILITY +void swap(any & __lhs, any & __rhs) _NOEXCEPT +{ + __lhs.swap(__rhs); +} + +template <class _Tp, class ..._Args> +inline _LIBCPP_INLINE_VISIBILITY +any make_any(_Args&&... __args) { + return any(in_place_type<_Tp>, _VSTD::forward<_Args>(__args)...); +} + +template <class _Tp, class _Up, class ..._Args> +inline _LIBCPP_INLINE_VISIBILITY +any make_any(initializer_list<_Up> __il, _Args&&... __args) { + return any(in_place_type<_Tp>, __il, _VSTD::forward<_Args>(__args)...); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any const & __v) +{ + using _RawValueType = __uncvref_t<_ValueType>; + static_assert(is_constructible<_ValueType, _RawValueType const &>::value, + "ValueType is required to be a const lvalue reference " + "or a CopyConstructible type"); + auto __tmp = _VSTD::any_cast<add_const_t<_RawValueType>>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return static_cast<_ValueType>(*__tmp); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any & __v) +{ + using _RawValueType = __uncvref_t<_ValueType>; + static_assert(is_constructible<_ValueType, _RawValueType &>::value, + "ValueType is required to be an lvalue reference " + "or a CopyConstructible type"); + auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return static_cast<_ValueType>(*__tmp); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +_ValueType any_cast(any && __v) +{ + using _RawValueType = __uncvref_t<_ValueType>; + static_assert(is_constructible<_ValueType, _RawValueType>::value, + "ValueType is required to be an rvalue reference " + "or a CopyConstructible type"); + auto __tmp = _VSTD::any_cast<_RawValueType>(&__v); + if (__tmp == nullptr) + __throw_bad_any_cast(); + return static_cast<_ValueType>(_VSTD::move(*__tmp)); +} + +template <class _ValueType> +inline _LIBCPP_INLINE_VISIBILITY +add_pointer_t<add_const_t<_ValueType>> +any_cast(any const * __any) _NOEXCEPT +{ + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any)); +} + +template <class _RetType> +inline _LIBCPP_INLINE_VISIBILITY +_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept { + return static_cast<_RetType>(__p); +} + +template <class _RetType> +inline _LIBCPP_INLINE_VISIBILITY +_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept { + return nullptr; +} + +template <class _ValueType> +add_pointer_t<_ValueType> +any_cast(any * __any) _NOEXCEPT +{ + using __any_imp::_Action; + static_assert(!is_reference<_ValueType>::value, + "_ValueType may not be a reference."); + typedef typename add_pointer<_ValueType>::type _ReturnType; + if (__any && __any->__h) { + void *__p = __any->__call(_Action::_Get, nullptr, +#if !defined(_LIBCPP_NO_RTTI) + &typeid(_ValueType), +#else + nullptr, +#endif + __any_imp::__get_fallback_typeid<_ValueType>()); + return _VSTD::__pointer_or_func_cast<_ReturnType>( + __p, is_function<_ValueType>{}); + } + return nullptr; +} + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_ANY diff --git a/include/array b/include/array index 719286d52ea3..d3f8463cf664 100644 --- a/include/array +++ b/include/array @@ -108,9 +108,6 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce #include <iterator> #include <algorithm> #include <stdexcept> -#if defined(_LIBCPP_NO_EXCEPTIONS) - #include <cassert> -#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -209,11 +206,8 @@ typename array<_Tp, _Size>::reference array<_Tp, _Size>::at(size_type __n) { if (__n >= _Size) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("array::at"); -#else - assert(!"array::at out_of_range"); -#endif + __throw_out_of_range("array::at"); + return __elems_[__n]; } @@ -223,11 +217,7 @@ typename array<_Tp, _Size>::const_reference array<_Tp, _Size>::at(size_type __n) const { if (__n >= _Size) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("array::at"); -#else - assert(!"array::at out_of_range"); -#endif + __throw_out_of_range("array::at"); return __elems_[__n]; } diff --git a/include/atomic b/include/atomic index 11f2152e5bc6..7e3fac81b801 100644 --- a/include/atomic +++ b/include/atomic @@ -557,7 +557,6 @@ void atomic_signal_fence(memory_order m) noexcept; #endif #if _LIBCPP_STD_VER > 14 -// FIXME: use the right feature test macro value as chose by SG10. # define __cpp_lib_atomic_is_always_lock_free 201603L #endif @@ -580,11 +579,11 @@ struct __gcc_atomic_t { #endif _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifndef _LIBCPP_CXX03_LANG __gcc_atomic_t() _NOEXCEPT = default; #else __gcc_atomic_t() _NOEXCEPT : __a_value() {} -#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#endif // _LIBCPP_CXX03_LANG _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT : __a_value(value) {} _Tp __a_value; @@ -936,11 +935,11 @@ struct __atomic_base // false {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifndef _LIBCPP_CXX03_LANG __atomic_base() _NOEXCEPT = default; #else __atomic_base() _NOEXCEPT : __a_() {} -#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} @@ -1691,11 +1690,11 @@ typedef struct atomic_flag {__c11_atomic_store(&__a_, false, __m);} _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifndef _LIBCPP_CXX03_LANG atomic_flag() _NOEXCEPT = default; #else atomic_flag() _NOEXCEPT : __a_() {} -#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION diff --git a/include/bitset b/include/bitset index 3f9b964e45ac..edc6c133c328 100644 --- a/include/bitset +++ b/include/bitset @@ -125,9 +125,6 @@ template <size_t N> struct hash<std::bitset<N>>; #include <stdexcept> #include <iosfwd> #include <__functional_base> -#if defined(_LIBCPP_NO_EXCEPTIONS) - #include <cassert> -#endif #include <__undef_min_max> @@ -262,7 +259,7 @@ __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT #if __SIZEOF_SIZE_T__ == 8 : __first_{__v} #elif __SIZEOF_SIZE_T__ == 4 - : __first_{__v, __v >> __bits_per_word} + : __first_{static_cast<__storage_type>(__v), static_cast<__storage_type>(__v >> __bits_per_word)} #else #error This constructor has not been ported to this platform #endif @@ -326,11 +323,8 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const const_iterator __e = __make_iter(_Size); const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long) * CHAR_BIT), __e, true); if (__i != __e) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw overflow_error("bitset to_ulong overflow error"); -#else - assert(!"bitset to_ulong overflow error"); -#endif + __throw_overflow_error("bitset to_ulong overflow error"); + return __first_[0]; } @@ -349,11 +343,8 @@ __bitset<_N_words, _Size>::to_ullong(false_type) const const_iterator __e = __make_iter(_Size); const_iterator __i = _VSTD::find(__make_iter(sizeof(unsigned long long) * CHAR_BIT), __e, true); if (__i != __e) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw overflow_error("bitset to_ullong overflow error"); -#else - assert(!"bitset to_ullong overflow error"); -#endif + __throw_overflow_error("bitset to_ullong overflow error"); + return to_ullong(true_type()); } @@ -763,11 +754,8 @@ bitset<_Size>::bitset(const _CharT* __str, size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str)); for (size_t __i = 0; __i < __rlen; ++__i) if (__str[__i] != __zero && __str[__i] != __one) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw invalid_argument("bitset string ctor has invalid argument"); -#else - assert(!"bitset string ctor has invalid argument"); -#endif + __throw_invalid_argument("bitset string ctor has invalid argument"); + size_t _Mp = _VSTD::min(__rlen, _Size); size_t __i = 0; for (; __i < _Mp; ++__i) @@ -789,19 +777,13 @@ bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __zero, _CharT __one) { if (__pos > __str.size()) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("bitset string pos out of range"); -#else - assert(!"bitset string pos out of range"); -#endif + __throw_out_of_range("bitset string pos out of range"); + size_t __rlen = _VSTD::min(__n, __str.size() - __pos); for (size_t __i = __pos; __i < __pos + __rlen; ++__i) if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one)) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw invalid_argument("bitset string ctor has invalid argument"); -#else - assert(!"bitset string ctor has invalid argument"); -#endif + __throw_invalid_argument("bitset string ctor has invalid argument"); + size_t _Mp = _VSTD::min(__rlen, _Size); size_t __i = 0; for (; __i < _Mp; ++__i) @@ -876,11 +858,8 @@ bitset<_Size>& bitset<_Size>::set(size_t __pos, bool __val) { if (__pos >= _Size) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("bitset set argument out of range"); -#else - assert(!"bitset set argument out of range"); -#endif + __throw_out_of_range("bitset set argument out of range"); + (*this)[__pos] = __val; return *this; } @@ -899,11 +878,8 @@ bitset<_Size>& bitset<_Size>::reset(size_t __pos) { if (__pos >= _Size) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("bitset reset argument out of range"); -#else - assert(!"bitset reset argument out of range"); -#endif + __throw_out_of_range("bitset reset argument out of range"); + (*this)[__pos] = false; return *this; } @@ -932,11 +908,8 @@ bitset<_Size>& bitset<_Size>::flip(size_t __pos) { if (__pos >= _Size) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("bitset flip argument out of range"); -#else - assert(!"bitset flip argument out of range"); -#endif + __throw_out_of_range("bitset flip argument out of range"); + reference r = base::__make_ref(__pos); r = ~r; return *this; @@ -1027,11 +1000,8 @@ bool bitset<_Size>::test(size_t __pos) const { if (__pos >= _Size) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("bitset test argument out of range"); -#else - assert(!"bitset test argument out of range"); -#endif + __throw_out_of_range("bitset test argument out of range"); + return (*this)[__pos]; } diff --git a/include/chrono b/include/chrono index 68484e982432..74e359c58dc2 100644 --- a/include/chrono +++ b/include/chrono @@ -529,7 +529,7 @@ private: public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifndef _LIBCPP_CXX03_LANG duration() = default; #else duration() {} @@ -1026,7 +1026,8 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { - return __lhs + (-__rhs); + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() -__rhs); } // duration operator-(time_point x, time_point y); diff --git a/include/cmath b/include/cmath index b3e959405e9e..724935623db7 100644 --- a/include/cmath +++ b/include/cmath @@ -331,7 +331,6 @@ using ::double_t; using ::abs; #endif -#ifndef __sun__ using ::acos; using ::acosf; using ::asin; @@ -346,58 +345,47 @@ using ::cos; using ::cosf; using ::cosh; using ::coshf; -#endif // __sun__ using ::exp; using ::expf; -#ifndef __sun__ using ::fabs; using ::fabsf; using ::floor; using ::floorf; -#endif //__sun__ using ::fmod; using ::fmodf; -#ifndef __sun__ using ::frexp; using ::frexpf; using ::ldexp; using ::ldexpf; -#endif // __sun__ using ::log; using ::logf; -#ifndef __sun__ using ::log10; using ::log10f; using ::modf; using ::modff; -#endif // __sun__ using ::pow; using ::powf; -#ifndef __sun__ using ::sin; using ::sinf; using ::sinh; using ::sinhf; -#endif // __sun__ using ::sqrt; using ::sqrtf; using ::tan; using ::tanf; -#ifndef __sun__ using ::tanh; using ::tanhf; -#ifndef _LIBCPP_MSVCRT using ::acosh; using ::acoshf; using ::asinh; @@ -406,7 +394,6 @@ using ::atanh; using ::atanhf; using ::cbrt; using ::cbrtf; -#endif using ::copysign; using ::copysignf; @@ -449,14 +436,10 @@ using ::lrintf; using ::lround; using ::lroundf; #endif // _LIBCPP_MSVCRT -#endif // __sun__ -#ifndef _LIBCPP_MSVCRT using ::nan; using ::nanf; -#endif // _LIBCPP_MSVCRT -#ifndef __sun__ #ifndef _LIBCPP_MSVCRT using ::nearbyint; using ::nearbyintf; @@ -504,13 +487,11 @@ using ::sinhl; using ::sqrtl; using ::tanl; -#ifndef _LIBCPP_MSVCRT using ::tanhl; using ::acoshl; using ::asinhl; using ::atanhl; using ::cbrtl; -#endif // !_LIBCPP_MSVCRT using ::copysignl; @@ -547,11 +528,6 @@ using ::tgammal; using ::truncl; #endif // !_LIBCPP_MSVCRT -#else -using ::lgamma; -using ::lgammaf; -#endif // __sun__ - #if _LIBCPP_STD_VER > 14 inline _LIBCPP_INLINE_VISIBILITY float hypot( float x, float y, float z ) { return sqrt(x*x + y*y + z*z); } inline _LIBCPP_INLINE_VISIBILITY double hypot( double x, double y, double z ) { return sqrt(x*x + y*y + z*z); } @@ -559,23 +535,83 @@ inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double x, long double y template <class _A1, class _A2, class _A3> inline _LIBCPP_INLINE_VISIBILITY -typename std::__lazy_enable_if +typename __lazy_enable_if < - std::is_arithmetic<_A1>::value && - std::is_arithmetic<_A2>::value && - std::is_arithmetic<_A3>::value, - std::__promote<_A1, _A2, _A3> + is_arithmetic<_A1>::value && + is_arithmetic<_A2>::value && + is_arithmetic<_A3>::value, + __promote<_A1, _A2, _A3> >::type hypot(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT { - typedef typename std::__promote<_A1, _A2, _A3>::type __result_type; - static_assert((!(std::is_same<_A1, __result_type>::value && - std::is_same<_A2, __result_type>::value && - std::is_same<_A3, __result_type>::value)), ""); + typedef typename __promote<_A1, _A2, _A3>::type __result_type; + static_assert((!(is_same<_A1, __result_type>::value && + is_same<_A2, __result_type>::value && + is_same<_A3, __result_type>::value)), ""); return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z); } #endif +template <class _A1> +_LIBCPP_ALWAYS_INLINE +_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type +__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT +{ +#if __has_builtin(__builtin_isnan) + return __builtin_isnan(__lcpp_x); +#else + return isnan(__lcpp_x); +#endif +} + +template <class _A1> +_LIBCPP_ALWAYS_INLINE +_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type +__libcpp_isnan(_A1 __lcpp_x) _NOEXCEPT +{ + return isnan(__lcpp_x); +} + +template <class _A1> +_LIBCPP_ALWAYS_INLINE +_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type +__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT +{ +#if __has_builtin(__builtin_isinf) + return __builtin_isinf(__lcpp_x); +#else + return isinf(__lcpp_x); +#endif +} + +template <class _A1> +_LIBCPP_ALWAYS_INLINE +_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type +__libcpp_isinf(_A1 __lcpp_x) _NOEXCEPT +{ + return isinf(__lcpp_x); +} + +template <class _A1> +_LIBCPP_ALWAYS_INLINE +_LIBCPP_CONSTEXPR typename enable_if<is_floating_point<_A1>::value, bool>::type +__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT +{ +#if __has_builtin(__builtin_isfinite) + return __builtin_isfinite(__lcpp_x); +#else + return isfinite(__lcpp_x); +#endif +} + +template <class _A1> +_LIBCPP_ALWAYS_INLINE +_LIBCPP_CONSTEXPR typename enable_if<!is_floating_point<_A1>::value, bool>::type +__libcpp_isfinite(_A1 __lcpp_x) _NOEXCEPT +{ + return isfinite(__lcpp_x); +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_CMATH diff --git a/include/complex b/include/complex index f56138fa2d16..22f568f555e7 100644 --- a/include/complex +++ b/include/complex @@ -245,9 +245,6 @@ template<class T, class charT, class traits> #include <stdexcept> #include <cmath> #include <sstream> -#if defined(_LIBCPP_NO_EXCEPTIONS) - #include <cassert> -#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -602,39 +599,39 @@ operator*(const complex<_Tp>& __z, const complex<_Tp>& __w) _Tp __bc = __b * __c; _Tp __x = __ac - __bd; _Tp __y = __ad + __bc; - if (isnan(__x) && isnan(__y)) + if (__libcpp_isnan(__x) && __libcpp_isnan(__y)) { bool __recalc = false; - if (isinf(__a) || isinf(__b)) + if (__libcpp_isinf(__a) || __libcpp_isinf(__b)) { - __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a); - __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b); - if (isnan(__c)) + __a = copysign(__libcpp_isinf(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(__libcpp_isinf(__b) ? _Tp(1) : _Tp(0), __b); + if (__libcpp_isnan(__c)) __c = copysign(_Tp(0), __c); - if (isnan(__d)) + if (__libcpp_isnan(__d)) __d = copysign(_Tp(0), __d); __recalc = true; } - if (isinf(__c) || isinf(__d)) + if (__libcpp_isinf(__c) || __libcpp_isinf(__d)) { - __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c); - __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d); - if (isnan(__a)) + __c = copysign(__libcpp_isinf(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(__libcpp_isinf(__d) ? _Tp(1) : _Tp(0), __d); + if (__libcpp_isnan(__a)) __a = copysign(_Tp(0), __a); - if (isnan(__b)) + if (__libcpp_isnan(__b)) __b = copysign(_Tp(0), __b); __recalc = true; } - if (!__recalc && (isinf(__ac) || isinf(__bd) || - isinf(__ad) || isinf(__bc))) + if (!__recalc && (__libcpp_isinf(__ac) || __libcpp_isinf(__bd) || + __libcpp_isinf(__ad) || __libcpp_isinf(__bc))) { - if (isnan(__a)) + if (__libcpp_isnan(__a)) __a = copysign(_Tp(0), __a); - if (isnan(__b)) + if (__libcpp_isnan(__b)) __b = copysign(_Tp(0), __b); - if (isnan(__c)) + if (__libcpp_isnan(__c)) __c = copysign(_Tp(0), __c); - if (isnan(__d)) + if (__libcpp_isnan(__d)) __d = copysign(_Tp(0), __d); __recalc = true; } @@ -677,7 +674,7 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) _Tp __c = __w.real(); _Tp __d = __w.imag(); _Tp __logbw = logb(fmax(fabs(__c), fabs(__d))); - if (isfinite(__logbw)) + if (__libcpp_isfinite(__logbw)) { __ilogbw = static_cast<int>(__logbw); __c = scalbn(__c, -__ilogbw); @@ -686,24 +683,24 @@ operator/(const complex<_Tp>& __z, const complex<_Tp>& __w) _Tp __denom = __c * __c + __d * __d; _Tp __x = scalbn((__a * __c + __b * __d) / __denom, -__ilogbw); _Tp __y = scalbn((__b * __c - __a * __d) / __denom, -__ilogbw); - if (isnan(__x) && isnan(__y)) + if (__libcpp_isnan(__x) && __libcpp_isnan(__y)) { - if ((__denom == _Tp(0)) && (!isnan(__a) || !isnan(__b))) + if ((__denom == _Tp(0)) && (!__libcpp_isnan(__a) || !__libcpp_isnan(__b))) { __x = copysign(_Tp(INFINITY), __c) * __a; __y = copysign(_Tp(INFINITY), __c) * __b; } - else if ((isinf(__a) || isinf(__b)) && isfinite(__c) && isfinite(__d)) + else if ((__libcpp_isinf(__a) || __libcpp_isinf(__b)) && __libcpp_isfinite(__c) && __libcpp_isfinite(__d)) { - __a = copysign(isinf(__a) ? _Tp(1) : _Tp(0), __a); - __b = copysign(isinf(__b) ? _Tp(1) : _Tp(0), __b); + __a = copysign(__libcpp_isinf(__a) ? _Tp(1) : _Tp(0), __a); + __b = copysign(__libcpp_isinf(__b) ? _Tp(1) : _Tp(0), __b); __x = _Tp(INFINITY) * (__a * __c + __b * __d); __y = _Tp(INFINITY) * (__b * __c - __a * __d); } - else if (isinf(__logbw) && __logbw > _Tp(0) && isfinite(__a) && isfinite(__b)) + else if (__libcpp_isinf(__logbw) && __logbw > _Tp(0) && __libcpp_isfinite(__a) && __libcpp_isfinite(__b)) { - __c = copysign(isinf(__c) ? _Tp(1) : _Tp(0), __c); - __d = copysign(isinf(__d) ? _Tp(1) : _Tp(0), __d); + __c = copysign(__libcpp_isinf(__c) ? _Tp(1) : _Tp(0), __c); + __d = copysign(__libcpp_isinf(__d) ? _Tp(1) : _Tp(0), __d); __x = _Tp(0) * (__a * __c + __b * __d); __y = _Tp(0) * (__b * __c - __a * __d); } @@ -795,45 +792,41 @@ operator!=(const _Tp& __x, const complex<_Tp>& __y) // 26.3.7 values: -// real +template <class _Tp, bool = is_integral<_Tp>::value, + bool = is_floating_point<_Tp>::value + > +struct __libcpp_complex_overload_traits {}; -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -_Tp -real(const complex<_Tp>& __c) +// Integral Types +template <class _Tp> +struct __libcpp_complex_overload_traits<_Tp, true, false> { - return __c.real(); -} + typedef double _ValueType; + typedef complex<double> _ComplexType; +}; -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -long double -real(long double __re) +// Floating point types +template <class _Tp> +struct __libcpp_complex_overload_traits<_Tp, false, true> { - return __re; -} + typedef _Tp _ValueType; + typedef complex<_Tp> _ComplexType; +}; -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -double -real(double __re) -{ - return __re; -} +// real template<class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename enable_if -< - is_integral<_Tp>::value, - double ->::type -real(_Tp __re) +_Tp +real(const complex<_Tp>& __c) { - return __re; + return __c.real(); } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -float -real(float __re) +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +real(_Tp __re) { return __re; } @@ -848,35 +841,10 @@ imag(const complex<_Tp>& __c) return __c.imag(); } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -long double -imag(long double __re) -{ - return 0; -} - -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -double -imag(double __re) -{ - return 0; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -typename enable_if -< - is_integral<_Tp>::value, - double ->::type -imag(_Tp __re) -{ - return 0; -} - -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -float -imag(float __re) +typename __libcpp_complex_overload_traits<_Tp>::_ValueType +imag(_Tp) { return 0; } @@ -901,25 +869,22 @@ arg(const complex<_Tp>& __c) return atan2(__c.imag(), __c.real()); } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -long double -arg(long double __re) +typename enable_if< + is_same<_Tp, long double>::value, + long double +>::type +arg(_Tp __re) { return atan2l(0.L, __re); } -inline _LIBCPP_INLINE_VISIBILITY -double -arg(double __re) -{ - return atan2(0., __re); -} - template<class _Tp> inline _LIBCPP_INLINE_VISIBILITY typename enable_if < - is_integral<_Tp>::value, + is_integral<_Tp>::value || is_same<_Tp, double>::value, double >::type arg(_Tp __re) @@ -927,9 +892,13 @@ arg(_Tp __re) return atan2(0., __re); } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -float -arg(float __re) +typename enable_if< + is_same<_Tp, float>::value, + float +>::type +arg(_Tp __re) { return atan2f(0.F, __re); } @@ -941,44 +910,20 @@ inline _LIBCPP_INLINE_VISIBILITY _Tp norm(const complex<_Tp>& __c) { - if (isinf(__c.real())) + if (__libcpp_isinf(__c.real())) return abs(__c.real()); - if (isinf(__c.imag())) + if (__libcpp_isinf(__c.imag())) return abs(__c.imag()); return __c.real() * __c.real() + __c.imag() * __c.imag(); } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -long double -norm(long double __re) -{ - return __re * __re; -} - -inline _LIBCPP_INLINE_VISIBILITY -double -norm(double __re) -{ - return __re * __re; -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - double ->::type +typename __libcpp_complex_overload_traits<_Tp>::_ValueType norm(_Tp __re) { - return (double)__re * __re; -} - -inline _LIBCPP_INLINE_VISIBILITY -float -norm(float __re) -{ - return __re * __re; + typedef typename __libcpp_complex_overload_traits<_Tp>::_ValueType _ValueType; + return static_cast<_ValueType>(__re) * __re; } // conj @@ -991,38 +936,16 @@ conj(const complex<_Tp>& __c) return complex<_Tp>(__c.real(), -__c.imag()); } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -complex<long double> -conj(long double __re) -{ - return complex<long double>(__re); -} - -inline _LIBCPP_INLINE_VISIBILITY -complex<double> -conj(double __re) -{ - return complex<double>(__re); -} - -template<class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - complex<double> ->::type +typename __libcpp_complex_overload_traits<_Tp>::_ComplexType conj(_Tp __re) { - return complex<double>(__re); + typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; + return _ComplexType(__re); } -inline _LIBCPP_INLINE_VISIBILITY -complex<float> -conj(float __re) -{ - return complex<float>(__re); -} + // proj @@ -1032,48 +955,36 @@ complex<_Tp> proj(const complex<_Tp>& __c) { std::complex<_Tp> __r = __c; - if (isinf(__c.real()) || isinf(__c.imag())) + if (__libcpp_isinf(__c.real()) || __libcpp_isinf(__c.imag())) __r = complex<_Tp>(INFINITY, copysign(_Tp(0), __c.imag())); return __r; } +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -complex<long double> -proj(long double __re) -{ - if (isinf(__re)) - __re = abs(__re); - return complex<long double>(__re); -} - -inline _LIBCPP_INLINE_VISIBILITY -complex<double> -proj(double __re) +typename enable_if +< + is_floating_point<_Tp>::value, + typename __libcpp_complex_overload_traits<_Tp>::_ComplexType +>::type +proj(_Tp __re) { - if (isinf(__re)) + if (__libcpp_isinf(__re)) __re = abs(__re); - return complex<double>(__re); + return complex<_Tp>(__re); } -template<class _Tp> +template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY typename enable_if < is_integral<_Tp>::value, - complex<double> + typename __libcpp_complex_overload_traits<_Tp>::_ComplexType >::type proj(_Tp __re) { - return complex<double>(__re); -} - -inline _LIBCPP_INLINE_VISIBILITY -complex<float> -proj(float __re) -{ - if (isinf(__re)) - __re = abs(__re); - return complex<float>(__re); + typedef typename __libcpp_complex_overload_traits<_Tp>::_ComplexType _ComplexType; + return _ComplexType(__re); } // polar @@ -1082,25 +993,25 @@ template<class _Tp> complex<_Tp> polar(const _Tp& __rho, const _Tp& __theta = _Tp(0)) { - if (isnan(__rho) || signbit(__rho)) + if (__libcpp_isnan(__rho) || signbit(__rho)) return complex<_Tp>(_Tp(NAN), _Tp(NAN)); - if (isnan(__theta)) + if (__libcpp_isnan(__theta)) { - if (isinf(__rho)) + if (__libcpp_isinf(__rho)) return complex<_Tp>(__rho, __theta); return complex<_Tp>(__theta, __theta); } - if (isinf(__theta)) + if (__libcpp_isinf(__theta)) { - if (isinf(__rho)) + if (__libcpp_isinf(__rho)) return complex<_Tp>(__rho, _Tp(NAN)); return complex<_Tp>(_Tp(NAN), _Tp(NAN)); } _Tp __x = __rho * cos(__theta); - if (isnan(__x)) + if (__libcpp_isnan(__x)) __x = 0; _Tp __y = __rho * sin(__theta); - if (isnan(__y)) + if (__libcpp_isnan(__y)) __y = 0; return complex<_Tp>(__x, __y); } @@ -1131,13 +1042,13 @@ template<class _Tp> complex<_Tp> sqrt(const complex<_Tp>& __x) { - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(_Tp(INFINITY), __x.imag()); - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { if (__x.real() > _Tp(0)) - return complex<_Tp>(__x.real(), isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); - return complex<_Tp>(isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); + return complex<_Tp>(__x.real(), __libcpp_isnan(__x.imag()) ? __x.imag() : copysign(_Tp(0), __x.imag())); + return complex<_Tp>(__libcpp_isnan(__x.imag()) ? __x.imag() : _Tp(0), copysign(__x.real(), __x.imag())); } return polar(sqrt(abs(__x)), arg(__x) / _Tp(2)); } @@ -1149,21 +1060,21 @@ complex<_Tp> exp(const complex<_Tp>& __x) { _Tp __i = __x.imag(); - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { if (__x.real() < _Tp(0)) { - if (!isfinite(__i)) + if (!__libcpp_isfinite(__i)) __i = _Tp(1); } - else if (__i == 0 || !isfinite(__i)) + else if (__i == 0 || !__libcpp_isfinite(__i)) { - if (isinf(__i)) + if (__libcpp_isinf(__i)) __i = _Tp(NAN); return complex<_Tp>(__x.real(), __i); } } - else if (isnan(__x.real()) && __x.imag() == 0) + else if (__libcpp_isnan(__x.real()) && __x.imag() == 0) return __x; _Tp __e = exp(__x.real()); return complex<_Tp>(__e * cos(__i), __e * sin(__i)); @@ -1221,23 +1132,23 @@ complex<_Tp> asinh(const complex<_Tp>& __x) { const _Tp __pi(atan2(+0., -0.)); - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { - if (isnan(__x.imag())) + if (__libcpp_isnan(__x.imag())) return __x; - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); } - if (isnan(__x.real())) + if (__libcpp_isnan(__x.real())) { - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(__x.imag(), __x.real()); if (__x.imag() == 0) return __x; return complex<_Tp>(__x.real(), __x.real()); } - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(copysign(__x.imag(), __x.real()), copysign(__pi/_Tp(2), __x.imag())); complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) + _Tp(1))); return complex<_Tp>(copysign(__z.real(), __x.real()), copysign(__z.imag(), __x.imag())); @@ -1250,11 +1161,11 @@ complex<_Tp> acosh(const complex<_Tp>& __x) { const _Tp __pi(atan2(+0., -0.)); - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { - if (isnan(__x.imag())) + if (__libcpp_isnan(__x.imag())) return complex<_Tp>(abs(__x.real()), __x.imag()); - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) { if (__x.real() > 0) return complex<_Tp>(__x.real(), copysign(__pi * _Tp(0.25), __x.imag())); @@ -1265,13 +1176,13 @@ acosh(const complex<_Tp>& __x) return complex<_Tp>(-__x.real(), copysign(__pi, __x.imag())); return complex<_Tp>(__x.real(), copysign(_Tp(0), __x.imag())); } - if (isnan(__x.real())) + if (__libcpp_isnan(__x.real())) { - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(abs(__x.imag()), __x.real()); return complex<_Tp>(__x.real(), __x.real()); } - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(abs(__x.imag()), copysign(__pi/_Tp(2), __x.imag())); complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1))); return complex<_Tp>(copysign(__z.real(), _Tp(0)), copysign(__z.imag(), __x.imag())); @@ -1284,21 +1195,21 @@ complex<_Tp> atanh(const complex<_Tp>& __x) { const _Tp __pi(atan2(+0., -0.)); - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) { return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); } - if (isnan(__x.imag())) + if (__libcpp_isnan(__x.imag())) { - if (isinf(__x.real()) || __x.real() == 0) + if (__libcpp_isinf(__x.real()) || __x.real() == 0) return complex<_Tp>(copysign(_Tp(0), __x.real()), __x.imag()); return complex<_Tp>(__x.imag(), __x.imag()); } - if (isnan(__x.real())) + if (__libcpp_isnan(__x.real())) { return complex<_Tp>(__x.real(), __x.real()); } - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { return complex<_Tp>(copysign(_Tp(0), __x.real()), copysign(__pi/_Tp(2), __x.imag())); } @@ -1316,11 +1227,11 @@ template<class _Tp> complex<_Tp> sinh(const complex<_Tp>& __x) { - if (isinf(__x.real()) && !isfinite(__x.imag())) + if (__libcpp_isinf(__x.real()) && !__libcpp_isfinite(__x.imag())) return complex<_Tp>(__x.real(), _Tp(NAN)); - if (__x.real() == 0 && !isfinite(__x.imag())) + if (__x.real() == 0 && !__libcpp_isfinite(__x.imag())) return complex<_Tp>(__x.real(), _Tp(NAN)); - if (__x.imag() == 0 && !isfinite(__x.real())) + if (__x.imag() == 0 && !__libcpp_isfinite(__x.real())) return __x; return complex<_Tp>(sinh(__x.real()) * cos(__x.imag()), cosh(__x.real()) * sin(__x.imag())); } @@ -1331,13 +1242,13 @@ template<class _Tp> complex<_Tp> cosh(const complex<_Tp>& __x) { - if (isinf(__x.real()) && !isfinite(__x.imag())) + if (__libcpp_isinf(__x.real()) && !__libcpp_isfinite(__x.imag())) return complex<_Tp>(abs(__x.real()), _Tp(NAN)); - if (__x.real() == 0 && !isfinite(__x.imag())) + if (__x.real() == 0 && !__libcpp_isfinite(__x.imag())) return complex<_Tp>(_Tp(NAN), __x.real()); if (__x.real() == 0 && __x.imag() == 0) return complex<_Tp>(_Tp(1), __x.imag()); - if (__x.imag() == 0 && !isfinite(__x.real())) + if (__x.imag() == 0 && !__libcpp_isfinite(__x.real())) return complex<_Tp>(abs(__x.real()), __x.imag()); return complex<_Tp>(cosh(__x.real()) * cos(__x.imag()), sinh(__x.real()) * sin(__x.imag())); } @@ -1348,19 +1259,19 @@ template<class _Tp> complex<_Tp> tanh(const complex<_Tp>& __x) { - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { - if (!isfinite(__x.imag())) + if (!__libcpp_isfinite(__x.imag())) return complex<_Tp>(_Tp(1), _Tp(0)); return complex<_Tp>(_Tp(1), copysign(_Tp(0), sin(_Tp(2) * __x.imag()))); } - if (isnan(__x.real()) && __x.imag() == 0) + if (__libcpp_isnan(__x.real()) && __x.imag() == 0) return __x; _Tp __2r(_Tp(2) * __x.real()); _Tp __2i(_Tp(2) * __x.imag()); _Tp __d(cosh(__2r) + cos(__2i)); _Tp __2rsh(sinh(__2r)); - if (isinf(__2rsh) && isinf(__d)) + if (__libcpp_isinf(__2rsh) && __libcpp_isinf(__d)) return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); return complex<_Tp>(__2rsh/__d, sin(__2i)/__d); @@ -1383,11 +1294,11 @@ complex<_Tp> acos(const complex<_Tp>& __x) { const _Tp __pi(atan2(+0., -0.)); - if (isinf(__x.real())) + if (__libcpp_isinf(__x.real())) { - if (isnan(__x.imag())) + if (__libcpp_isnan(__x.imag())) return complex<_Tp>(__x.imag(), __x.real()); - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) { if (__x.real() < _Tp(0)) return complex<_Tp>(_Tp(0.75) * __pi, -__x.imag()); @@ -1397,13 +1308,13 @@ acos(const complex<_Tp>& __x) return complex<_Tp>(__pi, signbit(__x.imag()) ? -__x.real() : __x.real()); return complex<_Tp>(_Tp(0), signbit(__x.imag()) ? __x.real() : -__x.real()); } - if (isnan(__x.real())) + if (__libcpp_isnan(__x.real())) { - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(__x.real(), -__x.imag()); return complex<_Tp>(__x.real(), __x.real()); } - if (isinf(__x.imag())) + if (__libcpp_isinf(__x.imag())) return complex<_Tp>(__pi/_Tp(2), -__x.imag()); if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) return complex<_Tp>(__pi/_Tp(2), -__x.imag()); diff --git a/include/cstdio b/include/cstdio index 50fdd3457426..35941ce35156 100644 --- a/include/cstdio +++ b/include/cstdio @@ -98,6 +98,9 @@ void perror(const char* s); #include <__config> #include <stdio.h> +#if defined(_LIBCPP_MSVCRT) +#include <crtversion.h> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -118,11 +121,9 @@ using ::fscanf; using ::snprintf; using ::sprintf; using ::sscanf; -#ifndef _LIBCPP_MSVCRT using ::vfprintf; using ::vfscanf; using ::vsscanf; -#endif // _LIBCPP_MSVCRT using ::vsnprintf; using ::vsprintf; using ::fgetc; @@ -155,7 +156,8 @@ using ::tmpnam; #ifndef _LIBCPP_HAS_NO_STDIN using ::getchar; -#if _LIBCPP_STD_VER <= 11 +#if _LIBCPP_STD_VER <= 11 && \ + (!defined(_VC_CRT_MAJOR_VERSION) || _VC_CRT_MAJOR_VERSION < 14) using ::gets; #endif using ::scanf; diff --git a/include/cstdlib b/include/cstdlib index 10ed231078d8..2ca25ed56ca6 100644 --- a/include/cstdlib +++ b/include/cstdlib @@ -89,6 +89,12 @@ void *aligned_alloc(size_t alignment, size_t size); // C11 #pragma GCC system_header #endif +#ifdef __GNUC__ +#define _LIBCPP_UNREACHABLE() __builtin_unreachable() +#else +#define _LIBCPP_UNREACHABLE() _VSTD::abort() +#endif + _LIBCPP_BEGIN_NAMESPACE_STD using ::size_t; @@ -138,11 +144,9 @@ using ::ldiv; #ifndef _LIBCPP_HAS_NO_LONG_LONG using ::lldiv; #endif // _LIBCPP_HAS_NO_LONG_LONG -#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS using ::mblen; using ::mbtowc; using ::wctomb; -#endif using ::mbstowcs; using ::wcstombs; #ifdef _LIBCPP_HAS_QUICK_EXIT diff --git a/include/cwchar b/include/cwchar index 52dde9e18021..d268e8bbd393 100644 --- a/include/cwchar +++ b/include/cwchar @@ -123,11 +123,9 @@ using ::fwscanf; using ::swprintf; using ::vfwprintf; using ::vswprintf; -#ifndef _LIBCPP_MSVCRT using ::swscanf; using ::vfwscanf; using ::vswscanf; -#endif // _LIBCPP_MSVCRT using ::fgetwc; using ::fgetws; using ::fputwc; @@ -137,10 +135,8 @@ using ::getwc; using ::putwc; using ::ungetwc; using ::wcstod; -#ifndef _LIBCPP_MSVCRT using ::wcstof; using ::wcstold; -#endif // _LIBCPP_MSVCRT using ::wcstol; #ifndef _LIBCPP_HAS_NO_LONG_LONG using ::wcstoll; @@ -182,9 +178,7 @@ using ::wcsrtombs; #ifndef _LIBCPP_HAS_NO_STDIN using ::getwchar; -#ifndef _LIBCPP_MSVCRT using ::vwscanf; -#endif // _LIBCPP_MSVCRT using ::wscanf; #endif diff --git a/include/deque b/include/deque index 57650427645c..ed62edd3b3cd 100644 --- a/include/deque +++ b/include/deque @@ -110,8 +110,8 @@ public: void push_front(value_type&& v); void push_back(const value_type& v); void push_back(value_type&& v); - template <class... Args> void emplace_front(Args&&... args); - template <class... Args> void emplace_back(Args&&... args); + template <class... Args> reference emplace_front(Args&&... args); + template <class... Args> reference emplace_back(Args&&... args); template <class... Args> iterator emplace(const_iterator p, Args&&... args); iterator insert(const_iterator p, const value_type& v); iterator insert(const_iterator p, value_type&& v); @@ -895,26 +895,22 @@ template <bool> class __deque_base_common { protected: - void __throw_length_error() const; - void __throw_out_of_range() const; + _LIBCPP_NORETURN void __throw_length_error() const; + _LIBCPP_NORETURN void __throw_out_of_range() const; }; template <bool __b> void __deque_base_common<__b>::__throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw length_error("deque"); -#endif + _VSTD::__throw_length_error("deque"); } template <bool __b> void __deque_base_common<__b>::__throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("deque"); -#endif + _VSTD::__throw_out_of_range("deque"); } template <class _Tp, class _Allocator> @@ -1314,7 +1310,9 @@ public: size_type size() const _NOEXCEPT {return __base::size();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT - {return __alloc_traits::max_size(__base::__alloc());} + {return std::min<size_type>( + __alloc_traits::max_size(__base::__alloc()), + numeric_limits<difference_type>::max());} void resize(size_type __n); void resize(size_type __n, const value_type& __v); void shrink_to_fit() _NOEXCEPT; @@ -1344,8 +1342,8 @@ public: void push_back(const value_type& __v); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_VARIADICS - template <class... _Args> void emplace_front(_Args&&... __args); - template <class... _Args> void emplace_back(_Args&&... __args); + template <class... _Args> reference emplace_front(_Args&&... __args); + template <class... _Args> reference emplace_back(_Args&&... __args); template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args); #endif // _LIBCPP_HAS_NO_VARIADICS void push_front(value_type&& __v); @@ -1824,15 +1822,17 @@ deque<_Tp, _Allocator>::push_back(value_type&& __v) template <class _Tp, class _Allocator> template <class... _Args> -void +typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::emplace_back(_Args&&... __args) { allocator_type& __a = __base::__alloc(); if (__back_spare() == 0) __add_back_capacity(); // __back_spare() >= 1 - __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), _VSTD::forward<_Args>(__args)...); + __alloc_traits::construct(__a, _VSTD::addressof(*__base::end()), + _VSTD::forward<_Args>(__args)...); ++__base::size(); + return *--__base::end(); } #endif // _LIBCPP_HAS_NO_VARIADICS @@ -1870,7 +1870,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v) template <class _Tp, class _Allocator> template <class... _Args> -void +typename deque<_Tp, _Allocator>::reference deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) { allocator_type& __a = __base::__alloc(); @@ -1880,6 +1880,7 @@ deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) __alloc_traits::construct(__a, _VSTD::addressof(*--__base::begin()), _VSTD::forward<_Args>(__args)...); --__base::__start_; ++__base::size(); + return *__base::begin(); } #endif // _LIBCPP_HAS_NO_VARIADICS @@ -2734,7 +2735,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f) difference_type __pos = __f - __b; iterator __p = __b + __pos; allocator_type& __a = __base::__alloc(); - if (__pos <= (__base::size() - 1) / 2) + if (static_cast<size_t>(__pos) <= (__base::size() - 1) / 2) { // erase from front _VSTD::move_backward(__b, __p, _VSTD::next(__p)); __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); @@ -2772,7 +2773,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) if (__n > 0) { allocator_type& __a = __base::__alloc(); - if (__pos <= (__base::size() - __n) / 2) + if (static_cast<size_t>(__pos) <= (__base::size() - __n) / 2) { // erase from front iterator __i = _VSTD::move_backward(__b, __p, __p + __n); for (; __b != __i; ++__b) diff --git a/include/exception b/include/exception index 186d379f08f5..98e1f37f919e 100644 --- a/include/exception +++ b/include/exception @@ -79,11 +79,8 @@ template <class E> void rethrow_if_nested(const E& e); #include <__config> #include <cstddef> -#include <type_traits> -#if defined(_LIBCPP_NO_EXCEPTIONS) -#include <cstdio> #include <cstdlib> -#endif +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -165,7 +162,10 @@ make_exception_ptr(_Ep __e) _NOEXCEPT { return current_exception(); } -#endif // _LIBCPP_NO_EXCEPTIONS +#else + ((void)__e); + _VSTD::abort(); +#endif } // nested_exception @@ -209,6 +209,9 @@ throw_with_nested (_Tp& __t, typename enable_if< { #ifndef _LIBCPP_NO_EXCEPTIONS throw __nested<typename remove_reference<_Tp>::type>(_VSTD::forward<_Tp>(__t)); +#else + ((void)__t); + // FIXME: Make this abort. #endif } @@ -229,6 +232,9 @@ throw_with_nested (_Tp& __t, typename enable_if< { #ifndef _LIBCPP_NO_EXCEPTIONS throw _VSTD::forward<_Tp>(__t); +#else + ((void)__t); + // FIXME: Make this abort #endif } @@ -255,19 +261,4 @@ rethrow_if_nested(const _Ep&, typename enable_if< } // std -_LIBCPP_BEGIN_NAMESPACE_STD - -template <class _Exception> -_LIBCPP_INLINE_VISIBILITY -inline void __libcpp_throw(_Exception const& __e) { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw __e; -#else - _VSTD::fprintf(stderr, "%s\n", __e.what()); - _VSTD::abort(); -#endif -} - -_LIBCPP_END_NAMESPACE_STD - #endif // _LIBCPP_EXCEPTION diff --git a/include/experimental/algorithm b/include/experimental/algorithm index 3902111c54ea..392ca1fa41c0 100644 --- a/include/experimental/algorithm +++ b/include/experimental/algorithm @@ -58,61 +58,11 @@ _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searc template <class _PopulationIterator, class _SampleIterator, class _Distance, class _UniformRandomNumberGenerator> -_LIBCPP_INLINE_VISIBILITY -_SampleIterator __sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __out, - _Distance __n, - _UniformRandomNumberGenerator &&__g, - input_iterator_tag) { - - _Distance __k = 0; - for (; __first != __last && __k < __n; ++__first, (void)++__k) - __out[__k] = *__first; - _Distance __sz = __k; - for (; __first != __last; ++__first, (void)++__k) { - _Distance __r = _VSTD::uniform_int_distribution<_Distance>(0, __k)(__g); - if (__r < __sz) - __out[__r] = *__first; - } - return __out + _VSTD::min(__n, __k); -} - -template <class _PopulationIterator, class _SampleIterator, class _Distance, - class _UniformRandomNumberGenerator> -_LIBCPP_INLINE_VISIBILITY -_SampleIterator __sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __out, - _Distance __n, - _UniformRandomNumberGenerator &&__g, - forward_iterator_tag) { - _Distance __unsampled_sz = _VSTD::distance(__first, __last); - for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { - _Distance __r = - _VSTD::uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); - if (__r < __n) { - *__out++ = *__first; - --__n; - } - } - return __out; -} - -template <class _PopulationIterator, class _SampleIterator, class _Distance, - class _UniformRandomNumberGenerator> -_LIBCPP_INLINE_VISIBILITY -_SampleIterator sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __out, - _Distance __n, _UniformRandomNumberGenerator &&__g) { - typedef typename iterator_traits<_PopulationIterator>::iterator_category - _PopCategory; - typedef typename iterator_traits<_PopulationIterator>::difference_type - _Difference; - typedef typename common_type<_Distance, _Difference>::type _CommonType; - _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); - return _VSTD_LFTS::__sample( - __first, __last, __out, _CommonType(__n), - _VSTD::forward<_UniformRandomNumberGenerator>(__g), - _PopCategory()); +inline _LIBCPP_INLINE_VISIBILITY +_SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, + _SampleIterator __out, _Distance __n, + _UniformRandomNumberGenerator &&__g) { + return _VSTD::__sample(__first, __last, __out, __n, __g); } _LIBCPP_END_NAMESPACE_LFTS diff --git a/include/experimental/any b/include/experimental/any index 4c732496c52b..9ecafad637df 100644 --- a/include/experimental/any +++ b/include/experimental/any @@ -82,7 +82,6 @@ inline namespace fundamentals_v1 { #include <typeinfo> #include <type_traits> #include <cstdlib> -#include <cassert> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -98,13 +97,13 @@ public: #if _LIBCPP_STD_VER > 11 // C++ > 11 -_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY -inline void __throw_bad_any_cast() +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_bad_any_cast() { #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_any_cast(); #else - assert(!"bad_any_cast"); + _VSTD::abort(); #endif } diff --git a/include/experimental/dynarray b/include/experimental/dynarray index 4a06908e11b1..8ef45713ae4d 100644 --- a/include/experimental/dynarray +++ b/include/experimental/dynarray @@ -106,10 +106,6 @@ public: #include <__undef___deallocate> -#if defined(_LIBCPP_NO_EXCEPTIONS) - #include <cassert> -#endif - #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif @@ -142,13 +138,8 @@ private: static inline _LIBCPP_INLINE_VISIBILITY value_type* __allocate ( size_t count ) { if ( numeric_limits<size_t>::max() / sizeof (value_type) <= count ) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_array_length(); -#else - assert(!"dynarray::allocation"); -#endif - } + __throw_bad_array_length(); + return static_cast<value_type *> (_VSTD::__allocate (sizeof(value_type) * count)); } @@ -283,13 +274,8 @@ typename dynarray<_Tp>::reference dynarray<_Tp>::at(size_type __n) { if (__n >= __size_) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("dynarray::at"); -#else - assert(!"dynarray::at out_of_range"); -#endif - } + __throw_out_of_range("dynarray::at"); + return data()[__n]; } @@ -299,13 +285,8 @@ typename dynarray<_Tp>::const_reference dynarray<_Tp>::at(size_type __n) const { if (__n >= __size_) - { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("dynarray::at"); -#else - assert(!"dynarray::at out_of_range"); -#endif - } + __throw_out_of_range("dynarray::at"); + return data()[__n]; } diff --git a/include/experimental/filesystem b/include/experimental/filesystem index 7de93fdf8f15..739918bb2cbe 100644 --- a/include/experimental/filesystem +++ b/include/experimental/filesystem @@ -228,7 +228,7 @@ #include <system_error> #include <utility> #include <iomanip> // for quoted -#include <experimental/string_view> +#include <string_view> #include <__debug> @@ -249,7 +249,7 @@ struct _LIBCPP_TYPE_VIS space_info uintmax_t available; }; -enum class _LIBCPP_TYPE_VIS file_type : signed char +enum class _LIBCPP_ENUM_VIS file_type : signed char { none = 0, not_found = -1, @@ -263,7 +263,7 @@ enum class _LIBCPP_TYPE_VIS file_type : signed char unknown = 8 }; -enum class _LIBCPP_TYPE_VIS perms : unsigned +enum class _LIBCPP_ENUM_VIS perms : unsigned { none = 0, @@ -323,7 +323,7 @@ _LIBCPP_INLINE_VISIBILITY inline perms& operator^=(perms& _LHS, perms _RHS) { return _LHS = _LHS ^ _RHS; } -enum class _LIBCPP_TYPE_VIS copy_options : unsigned short +enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { none = 0, skip_existing = 1, @@ -367,7 +367,7 @@ inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) { return _LHS = _LHS ^ _RHS; } -enum class directory_options : unsigned char +enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { none = 0, follow_directory_symlink = 1, @@ -453,6 +453,9 @@ class _LIBCPP_TYPE_VIS directory_entry; template <class _Tp> struct __can_convert_char { static const bool value = false; }; +template <class _Tp> struct __can_convert_char<const _Tp> + : public __can_convert_char<_Tp> { +}; template <> struct __can_convert_char<char> { static const bool value = true; using __char_type = char; @@ -498,6 +501,21 @@ struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>, } }; + +template <class _ECharT, class _Traits> +struct __is_pathable_string<basic_string_view<_ECharT, _Traits>, + _Void<typename __can_convert_char<_ECharT>::__char_type>> +: public __can_convert_char<_ECharT> +{ + using _Str = basic_string_view<_ECharT, _Traits>; + using _Base = __can_convert_char<_ECharT>; + static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } + static _ECharT __first_or_null(_Str const& __s) { + return __s.empty() ? _ECharT{} : __s[0]; + } +}; + template <class _Source, class _DS = typename decay<_Source>::type, class _UnqualPtrType = typename remove_const< @@ -605,13 +623,23 @@ struct _PathCVT { template <> struct _PathCVT<char> { + template <class _Iter> - static void __append_range(string& __dest, _Iter __b, _Iter __e) { + static typename enable_if< + __is_exactly_input_iterator<_Iter>::value + >::type __append_range(string& __dest, _Iter __b, _Iter __e) { for (; __b != __e; ++__b) __dest.push_back(*__b); } template <class _Iter> + static typename enable_if< + __is_forward_iterator<_Iter>::value + >::type __append_range(string& __dest, _Iter __b, _Iter __e) { + __dest.__append_forward_unsafe(__b, __e); + } + + template <class _Iter> static void __append_range(string& __dest, _Iter __b, _NullSentinal) { const char __sentinal = char{}; for (; *__b != __sentinal; ++__b) @@ -622,7 +650,8 @@ struct _PathCVT<char> { static void __append_source(string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), + _Traits::__range_end(__s)); } }; @@ -642,6 +671,7 @@ class _LIBCPP_TYPE_VIS path public: typedef char value_type; typedef basic_string<value_type> string_type; + typedef _VSTD::string_view __string_view; static _LIBCPP_CONSTEXPR value_type preferred_separator = '/'; // constructors and destructor @@ -740,6 +770,8 @@ private: public: // appends path& operator/=(const path& __p) { + _LIBCPP_ASSERT(!__p.has_root_name(), + "cannot append to a path with a root name"); __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]); __pn_ += __p.native(); return *this; @@ -788,6 +820,12 @@ public: } _LIBCPP_INLINE_VISIBILITY + path& operator+=(__string_view __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY path& operator+=(const value_type* __x) { __pn_ += __x; return *this; @@ -799,7 +837,6 @@ public: return *this; } - template <class _ECharT> typename enable_if<__can_convert_char<_ECharT>::value, path&>::type operator+=(_ECharT __x) @@ -837,7 +874,15 @@ public: } path& make_preferred() { return *this; } - path& remove_filename() { return *this = parent_path(); } + + _LIBCPP_INLINE_VISIBILITY + path& remove_filename() { + if (__pn_.size() == __root_path_raw().size()) + clear(); + else + __pn_ = __parent_path(); + return *this; + } path& replace_filename(const path& __replacement) { remove_filename(); @@ -896,37 +941,39 @@ public: std::u32string generic_u32string() const { return string<char32_t>(); } private: - _LIBCPP_FUNC_VIS int __compare(const value_type*) const; - _LIBCPP_FUNC_VIS string_view __root_name() const; - _LIBCPP_FUNC_VIS string_view __root_directory() const; - _LIBCPP_FUNC_VIS string_view __relative_path() const; - _LIBCPP_FUNC_VIS string_view __parent_path() const; - _LIBCPP_FUNC_VIS string_view __filename() const; - _LIBCPP_FUNC_VIS string_view __stem() const; - _LIBCPP_FUNC_VIS string_view __extension() const; + _LIBCPP_FUNC_VIS int __compare(__string_view) const; + _LIBCPP_FUNC_VIS __string_view __root_name() const; + _LIBCPP_FUNC_VIS __string_view __root_directory() const; + _LIBCPP_FUNC_VIS __string_view __root_path_raw() const; + _LIBCPP_FUNC_VIS __string_view __relative_path() const; + _LIBCPP_FUNC_VIS __string_view __parent_path() const; + _LIBCPP_FUNC_VIS __string_view __filename() const; + _LIBCPP_FUNC_VIS __string_view __stem() const; + _LIBCPP_FUNC_VIS __string_view __extension() const; public: // compare - _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.c_str());} - _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s.c_str()); } + _LIBCPP_INLINE_VISIBILITY int compare(const path& __p) const _NOEXCEPT { return __compare(__p.__pn_);} + _LIBCPP_INLINE_VISIBILITY int compare(const string_type& __s) const { return __compare(__s); } + _LIBCPP_INLINE_VISIBILITY int compare(__string_view __s) const { return __compare(__s); } _LIBCPP_INLINE_VISIBILITY int compare(const value_type* __s) const { return __compare(__s); } // decomposition - _LIBCPP_INLINE_VISIBILITY path root_name() const { return __root_name().to_string(); } - _LIBCPP_INLINE_VISIBILITY path root_directory() const { return __root_directory().to_string(); } - _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(__root_directory().to_string()); } - _LIBCPP_INLINE_VISIBILITY path relative_path() const { return __relative_path().to_string(); } - _LIBCPP_INLINE_VISIBILITY path parent_path() const { return __parent_path().to_string(); } - _LIBCPP_INLINE_VISIBILITY path filename() const { return __filename().to_string(); } - _LIBCPP_INLINE_VISIBILITY path stem() const { return __stem().to_string();} - _LIBCPP_INLINE_VISIBILITY path extension() const { return __extension().to_string(); } + _LIBCPP_INLINE_VISIBILITY path root_name() const { return string_type(__root_name()); } + _LIBCPP_INLINE_VISIBILITY path root_directory() const { return string_type(__root_directory()); } + _LIBCPP_INLINE_VISIBILITY path root_path() const { return root_name().append(string_type(__root_directory())); } + _LIBCPP_INLINE_VISIBILITY path relative_path() const { return string_type(__relative_path()); } + _LIBCPP_INLINE_VISIBILITY path parent_path() const { return string_type(__parent_path()); } + _LIBCPP_INLINE_VISIBILITY path filename() const { return string_type(__filename()); } + _LIBCPP_INLINE_VISIBILITY path stem() const { return string_type(__stem());} + _LIBCPP_INLINE_VISIBILITY path extension() const { return string_type(__extension()); } // query _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT { return __pn_.empty(); } _LIBCPP_INLINE_VISIBILITY bool has_root_name() const { return !__root_name().empty(); } _LIBCPP_INLINE_VISIBILITY bool has_root_directory() const { return !__root_directory().empty(); } - _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !(__root_name().empty() && __root_directory().empty()); } + _LIBCPP_INLINE_VISIBILITY bool has_root_path() const { return !__root_path_raw().empty(); } _LIBCPP_INLINE_VISIBILITY bool has_relative_path() const { return !__relative_path().empty(); } _LIBCPP_INLINE_VISIBILITY bool has_parent_path() const { return !__parent_path().empty(); } _LIBCPP_INLINE_VISIBILITY bool has_filename() const { return !__filename().empty(); } @@ -945,7 +992,7 @@ public: private: inline _LIBCPP_INLINE_VISIBILITY - path& __assign_view(string_view const& __s) noexcept { __pn_ = __s.to_string(); return *this; } + path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; } string_type __pn_; }; @@ -1047,7 +1094,8 @@ public: typedef const path& reference; public: _LIBCPP_INLINE_VISIBILITY - iterator() : __elem_(), __path_ptr_(nullptr), __pos_(0) {} + iterator() : __stashed_elem_(), __path_ptr_(nullptr), + __entry_(), __state_(__singular) {} iterator(const iterator&) = default; ~iterator() = default; @@ -1056,16 +1104,20 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { - return __elem_; + return __stashed_elem_; } _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - return &__elem_; + return &__stashed_elem_; } _LIBCPP_INLINE_VISIBILITY iterator& operator++() { + _LIBCPP_ASSERT(__state_ != __singular, + "attempting to increment a singular iterator"); + _LIBCPP_ASSERT(__state_ != __at_end, + "attempting to increment the end iterator"); return __increment(); } @@ -1078,6 +1130,10 @@ public: _LIBCPP_INLINE_VISIBILITY iterator& operator--() { + _LIBCPP_ASSERT(__state_ != __singular, + "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), + "attempting to decrement the begin iterator"); return __decrement(); } @@ -1090,20 +1146,26 @@ public: private: friend class path; + + static constexpr unsigned char __singular = 0; + static constexpr unsigned char __at_end = 6; + + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, const iterator&); _LIBCPP_FUNC_VIS iterator& __increment(); _LIBCPP_FUNC_VIS iterator& __decrement(); - path __elem_; + path __stashed_elem_; const path* __path_ptr_; - size_t __pos_; + path::__string_view __entry_; + unsigned char __state_; }; inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) { return __lhs.__path_ptr_ == __rhs.__path_ptr_ && - __lhs.__pos_ == __rhs.__pos_; + __lhs.__entry_.data() == __rhs.__entry_.data(); } inline _LIBCPP_INLINE_VISIBILITY @@ -1154,6 +1216,21 @@ private: shared_ptr<_Storage> __paths_; }; +template <class... _Args> +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +#ifndef _LIBCPP_NO_EXCEPTIONS +void __throw_filesystem_error(_Args && ...__args) +{ + throw filesystem_error(std::forward<_Args>(__args)...); +} +#else +void __throw_filesystem_error(_Args&&...) +{ + _VSTD::abort(); +} +#endif + + // operational functions _LIBCPP_FUNC_VIS @@ -1865,6 +1942,7 @@ public: { return __increment(&__ec); } private: + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) _NOEXCEPT; @@ -2014,6 +2092,7 @@ private: _LIBCPP_FUNC_VIS void __pop(error_code* __ec=nullptr); + inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const recursive_directory_iterator&, const recursive_directory_iterator&) _NOEXCEPT; @@ -2023,9 +2102,9 @@ private: }; // class recursive_directory_iterator -_LIBCPP_INLINE_VISIBILITY -inline bool operator==(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) _NOEXCEPT +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) _NOEXCEPT { return __lhs.__imp_ == __rhs.__imp_; } diff --git a/include/experimental/memory_resource b/include/experimental/memory_resource index 9b345210ee5e..1a2cb10bbec5 100644 --- a/include/experimental/memory_resource +++ b/include/experimental/memory_resource @@ -182,9 +182,9 @@ public: _LIBCPP_INLINE_VISIBILITY _ValueType* allocate(size_t __n) { if (__n > max_size()) { - __libcpp_throw(length_error( + __throw_length_error( "std::experimental::pmr::polymorphic_allocator<T>::allocate(size_t n)" - " 'n' exceeds maximum supported size")); + " 'n' exceeds maximum supported size"); } return static_cast<_ValueType*>( __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType)) @@ -383,9 +383,9 @@ protected: virtual void * do_allocate(size_t __bytes, size_t) { if (__bytes > __max_size()) { - __libcpp_throw(length_error( + __throw_length_error( "std::experimental::pmr::resource_adaptor<T>::do_allocate(size_t bytes, size_t align)" - " 'bytes' exceeds maximum supported size")); + " 'bytes' exceeds maximum supported size"); } size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; return __alloc_.allocate(__s); diff --git a/include/experimental/numeric b/include/experimental/numeric new file mode 100644 index 000000000000..32b19a466358 --- /dev/null +++ b/include/experimental/numeric @@ -0,0 +1,103 @@ +// -*- C++ -*- +//===--------------------------- numeric ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_NUMERIC +#define _LIBCPP_EXPERIMENTAL_NUMERIC +/* + experimental/numeric synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v2 { + + // 13.1.2, Greatest common divisor + template<class M, class N> + constexpr common_type_t<M,N> gcd(M m, N n); + + // 13.1.3, Least common multiple + template<class M, class N> + constexpr common_type_t<M,N> lcm(M m, N n); + +} // namespace fundamentals_v2 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <numeric> +#include <type_traits> // is_integral +#include <limits> // numeric_limits + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 11 + +_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 + +template <typename _Tp, bool _IsSigned = is_signed<_Tp>::value> struct __abs; + +template <typename _Tp> +struct __abs<_Tp, true> { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _Tp operator()(_Tp __t) const noexcept { return __t >= 0 ? __t : -__t; } +}; + +template <typename _Tp> +struct __abs<_Tp, false> { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _Tp operator()(_Tp __t) const noexcept { return __t; } +}; + + +template<class _Tp> +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +_Tp __gcd(_Tp __m, _Tp __n) +{ + static_assert((!is_signed<_Tp>::value), "" ); + return __n == 0 ? __m : __gcd<_Tp>(__n, __m % __n); +} + + +template<class _Tp, class _Up> +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +common_type_t<_Tp,_Up> +gcd(_Tp __m, _Up __n) +{ + static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); + using _Rp = common_type_t<_Tp,_Up>; + using _Wp = make_unsigned_t<_Rp>; + return static_cast<_Rp>(__gcd(static_cast<_Wp>(__abs<_Tp>()(__m)), + static_cast<_Wp>(__abs<_Up>()(__n)))); +} + +template<class _Tp, class _Up> +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +common_type_t<_Tp,_Up> +lcm(_Tp __m, _Up __n) +{ + static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); + if (__m == 0 || __n == 0) + return 0; + + using _Rp = common_type_t<_Tp,_Up>; + _Rp __val1 = __abs<_Tp>()(__m) / gcd(__m,__n); + _Up __val2 = __abs<_Up>()(__n); + _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); + return __val1 * __val2; +} + +_LIBCPP_END_NAMESPACE_LFTS_V2 + +#endif /* _LIBCPP_STD_VER > 11 */ +#endif /* _LIBCPP_EXPERIMENTAL_NUMERIC */ diff --git a/include/experimental/optional b/include/experimental/optional index 3912438ec104..8dcda652319b 100644 --- a/include/experimental/optional +++ b/include/experimental/optional @@ -8,8 +8,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_OPTIONAL -#define _LIBCPP_OPTIONAL +#ifndef _LIBCPP_EXPERIMENTAL_OPTIONAL +#define _LIBCPP_EXPERIMENTAL_OPTIONAL /* optional synopsis @@ -211,7 +211,7 @@ protected: : __engaged_(__x.__engaged_) { if (__engaged_) - ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_); } _LIBCPP_INLINE_VISIBILITY @@ -220,7 +220,7 @@ protected: : __engaged_(__x.__engaged_) { if (__engaged_) - ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); } _LIBCPP_INLINE_VISIBILITY @@ -262,7 +262,7 @@ protected: : __engaged_(__x.__engaged_) { if (__engaged_) - ::new(_VSTD::addressof(__val_)) value_type(__x.__val_); + ::new((void*)_VSTD::addressof(__val_)) value_type(__x.__val_); } _LIBCPP_INLINE_VISIBILITY @@ -271,7 +271,7 @@ protected: : __engaged_(__x.__engaged_) { if (__engaged_) - ::new(_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); + ::new((void*)_VSTD::addressof(__val_)) value_type(_VSTD::move(__x.__val_)); } _LIBCPP_INLINE_VISIBILITY @@ -368,7 +368,7 @@ public: if (this->__engaged_) this->__val_.~value_type(); else - ::new(_VSTD::addressof(this->__val_)) value_type(__opt.__val_); + ::new((void*)_VSTD::addressof(this->__val_)) value_type(__opt.__val_); this->__engaged_ = __opt.__engaged_; } return *this; @@ -390,7 +390,8 @@ public: if (this->__engaged_) this->__val_.~value_type(); else - ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + ::new((void*)_VSTD::addressof(this->__val_)) + value_type(_VSTD::move(__opt.__val_)); this->__engaged_ = __opt.__engaged_; } return *this; @@ -412,7 +413,7 @@ public: this->__val_ = _VSTD::forward<_Up>(__v); else { - ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); + ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Up>(__v)); this->__engaged_ = true; } return *this; @@ -429,7 +430,8 @@ public: emplace(_Args&&... __args) { *this = nullopt; - ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); + ::new((void*)_VSTD::addressof(this->__val_)) + value_type(_VSTD::forward<_Args>(__args)...); this->__engaged_ = true; } @@ -444,7 +446,8 @@ public: emplace(initializer_list<_Up> __il, _Args&&... __args) { *this = nullopt; - ::new(_VSTD::addressof(this->__val_)) value_type(__il, _VSTD::forward<_Args>(__args)...); + ::new((void*)_VSTD::addressof(this->__val_)) + value_type(__il, _VSTD::forward<_Args>(__args)...); this->__engaged_ = true; } @@ -464,12 +467,14 @@ public: { if (this->__engaged_) { - ::new(_VSTD::addressof(__opt.__val_)) value_type(_VSTD::move(this->__val_)); + ::new((void*)_VSTD::addressof(__opt.__val_)) + value_type(_VSTD::move(this->__val_)); this->__val_.~value_type(); } else { - ::new(_VSTD::addressof(this->__val_)) value_type(_VSTD::move(__opt.__val_)); + ::new((void*)_VSTD::addressof(this->__val_)) + value_type(_VSTD::move(__opt.__val_)); __opt.__val_.~value_type(); } swap(this->__engaged_, __opt.__engaged_); @@ -482,7 +487,11 @@ public: operator->() const { _LIBCPP_ASSERT(this->__engaged_, "optional operator-> called for disengaged value"); +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF + return __builtin_addressof(this->__val_); +#else return __operator_arrow(__has_operator_addressof<value_type>{}); +#endif } _LIBCPP_INLINE_VISIBILITY @@ -513,15 +522,21 @@ public: _LIBCPP_INLINE_VISIBILITY constexpr explicit operator bool() const noexcept {return this->__engaged_;} + _LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY + constexpr void __throw_bad_optional_access() const + { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + _VSTD::abort(); +#endif + } + _LIBCPP_INLINE_VISIBILITY constexpr value_type const& value() const { if (!this->__engaged_) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_optional_access(); -#else - assert(!"bad optional access"); -#endif + __throw_bad_optional_access(); return this->__val_; } @@ -529,11 +544,7 @@ public: value_type& value() { if (!this->__engaged_) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_optional_access(); -#else - assert(!"bad optional access"); -#endif + __throw_bad_optional_access(); return this->__val_; } @@ -710,7 +721,7 @@ template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY constexpr bool -operator<=(nullopt_t, const optional<_Tp>& __x) noexcept +operator<=(nullopt_t, const optional<_Tp>&) noexcept { return true; } @@ -728,7 +739,7 @@ template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY constexpr bool -operator>(nullopt_t, const optional<_Tp>& __x) noexcept +operator>(nullopt_t, const optional<_Tp>&) noexcept { return false; } @@ -899,4 +910,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER > 11 -#endif // _LIBCPP_OPTIONAL +#endif // _LIBCPP_EXPERIMENTAL_OPTIONAL diff --git a/include/experimental/propagate_const b/include/experimental/propagate_const index f267ba275c2f..e7f7e9fc6831 100644 --- a/include/experimental/propagate_const +++ b/include/experimental/propagate_const @@ -123,8 +123,14 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 template <class _Tp> class propagate_const; -template <class _Up> _LIBCPP_CONSTEXPR const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; -template <class _Up> _LIBCPP_CONSTEXPR _Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; + +template <class _Up> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Up& get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; + +template <class _Up> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +_Up& get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; template <class _Tp> class propagate_const @@ -462,14 +468,12 @@ _LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& _ } template <class _Tp> -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const _Tp& get_underlying(const propagate_const<_Tp>& __pt) _NOEXCEPT { return __pt.__t_; } template <class _Tp> -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp& get_underlying(propagate_const<_Tp>& __pt) _NOEXCEPT { return __pt.__t_; diff --git a/include/experimental/string_view b/include/experimental/string_view index 0a7239b4c0bb..a62fe6e95a10 100644 --- a/include/experimental/string_view +++ b/include/experimental/string_view @@ -281,7 +281,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS const_reference at(size_type __pos) const { return __pos >= size() - ? (__libcpp_throw(out_of_range("string_view::at")), __data[0]) + ? (__throw_out_of_range("string_view::at"), __data[0]) : __data[__pos]; } @@ -352,7 +352,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { if ( __pos > size()) - __libcpp_throw(out_of_range("string_view::copy")); + __throw_out_of_range("string_view::copy"); size_type __rlen = _VSTD::min( __n, size() - __pos ); _VSTD::copy_n(begin() + __pos, __rlen, __s ); return __rlen; @@ -362,11 +362,11 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS basic_string_view substr(size_type __pos = 0, size_type __n = npos) const { // if (__pos > size()) -// throw out_of_range("string_view::substr"); +// __throw_out_of_range("string_view::substr"); // size_type __rlen = _VSTD::min( __n, size() - __pos ); // return basic_string_view(data() + __pos, __rlen); return __pos > size() - ? (__libcpp_throw((out_of_range("string_view::substr"))), basic_string_view()) + ? (__throw_out_of_range("string_view::substr"), basic_string_view()) : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); } diff --git a/include/experimental/type_traits b/include/experimental/type_traits index ae49fc176c01..d6901d41a61e 100644 --- a/include/experimental/type_traits +++ b/include/experimental/type_traits @@ -172,6 +172,45 @@ inline namespace fundamentals_v1 { template <class T> using raw_invocation_type_t = typename raw_invocation_type<T>::type; + // 3.3.3, Logical operator traits + template<class... B> struct conjunction; + template<class... B> constexpr bool conjunction_v = conjunction<B...>::value; + template<class... B> struct disjunction; + template<class... B> constexpr bool disjunction_v = disjunction<B...>::value; + template<class B> struct negation; + template<class B> constexpr bool negation_v = negation<B>::value; + + // 3.3.4, Detection idiom + template <class...> using void_t = void; + + struct nonesuch { + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + void operator=(nonesuch const&) = delete; + }; + + template <template<class...> class Op, class... Args> + using is_detected = see below; + template <template<class...> class Op, class... Args> + constexpr bool is_detected_v = is_detected<Op, Args...>::value; + template <template<class...> class Op, class... Args> + using detected_t = see below; + template <class Default, template<class...> class Op, class... Args> + using detected_or = see below; + template <class Default, template<class...> class Op, class... Args> + using detected_or_t = typename detected_or<Default, Op, Args...>::type; + template <class Expected, template<class...> class Op, class... Args> + using is_detected_exact = is_same<Expected, detected_t<Op, Args...>>; + template <class Expected, template<class...> class Op, class... Args> + constexpr bool is_detected_exact_v + = is_detected_exact<Expected, Op, Args...>::value; + template <class To, template<class...> class Op, class... Args> + using is_detected_convertible = is_convertible<detected_t<Op, Args...>, To>; + template <class To, template<class...> class Op, class... Args> + constexpr bool is_detected_convertible_v + = is_detected_convertible<To, Op, Args...>::value; + } // namespace fundamentals_v1 } // namespace experimental } // namespace std @@ -420,6 +459,70 @@ template <class _Tp> using raw_invocation_type_t = typename raw_invocation_type<_Tp>::type; */ +// 3.3.3, Logical operator traits +template <class...> using void_t = void; + +template <class... _Args> +struct conjunction : _VSTD::__and_<_Args...> {}; +template <class... _Args> +_LIBCPP_CONSTEXPR bool conjunction_v = conjunction<_Args...>::value; + +template <class... _Args> +struct disjunction : _VSTD::__or_<_Args...> {}; +template <class... _Args> +_LIBCPP_CONSTEXPR bool disjunction_v = disjunction<_Args...>::value; + +template <class _Tp> +struct negation : _VSTD::__not_<_Tp> {}; +template<class _Tp> +_LIBCPP_CONSTEXPR bool negation_v = negation<_Tp>::value; + +// 3.3.4, Detection idiom +template <class...> using void_t = void; + +struct nonesuch { + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch (nonesuch const&) = delete; + void operator=(nonesuch const&) = delete; + }; + +template <class _Default, class _AlwaysVoid, template <class...> class _Op, class... _Args> +struct _DETECTOR { + using value_t = false_type; + using type = _Default; + }; + +template <class _Default, template <class...> class _Op, class... _Args> +struct _DETECTOR<_Default, void_t<_Op<_Args...>>, _Op, _Args...> { + using value_t = true_type; + using type = _Op<_Args...>; + }; + + +template <template<class...> class _Op, class... _Args> + using is_detected = typename _DETECTOR<nonesuch, void, _Op, _Args...>::value_t; +template <template<class...> class _Op, class... _Args> + using detected_t = typename _DETECTOR<nonesuch, void, _Op, _Args...>::type; +template <template<class...> class _Op, class... _Args> + _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value; + +template <class Default, template<class...> class _Op, class... _Args> + using detected_or = _DETECTOR<Default, void, _Op, _Args...>; +template <class Default, template<class...> class _Op, class... _Args> + using detected_or_t = typename detected_or<Default, _Op, _Args...>::type; + +template <class Expected, template<class...> class _Op, class... _Args> + using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>; +template <class Expected, template<class...> class _Op, class... _Args> + _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value; + +template <class To, template<class...> class _Op, class... _Args> + using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>; +template <class To, template<class...> class _Op, class... _Args> + _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<To, _Op, _Args...>::value; + + _LIBCPP_END_NAMESPACE_LFTS #endif /* _LIBCPP_STD_VER > 11 */ diff --git a/include/forward_list b/include/forward_list index 18b300d84703..d70f7eddef6c 100644 --- a/include/forward_list +++ b/include/forward_list @@ -87,7 +87,7 @@ public: reference front(); const_reference front() const; - template <class... Args> void emplace_front(Args&&... args); + template <class... Args> reference emplace_front(Args&&... args); void push_front(const value_type& v); void push_front(value_type&& v); @@ -531,7 +531,7 @@ private: } _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__forward_list_base& __x, false_type) _NOEXCEPT + void __move_assign_alloc(__forward_list_base&, false_type) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__forward_list_base& __x, true_type) @@ -734,8 +734,11 @@ public: bool empty() const _NOEXCEPT {return base::__before_begin()->__next_ == nullptr;} _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT - {return numeric_limits<size_type>::max();} + size_type max_size() const _NOEXCEPT { + return std::min<size_type>( + __node_traits::max_size(base::__alloc()), + numeric_limits<difference_type>::max()); + } _LIBCPP_INLINE_VISIBILITY reference front() {return base::__before_begin()->__next_->__value_;} @@ -744,7 +747,7 @@ public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_VARIADICS - template <class... _Args> void emplace_front(_Args&&... __args); + template <class... _Args> reference emplace_front(_Args&&... __args); #endif void push_front(value_type&& __v); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -873,8 +876,9 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n) #if _LIBCPP_STD_VER > 11 template <class _Tp, class _Alloc> -forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a) - : base ( __a ) +forward_list<_Tp, _Alloc>::forward_list(size_type __n, + const allocator_type& __base_alloc) + : base ( __base_alloc ) { if (__n > 0) { @@ -1099,7 +1103,7 @@ forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) template <class _Tp, class _Alloc> template <class... _Args> -void +typename forward_list<_Tp, _Alloc>::reference forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_allocator& __a = base::__alloc(); @@ -1109,6 +1113,7 @@ forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) _VSTD::forward<_Args>(__args)...); __h->__next_ = base::__before_begin()->__next_; base::__before_begin()->__next_ = __h.release(); + return base::__before_begin()->__next_->__value_; } #endif // _LIBCPP_HAS_NO_VARIADICS @@ -1421,7 +1426,7 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, template <class _Tp, class _Alloc> void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list& __x, + forward_list& /*__other*/, const_iterator __i) { const_iterator __lm1 = _VSTD::next(__i); @@ -1436,7 +1441,7 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, template <class _Tp, class _Alloc> void forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, - forward_list& __x, + forward_list& /*__other*/, const_iterator __f, const_iterator __l) { if (__f != __l && __p != __f) diff --git a/include/fstream b/include/fstream index 3cb3b13bd10f..b8d18aadb1c9 100644 --- a/include/fstream +++ b/include/fstream @@ -618,10 +618,9 @@ basic_filebuf<_CharT, _Traits>::underflow() size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_); if (__nr != 0) { -#ifndef _LIBCPP_NO_EXCEPTIONS if (!__cv_) - throw bad_cast(); -#endif + __throw_bad_cast(); + __extbufend_ = __extbufnext_ + __nr; char_type* __inext; __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, @@ -700,10 +699,9 @@ basic_filebuf<_CharT, _Traits>::overflow(int_type __c) codecvt_base::result __r; do { -#ifndef _LIBCPP_NO_EXCEPTIONS if (!__cv_) - throw bad_cast(); -#endif + __throw_bad_cast(); + const char_type* __e; __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, __extbuf_, __extbuf_ + __ebs_, __extbe); @@ -793,10 +791,9 @@ typename basic_filebuf<_CharT, _Traits>::pos_type basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode) { -#ifndef _LIBCPP_NO_EXCEPTIONS if (!__cv_) - throw bad_cast(); -#endif + __throw_bad_cast(); + int __width = __cv_->encoding(); if (__file_ == 0 || (__width <= 0 && __off != 0) || sync()) return pos_type(off_type(-1)); @@ -816,7 +813,7 @@ basic_filebuf<_CharT, _Traits>::seekoff(off_type __off, ios_base::seekdir __way, default: return pos_type(off_type(-1)); } -#if defined(_WIN32) || defined(_NEWLIB_VERSION) +#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) if (fseek(__file_, __width > 0 ? __width * __off : 0, __whence)) return pos_type(off_type(-1)); pos_type __r = ftell(__file_); @@ -835,7 +832,7 @@ basic_filebuf<_CharT, _Traits>::seekpos(pos_type __sp, ios_base::openmode) { if (__file_ == 0 || sync()) return pos_type(off_type(-1)); -#if defined(_WIN32) || defined(_NEWLIB_VERSION) +#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) if (fseek(__file_, __sp, SEEK_SET)) return pos_type(off_type(-1)); #else @@ -852,10 +849,9 @@ basic_filebuf<_CharT, _Traits>::sync() { if (__file_ == 0) return 0; -#ifndef _LIBCPP_NO_EXCEPTIONS if (!__cv_) - throw bad_cast(); -#endif + __throw_bad_cast(); + if (__cm_ & ios_base::out) { if (this->pptr() != this->pbase()) @@ -900,7 +896,7 @@ basic_filebuf<_CharT, _Traits>::sync() } } } -#if defined(_WIN32) || defined(_NEWLIB_VERSION) +#if defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) if (fseek(__file_, -__c, SEEK_CUR)) return -1; #else diff --git a/include/functional b/include/functional index 581f965b2b81..eb8609f1469b 100644 --- a/include/functional +++ b/include/functional @@ -212,6 +212,13 @@ template <class F> unspecified not_fn(F&& f); // C++17 template<class T> struct is_bind_expression; template<class T> struct is_placeholder; + // See C++14 20.9.9, Function object binders +template <class T> constexpr bool is_bind_expression_v + = is_bind_expression<T>::value; // C++17 +template <class T> constexpr int is_placeholder_v + = is_placeholder<T>::value; // C++17 + + template<class Fn, class... BoundArgs> unspecified bind(Fn&&, BoundArgs&&...); template<class R, class Fn, class... BoundArgs> @@ -386,15 +393,15 @@ public: template<class F> function(F); template<Allocator Alloc> - function(allocator_arg_t, const Alloc&) noexcept; + function(allocator_arg_t, const Alloc&) noexcept; // removed in C++17 template<Allocator Alloc> - function(allocator_arg_t, const Alloc&, nullptr_t) noexcept; + function(allocator_arg_t, const Alloc&, nullptr_t) noexcept; // removed in C++17 template<Allocator Alloc> - function(allocator_arg_t, const Alloc&, const function&); + function(allocator_arg_t, const Alloc&, const function&); // removed in C++17 template<Allocator Alloc> - function(allocator_arg_t, const Alloc&, function&&); + function(allocator_arg_t, const Alloc&, function&&); // removed in C++17 template<class F, Allocator Alloc> - function(allocator_arg_t, const Alloc&, F); + function(allocator_arg_t, const Alloc&, F); // removed in C++17 function& operator=(const function&); function& operator=(function&&) noexcept; @@ -1382,6 +1389,16 @@ class _LIBCPP_EXCEPTION_ABI bad_function_call { }; +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_bad_function_call() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_function_call(); +#else + _VSTD::abort(); +#endif +} + template<class _Fp> class _LIBCPP_TYPE_VIS_ONLY function; // undefined namespace __function @@ -1595,13 +1612,12 @@ public: function(nullptr_t) _NOEXCEPT : __f_(0) {} function(const function&); function(function&&) _NOEXCEPT; - template<class _Fp> - function(_Fp, typename enable_if - < - __callable<_Fp>::value && - !is_same<_Fp, function>::value - >::type* = 0); + template<class _Fp, class = typename enable_if< + __callable<_Fp>::value && !is_same<_Fp, function>::value + >::type> + function(_Fp); +#if _LIBCPP_STD_VER <= 14 template<class _Alloc> _LIBCPP_INLINE_VISIBILITY function(allocator_arg_t, const _Alloc&) _NOEXCEPT : __f_(0) {} @@ -1612,9 +1628,9 @@ public: function(allocator_arg_t, const _Alloc&, const function&); template<class _Alloc> function(allocator_arg_t, const _Alloc&, function&&); - template<class _Fp, class _Alloc> - function(allocator_arg_t, const _Alloc& __a, _Fp __f, - typename enable_if<__callable<_Fp>::value>::type* = 0); + template<class _Fp, class _Alloc, class = typename enable_if<__callable<_Fp>::value>::type> + function(allocator_arg_t, const _Alloc& __a, _Fp __f); +#endif function& operator=(const function&); function& operator=(function&&) _NOEXCEPT; @@ -1675,6 +1691,7 @@ function<_Rp(_ArgTypes...)>::function(const function& __f) __f_ = __f.__f_->__clone(); } +#if _LIBCPP_STD_VER <= 14 template<class _Rp, class ..._ArgTypes> template <class _Alloc> function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, @@ -1690,6 +1707,7 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, else __f_ = __f.__f_->__clone(); } +#endif template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT @@ -1708,6 +1726,7 @@ function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT } } +#if _LIBCPP_STD_VER <= 14 template<class _Rp, class ..._ArgTypes> template <class _Alloc> function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, @@ -1726,15 +1745,11 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, __f.__f_ = 0; } } +#endif template<class _Rp, class ..._ArgTypes> -template <class _Fp> -function<_Rp(_ArgTypes...)>::function(_Fp __f, - typename enable_if - < - __callable<_Fp>::value && - !is_same<_Fp, function>::value - >::type*) +template <class _Fp, class> +function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(0) { if (__function::__not_null(__f)) @@ -1756,10 +1771,10 @@ function<_Rp(_ArgTypes...)>::function(_Fp __f, } } +#if _LIBCPP_STD_VER <= 14 template<class _Rp, class ..._ArgTypes> -template <class _Fp, class _Alloc> -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f, - typename enable_if<__callable<_Fp>::value>::type*) +template <class _Fp, class _Alloc, class> +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp __f) : __f_(0) { typedef allocator_traits<_Alloc> __alloc_traits; @@ -1782,6 +1797,7 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp _ } } } +#endif template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& @@ -1854,6 +1870,8 @@ template<class _Rp, class ..._ArgTypes> void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { + if (_VSTD::addressof(__f) == this) + return; if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; @@ -1891,10 +1909,8 @@ template<class _Rp, class ..._ArgTypes> _Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { -#ifndef _LIBCPP_NO_EXCEPTIONS if (__f_ == 0) - throw bad_function_call(); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_bad_function_call(); return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...); } @@ -1971,10 +1987,20 @@ template<class _Tp> struct __is_bind_expression : public false_type {}; template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_bind_expression : public __is_bind_expression<typename remove_cv<_Tp>::type> {}; +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; +#endif + template<class _Tp> struct __is_placeholder : public integral_constant<int, 0> {}; template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_placeholder : public __is_placeholder<typename remove_cv<_Tp>::type> {}; +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value; +#endif + namespace placeholders { @@ -2204,36 +2230,6 @@ private: typedef typename __make_tuple_indices<sizeof...(_BoundArgs)>::type __indices; public: -#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS - - _LIBCPP_INLINE_VISIBILITY - __bind(const __bind& __b) - : __f_(__b.__f_), - __bound_args_(__b.__bound_args_) {} - - _LIBCPP_INLINE_VISIBILITY - __bind& operator=(const __bind& __b) - { - __f_ = __b.__f_; - __bound_args_ = __b.__bound_args_; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __bind(__bind&& __b) - : __f_(_VSTD::move(__b.__f_)), - __bound_args_(_VSTD::move(__b.__bound_args_)) {} - - _LIBCPP_INLINE_VISIBILITY - __bind& operator=(__bind&& __b) - { - __f_ = _VSTD::move(__b.__f_); - __bound_args_ = _VSTD::move(__b.__bound_args_); - return *this; - } - -#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS - template <class _Gp, class ..._BA, class = typename enable_if < @@ -2278,31 +2274,6 @@ class __bind_r public: typedef _Rp result_type; -#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS - - _LIBCPP_INLINE_VISIBILITY - __bind_r(const __bind_r& __b) - : base(_VSTD::forward<const base&>(__b)) {} - - _LIBCPP_INLINE_VISIBILITY - __bind_r& operator=(const __bind_r& __b) - { - base::operator=(_VSTD::forward<const base&>(__b)); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __bind_r(__bind_r&& __b) - : base(_VSTD::forward<base>(__b)) {} - - _LIBCPP_INLINE_VISIBILITY - __bind_r& operator=(__bind_r&& __b) - { - base::operator=(_VSTD::forward<base>(__b)); - return *this; - } - -#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS template <class _Gp, class ..._BA, class = typename enable_if @@ -2583,12 +2554,11 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<long double> }; #if _LIBCPP_STD_VER > 11 -template <class _Tp> -struct _LIBCPP_TYPE_VIS_ONLY hash + +template <class _Tp, bool = is_enum<_Tp>::value> +struct _LIBCPP_TYPE_VIS_ONLY __enum_hash : public unary_function<_Tp, size_t> { - static_assert(is_enum<_Tp>::value, "This hash only works for enumeration types"); - _LIBCPP_INLINE_VISIBILITY size_t operator()(_Tp __v) const _NOEXCEPT { @@ -2596,11 +2566,24 @@ struct _LIBCPP_TYPE_VIS_ONLY hash return hash<type>{}(static_cast<type>(__v)); } }; +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY __enum_hash<_Tp, false> { + __enum_hash() = delete; + __enum_hash(__enum_hash const&) = delete; + __enum_hash& operator=(__enum_hash const&) = delete; +}; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY hash : public __enum_hash<_Tp> +{ +}; #endif #if _LIBCPP_STD_VER > 14 +#define __cpp_lib_invoke 201411 + template <class _Fn, class ..._Args> result_of_t<_Fn&&(_Args&&...)> invoke(_Fn&& __f, _Args&&... __args) @@ -2620,30 +2603,30 @@ public: _LIBCPP_INLINE_VISIBILITY auto operator()(_Args&& ...__args) & noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))) - -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)) - { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); } + -> decltype( !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); } template <class ..._Args> _LIBCPP_INLINE_VISIBILITY auto operator()(_Args&& ...__args) && noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))) - -> decltype(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)) - { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); } + -> decltype( !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); } template <class ..._Args> _LIBCPP_INLINE_VISIBILITY auto operator()(_Args&& ...__args) const& noexcept(noexcept(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...))) - -> decltype(!_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)) - { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); } + -> decltype( !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(__fd, _VSTD::forward<_Args>(__args)...); } template <class ..._Args> _LIBCPP_INLINE_VISIBILITY auto operator()(_Args&& ...__args) const&& noexcept(noexcept(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...))) - -> decltype(!_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)) - { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); } + -> decltype( !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...)) + { return !_VSTD::invoke(_VSTD::move(__fd), _VSTD::forward<_Args>(__args)...); } private: template <class _RawFunc, diff --git a/include/future b/include/future index 936060e173b8..d1d42f6a7274 100644 --- a/include/future +++ b/include/future @@ -50,7 +50,7 @@ class future_error { public: future_error(error_code ec); // exposition only - + explicit future_error(future_errc); // C++17 const error_code& code() const noexcept; const char* what() const noexcept; }; @@ -505,20 +505,23 @@ class _LIBCPP_EXCEPTION_ABI future_error error_code __ec_; public: future_error(error_code __ec); - +#if _LIBCPP_STD_VERS > 14 + explicit future_error(future_errc _Ev) : logic_error(), __ec_(make_error_code(_Ev)) {} +#endif _LIBCPP_INLINE_VISIBILITY const error_code& code() const _NOEXCEPT {return __ec_;} virtual ~future_error() _NOEXCEPT; }; -inline _LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE void __throw_future_error(future_errc _Ev) { #ifndef _LIBCPP_NO_EXCEPTIONS throw future_error(make_error_code(_Ev)); #else - assert(!"future_error"); + ((void)_Ev); + _VSTD::abort(); #endif } @@ -2372,7 +2375,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_future() _NOEXCEPT : __state_(nullptr) {} _LIBCPP_INLINE_VISIBILITY - shared_future(const shared_future& __rhs) : __state_(__rhs.__state_) + shared_future(const shared_future& __rhs) _NOEXCEPT : __state_(__rhs.__state_) {if (__state_) __state_->__add_shared();} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -2383,7 +2386,7 @@ public: {__rhs.__state_ = nullptr;} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~shared_future(); - shared_future& operator=(const shared_future& __rhs); + shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY shared_future& operator=(shared_future&& __rhs) _NOEXCEPT @@ -2427,7 +2430,7 @@ shared_future<_Rp>::~shared_future() template <class _Rp> shared_future<_Rp>& -shared_future<_Rp>::operator=(const shared_future& __rhs) +shared_future<_Rp>::operator=(const shared_future& __rhs) _NOEXCEPT { if (__rhs.__state_) __rhs.__state_->__add_shared(); diff --git a/include/inttypes.h b/include/inttypes.h index 5c5618bef884..058f54b5161f 100644 --- a/include/inttypes.h +++ b/include/inttypes.h @@ -237,6 +237,13 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int #pragma GCC system_header #endif +/* C99 stdlib (e.g. glibc < 2.18) does not provide format macros needed + for C++11 unless __STDC_FORMAT_MACROS is defined +*/ +#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) +# define __STDC_FORMAT_MACROS +#endif + #include_next <inttypes.h> #ifdef __cplusplus diff --git a/include/iomanip b/include/iomanip index 9efcbe03d1ae..a6bee736f45b 100644 --- a/include/iomanip +++ b/include/iomanip @@ -44,6 +44,7 @@ template <class charT, class traits, class Allocator> */ #include <__config> +#include <__string> #include <istream> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -567,19 +568,6 @@ __quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _Char } -template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> > -struct __quoted_output_proxy -{ - _Iter __first; - _Iter __last; - _CharT __delim; - _CharT __escape; - - __quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e) - : __first(__f), __last(__l), __delim(__d), __escape(__e) {} - // This would be a nice place for a string_ref -}; - template <class _CharT, class _Traits, class _Iter> basic_ostream<_CharT, _Traits>& operator<<( basic_ostream<_CharT, _Traits>& __os, @@ -666,6 +654,15 @@ quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _Char { return __quoted(__s, __delim, __escape); } + +template <class _CharT, class _Traits> +__quoted_output_proxy<_CharT, const _CharT *, _Traits> +quoted (basic_string_view <_CharT, _Traits> __sv, + _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted_output_proxy<_CharT, const _CharT *, _Traits> + ( __sv.data(), __sv.data() + __sv.size(), __delim, __escape ); +} #endif _LIBCPP_END_NAMESPACE_STD diff --git a/include/ios b/include/ios index cbea478a74a8..fb8f88dddab2 100644 --- a/include/ios +++ b/include/ios @@ -572,6 +572,13 @@ ios_base::exceptions(iostate __iostate) clear(__rdstate_); } +#if defined(_LIBCPP_CXX03_LANG) +struct _LIBCPP_TYPE_VIS_ONLY __cxx03_bool { + typedef void (__cxx03_bool::*__bool_type)(); + void __true_value() {} +}; +#endif + template <class _CharT, class _Traits> class _LIBCPP_TYPE_VIS_ONLY basic_ios : public ios_base @@ -585,9 +592,19 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + // __true_value will generate undefined references when linking unless + // we give it internal linkage. + +#if defined(_LIBCPP_CXX03_LANG) _LIBCPP_ALWAYS_INLINE - _LIBCPP_EXPLICIT - operator bool() const {return !fail();} + operator __cxx03_bool::__bool_type() const { + return !fail() ? &__cxx03_bool::__true_value : nullptr; + } +#else + _LIBCPP_ALWAYS_INLINE + _LIBCPP_EXPLICIT operator bool() const {return !fail();} +#endif + _LIBCPP_ALWAYS_INLINE bool operator!() const {return fail();} _LIBCPP_ALWAYS_INLINE iostate rdstate() const {return ios_base::rdstate();} _LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);} diff --git a/include/istream b/include/istream index ee694003a3d8..04845a24341e 100644 --- a/include/istream +++ b/include/istream @@ -184,19 +184,26 @@ public: typedef typename traits_type::off_type off_type; // 27.7.1.1.1 Constructor/destructor: - explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit basic_istream(basic_streambuf<char_type, traits_type>* __sb) : __gc_(0) + { this->init(__sb); } virtual ~basic_istream(); protected: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY basic_istream(basic_istream&& __rhs); #endif // 27.7.1.1.2 Assign/swap: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY basic_istream& operator=(basic_istream&& __rhs); #endif - void swap(basic_istream& __rhs); + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void swap(basic_istream& __rhs) { + _VSTD::swap(__gc_, __rhs.__gc_); + basic_ios<char_type, traits_type>::swap(__rhs); + } #if _LIBCPP_STD_VER > 11 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS @@ -213,10 +220,19 @@ public: class _LIBCPP_TYPE_VIS_ONLY sentry; // 27.7.1.2 Formatted input: - basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& operator>>(basic_istream& (*__pf)(basic_istream&)) + { return __pf(*this); } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_istream& operator>>(basic_ios<char_type, traits_type>& - (*__pf)(basic_ios<char_type, traits_type>&)); - basic_istream& operator>>(ios_base& (*__pf)(ios_base&)); + (*__pf)(basic_ios<char_type, traits_type>&)) + { __pf(*this); return *this; } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& operator>>(ios_base& (*__pf)(ios_base&)) + { __pf(*this); return *this; } + basic_istream& operator>>(basic_streambuf<char_type, traits_type>* __sb); basic_istream& operator>>(bool& __n); basic_istream& operator>>(short& __n); @@ -236,13 +252,31 @@ public: _LIBCPP_INLINE_VISIBILITY streamsize gcount() const {return __gc_;} int_type get(); - basic_istream& get(char_type& __c); - basic_istream& get(char_type* __s, streamsize __n); + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& get(char_type& __c) { + int_type __ch = get(); + if (__ch != traits_type::eof()) + __c = traits_type::to_char_type(__ch); + return *this; + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& get(char_type* __s, streamsize __n) + { return get(__s, __n, this->widen('\n')); } + basic_istream& get(char_type* __s, streamsize __n, char_type __dlm); - basic_istream& get(basic_streambuf<char_type, traits_type>& __sb); + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& get(basic_streambuf<char_type, traits_type>& __sb) + { return get(__sb, this->widen('\n')); } + basic_istream& get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm); - basic_istream& getline(char_type* __s, streamsize __n); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_istream& getline(char_type* __s, streamsize __n) + { return getline(__s, __n, this->widen('\n')); } + basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm); basic_istream& ignore(streamsize __n = 1, int_type __dlm = traits_type::eof()); @@ -303,18 +337,9 @@ basic_istream<_CharT, _Traits>::sentry::sentry(basic_istream<_CharT, _Traits>& _ __is.setstate(ios_base::failbit); } -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>::basic_istream(basic_streambuf<char_type, traits_type>* __sb) - : __gc_(0) -{ - this->init(__sb); -} - #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs) : __gc_(__rhs.__gc_) { @@ -323,7 +348,6 @@ basic_istream<_CharT, _Traits>::basic_istream(basic_istream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator=(basic_istream&& __rhs) { @@ -339,15 +363,6 @@ basic_istream<_CharT, _Traits>::~basic_istream() } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_istream<_CharT, _Traits>::swap(basic_istream& __rhs) -{ - _VSTD::swap(__gc_, __rhs.__gc_); - basic_ios<char_type, traits_type>::swap(__rhs); -} - -template <class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::operator>>(unsigned short& __n) { @@ -724,33 +739,6 @@ basic_istream<_CharT, _Traits>::operator>>(int& __n) return *this; } -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(basic_istream& (*__pf)(basic_istream&)) -{ - return __pf(*this); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(basic_ios<char_type, traits_type>& - (*__pf)(basic_ios<char_type, traits_type>&)) -{ - __pf(*this); - return *this; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::operator>>(ios_base& (*__pf)(ios_base&)) -{ - __pf(*this); - return *this; -} - template<class _CharT, class _Traits> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s) @@ -947,17 +935,6 @@ basic_istream<_CharT, _Traits>::get() } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::get(char_type& __c) -{ - int_type __ch = get(); - if (__ch != traits_type::eof()) - __c = traits_type::to_char_type(__ch); - return *this; -} - -template<class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm) { @@ -1006,14 +983,6 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __ } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n) -{ - return get(__s, __n, this->widen('\n')); -} - -template<class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb, char_type __dlm) @@ -1068,14 +1037,6 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __sb) -{ - return get(__sb, this->widen('\n')); -} - -template<class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_type __dlm) { @@ -1129,14 +1090,6 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ } template<class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n) -{ - return getline(__s, __n, this->widen('\n')); -} - -template<class _CharT, class _Traits> basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) { @@ -1481,9 +1434,9 @@ ws(basic_istream<_CharT, _Traits>& __is) template <class _CharT, class _Traits, class _Tp> inline _LIBCPP_INLINE_VISIBILITY basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x) +operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp&& __x) { - __is >> __x; + __is >> _VSTD::forward<_Tp>(__x); return __is; } @@ -1503,41 +1456,38 @@ public: typedef typename traits_type::off_type off_type; // constructor/destructor - explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit basic_iostream(basic_streambuf<char_type, traits_type>* __sb) + : basic_istream<_CharT, _Traits>(__sb) + {} + virtual ~basic_iostream(); protected: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY basic_iostream(basic_iostream&& __rhs); #endif // assign/swap #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY basic_iostream& operator=(basic_iostream&& __rhs); #endif - void swap(basic_iostream& __rhs); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void swap(basic_iostream& __rhs) + { basic_istream<char_type, traits_type>::swap(__rhs); } public: }; -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_iostream<_CharT, _Traits>::basic_iostream(basic_streambuf<char_type, traits_type>* __sb) - : basic_istream<_CharT, _Traits>(__sb) -{ -} - #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_iostream<_CharT, _Traits>::basic_iostream(basic_iostream&& __rhs) : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)) { } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_iostream<_CharT, _Traits>& basic_iostream<_CharT, _Traits>::operator=(basic_iostream&& __rhs) { @@ -1552,14 +1502,6 @@ basic_iostream<_CharT, _Traits>::~basic_iostream() { } -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_iostream<_CharT, _Traits>::swap(basic_iostream& __rhs) -{ - basic_istream<char_type, traits_type>::swap(__rhs); -} - template<class _CharT, class _Traits, class _Allocator> basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, @@ -1705,7 +1647,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) { basic_string<_CharT, _Traits> __str; const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__is.getloc()); - streamsize __c = 0; + size_t __c = 0; ios_base::iostate __err = ios_base::goodbit; _CharT __zero = __ct.widen('0'); _CharT __one = __ct.widen('1'); @@ -1741,9 +1683,9 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) return __is; } -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_istream<wchar_t>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_iostream<char>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>) _LIBCPP_END_NAMESPACE_STD diff --git a/include/iterator b/include/iterator index 0caabbb2ea1a..ba9a83b9e5e5 100644 --- a/include/iterator +++ b/include/iterator @@ -89,57 +89,60 @@ public: typedef typename iterator_traits<Iterator>::reference reference; typedef typename iterator_traits<Iterator>::pointer pointer; - reverse_iterator(); - explicit reverse_iterator(Iterator x); - template <class U> reverse_iterator(const reverse_iterator<U>& u); - Iterator base() const; - reference operator*() const; - pointer operator->() const; - reverse_iterator& operator++(); - reverse_iterator operator++(int); - reverse_iterator& operator--(); - reverse_iterator operator--(int); - reverse_iterator operator+ (difference_type n) const; - reverse_iterator& operator+=(difference_type n); - reverse_iterator operator- (difference_type n) const; - reverse_iterator& operator-=(difference_type n); - reference operator[](difference_type n) const; + constexpr reverse_iterator(); + constexpr explicit reverse_iterator(Iterator x); + template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u); + template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u); + constexpr Iterator base() const; + constexpr reference operator*() const; + constexpr pointer operator->() const; + constexpr reverse_iterator& operator++(); + constexpr reverse_iterator operator++(int); + constexpr reverse_iterator& operator--(); + constexpr reverse_iterator operator--(int); + constexpr reverse_iterator operator+ (difference_type n) const; + constexpr reverse_iterator& operator+=(difference_type n); + constexpr reverse_iterator operator- (difference_type n) const; + constexpr reverse_iterator& operator-=(difference_type n); + constexpr reference operator[](difference_type n) const; }; template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -auto +constexpr auto operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) --> decltype(__y.base() - __x.base()); +-> decltype(__y.base() - __x.base()); // constexpr in C++17 template <class Iterator> -reverse_iterator<Iterator> -operator+(typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& x); +constexpr reverse_iterator<Iterator> +operator+(typename reverse_iterator<Iterator>::difference_type n, + const reverse_iterator<Iterator>& x); // constexpr in C++17 -template <class Iterator> reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14 +template <class Iterator> +constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i); // C++14, constexpr in C++17 template <class Container> class back_insert_iterator @@ -216,61 +219,64 @@ public: typedef typename iterator_traits<Iterator>::iterator_category iterator_category; typedef value_type&& reference; - move_iterator(); - explicit move_iterator(Iterator i); - template <class U> move_iterator(const move_iterator<U>& u); - template <class U> move_iterator& operator=(const move_iterator<U>& u); - iterator_type base() const; - reference operator*() const; - pointer operator->() const; - move_iterator& operator++(); - move_iterator operator++(int); - move_iterator& operator--(); - move_iterator operator--(int); - move_iterator operator+(difference_type n) const; - move_iterator& operator+=(difference_type n); - move_iterator operator-(difference_type n) const; - move_iterator& operator-=(difference_type n); - unspecified operator[](difference_type n) const; + constexpr move_iterator(); // all the constexprs are in C++17 + constexpr explicit move_iterator(Iterator i); + template <class U> + constexpr move_iterator(const move_iterator<U>& u); + template <class U> + constexpr move_iterator& operator=(const move_iterator<U>& u); + constexpr iterator_type base() const; + constexpr reference operator*() const; + constexpr pointer operator->() const; + constexpr move_iterator& operator++(); + constexpr move_iterator operator++(int); + constexpr move_iterator& operator--(); + constexpr move_iterator operator--(int); + constexpr move_iterator operator+(difference_type n) const; + constexpr move_iterator& operator+=(difference_type n); + constexpr move_iterator operator-(difference_type n) const; + constexpr move_iterator& operator-=(difference_type n); + constexpr unspecified operator[](difference_type n) const; private: Iterator current; // exposition only }; template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -bool +constexpr bool // constexpr in C++17 operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -auto +constexpr auto // constexpr in C++17 operator-(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base()); template <class Iterator> -move_iterator<Iterator> operator+(typename move_iterator<Iterator>::difference_type n, - const move_iterator<Iterator>& x); +constexpr move_iterator<Iterator> operator+( // constexpr in C++17 + typename move_iterator<Iterator>::difference_type n, + const move_iterator<Iterator>& x); -template <class Iterator> -move_iterator<Iterator> make_move_iterator(const Iterator& i); +template <class Iterator> // constexpr in C++17 +constexpr move_iterator<Iterator> make_move_iterator(const Iterator& i); template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> @@ -508,8 +514,8 @@ struct __is_random_access_iterator : public __has_iterator_category_convertible_ template <class _Tp> struct __is_exactly_input_iterator : public integral_constant<bool, - __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && - !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; + __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && + !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; template<class _Category, class _Tp, class _Distance = ptrdiff_t, class _Pointer = _Tp*, class _Reference = _Tp&> @@ -618,7 +624,7 @@ class _LIBCPP_TYPE_VIS_ONLY reverse_iterator typename iterator_traits<_Iter>::reference> { private: - mutable _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break + /*mutable*/ _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break protected: _Iter current; public: @@ -627,33 +633,45 @@ public: typedef typename iterator_traits<_Iter>::reference reference; typedef typename iterator_traits<_Iter>::pointer pointer; - _LIBCPP_INLINE_VISIBILITY reverse_iterator() : current() {} - _LIBCPP_INLINE_VISIBILITY explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} - template <class _Up> _LIBCPP_INLINE_VISIBILITY reverse_iterator(const reverse_iterator<_Up>& __u) - : __t(__u.base()), current(__u.base()) {} - _LIBCPP_INLINE_VISIBILITY _Iter base() const {return current;} - _LIBCPP_INLINE_VISIBILITY reference operator*() const {_Iter __tmp = current; return *--__tmp;} - _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return _VSTD::addressof(operator*());} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator++() {--current; return *this;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator++(int) - {reverse_iterator __tmp(*this); --current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator--() {++current; return *this;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator--(int) - {reverse_iterator __tmp(*this); ++current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator+ (difference_type __n) const - {return reverse_iterator(current - __n);} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator+=(difference_type __n) - {current -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY reverse_iterator operator- (difference_type __n) const - {return reverse_iterator(current + __n);} - _LIBCPP_INLINE_VISIBILITY reverse_iterator& operator-=(difference_type __n) - {current += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const - {return *(*this + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator() : __t(), current() {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit reverse_iterator(_Iter __x) : __t(__x), current(__x) {} + template <class _Up> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator(const reverse_iterator<_Up>& __u) : __t(__u.base()), current(__u.base()) {} + template <class _Up> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator=(const reverse_iterator<_Up>& __u) + { __t = current = __u.base(); return *this; } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + _Iter base() const {return current;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator*() const {_Iter __tmp = current; return *--__tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const {return _VSTD::addressof(operator*());} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator++() {--current; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator--() {++current; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator[](difference_type __n) const {return *(*this + __n);} }; template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -661,7 +679,7 @@ operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -669,7 +687,7 @@ operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -677,7 +695,7 @@ operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -685,7 +703,7 @@ operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -693,7 +711,7 @@ operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { @@ -702,7 +720,7 @@ operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) -> decltype(__y.base() - __x.base()) @@ -720,7 +738,7 @@ operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ #endif template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator<_Iter> operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) { @@ -729,7 +747,7 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i #if _LIBCPP_STD_VER > 11 template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) { return reverse_iterator<_Iter>(__i); @@ -889,9 +907,9 @@ private: ostream_type* __out_stream_; const char_type* __delim_; public: - _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT : __out_stream_(_VSTD::addressof(__s)), __delim_(0) {} - _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) + _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_) { @@ -1040,37 +1058,40 @@ public: typedef typename iterator_traits<iterator_type>::reference reference; #endif - _LIBCPP_INLINE_VISIBILITY move_iterator() : __i() {} - _LIBCPP_INLINE_VISIBILITY explicit move_iterator(_Iter __x) : __i(__x) {} - template <class _Up> _LIBCPP_INLINE_VISIBILITY move_iterator(const move_iterator<_Up>& __u) - : __i(__u.base()) {} - _LIBCPP_INLINE_VISIBILITY _Iter base() const {return __i;} - _LIBCPP_INLINE_VISIBILITY reference operator*() const { - return static_cast<reference>(*__i); - } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const { return __i;} - _LIBCPP_INLINE_VISIBILITY move_iterator& operator++() {++__i; return *this;} - _LIBCPP_INLINE_VISIBILITY move_iterator operator++(int) - {move_iterator __tmp(*this); ++__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY move_iterator& operator--() {--__i; return *this;} - _LIBCPP_INLINE_VISIBILITY move_iterator operator--(int) - {move_iterator __tmp(*this); --__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY move_iterator operator+ (difference_type __n) const - {return move_iterator(__i + __n);} - _LIBCPP_INLINE_VISIBILITY move_iterator& operator+=(difference_type __n) - {__i += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY move_iterator operator- (difference_type __n) const - {return move_iterator(__i - __n);} - _LIBCPP_INLINE_VISIBILITY move_iterator& operator-=(difference_type __n) - {__i -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const - { - return static_cast<reference>(__i[__n]); - } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator() : __i() {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + explicit move_iterator(_Iter __x) : __i(__x) {} + template <class _Up> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator(const move_iterator<_Up>& __u) : __i(__u.base()) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Iter base() const {return __i;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator*() const { return static_cast<reference>(*__i); } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const { return __i;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator++() {++__i; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator++(int) {move_iterator __tmp(*this); ++__i; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator--() {--__i; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator--(int) {move_iterator __tmp(*this); --__i; return __tmp;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator+ (difference_type __n) const {return move_iterator(__i + __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator+=(difference_type __n) {__i += __n; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator operator- (difference_type __n) const {return move_iterator(__i - __n);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator-=(difference_type __n) {__i -= __n; return *this;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + reference operator[](difference_type __n) const { return static_cast<reference>(__i[__n]); } }; template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -1078,7 +1099,7 @@ operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -1086,7 +1107,7 @@ operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -1094,7 +1115,7 @@ operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -1102,7 +1123,7 @@ operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -1110,7 +1131,7 @@ operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) } template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { @@ -1119,7 +1140,7 @@ operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) @@ -1137,7 +1158,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) #endif template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { @@ -1145,7 +1166,7 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato } template <class _Iter> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> make_move_iterator(_Iter __i) { @@ -1159,56 +1180,58 @@ template <class _Iter> class __wrap_iter; template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY bool -operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY bool -operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY bool -operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY bool -operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY bool -operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY bool -operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY auto -operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG -> decltype(__x.base() - __y.base()); #else template <class _Iter1, class _Iter2> _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type -operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #endif template <class _Iter> _LIBCPP_INLINE_VISIBILITY __wrap_iter<_Iter> -operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT; +operator+(typename __wrap_iter<_Iter>::difference_type, __wrap_iter<_Iter>) _NOEXCEPT_DEBUG; template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY copy(_Ip, _Ip, _Op); template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY copy_backward(_B1, _B1, _B2); template <class _Ip, class _Op> _Op _LIBCPP_INLINE_VISIBILITY move(_Ip, _Ip, _Op); template <class _B1, class _B2> _B2 _LIBCPP_INLINE_VISIBILITY move_backward(_B1, _B1, _B2); +#if _LIBCPP_DEBUG_LEVEL < 2 + template <class _Tp> _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -1218,6 +1241,19 @@ typename enable_if >::type __unwrap_iter(__wrap_iter<_Tp*>); +#else + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_trivially_copy_assignable<_Tp>::value, + __wrap_iter<_Tp*> +>::type +__unwrap_iter(__wrap_iter<_Tp*> __i); + +#endif + template <class _Iter> class __wrap_iter { @@ -1231,7 +1267,7 @@ public: private: iterator_type __i; public: - _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT_DEBUG #if _LIBCPP_STD_VER > 11 : __i{} #endif @@ -1241,7 +1277,7 @@ public: #endif } template <class _Up> _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u, - typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT + typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = 0) _NOEXCEPT_DEBUG : __i(__u.base()) { #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1271,7 +1307,7 @@ public: __get_db()->__erase_i(this); } #endif - _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1279,7 +1315,7 @@ public: #endif return *__i; } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1287,7 +1323,7 @@ public: #endif return (pointer)_VSTD::addressof(*__i); } - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), @@ -1296,9 +1332,9 @@ public: ++__i; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT_DEBUG {__wrap_iter __tmp(*this); ++(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), @@ -1307,11 +1343,11 @@ public: --__i; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT_DEBUG {__wrap_iter __tmp(*this); --(*this); return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT_DEBUG {__wrap_iter __w(*this); __w += __n; return __w;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), @@ -1320,11 +1356,11 @@ public: __i += __n; return *this; } - _LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT_DEBUG {return *this + (-__n);} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT_DEBUG {*this += -__n; return *this;} - _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), @@ -1333,7 +1369,7 @@ public: return __i[__n]; } - _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;} + _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT_DEBUG {return __i;} private: #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1342,7 +1378,7 @@ private: __get_db()->__insert_ic(this, __p); } #else - _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} + _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {} #endif template <class _Up> friend class __wrap_iter; @@ -1352,56 +1388,57 @@ private: template <class _Iter1, class _Iter2> friend bool - operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator==(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend bool - operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator<(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend bool - operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator!=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend bool - operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator>(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend bool - operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator>=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; template <class _Iter1, class _Iter2> friend bool - operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> friend auto - operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT + operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG -> decltype(__x.base() - __y.base()); #else template <class _Iter1, class _Iter2> friend typename __wrap_iter<_Iter1>::difference_type - operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; + operator-(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT_DEBUG; #endif template <class _Iter1> friend __wrap_iter<_Iter1> - operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT; + operator+(typename __wrap_iter<_Iter1>::difference_type, __wrap_iter<_Iter1>) _NOEXCEPT_DEBUG; template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op); template <class _B1, class _B2> friend _B2 copy_backward(_B1, _B1, _B2); template <class _Ip, class _Op> friend _Op move(_Ip, _Ip, _Op); template <class _B1, class _B2> friend _B2 move_backward(_B1, _B1, _B2); +#if _LIBCPP_DEBUG_LEVEL < 2 template <class _Tp> friend typename enable_if @@ -1410,12 +1447,22 @@ private: _Tp* >::type __unwrap_iter(__wrap_iter<_Tp*>); +#else + template <class _Tp> + inline _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + is_trivially_copy_assignable<_Tp>::value, + __wrap_iter<_Tp*> + >::type + __unwrap_iter(__wrap_iter<_Tp*> __i); +#endif }; template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY bool -operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { return __x.base() == __y.base(); } @@ -1423,7 +1470,7 @@ operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY bool -operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), @@ -1435,7 +1482,7 @@ operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY bool -operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { return !(__x == __y); } @@ -1443,7 +1490,7 @@ operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY bool -operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { return __y < __x; } @@ -1451,7 +1498,7 @@ operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY bool -operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { return !(__x < __y); } @@ -1459,7 +1506,7 @@ operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY bool -operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { return !(__y < __x); } @@ -1467,7 +1514,7 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEX template <class _Iter1> inline _LIBCPP_INLINE_VISIBILITY bool -operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { return !(__x == __y); } @@ -1475,7 +1522,7 @@ operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX template <class _Iter1> inline _LIBCPP_INLINE_VISIBILITY bool -operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { return __y < __x; } @@ -1483,7 +1530,7 @@ operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXC template <class _Iter1> inline _LIBCPP_INLINE_VISIBILITY bool -operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { return !(__x < __y); } @@ -1491,7 +1538,7 @@ operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX template <class _Iter1> inline _LIBCPP_INLINE_VISIBILITY bool -operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT +operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT_DEBUG { return !(__y < __x); } @@ -1500,7 +1547,7 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY auto -operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG -> decltype(__x.base() - __y.base()) { #if _LIBCPP_DEBUG_LEVEL >= 2 @@ -1513,7 +1560,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type -operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT_DEBUG { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), @@ -1527,7 +1574,7 @@ template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type __n, - __wrap_iter<_Iter> __x) _NOEXCEPT + __wrap_iter<_Iter> __x) _NOEXCEPT_DEBUG { __x += __n; return __x; @@ -1535,19 +1582,19 @@ operator+(typename __wrap_iter<_Iter>::difference_type __n, template <class _Iter> struct __libcpp_is_trivial_iterator - : public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {}; - + : public _LIBCPP_BOOL_CONSTANT(is_pointer<_Iter>::value) {}; + template <class _Iter> struct __libcpp_is_trivial_iterator<move_iterator<_Iter> > - : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; + : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; template <class _Iter> struct __libcpp_is_trivial_iterator<reverse_iterator<_Iter> > - : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; + : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; template <class _Iter> struct __libcpp_is_trivial_iterator<__wrap_iter<_Iter> > - : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; + : public _LIBCPP_BOOL_CONSTANT(__libcpp_is_trivial_iterator<_Iter>::value) {}; template <class _Tp, size_t _Np> @@ -1566,7 +1613,7 @@ end(_Tp (&__array)[_Np]) return __array + _Np; } -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) +#if !defined(_LIBCPP_CXX03_LANG) template <class _Cp> inline _LIBCPP_INLINE_VISIBILITY @@ -1689,7 +1736,7 @@ auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) #endif -#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) +#else // defined(_LIBCPP_CXX03_LANG) template <class _Cp> inline _LIBCPP_INLINE_VISIBILITY @@ -1723,20 +1770,20 @@ end(const _Cp& __c) return __c.end(); } -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_TRAILING_RETURN) +#endif // !defined(_LIBCPP_CXX03_LANG) #if _LIBCPP_STD_VER > 14 template <class _Cont> constexpr auto size(const _Cont& __c) -> decltype(__c.size()) { return __c.size(); } template <class _Tp, size_t _Sz> -constexpr size_t size(const _Tp (&__array)[_Sz]) noexcept { return _Sz; } +constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; } template <class _Cont> constexpr auto empty(const _Cont& __c) -> decltype(__c.empty()) { return __c.empty(); } template <class _Tp, size_t _Sz> -constexpr bool empty(const _Tp (&__array)[_Sz]) noexcept { return false; } +constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } template <class _Ep> constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } diff --git a/include/limits b/include/limits index 80a1be40fe47..4e67a7b63d56 100644 --- a/include/limits +++ b/include/limits @@ -182,7 +182,7 @@ protected: static _LIBCPP_CONSTEXPR const float_round_style round_style = round_toward_zero; }; -template <class _Tp, int digits, bool is_signed> +template <class _Tp, int digits, bool _IsSigned> struct __libcpp_compute_min { static _LIBCPP_CONSTEXPR const _Tp value = _Tp(_Tp(1) << digits); @@ -306,7 +306,7 @@ protected: static _LIBCPP_CONSTEXPR const bool is_signed = true; static _LIBCPP_CONSTEXPR const int digits = __FLT_MANT_DIG__; static _LIBCPP_CONSTEXPR const int digits10 = __FLT_DIG__; - static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103)/100000; + static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103l)/100000l; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __FLT_MIN__;} _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __FLT_MAX__;} _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();} @@ -352,7 +352,7 @@ protected: static _LIBCPP_CONSTEXPR const bool is_signed = true; static _LIBCPP_CONSTEXPR const int digits = __DBL_MANT_DIG__; static _LIBCPP_CONSTEXPR const int digits10 = __DBL_DIG__; - static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103)/100000; + static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103l)/100000l; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __DBL_MIN__;} _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __DBL_MAX__;} _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();} @@ -398,7 +398,7 @@ protected: static _LIBCPP_CONSTEXPR const bool is_signed = true; static _LIBCPP_CONSTEXPR const int digits = __LDBL_MANT_DIG__; static _LIBCPP_CONSTEXPR const int digits10 = __LDBL_DIG__; - static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103)/100000; + static _LIBCPP_CONSTEXPR const int max_digits10 = 2+(digits * 30103l)/100000l; _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type min() _NOEXCEPT {return __LDBL_MIN__;} _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT {return __LDBL_MAX__;} _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type lowest() _NOEXCEPT {return -max();} diff --git a/include/limits.h b/include/limits.h new file mode 100644 index 000000000000..1867b1048574 --- /dev/null +++ b/include/limits.h @@ -0,0 +1,65 @@ +// -*- C++ -*- +//===--------------------------- limits.h ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LIMITS_H +#define _LIBCPP_LIMITS_H + +/* + limits.h synopsis + +Macros: + + CHAR_BIT + SCHAR_MIN + SCHAR_MAX + UCHAR_MAX + CHAR_MIN + CHAR_MAX + MB_LEN_MAX + SHRT_MIN + SHRT_MAX + USHRT_MAX + INT_MIN + INT_MAX + UINT_MAX + LONG_MIN + LONG_MAX + ULONG_MAX + LLONG_MIN // C99 + LLONG_MAX // C99 + ULLONG_MAX // C99 + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#ifndef __GNUC__ +#include_next <limits.h> +#else +// GCC header limits.h recursively includes itself through another header called +// syslimits.h for some reason. This setup breaks down if we directly +// #include_next GCC's limits.h (reasons not entirely clear to me). Therefore, +// we manually re-create the necessary include sequence below: + +// Get the system limits.h defines (force recurse into the next level) +#define _GCC_LIMITS_H_ +#define _GCC_NEXT_LIMITS_H +#include_next <limits.h> + +// Get the ISO C defines +#undef _GCC_LIMITS_H_ +#include_next <limits.h> +#endif // __GNUC__ + +#endif // _LIBCPP_LIMITS_H diff --git a/include/list b/include/list index cff0a853eff9..6b96fbfc57e0 100644 --- a/include/list +++ b/include/list @@ -93,10 +93,10 @@ public: size_type max_size() const noexcept; template <class... Args> - void emplace_front(Args&&... args); + reference emplace_front(Args&&... args); void pop_front(); template <class... Args> - void emplace_back(Args&&... args); + reference emplace_back(Args&&... args); void pop_back(); void push_front(const value_type& x); void push_front(value_type&& x); @@ -571,6 +571,10 @@ protected: {return __size_alloc_.second();} _LIBCPP_INLINE_VISIBILITY + size_type __node_alloc_max_size() const _NOEXCEPT { + return __node_alloc_traits::max_size(__node_alloc()); + } + _LIBCPP_INLINE_VISIBILITY static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY @@ -622,9 +626,9 @@ protected: void swap(__list_imp& __c) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; + _NOEXCEPT_DEBUG; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif @@ -651,7 +655,7 @@ private: } _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __list_imp& __c, false_type) + void __copy_assign_alloc(const __list_imp&, false_type) {} _LIBCPP_INLINE_VISIBILITY @@ -662,9 +666,16 @@ private: } _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__list_imp& __c, false_type) + void __move_assign_alloc(__list_imp&, false_type) _NOEXCEPT {} + + _LIBCPP_INLINE_VISIBILITY + void __invalidate_all_iterators() { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__invalidate_all(this); +#endif + } }; // Unlink nodes [__f, __l] @@ -720,21 +731,7 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); __node_alloc_traits::deallocate(__na, __np, 1); } -#if _LIBCPP_DEBUG_LEVEL >= 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); - if (__i->__ptr_ != __l) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif + __invalidate_all_iterators(); } } @@ -742,9 +739,9 @@ template <class _Tp, class _Alloc> void __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT_DEBUG #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -904,7 +901,11 @@ public: bool empty() const _NOEXCEPT {return base::empty();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT - {return numeric_limits<difference_type>::max();} + { + return std::min<size_type>( + base::__node_alloc_max_size(), + numeric_limits<difference_type >::max()); + } _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return base::begin();} @@ -968,9 +969,9 @@ public: void push_back(value_type&& __x); #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args> - void emplace_front(_Args&&... __args); + reference emplace_front(_Args&&... __args); template <class... _Args> - void emplace_back(_Args&&... __args); + reference emplace_back(_Args&&... __args); template <class... _Args> iterator emplace(const_iterator __p, _Args&&... __args); #endif // _LIBCPP_HAS_NO_VARIADICS @@ -994,9 +995,9 @@ public: _LIBCPP_INLINE_VISIBILITY void swap(list& __c) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT_DEBUG #else - _NOEXCEPT_(!__node_alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__node_alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__node_allocator>::value) #endif {base::swap(__c);} @@ -1353,6 +1354,9 @@ list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l, insert(__e, __f, __l); else erase(__i, __e); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__invalidate_all(this); +#endif } template <class _Tp, class _Alloc> @@ -1367,6 +1371,9 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) insert(__e, __n, __x); else erase(__i, __e); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__invalidate_all(this); +#endif } template <class _Tp, class _Alloc> @@ -1593,7 +1600,7 @@ list<_Tp, _Alloc>::push_back(value_type&& __x) template <class _Tp, class _Alloc> template <class... _Args> -void +typename list<_Tp, _Alloc>::reference list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_allocator& __na = base::__node_alloc(); @@ -1602,12 +1609,12 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args) __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); ++base::__sz(); - __hold.release(); + return __hold.release()->__value_; } template <class _Tp, class _Alloc> template <class... _Args> -void +typename list<_Tp, _Alloc>::reference list<_Tp, _Alloc>::emplace_back(_Args&&... __args) { __node_allocator& __na = base::__node_alloc(); @@ -1617,7 +1624,7 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args) __link_pointer __nl = __hold->__as_link(); __link_nodes_at_back(__nl, __nl); ++base::__sz(); - __hold.release(); + return __hold.release()->__value_; } template <class _Tp, class _Alloc> @@ -1751,15 +1758,15 @@ list<_Tp, _Alloc>::erase(const_iterator __p) --base::__sz(); #if _LIBCPP_DEBUG_LEVEL >= 2 __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) + for (__i_node** __ip = __c->end_; __ip != __c->beg_; ) { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); + --__ip; + iterator* __i = static_cast<iterator*>((*__ip)->__i_); if (__i->__ptr_ == __n) { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + (*__ip)->__c_ = nullptr; + if (--__c->end_ != __ip) + memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*)); } } __get_db()->unlock(); @@ -1782,6 +1789,9 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__f) == this, "list::erase(iterator, iterator) called with an iterator not" " referring to this list"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__l) == this, + "list::erase(iterator, iterator) called with an iterator not" + " referring to this list"); #endif if (__f != __l) { @@ -1961,16 +1971,16 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) __libcpp_db* __db = __get_db(); __c_node* __cn1 = __db->__find_c_and_lock(this); __c_node* __cn2 = __db->__find_c(&__c); - for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) { - --__p; - iterator* __i = static_cast<iterator*>((*__p)->__i_); + --__ip; + iterator* __i = static_cast<iterator*>((*__ip)->__i_); if (__i->__ptr_ != __c.__end_as_link()) { - __cn1->__add(*__p); - (*__p)->__c_ = __cn1; - if (--__cn2->end_ != __p) - memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + __cn1->__add(*__ip); + (*__ip)->__c_ = __cn1; + if (--__cn2->end_ != __ip) + memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); } } __db->unlock(); @@ -2004,16 +2014,16 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) __libcpp_db* __db = __get_db(); __c_node* __cn1 = __db->__find_c_and_lock(this); __c_node* __cn2 = __db->__find_c(&__c); - for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) { - --__p; - iterator* __j = static_cast<iterator*>((*__p)->__i_); + --__ip; + iterator* __j = static_cast<iterator*>((*__ip)->__i_); if (__j->__ptr_ == __f) { - __cn1->__add(*__p); - (*__p)->__c_ = __cn1; - if (--__cn2->end_ != __p) - memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + __cn1->__add(*__ip); + (*__ip)->__c_ = __cn1; + if (--__cn2->end_ != __ip) + memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); } } __db->unlock(); @@ -2058,19 +2068,19 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con __libcpp_db* __db = __get_db(); __c_node* __cn1 = __db->__find_c_and_lock(this); __c_node* __cn2 = __db->__find_c(&__c); - for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) + for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) { - --__p; - iterator* __j = static_cast<iterator*>((*__p)->__i_); + --__ip; + iterator* __j = static_cast<iterator*>((*__ip)->__i_); for (__link_pointer __k = __f.__ptr_; __k != __l.__ptr_; __k = __k->__next_) { if (__j->__ptr_ == __k) { - __cn1->__add(*__p); - (*__p)->__c_ = __cn1; - if (--__cn2->end_ != __p) - memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); + __cn1->__add(*__ip); + (*__ip)->__c_ = __cn1; + if (--__cn2->end_ != __ip) + memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); } } } @@ -2083,7 +2093,7 @@ template <class _Tp, class _Alloc> void list<_Tp, _Alloc>::remove(const value_type& __x) { - list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing + list<_Tp, _Alloc> __deleted_nodes(get_allocator()); // collect the nodes we're removing for (const_iterator __i = begin(), __e = end(); __i != __e;) { if (*__i == __x) @@ -2328,14 +2338,14 @@ list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const template <class _Tp, class _Alloc> bool -list<_Tp, _Alloc>::__addable(const const_iterator* __i, ptrdiff_t __n) const +list<_Tp, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const { return false; } template <class _Tp, class _Alloc> bool -list<_Tp, _Alloc>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const +list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const { return false; } diff --git a/include/locale b/include/locale index 3d804e86f4d1..a567085f68f4 100644 --- a/include/locale +++ b/include/locale @@ -523,8 +523,8 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex return 0; } -_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<char>) -_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_get<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>) +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>) template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > class _LIBCPP_TYPE_VIS_ONLY num_get @@ -779,6 +779,7 @@ long double __do_strtod<long double>(const char* __a, char** __p2) { } template <class _Tp> +_LIBCPP_HIDDEN _Tp __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) { @@ -1042,8 +1043,8 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return __b; } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_get<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>) struct _LIBCPP_TYPE_VIS __num_put_base { @@ -1192,8 +1193,8 @@ __num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, __op = __ob + (__np - __nb); } -_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<char>) -_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_TYPE_VIS __num_put<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<char>) +_LIBCPP_EXTERN_TEMPLATE2(struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_put<wchar_t>) template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > class _LIBCPP_TYPE_VIS_ONLY num_put @@ -1621,8 +1622,8 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS num_put<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_put<wchar_t>) template <class _CharT, class _InputIterator> _LIBCPP_HIDDEN @@ -2291,8 +2292,8 @@ time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return __b; } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>) class _LIBCPP_TYPE_VIS __time_get { @@ -2374,8 +2375,8 @@ private: virtual const string_type& __X() const {return this->__X_;} }; -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_get_byname<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>) class _LIBCPP_TYPE_VIS __time_put { @@ -2487,8 +2488,8 @@ time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, return _VSTD::copy(__nb, __ne, __s); } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put<wchar_t>) template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > class _LIBCPP_TYPE_VIS_ONLY time_put_byname @@ -2508,8 +2509,8 @@ protected: ~time_put_byname() {} }; -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS time_put_byname<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>) // money_base @@ -2575,10 +2576,10 @@ template <class _CharT, bool _International> const bool moneypunct<_CharT, _International>::intl; -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, false>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<char, true>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, false>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct<wchar_t, true>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, false>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<char, true>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, false>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct<wchar_t, true>) // moneypunct_byname @@ -2632,10 +2633,10 @@ template<> void moneypunct_byname<char, true>::init(const char*); template<> void moneypunct_byname<wchar_t, false>::init(const char*); template<> void moneypunct_byname<wchar_t, true>::init(const char*); -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, false>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<char, true>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, false>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS moneypunct_byname<wchar_t, true>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>) // money_get @@ -2691,8 +2692,8 @@ __money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, } } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_get<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_get<wchar_t>) template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > class _LIBCPP_TYPE_VIS_ONLY money_get @@ -3074,8 +3075,8 @@ money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, return __b; } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_get<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_get<wchar_t>) // money_put @@ -3249,8 +3250,8 @@ __money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __m __mi = __mb; } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS __money_put<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __money_put<wchar_t>) template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > class _LIBCPP_TYPE_VIS_ONLY money_put @@ -3402,8 +3403,8 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS money_put<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>) // messages @@ -3512,8 +3513,8 @@ messages<_CharT>::do_close(catalog __c) const #endif // _LIBCPP_HAS_CATOPEN } -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages<wchar_t>) template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY messages_byname @@ -3536,8 +3537,8 @@ protected: ~messages_byname() {} }; -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<char>) -_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS messages_byname<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<char>) +_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>) template<class _Codecvt, class _Elem = wchar_t, class _Wide_alloc = allocator<_Elem>, @@ -3701,10 +3702,10 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: if (__r == codecvt_base::ok) return __ws; } -#ifndef _LIBCPP_NO_EXCEPTIONS + if (__wide_err_string_.empty()) - throw range_error("wstring_convert: from_bytes error"); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_range_error("wstring_convert: from_bytes error"); + return __wide_err_string_; } @@ -3790,10 +3791,10 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: return __bs; } } -#ifndef _LIBCPP_NO_EXCEPTIONS + if (__byte_err_string_.empty()) - throw range_error("wstring_convert: to_bytes error"); -#endif // _LIBCPP_NO_EXCEPTIONS + __throw_range_error("wstring_convert: to_bytes error"); + return __byte_err_string_; } @@ -3932,7 +3933,8 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), static_cast<streamsize>(__extbufend_ - __extbufnext_)); codecvt_base::result __r; - state_type __svs = __st_; + // FIXME: Do we ever need to restore the state here? + //state_type __svs = __st_; streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); if (__nr != 0) { diff --git a/include/locale.h b/include/locale.h new file mode 100644 index 000000000000..cad7b8b53eb1 --- /dev/null +++ b/include/locale.h @@ -0,0 +1,45 @@ +// -*- C++ -*- +//===---------------------------- locale.h --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_LOCALE_H +#define _LIBCPP_LOCALE_H + +/* + locale.h synopsis + +Macros: + + LC_ALL + LC_COLLATE + LC_CTYPE + LC_MONETARY + LC_NUMERIC + LC_TIME + +Types: + + lconv + +Functions: + + setlocale + localeconv + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next <locale.h> + +#endif // _LIBCPP_LOCALE_H diff --git a/include/math.h b/include/math.h index 20205544d51d..fb0b6083010b 100644 --- a/include/math.h +++ b/include/math.h @@ -308,10 +308,6 @@ extern "C++" { #include <type_traits> -#ifdef _LIBCPP_MSVCRT -#include "support/win32/math_win32.h" -#endif - // signbit #ifdef signbit @@ -636,11 +632,9 @@ isunordered(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT #endif // isunordered -#ifndef __sun__ - // abs -#if !defined(_AIX) +#if !(defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);} @@ -652,11 +646,11 @@ 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) +#endif // !(defined(_AIX) || defined(__sun__)) // acos -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float acos(float __lcpp_x) _NOEXCEPT {return acosf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double acos(long double __lcpp_x) _NOEXCEPT {return acosl(__lcpp_x);} #endif @@ -668,7 +662,7 @@ acos(_A1 __lcpp_x) _NOEXCEPT {return acos((double)__lcpp_x);} // asin -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float asin(float __lcpp_x) _NOEXCEPT {return asinf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double asin(long double __lcpp_x) _NOEXCEPT {return asinl(__lcpp_x);} #endif @@ -680,7 +674,7 @@ asin(_A1 __lcpp_x) _NOEXCEPT {return asin((double)__lcpp_x);} // atan -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float atan(float __lcpp_x) _NOEXCEPT {return atanf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double atan(long double __lcpp_x) _NOEXCEPT {return atanl(__lcpp_x);} #endif @@ -692,7 +686,7 @@ atan(_A1 __lcpp_x) _NOEXCEPT {return atan((double)__lcpp_x);} // atan2 -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float atan2(float __lcpp_y, float __lcpp_x) _NOEXCEPT {return atan2f(__lcpp_y, __lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long double __lcpp_x) _NOEXCEPT {return atan2l(__lcpp_y, __lcpp_x);} #endif @@ -715,7 +709,7 @@ atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT // ceil -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float ceil(float __lcpp_x) _NOEXCEPT {return ceilf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double ceil(long double __lcpp_x) _NOEXCEPT {return ceill(__lcpp_x);} #endif @@ -727,7 +721,7 @@ ceil(_A1 __lcpp_x) _NOEXCEPT {return ceil((double)__lcpp_x);} // cos -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float cos(float __lcpp_x) _NOEXCEPT {return cosf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double cos(long double __lcpp_x) _NOEXCEPT {return cosl(__lcpp_x);} #endif @@ -739,7 +733,7 @@ cos(_A1 __lcpp_x) _NOEXCEPT {return cos((double)__lcpp_x);} // cosh -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float cosh(float __lcpp_x) _NOEXCEPT {return coshf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double cosh(long double __lcpp_x) _NOEXCEPT {return coshl(__lcpp_x);} #endif @@ -751,7 +745,7 @@ cosh(_A1 __lcpp_x) _NOEXCEPT {return cosh((double)__lcpp_x);} // exp -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float exp(float __lcpp_x) _NOEXCEPT {return expf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double exp(long double __lcpp_x) _NOEXCEPT {return expl(__lcpp_x);} #endif @@ -763,7 +757,7 @@ exp(_A1 __lcpp_x) _NOEXCEPT {return exp((double)__lcpp_x);} // fabs -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float fabs(float __lcpp_x) _NOEXCEPT {return fabsf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double fabs(long double __lcpp_x) _NOEXCEPT {return fabsl(__lcpp_x);} #endif @@ -775,7 +769,7 @@ fabs(_A1 __lcpp_x) _NOEXCEPT {return fabs((double)__lcpp_x);} // floor -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float floor(float __lcpp_x) _NOEXCEPT {return floorf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double floor(long double __lcpp_x) _NOEXCEPT {return floorl(__lcpp_x);} #endif @@ -787,7 +781,7 @@ floor(_A1 __lcpp_x) _NOEXCEPT {return floor((double)__lcpp_x);} // fmod -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float fmod(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return fmodf(__lcpp_x, __lcpp_y);} inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return fmodl(__lcpp_x, __lcpp_y);} #endif @@ -810,7 +804,7 @@ fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT // frexp -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float frexp(float __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpf(__lcpp_x, __lcpp_e);} inline _LIBCPP_INLINE_VISIBILITY long double frexp(long double __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexpl(__lcpp_x, __lcpp_e);} #endif @@ -822,7 +816,7 @@ frexp(_A1 __lcpp_x, int* __lcpp_e) _NOEXCEPT {return frexp((double)__lcpp_x, __l // ldexp -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float ldexp(float __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpf(__lcpp_x, __lcpp_e);} inline _LIBCPP_INLINE_VISIBILITY long double ldexp(long double __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexpl(__lcpp_x, __lcpp_e);} #endif @@ -834,7 +828,7 @@ ldexp(_A1 __lcpp_x, int __lcpp_e) _NOEXCEPT {return ldexp((double)__lcpp_x, __lc // log -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float log(float __lcpp_x) _NOEXCEPT {return logf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double log(long double __lcpp_x) _NOEXCEPT {return logl(__lcpp_x);} #endif @@ -846,7 +840,7 @@ log(_A1 __lcpp_x) _NOEXCEPT {return log((double)__lcpp_x);} // log10 -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float log10(float __lcpp_x) _NOEXCEPT {return log10f(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double log10(long double __lcpp_x) _NOEXCEPT {return log10l(__lcpp_x);} #endif @@ -858,14 +852,14 @@ log10(_A1 __lcpp_x) _NOEXCEPT {return log10((double)__lcpp_x);} // modf -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float modf(float __lcpp_x, float* __lcpp_y) _NOEXCEPT {return modff(__lcpp_x, __lcpp_y);} inline _LIBCPP_INLINE_VISIBILITY long double modf(long double __lcpp_x, long double* __lcpp_y) _NOEXCEPT {return modfl(__lcpp_x, __lcpp_y);} #endif // pow -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float pow(float __lcpp_x, float __lcpp_y) _NOEXCEPT {return powf(__lcpp_x, __lcpp_y);} inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long double __lcpp_y) _NOEXCEPT {return powl(__lcpp_x, __lcpp_y);} #endif @@ -888,7 +882,7 @@ pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT // sin -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float sin(float __lcpp_x) _NOEXCEPT {return sinf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double sin(long double __lcpp_x) _NOEXCEPT {return sinl(__lcpp_x);} #endif @@ -900,7 +894,7 @@ sin(_A1 __lcpp_x) _NOEXCEPT {return sin((double)__lcpp_x);} // sinh -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float sinh(float __lcpp_x) _NOEXCEPT {return sinhf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double sinh(long double __lcpp_x) _NOEXCEPT {return sinhl(__lcpp_x);} #endif @@ -912,21 +906,19 @@ sinh(_A1 __lcpp_x) _NOEXCEPT {return sinh((double)__lcpp_x);} // sqrt -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float sqrt(float __lcpp_x) _NOEXCEPT {return sqrtf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double sqrt(long double __lcpp_x) _NOEXCEPT {return sqrtl(__lcpp_x);} #endif -#endif // __sun__ template <class _A1> inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if<std::is_integral<_A1>::value, double>::type sqrt(_A1 __lcpp_x) _NOEXCEPT {return sqrt((double)__lcpp_x);} -#ifndef __sun__ // tan -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float tan(float __lcpp_x) _NOEXCEPT {return tanf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double tan(long double __lcpp_x) _NOEXCEPT {return tanl(__lcpp_x);} #endif @@ -938,7 +930,7 @@ tan(_A1 __lcpp_x) _NOEXCEPT {return tan((double)__lcpp_x);} // tanh -#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX)) +#if !(defined(_LIBCPP_MSVCRT) || defined(_AIX) || defined(__sun__)) inline _LIBCPP_INLINE_VISIBILITY float tanh(float __lcpp_x) _NOEXCEPT {return tanhf(__lcpp_x);} inline _LIBCPP_INLINE_VISIBILITY long double tanh(long double __lcpp_x) _NOEXCEPT {return tanhl(__lcpp_x);} #endif @@ -1410,7 +1402,6 @@ typename std::enable_if<std::is_integral<_A1>::value, double>::type trunc(_A1 __lcpp_x) _NOEXCEPT {return trunc((double)__lcpp_x);} #endif // !_LIBCPP_MSVCRT -#endif // __sun__ } // extern "C++" diff --git a/include/memory b/include/memory index 7a3281e17931..b4c2b35c0b73 100644 --- a/include/memory +++ b/include/memory @@ -164,6 +164,7 @@ template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept template <class T> void return_temporary_buffer(T* p) noexcept; template <class T> T* addressof(T& r) noexcept; +template <class T> T* addressof(const T&& r) noexcept = delete; template <class InputIterator, class ForwardIterator> ForwardIterator @@ -180,6 +181,33 @@ template <class ForwardIterator, class Size, class T> ForwardIterator uninitialized_fill_n(ForwardIterator first, Size n, const T& x); +template <class T> +void destroy_at(T* location); + +template <class ForwardIterator> + void destroy(ForwardIterator first, ForwardIterator last); + +template <class ForwardIterator, class Size> + ForwardIterator destroy_n(ForwardIterator first, Size n); + +template <class InputIterator, class ForwardIterator> + ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result); + +template <class InputIterator, class Size, class ForwardIterator> + pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result); + +template <class ForwardIterator> + void uninitialized_value_construct(ForwardIterator first, ForwardIterator last); + +template <class ForwardIterator, class Size> + ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n); + +template <class ForwardIterator> + void uninitialized_default_construct(ForwardIterator first, ForwardIterator last); + +template <class ForwardIterator, class Size> + ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n); + template <class Y> struct auto_ptr_ref {}; template<class X> @@ -610,9 +638,6 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include <tuple> #include <stdexcept> #include <cstring> -#if defined(_LIBCPP_NO_EXCEPTIONS) - #include <cassert> -#endif #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) # include <atomic> @@ -639,7 +664,19 @@ _ValueType __libcpp_relaxed_load(_ValueType const* __value) { #endif } -// addressof moved to <__functional_base> +template <class _ValueType> +inline _LIBCPP_ALWAYS_INLINE +_ValueType __libcpp_acquire_load(_ValueType const* __value) { +#if !defined(_LIBCPP_HAS_NO_THREADS) && \ + defined(__ATOMIC_ACQUIRE) && \ + (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407) + return __atomic_load_n(__value, __ATOMIC_ACQUIRE); +#else + return *__value; +#endif +} + +// addressof moved to <type_traits> template <class _Tp> class allocator; @@ -792,7 +829,7 @@ public: template <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value> struct __pointer_traits_rebind { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Tp::template rebind<_Up> type; #else typedef typename _Tp::template rebind<_Up>::other type; @@ -804,7 +841,7 @@ struct __pointer_traits_rebind template <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up> struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Sp<_Tp, _Args...>::template rebind<_Up> type; #else typedef typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type; @@ -822,7 +859,7 @@ struct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false> template <template <class> class _Sp, class _Tp, class _Up> struct __pointer_traits_rebind<_Sp<_Tp>, _Up, true> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Sp<_Tp>::template rebind<_Up> type; #else typedef typename _Sp<_Tp>::template rebind<_Up>::other type; @@ -838,7 +875,7 @@ struct __pointer_traits_rebind<_Sp<_Tp>, _Up, false> template <template <class, class> class _Sp, class _Tp, class _A0, class _Up> struct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, true> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Sp<_Tp, _A0>::template rebind<_Up> type; #else typedef typename _Sp<_Tp, _A0>::template rebind<_Up>::other type; @@ -855,7 +892,7 @@ template <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1, class _Up> struct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, true> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up> type; #else typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up>::other type; @@ -873,7 +910,7 @@ template <template <class, class, class, class> class _Sp, class _Tp, class _A0, class _A1, class _A2, class _Up> struct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, true> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up> type; #else typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type; @@ -896,12 +933,12 @@ struct _LIBCPP_TYPE_VIS_ONLY pointer_traits typedef typename __pointer_traits_element_type<pointer>::type element_type; typedef typename __pointer_traits_difference_type<pointer>::type difference_type; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type; #else template <class _Up> struct rebind {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;}; -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif // _LIBCPP_CXX03_LANG private: struct __nat {}; @@ -919,7 +956,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pointer_traits<_Tp*> typedef _Tp element_type; typedef ptrdiff_t difference_type; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _Up> using rebind = _Up*; #else template <class _Up> struct rebind {typedef _Up* other;}; @@ -936,7 +973,7 @@ public: template <class _From, class _To> struct __rebind_pointer { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename pointer_traits<_From>::template rebind<_To> type; #else typedef typename pointer_traits<_From>::template rebind<_To>::other type; @@ -1000,7 +1037,7 @@ struct __const_pointer template <class _Tp, class _Ptr, class _Alloc> struct __const_pointer<_Tp, _Ptr, _Alloc, false> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename pointer_traits<_Ptr>::template rebind<const _Tp> type; #else typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type; @@ -1027,7 +1064,7 @@ struct __void_pointer template <class _Ptr, class _Alloc> struct __void_pointer<_Ptr, _Alloc, false> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename pointer_traits<_Ptr>::template rebind<void> type; #else typedef typename pointer_traits<_Ptr>::template rebind<void>::other type; @@ -1054,7 +1091,7 @@ struct __const_void_pointer template <class _Ptr, class _Alloc> struct __const_void_pointer<_Ptr, _Alloc, false> { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename pointer_traits<_Ptr>::template rebind<const void> type; #else typedef typename pointer_traits<_Ptr>::template rebind<const void>::other type; @@ -1285,7 +1322,7 @@ struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false> #endif // _LIBCPP_HAS_NO_VARIADICS -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE +#ifndef _LIBCPP_CXX03_LANG template <class _Alloc, class _SizeType, class _ConstVoidPtr> auto @@ -1308,7 +1345,7 @@ struct __has_allocate_hint { }; -#else // _LIBCPP_HAS_NO_ADVANCED_SFINAE +#else // _LIBCPP_CXX03_LANG template <class _Alloc, class _SizeType, class _ConstVoidPtr> struct __has_allocate_hint @@ -1316,9 +1353,9 @@ struct __has_allocate_hint { }; -#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE +#endif // _LIBCPP_CXX03_LANG -#if !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) && !defined(_LIBCPP_HAS_NO_VARIADICS) +#if !defined(_LIBCPP_CXX03_LANG) template <class _Alloc, class _Tp, class ..._Args> decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(), @@ -1399,7 +1436,7 @@ struct __has_select_on_container_copy_construction { }; -#else // _LIBCPP_HAS_NO_ADVANCED_SFINAE +#else // _LIBCPP_CXX03_LANG #ifndef _LIBCPP_HAS_NO_VARIADICS @@ -1437,7 +1474,7 @@ struct __has_select_on_container_copy_construction { }; -#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE +#endif // _LIBCPP_CXX03_LANG template <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value> struct __alloc_traits_difference_type @@ -1474,16 +1511,16 @@ struct _LIBCPP_TYPE_VIS_ONLY allocator_traits typedef typename __is_always_equal<allocator_type>::type is_always_equal; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp> using rebind_alloc = typename __allocator_traits_rebind<allocator_type, _Tp>::type; template <class _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp>>; -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#else // _LIBCPP_CXX03_LANG template <class _Tp> struct rebind_alloc {typedef typename __allocator_traits_rebind<allocator_type, _Tp>::type other;}; template <class _Tp> struct rebind_traits {typedef allocator_traits<typename rebind_alloc<_Tp>::other> other;}; -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY static pointer allocate(allocator_type& __a, size_type __n) @@ -1568,7 +1605,7 @@ struct _LIBCPP_TYPE_VIS_ONLY allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) @@ -1598,7 +1635,7 @@ struct _LIBCPP_TYPE_VIS_ONLY allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_range_forward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) + __construct_range_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) { typedef typename remove_const<_Tp>::type _Vp; ptrdiff_t _Np = __end1 - __begin1; @@ -1632,7 +1669,7 @@ struct _LIBCPP_TYPE_VIS_ONLY allocator_traits is_trivially_move_constructible<_Tp>::value, void >::type - __construct_backward(allocator_type& __a, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) + __construct_backward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) { ptrdiff_t _Np = __end1 - __begin1; __end2 -= _Np; @@ -1695,7 +1732,7 @@ private: template <class _Traits, class _Tp> struct __rebind_alloc_helper { -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG typedef typename _Traits::template rebind_alloc<_Tp> type; #else typedef typename _Traits::template rebind_alloc<_Tp>::other type; @@ -1730,8 +1767,8 @@ public: _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) { if (__n > max_size()) - __libcpp_throw(length_error("allocator<T>::allocate(size_t n)" - " 'n' exceeds maximum supported size")); + __throw_length_error("allocator<T>::allocate(size_t n)" + " 'n' exceeds maximum supported size"); return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT @@ -1826,8 +1863,8 @@ public: _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) { if (__n > max_size()) - __libcpp_throw(length_error("allocator<const T>::allocate(size_t n)" - " 'n' exceeds maximum supported size")); + __throw_length_error("allocator<const T>::allocate(size_t n)" + " 'n' exceeds maximum supported size"); return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); } _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT @@ -2068,49 +2105,11 @@ public: _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) : __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {} -#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value && - is_nothrow_copy_constructible<_T2>::value) - : __first_(__p.first()), - __second_(__p.second()) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value && - is_nothrow_copy_assignable<_T2>::value) - { - __first_ = __p.first(); - __second_ = __p.second(); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value && - is_nothrow_move_constructible<_T2>::value) - : __first_(_VSTD::forward<_T1>(__p.first())), - __second_(_VSTD::forward<_T2>(__p.second())) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value && - is_nothrow_move_assignable<_T2>::value) - { - __first_ = _VSTD::forward<_T1>(__p.first()); - __second_ = _VSTD::forward<_T2>(__p.second()); - return *this; - } - -#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(piecewise_construct_t __pc, + __libcpp_compressed_pair_imp(piecewise_construct_t, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args, __tuple_indices<_I1...>, @@ -2161,47 +2160,11 @@ public: _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) : _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {} -#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value && - is_nothrow_copy_constructible<_T2>::value) - : _T1(__p.first()), __second_(__p.second()) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value && - is_nothrow_copy_assignable<_T2>::value) - { - _T1::operator=(__p.first()); - __second_ = __p.second(); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value && - is_nothrow_move_constructible<_T2>::value) - : _T1(_VSTD::move(__p.first())), __second_(_VSTD::forward<_T2>(__p.second())) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value && - is_nothrow_move_assignable<_T2>::value) - { - _T1::operator=(_VSTD::move(__p.first())); - __second_ = _VSTD::forward<_T2>(__p.second()); - return *this; - } - -#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(piecewise_construct_t __pc, + __libcpp_compressed_pair_imp(piecewise_construct_t, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args, __tuple_indices<_I1...>, @@ -2253,47 +2216,11 @@ public: is_nothrow_move_constructible<_T2>::value) : _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {} -#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value && - is_nothrow_copy_constructible<_T2>::value) - : _T2(__p.second()), __first_(__p.first()) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value && - is_nothrow_copy_assignable<_T2>::value) - { - _T2::operator=(__p.second()); - __first_ = __p.first(); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value && - is_nothrow_move_constructible<_T2>::value) - : _T2(_VSTD::forward<_T2>(__p.second())), __first_(_VSTD::move(__p.first())) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value && - is_nothrow_move_assignable<_T2>::value) - { - _T2::operator=(_VSTD::forward<_T2>(__p.second())); - __first_ = _VSTD::move(__p.first()); - return *this; - } - -#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(piecewise_construct_t __pc, + __libcpp_compressed_pair_imp(piecewise_construct_t, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args, __tuple_indices<_I1...>, @@ -2343,47 +2270,11 @@ public: _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) : _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {} -#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value && - is_nothrow_copy_constructible<_T2>::value) - : _T1(__p.first()), _T2(__p.second()) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(const __libcpp_compressed_pair_imp& __p) - _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value && - is_nothrow_copy_assignable<_T2>::value) - { - _T1::operator=(__p.first()); - _T2::operator=(__p.second()); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value && - is_nothrow_move_constructible<_T2>::value) - : _T1(_VSTD::move(__p.first())), _T2(_VSTD::move(__p.second())) {} - - _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp& operator=(__libcpp_compressed_pair_imp&& __p) - _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value && - is_nothrow_move_assignable<_T2>::value) - { - _T1::operator=(_VSTD::move(__p.first())); - _T2::operator=(_VSTD::move(__p.second())); - return *this; - } - -#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> _LIBCPP_INLINE_VISIBILITY - __libcpp_compressed_pair_imp(piecewise_construct_t __pc, + __libcpp_compressed_pair_imp(piecewise_construct_t, tuple<_Args1...> __first_args, tuple<_Args2...> __second_args, __tuple_indices<_I1...>, @@ -2430,40 +2321,6 @@ public: _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2) : base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {} -#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - - _LIBCPP_INLINE_VISIBILITY - __compressed_pair(const __compressed_pair& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<_T1>::value && - is_nothrow_copy_constructible<_T2>::value) - : base(__p) {} - - _LIBCPP_INLINE_VISIBILITY - __compressed_pair& operator=(const __compressed_pair& __p) - _NOEXCEPT_(is_nothrow_copy_assignable<_T1>::value && - is_nothrow_copy_assignable<_T2>::value) - { - base::operator=(__p); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __compressed_pair(__compressed_pair&& __p) - _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value && - is_nothrow_move_constructible<_T2>::value) - : base(_VSTD::move(__p)) {} - - _LIBCPP_INLINE_VISIBILITY - __compressed_pair& operator=(__compressed_pair&& __p) - _NOEXCEPT_(is_nothrow_move_assignable<_T1>::value && - is_nothrow_move_assignable<_T2>::value) - { - base::operator=(_VSTD::move(__p)); - return *this; - } - -#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args1, class... _Args2> @@ -2526,7 +2383,7 @@ struct __same_or_less_cv_qualified<_Ptr1, _Ptr2, false> template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY default_delete { -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default; #else _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {} @@ -2546,7 +2403,7 @@ template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY default_delete<_Tp[]> { public: -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT = default; #else _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete() _NOEXCEPT {} @@ -3488,6 +3345,17 @@ struct __scalar_hash<_Tp, 4> } }; +_LIBCPP_INLINE_VISIBILITY +inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { + struct _PairT { + size_t first; + size_t second; + }; + typedef __scalar_hash<_PairT> _HashT; + const _PairT __p = {__lhs, __rhs}; + return _HashT()(__p); +} + template<class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash<_Tp*> : public unary_function<_Tp*, size_t> @@ -3671,6 +3539,148 @@ uninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x) return __f; } +#if _LIBCPP_STD_VER > 14 + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +void destroy_at(_Tp* __loc) { + _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at"); + __loc->~_Tp(); +} + +template <class _ForwardIterator> +inline _LIBCPP_INLINE_VISIBILITY +void destroy(_ForwardIterator __first, _ForwardIterator __last) { + for (; __first != __last; ++__first) + _VSTD::destroy_at(_VSTD::addressof(*__first)); +} + +template <class _ForwardIterator, class _Size> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) { + for (; __n > 0; (void)++__first, --__n) + _VSTD::destroy_at(_VSTD::addressof(*__first)); + return __first; +} + +template <class _ForwardIterator> +inline _LIBCPP_INLINE_VISIBILITY +void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + auto __idx = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __idx != __last; ++__idx) + ::new((void*)_VSTD::addressof(*__idx)) _Vt; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); + throw; + } +#endif +} + +template <class _ForwardIterator, class _Size> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + auto __idx = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __n > 0; (void)++__idx, --__n) + ::new((void*)_VSTD::addressof(*__idx)) _Vt; + return __idx; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); + throw; + } +#endif +} + + +template <class _ForwardIterator> +inline _LIBCPP_INLINE_VISIBILITY +void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + auto __idx = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __idx != __last; ++__idx) + ::new((void*)_VSTD::addressof(*__idx)) _Vt(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); + throw; + } +#endif +} + +template <class _ForwardIterator, class _Size> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { + using _Vt = typename iterator_traits<_ForwardIterator>::value_type; + auto __idx = __first; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __n > 0; (void)++__idx, --__n) + ::new((void*)_VSTD::addressof(*__idx)) _Vt(); + return __idx; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first, __idx); + throw; + } +#endif +} + + +template <class _InputIt, class _ForwardIt> +inline _LIBCPP_INLINE_VISIBILITY +_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) { + using _Vt = typename iterator_traits<_ForwardIt>::value_type; + auto __idx = __first_res; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __first != __last; (void)++__idx, ++__first) + ::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first)); + return __idx; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first_res, __idx); + throw; + } +#endif +} + +template <class _InputIt, class _Size, class _ForwardIt> +inline _LIBCPP_INLINE_VISIBILITY +pair<_InputIt, _ForwardIt> +uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) { + using _Vt = typename iterator_traits<_ForwardIt>::value_type; + auto __idx = __first_res; +#ifndef _LIBCPP_NO_EXCEPTIONS + try { +#endif + for (; __n > 0; ++__idx, (void)++__first, --__n) + ::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first)); + return {__first, __idx}; +#ifndef _LIBCPP_NO_EXCEPTIONS + } catch (...) { + _VSTD::destroy(__first_res, __idx); + throw; + } +#endif +} + + +#endif // _LIBCPP_STD_VER > 14 + class _LIBCPP_EXCEPTION_ABI bad_weak_ptr : public std::exception { @@ -3679,6 +3689,16 @@ public: virtual const char* what() const _NOEXCEPT; }; +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_bad_weak_ptr() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_weak_ptr(); +#else + _VSTD::abort(); +#endif +} + template<class _Tp> class _LIBCPP_TYPE_VIS_ONLY weak_ptr; class _LIBCPP_TYPE_VIS __shared_count @@ -5335,11 +5355,7 @@ shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r, __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_) { if (__cntrl_ == 0) -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_weak_ptr(); -#else - assert(!"bad_weak_ptr"); -#endif + __throw_bad_weak_ptr(); } template<class _Tp> diff --git a/include/module.modulemap b/include/module.modulemap index 3fb7428411df..95610bfb735e 100644 --- a/include/module.modulemap +++ b/include/module.modulemap @@ -1,13 +1,224 @@ +// define the module for __config outside of the top level 'std' module +// since __config may be included from C headers which may create an +// include cycle. +module std_config [system] [extern_c] { + header "__config" +} + module std [system] { + export std_config // FIXME: The standard does not require that each of these submodules // re-exports its imported modules. We should provide an alternative form of // export that issues a warning if a name from the submodule is used, and // use that to provide a 'strict mode' for libc++. + + // Deprecated C-compatibility headers. These can all be included from within + // an 'extern "C"' context. + module depr [extern_c] { + // <assert.h> provided by C library. + module ctype_h { + header "ctype.h" + export * + } + module errno_h { + header "errno.h" + export * + } + // <fenv.h> provided by C library. + // <float.h> provided by compiler or C library. + module inttypes_h { + header "inttypes.h" + export stdint_h + export * + } + // <iso646.h> provided by compiler. + // <limits.h> provided by compiler or C library. + module locale_h { + header "locale.h" + export * + } + module math_h { + header "math.h" + export * + } + module setjmp_h { + header "setjmp.h" + export * + } + // FIXME: <stdalign.h> is missing. + // <signal.h> provided by C library. + // <stdarg.h> provided by compiler. + // <stdbool.h> provided by compiler. + module stddef_h { + // <stddef.h>'s __need_* macros require textual inclusion. + textual header "stddef.h" + } + module stdint_h { + header "stdint.h" + export * + // FIXME: This module only exists on OS X and for some reason the + // wildcard above doesn't export it. + export Darwin.C.stdint + } + module stdio_h { + // <stdio.h>'s __need_* macros require textual inclusion. + textual header "stdio.h" + export * + export Darwin.C.stdio + } + module stdlib_h { + // <stdlib.h>'s __need_* macros require textual inclusion. + textual header "stdlib.h" + export * + } + module string_h { + header "string.h" + export * + } + // FIXME: <uchar.h> is missing. + // <time.h> provided by C library. + module wchar_h { + // <wchar.h>'s __need_* macros require textual inclusion. + textual header "wchar.h" + export * + } + module wctype_h { + header "wctype.h" + export * + } + } + + // <complex.h> and <tgmath.h> are not C headers in any real sense, do not + // allow their use in extern "C" contexts. + module complex_h { + header "complex.h" + export ccomplex + export * + } + module tgmath_h { + header "tgmath.h" + export ccomplex + export cmath + export * + } + + // C compatibility headers. + module compat { + module cassert { + // <cassert>'s use of NDEBUG requires textual inclusion. + textual header "cassert" + } + module ccomplex { + header "ccomplex" + export complex + export * + } + module cctype { + header "cctype" + export * + } + module cerrno { + header "cerrno" + export * + } + module cfenv { + header "cfenv" + export * + } + module cfloat { + header "cfloat" + export * + } + module cinttypes { + header "cinttypes" + export cstdint + export * + } + module ciso646 { + header "ciso646" + export * + } + module climits { + header "climits" + export * + } + module clocale { + header "clocale" + export * + } + module cmath { + header "cmath" + export * + } + module csetjmp { + header "csetjmp" + export * + } + module csignal { + header "csignal" + export * + } + // FIXME: <cstdalign> is missing. + module cstdarg { + header "cstdarg" + export * + } + module cstdbool { + header "cstdbool" + export * + } + module cstddef { + header "cstddef" + export * + } + module cstdint { + header "cstdint" + export depr.stdint_h + export * + } + module cstdio { + header "cstdio" + export * + } + module cstdlib { + header "cstdlib" + export * + } + module cstring { + header "cstring" + export * + } + module ctgmath { + header "ctgmath" + export ccomplex + export cmath + export * + } + module ctime { + header "ctime" + export * + } + // FIXME: <cuchar> is missing. + module cwchar { + header "cwchar" + export depr.stdio_h + export * + } + module cwctype { + header "cwctype" + export * + } + } + module algorithm { header "algorithm" export initializer_list export * } + module any { + header "any" + export * + } module array { header "array" export initializer_list @@ -16,7 +227,6 @@ module std [system] { module atomic { header "atomic" export * - requires cplusplus11 } module bitset { header "bitset" @@ -25,118 +235,10 @@ module std [system] { export * } // No submodule for cassert. It fundamentally needs repeated, textual inclusion. - module ccomplex { - header "ccomplex" - export complex - export * - } - module cctype { - header "cctype" - export * - } - module cerrno { - header "cerrno" -/* - export_macros ECONNREFUSED, EIO, ENODEV, ENOTEMPTY, ERANGE, - E2BIG, ECONNRESET, EISCONN, ENOENT, ENOTRECOVERABLE, EROFS, - EACCES, EDEADLK, EISDIR, ENOEXEC, ENOTSOCK, ESPIPE, - EADDRINUSE, EDESTADDRREQ, ELOOP, ENOLCK, ENOTSUP, ESRCH, - EADDRNOTAVAIL, EDOM, EMFILE, ENOLINK, ENOTTY, ETIME, - EAFNOSUPPORT, EEXIST, EMLINK, ENOMEM, ENXIO, ETIMEDOUT, - EAGAIN, EFAULT, EMSGSIZE, ENOMSG, EOPNOTSUPP, ETXTBSY, - EALREADY, EFBIG, ENAMETOOLONG, ENOPROTOOPT, EOVERFLOW, EWOULDBLOCK, - EBADF, EHOSTUNREACH, ENETDOWN, ENOSPC, EOWNERDEAD, EXDEV, - EBADMSG, EIDRM, ENETRESET, ENOSR, EPERM, errno, - EBUSY, EILSEQ, ENETUNREACH, ENOSTR, EPIPE, - ECANCELED, EINPROGRESS, ENFILE, ENOSYS, EPROTO, - ECHILD, EINTR, ENOBUFS, ENOTCONN, EPROTONOSUPPORT, - ECONNABORTED, EINVAL, ENODATA, ENOTDIR, EPROTOTYPE -*/ - export * - } - module cfenv { - header "cfenv" -/* - export_macros FE_ALL_EXCEPT, FE_DIVBYZERO, FE_INEXACT, FE_INVALID, FE_OVERFLOW, - FE_UNDERFLOW, FE_DOWNWARD, FE_TONEAREST, FE_TOWARDZERO, FE_UPWARD, - FE_DFL_ENV -*/ - export * - } - module cfloat { - header "cfloat" -/* - export_macros FLT_EVAL_METHOD, FLT_RADIX, FLT_ROUNDS, - FLT_DIG, FLT_EPSILON, FLT_MANT_DIG, - FLT_MAX, FLT_MAX_10_EXP, FLT_MAX_EXP, - FLT_MIN, FLT_MIN_10_EXP, FLT_MIN_EXP, - DBL_DIG, DBL_EPSILON, DBL_MANT_DIG, - DBL_MAX, DBL_MAX_10_EXP, DBL_MAX_EXP, - DBL_MIN, DBL_MIN_10_EXP, DBL_MIN_EXP, - LDBL_DIG, LDBL_EPSILON, LDBL_MANT_DIG, - LDBL_MAX, LDBL_MAX_10_EXP, LDBL_MAX_EXP, - LDBL_MIN, LDBL_MIN_10_EXP, LDBL_MIN_EXP -*/ - export * - } module chrono { header "chrono" export * } - module cinttypes { - header "cinttypes" - export cstdint -/* - export_macros - PRId8, PRId16, PRId32, PRId64, PRIdFAST8, PRIdFAST16, PRIdFAST32, PRIdFAST64, PRIdLEAST8, PRIdLEAST16, PRIdLEAST32, PRIdLEAST64, PRIdMAX, PRIdPTR, - PRIi8, PRIi16, PRIi32, PRIi64, PRIiFAST8, PRIiFAST16, PRIiFAST32, PRIiFAST64, PRIiLEAST8, PRIiLEAST16, PRIiLEAST32, PRIiLEAST64, PRIiMAX, PRIiPTR, - PRIo8, PRIo16, PRIo32, PRIo64, PRIoFAST8, PRIoFAST16, PRIoFAST32, PRIoFAST64, PRIoLEAST8, PRIoLEAST16, PRIoLEAST32, PRIoLEAST64, PRIoMAX, PRIoPTR, - PRIu8, PRIu16, PRIu32, PRIu64, PRIuFAST8, PRIuFAST16, PRIuFAST32, PRIuFAST64, PRIuLEAST8, PRIuLEAST16, PRIuLEAST32, PRIuLEAST64, PRIuMAX, PRIuPTR, - PRIx8, PRIx16, PRIx32, PRIx64, PRIxFAST8, PRIxFAST16, PRIxFAST32, PRIxFAST64, PRIxLEAST8, PRIxLEAST16, PRIxLEAST32, PRIxLEAST64, PRIxMAX, PRIxPTR, - PRIX8, PRIX16, PRIX32, PRIX64, PRIXFAST8, PRIXFAST16, PRIXFAST32, PRIXFAST64, PRIXLEAST8, PRIXLEAST16, PRIXLEAST32, PRIXLEAST64, PRIXMAX, PRIXPTR, - SCNd8, SCNd16, SCNd32, SCNd64, SCNdFAST8, SCNdFAST16, SCNdFAST32, SCNdFAST64, SCNdLEAST8, SCNdLEAST16, SCNdLEAST32, SCNdLEAST64, SCNdMAX, SCNdPTR, - SCNi8, SCNi16, SCNi32, SCNi64, SCNiFAST8, SCNiFAST16, SCNiFAST32, SCNiFAST64, SCNiLEAST8, SCNiLEAST16, SCNiLEAST32, SCNiLEAST64, SCNiMAX, SCNiPTR, - SCNo8, SCNo16, SCNo32, SCNo64, SCNoFAST8, SCNoFAST16, SCNoFAST32, SCNoFAST64, SCNoLEAST8, SCNoLEAST16, SCNoLEAST32, SCNoLEAST64, SCNoMAX, SCNoPTR, - SCNu8, SCNu16, SCNu32, SCNu64, SCNuFAST8, SCNuFAST16, SCNuFAST32, SCNuFAST64, SCNuLEAST8, SCNuLEAST16, SCNuLEAST32, SCNuLEAST64, SCNuMAX, SCNuPTR, - SCNx8, SCNx16, SCNx32, SCNx64, SCNxFAST8, SCNxFAST16, SCNxFAST32, SCNxFAST64, SCNxLEAST8, SCNxLEAST16, SCNxLEAST32, SCNxLEAST64, SCNxMAX, SCNxPTR, - SCNX8, SCNX16, SCNX32, SCNX64, SCNXFAST8, SCNXFAST16, SCNXFAST32, SCNXFAST64, SCNXLEAST8, SCNXLEAST16, SCNXLEAST32, SCNXLEAST64, SCNXMAX, SCNXPTR -*/ - export * - } - module ciso646 { - header "ciso646" - export * - } - module climits { - header "climits" -/* - export_macros CHAR_BIT, CHAR_MIN, CHAR_MAX, - SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, - SHRT_MIN, SHRT_MAX, USHRT_MAX, - INT_MIN, INT_MAX, UINT_MAX, - LONG_MIN, LONG_MAX, ULONG_MAX, - LLONG_MIN, LLONG_MAX, ULLONG_MAX, - MB_LEN_MAX -*/ - export * - } - module clocale { - header "clocale" -/* - export_macros LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, NULL -*/ - export * - } - module cmath { - header "cmath" -/* - export_macros FP_FAST_FMA, FP_FAST_FMAF, FP_FAST_FMAL, FP_ILOGBO, FP_ILOGBNAN, - FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, - HUGE_VAL, HUGE_VALF, HUGE_VALL, INFINITY, NAN, - MATH_ERRNO, MATH_ERREXCEPT, math_errhandling -*/ - export * - } module codecvt { header "codecvt" export * @@ -149,108 +251,6 @@ module std [system] { header "condition_variable" export * } - module csetjmp { - header "csetjmp" -/* - export_macros setjmp -*/ - export * - } - module csignal { - header "csignal" -/* - export_macros SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, - SIG_DFL, SIG_IGN, SIG_ERR -*/ - export * - } - module cstdarg { - header "cstdarg" -/* - export_macros va_arg, va_start, va_end, va_copy -*/ - export * - } - module cstdbool { - header "cstdbool" -/* - export_macros __bool_true_false_are_defined -*/ - export * - } - module cstddef { - header "cstddef" -/* - export_macros NULL, offsetof -*/ - export * - } - module cstdint { - header "cstdint" -/* - export_macros - INT_8_MIN, INT_8_MAX, UINT_8_MAX, INT_16_MIN, INT_16_MAX, UINT_16_MAX, - INT_32_MIN, INT_32_MAX, UINT_32_MAX, INT_64_MIN, INT_64_MAX, UINT_64_MAX, - INT_FAST8_MIN, INT_FAST8_MAX, UINT_FAST8_MAX, INT_FAST16_MIN, INT_FAST16_MAX, UINT_FAST16_MAX, - INT_FAST32_MIN, INT_FAST32_MAX, UINT_FAST32_MAX, INT_FAST64_MIN, INT_FAST64_MAX, UINT_FAST64_MAX, - INT_LEAST8_MIN, INT_LEAST8_MAX, UINT_LEAST8_MAX, INT_LEAST16_MIN, INT_LEAST16_MAX, UINT_LEAST16_MAX, - INT_LEAST32_MIN, INT_LEAST32_MAX, UINT_LEAST32_MAX, INT_LEAST64_MIN, INT_LEAST64_MAX, UINT_LEAST64_MAX, - INT_MAX_MIN, INT_MAX_MAX, UINT_MAX_MAX, INT_PTR_MIN, INT_PTR_MAX, UINT_PTR_MAX, - PTRDIFF_MIN, PTRDIFF_MAX, SIG_ATOMIC_MIN, SIG_ATOMIC_MAX, WCHAR_MIN, WCHAR_MAX, WINT_MIN, WINT_MAX, - SIZE_MAX -*/ - export * - } - module cstdio { - header "cstdio" -/* - export_macros BUFSIZ, EOF, FILENAME_MAX, FOPEN_MAX, L_tmpnam, NULL, - SEEK_CUR, SEEK_END, SEEK_SET, TMP_MAX, _IOFBF, _IOLBF, - stdin, stdout, stderr -*/ - export * - } - module cstdlib { - header "cstdlib" -/* - export_macros RAND_MAX -*/ - export * - } - module cstring { - header "cstring" -/* - export_macros NULL -*/ - export * - } - module ctgmath { - header "ctgmath" - export ccomplex - export cmath - export * - } - module ctime { - header "ctime" -/* - export_macros NULL, CLOCKS_PER_SEC -*/ - export * - } - module cwchar { - header "cwchar" -/* - export_macros NULL, WCHAR_MAX, WCHAR_MIN, WEOF -*/ - export * - } - module cwctype { - header "cwctype" -/* - export_macros WEOF -*/ - export * - } module deque { header "deque" export initializer_list @@ -345,6 +345,10 @@ module std [system] { header "numeric" export * } + module optional { + header "optional" + export * + } module ostream { header "ostream" // FIXME: should re-export ios, streambuf? @@ -399,11 +403,19 @@ module std [system] { module string { header "string" export initializer_list + export string_view + export __string + export * + } + module string_view { + header "string_view" + export initializer_list + export __string export * } module strstream { header "strstream" - requires !cplusplus11 + export * } module system_error { header "system_error" @@ -449,17 +461,16 @@ module std [system] { export initializer_list export * } + module variant { + header "variant" + export * + } module vector { header "vector" export initializer_list export * } - // FIXME: We don't have modules for the <foo.h> headers, because they might - // be included from the C library's headers, and that would create a #include - // cycle. For the same reason, we don't have a module for __config. - //module __config { header "__config" export * } - // FIXME: These should be private. module __bit_reference { header "__bit_reference" export * } module __debug { header "__debug" export * } @@ -470,8 +481,127 @@ module std [system] { module __split_buffer { header "__split_buffer" export * } module __sso_allocator { header "__sso_allocator" export * } module __std_stream { header "__std_stream" export * } + module __string { header "__string" export * } module __tree { header "__tree" export * } module __tuple { header "__tuple" export * } module __undef_min_max { header "__undef_min_max" export * } module __undef___deallocate { header "__undef___deallocate" export * } + + module experimental { + requires cplusplus11 + + module algorithm { + header "experimental/algorithm" + export * + } + module any { + header "experimental/any" + export * + } + module chrono { + header "experimental/chrono" + export * + } + module deque { + header "experimental/deque" + export * + } + module dynarray { + header "experimental/dynarray" + export * + } + module filesystem { + header "experimental/filesystem" + export * + } + module forward_list { + header "experimental/forward_list" + export * + } + module functional { + header "experimental/functional" + export * + } + module iterator { + header "experimental/iterator" + export * + } + module list { + header "experimental/list" + export * + } + module map { + header "experimental/map" + export * + } + module memory_resource { + header "experimental/memory_resource" + export * + } + module numeric { + header "experimental/numeric" + export * + } + module optional { + header "experimental/optional" + export * + } + module propagate_const { + header "experimental/propagate_const" + export * + } + module ratio { + header "experimental/ratio" + export * + } + module regex { + header "experimental/regex" + export * + } + module set { + header "experimental/set" + export * + } + module string { + header "experimental/string" + export * + } + module string_view { + header "experimental/string_view" + export * + } + module system_error { + header "experimental/system_error" + export * + } + module tuple { + header "experimental/tuple" + export * + } + module type_traits { + header "experimental/type_traits" + export * + } + module unordered_map { + header "experimental/unordered_map" + export * + } + module unordered_set { + header "experimental/unordered_set" + export * + } + module utility { + header "experimental/utility" + export * + } + module vector { + header "experimental/vector" + export * + } + // FIXME these should be private + module __memory { + header "experimental/__memory" + export * + } + } // end experimental } diff --git a/include/mutex b/include/mutex index c047cf943e8c..79befbeb56fe 100644 --- a/include/mutex +++ b/include/mutex @@ -574,7 +574,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) { - if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) + if (__libcpp_acquire_load(&__flag.__state_) != ~0ul) { typedef tuple<_Callable&&, _Args&&...> _Gp; _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); @@ -590,7 +590,7 @@ inline _LIBCPP_INLINE_VISIBILITY void call_once(once_flag& __flag, _Callable& __func) { - if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) + if (__libcpp_acquire_load(&__flag.__state_) != ~0ul) { __call_once_param<_Callable> __p(__func); __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); diff --git a/include/new b/include/new index d2b2ae648b48..6b432f231bf6 100644 --- a/include/new +++ b/include/new @@ -27,18 +27,19 @@ public: virtual const char* what() const noexcept; }; -class bad_array_length : public bad_alloc // C++14 +class bad_array_length : public bad_alloc // FIXME: Not part of C++ { public: bad_array_length() noexcept; }; -class bad_array_new_length : public bad_alloc +class bad_array_new_length : public bad_alloc // C++14 { public: bad_array_new_length() noexcept; }; +enum class align_val_t : size_t {}; // C++17 struct nothrow_t {}; extern const nothrow_t nothrow; typedef void (*new_handler)(); @@ -48,16 +49,34 @@ new_handler get_new_handler() noexcept; } // std void* operator new(std::size_t size); // replaceable +void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17 void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable +void* operator new(std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; // replaceable, C++17 void operator delete(void* ptr) noexcept; // replaceable void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14 +void operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17 +void operator delete(void* ptr, std::size_t size, + std::align_val_t alignment) noexcept; // replaceable, C++17 void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable +void operator delete(void* ptr, std:align_val_t alignment, + const std::nothrow_t&) noexcept; // replaceable, C++17 void* operator new[](std::size_t size); // replaceable +void* operator new[](std::size_t size, + std::align_val_t alignment) noexcept; // replaceable, C++17 void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable +void* operator new[](std::size_t size, std::align_val_t alignment, + const std::nothrow_t&) noexcept; // replaceable, C++17 void operator delete[](void* ptr) noexcept; // replaceable void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14 +void operator delete[](void* ptr, + std::align_val_t alignment) noexcept; // replaceable, C++17 +void operator delete[](void* ptr, std::size_t size, + std::align_val_t alignment) noexcept; // replaceable, C++17 void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable +void operator delete[](void* ptr, std::align_val_t alignment, + const std::nothrow_t&) noexcept; // replaceable, C++17 void* operator new (std::size_t size, void* ptr) noexcept; void* operator new[](std::size_t size, void* ptr) noexcept; @@ -69,6 +88,9 @@ void operator delete[](void* ptr, void*) noexcept; #include <__config> #include <exception> #include <cstddef> +#ifdef _LIBCPP_NO_EXCEPTIONS +#include <cstdlib> +#endif #include <__undef___deallocate> @@ -76,6 +98,16 @@ void operator delete[](void* ptr, void*) noexcept; #pragma GCC system_header #endif +#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \ + (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)) +# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION +#endif + +#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \ + (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606)) +# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#endif + namespace std // purposefully not using versioning namespace { @@ -97,6 +129,8 @@ public: virtual const char* what() const _NOEXCEPT; }; +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec + #if defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11) class _LIBCPP_EXCEPTION_ABI bad_array_length @@ -112,7 +146,13 @@ public: #endif // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11) -_LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec +#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#ifndef _LIBCPP_CXX03_LANG +enum class _LIBCPP_ENUM_VIS align_val_t : size_t { }; +#else +enum align_val_t { __zero = 0, __max = (size_t)-1 }; +#endif +#endif struct _LIBCPP_TYPE_VIS nothrow_t {}; extern _LIBCPP_FUNC_VIS const nothrow_t nothrow; @@ -122,36 +162,44 @@ _LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT; } // std -#if defined(_WIN32) && !defined(cxx_EXPORTS) -# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS_ONLY +#if !__has_feature(cxx_noexcept) +#define _THROW_BAD_ALLOC throw(std::bad_alloc) #else -# define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS +#define _THROW_BAD_ALLOC #endif -_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz) -#if !__has_feature(cxx_noexcept) - throw(std::bad_alloc) +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC; +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; +#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; #endif -; -_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; -_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p) _NOEXCEPT; -_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; -#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \ - (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309) -_LIBCPP_NEW_DELETE_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; + +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC; +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; +#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; #endif -_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz) -#if !__has_feature(cxx_noexcept) - throw(std::bad_alloc) +#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; +#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; +#endif + +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; +_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT; +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; +#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION +_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; #endif -; -_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS; -_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p) _NOEXCEPT; -_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; -#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \ - (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309) -_LIBCPP_NEW_DELETE_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; #endif inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;} @@ -177,6 +225,18 @@ inline _LIBCPP_INLINE_VISIBILITY void __deallocate(void *__ptr) { #endif } +#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_bad_array_length() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_array_length(); +#else + _VSTD::abort(); +#endif +} +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_NEW diff --git a/include/numeric b/include/numeric index 21c3781ab6a4..e00580854d41 100644 --- a/include/numeric +++ b/include/numeric @@ -53,6 +53,12 @@ template <class InputIterator, class OutputIterator, class BinaryOperation> template <class ForwardIterator, class T> void iota(ForwardIterator first, ForwardIterator last, T value); +template <class M, class N> + constexpr common_type_t<M,N> gcd(M m, N n); // C++17 + +template <class M, class N> + constexpr common_type_t<M,N> lcm(M m, N n); // C++17 + } // std */ @@ -192,6 +198,66 @@ iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value_) *__first = __value_; } + +#if _LIBCPP_STD_VER > 14 +template <typename _Tp, bool _IsSigned = is_signed<_Tp>::value> struct __abs; + +template <typename _Tp> +struct __abs<_Tp, true> { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _Tp operator()(_Tp __t) const noexcept { return __t >= 0 ? __t : -__t; } +}; + +template <typename _Tp> +struct __abs<_Tp, false> { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + _Tp operator()(_Tp __t) const noexcept { return __t; } +}; + + +template<class _Tp> +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +_Tp __gcd(_Tp __m, _Tp __n) +{ + static_assert((!is_signed<_Tp>::value), "" ); + return __n == 0 ? __m : __gcd<_Tp>(__n, __m % __n); +} + + +template<class _Tp, class _Up> +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +common_type_t<_Tp,_Up> +gcd(_Tp __m, _Up __n) +{ + static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to gcd must be integer types"); + static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to gcd cannot be bool" ); + static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to gcd cannot be bool" ); + using _Rp = common_type_t<_Tp,_Up>; + using _Wp = make_unsigned_t<_Rp>; + return static_cast<_Rp>(__gcd(static_cast<_Wp>(__abs<_Tp>()(__m)), + static_cast<_Wp>(__abs<_Up>()(__n)))); +} + +template<class _Tp, class _Up> +_LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY +common_type_t<_Tp,_Up> +lcm(_Tp __m, _Up __n) +{ + static_assert((is_integral<_Tp>::value && is_integral<_Up>::value), "Arguments to lcm must be integer types"); + static_assert((!is_same<typename remove_cv<_Tp>::type, bool>::value), "First argument to lcm cannot be bool" ); + static_assert((!is_same<typename remove_cv<_Up>::type, bool>::value), "Second argument to lcm cannot be bool" ); + if (__m == 0 || __n == 0) + return 0; + + using _Rp = common_type_t<_Tp,_Up>; + _Rp __val1 = __abs<_Tp>()(__m) / gcd(__m,__n); + _Up __val2 = __abs<_Up>()(__n); + _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); + return __val1 * __val2; +} + +#endif /* _LIBCPP_STD_VER > 14 */ + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_NUMERIC diff --git a/include/optional b/include/optional new file mode 100644 index 000000000000..b950efd0bda7 --- /dev/null +++ b/include/optional @@ -0,0 +1,1314 @@ +// -*- C++ -*- +//===-------------------------- optional ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_OPTIONAL +#define _LIBCPP_OPTIONAL + +/* + optional synopsis + +// C++1z + +namespace std { + // 20.6.3, optional for object types + template <class T> class optional; + + // 20.6.4, no-value state indicator + struct nullopt_t{see below }; + constexpr nullopt_t nullopt(unspecified ); + + // 20.6.5, class bad_optional_access + class bad_optional_access; + + // 20.6.6, relational operators + template <class T> + constexpr bool operator==(const optional<T>&, const optional<T>&); + template <class T> + constexpr bool operator!=(const optional<T>&, const optional<T>&); + template <class T> + constexpr bool operator<(const optional<T>&, const optional<T>&); + template <class T> + constexpr bool operator>(const optional<T>&, const optional<T>&); + template <class T> + constexpr bool operator<=(const optional<T>&, const optional<T>&); + template <class T> + constexpr bool operator>=(const optional<T>&, const optional<T>&); + template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; + template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; + template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; + template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; + template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; + template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; + template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; + template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; + template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; + template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; + template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; + template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; + + // 20.6.8, comparison with T + template <class T> constexpr bool operator==(const optional<T>&, const T&); + template <class T> constexpr bool operator==(const T&, const optional<T>&); + template <class T> constexpr bool operator!=(const optional<T>&, const T&); + template <class T> constexpr bool operator!=(const T&, const optional<T>&); + template <class T> constexpr bool operator<(const optional<T>&, const T&); + template <class T> constexpr bool operator<(const T&, const optional<T>&); + template <class T> constexpr bool operator<=(const optional<T>&, const T&); + template <class T> constexpr bool operator<=(const T&, const optional<T>&); + template <class T> constexpr bool operator>(const optional<T>&, const T&); + template <class T> constexpr bool operator>(const T&, const optional<T>&); + template <class T> constexpr bool operator>=(const optional<T>&, const T&); + template <class T> constexpr bool operator>=(const T&, const optional<T>&); + + // 20.6.9, specialized algorithms + template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); + template <class T> constexpr optional<see below > make_optional(T&&); + template <class T, class... Args> + constexpr optional<T> make_optional(Args&&... args); + template <class T, class U, class... Args> + constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); + + // 20.6.10, hash support + template <class T> struct hash; + template <class T> struct hash<optional<T>>; + + template <class T> class optional { + public: + using value_type = T; + + // 20.6.3.1, constructors + constexpr optional() noexcept; + constexpr optional(nullopt_t) noexcept; + optional(const optional &); + optional(optional &&) noexcept(see below ); + template <class... Args> constexpr explicit optional(in_place_t, Args &&...); + template <class U, class... Args> + constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); + template <class U = T> + constexpr EXPLICIT optional(U &&); + template <class U> + constexpr EXPLICIT optional(const optional<U> &); + template <class U> + constexpr EXPLICIT optional(optional<U> &&); + + // 20.6.3.2, destructor + ~optional(); + + // 20.6.3.3, assignment + optional &operator=(nullopt_t) noexcept; + optional &operator=(const optional &); + optional &operator=(optional &&) noexcept(see below ); + template <class U = T> optional &operator=(U &&); + template <class U> optional &operator=(const optional<U> &); + template <class U> optional &operator=(optional<U> &&); + template <class... Args> void emplace(Args &&...); + template <class U, class... Args> + void emplace(initializer_list<U>, Args &&...); + + // 20.6.3.4, swap + void swap(optional &) noexcept(see below ); + + // 20.6.3.5, observers + constexpr T const *operator->() const; + constexpr T *operator->(); + constexpr T const &operator*() const &; + constexpr T &operator*() &; + constexpr T &&operator*() &&; + constexpr const T &&operator*() const &&; + constexpr explicit operator bool() const noexcept; + constexpr bool has_value() const noexcept; + constexpr T const &value() const &; + constexpr T &value() &; + constexpr T &&value() &&; + constexpr const T &&value() const &&; + template <class U> constexpr T value_or(U &&) const &; + template <class U> constexpr T value_or(U &&) &&; + + // 20.6.3.6, modifiers + void reset() noexcept; + + private: + T *val; // exposition only + }; +} // namespace std + +*/ + +#include <__config> +#include <__debug> +#include <__functional_base> +#include <__undef_min_max> +#include <functional> +#include <initializer_list> +#include <new> +#include <stdexcept> +#include <type_traits> +#include <utility> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std // purposefully not using versioning namespace +{ + +class _LIBCPP_EXCEPTION_ABI bad_optional_access + : public logic_error +{ +public: + _LIBCPP_INLINE_VISIBILITY + bad_optional_access() : logic_error("bad optional access") {} + + // Get the key function ~bad_optional_access() into the dylib + virtual ~bad_optional_access() _NOEXCEPT; +}; + +} // std + +#if _LIBCPP_STD_VER > 14 + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_NORETURN +inline _LIBCPP_INLINE_VISIBILITY +void __throw_bad_optional_access() { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_optional_access(); +#else + _VSTD::abort(); +#endif +} + +struct nullopt_t +{ + struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; }; + _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} +}; + +/* inline */ constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}}; + +template <class _Tp, bool = is_trivially_destructible<_Tp>::value> +struct __optional_destruct_base; + +template <class _Tp> +struct __optional_destruct_base<_Tp, false> +{ + typedef _Tp value_type; + static_assert(is_object_v<value_type>, + "instantiation of optional with a non-object type is undefined behavior"); + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_; + + _LIBCPP_INLINE_VISIBILITY + ~__optional_destruct_base() + { + if (__engaged_) + __val_.~value_type(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_destruct_base() noexcept + : __null_state_(), + __engaged_(false) {} + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} + + _LIBCPP_INLINE_VISIBILITY + void reset() noexcept + { + if (__engaged_) + { + __val_.~value_type(); + __engaged_ = false; + } + } +}; + +template <class _Tp> +struct __optional_destruct_base<_Tp, true> +{ + typedef _Tp value_type; + static_assert(is_object_v<value_type>, + "instantiation of optional with a non-object type is undefined behavior"); + union + { + char __null_state_; + value_type __val_; + }; + bool __engaged_; + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_destruct_base() noexcept + : __null_state_(), + __engaged_(false) {} + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) + : __val_(_VSTD::forward<_Args>(__args)...), + __engaged_(true) {} + + _LIBCPP_INLINE_VISIBILITY + void reset() noexcept + { + if (__engaged_) + { + __engaged_ = false; + } + } +}; + +template <class _Tp, bool = is_reference<_Tp>::value> +struct __optional_storage_base : __optional_destruct_base<_Tp> +{ + using __base = __optional_destruct_base<_Tp>; + using value_type = _Tp; + using __base::__base; + + _LIBCPP_INLINE_VISIBILITY + constexpr bool has_value() const noexcept + { + return this->__engaged_; + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type& __get() & noexcept + { + return this->__val_; + } + _LIBCPP_INLINE_VISIBILITY + constexpr const value_type& __get() const& noexcept + { + return this->__val_; + } + _LIBCPP_INLINE_VISIBILITY + constexpr value_type&& __get() && noexcept + { + return _VSTD::move(this->__val_); + } + _LIBCPP_INLINE_VISIBILITY + constexpr const value_type&& __get() const&& noexcept + { + return _VSTD::move(this->__val_); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + void __construct(_Args&&... __args) + { + _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); + ::new((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); + this->__engaged_ = true; + } + + template <class _That> + _LIBCPP_INLINE_VISIBILITY + void __construct_from(_That&& __opt) + { + if (__opt.has_value()) + __construct(_VSTD::forward<_That>(__opt).__get()); + } + + template <class _That> + _LIBCPP_INLINE_VISIBILITY + void __assign_from(_That&& __opt) + { + if (this->__engaged_ == __opt.has_value()) + { + if (this->__engaged_) + this->__val_ = _VSTD::forward<_That>(__opt).__get(); + } + else + { + if (this->__engaged_) + this->reset(); + else + __construct(_VSTD::forward<_That>(__opt).__get()); + } + } +}; + +// optional<T&> is currently required ill-formed, however it may to be in the +// future. For this reason it has already been implemented to ensure we can +// make the change in an ABI compatible manner. +template <class _Tp> +struct __optional_storage_base<_Tp, true> +{ + using value_type = _Tp; + using __raw_type = remove_reference_t<_Tp>; + __raw_type* __value_; + + template <class _Up> + static constexpr bool __can_bind_reference() { + using _RawUp = typename remove_reference<_Up>::type; + using _UpPtr = _RawUp*; + using _RawTp = typename remove_reference<_Tp>::type; + using _TpPtr = _RawTp*; + using _CheckLValueArg = integral_constant<bool, + (is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value) + || is_same<_RawUp, reference_wrapper<_RawTp>>::value + || is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value + >; + return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value) + || (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value && + is_convertible<_UpPtr, _TpPtr>::value); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr __optional_storage_base() noexcept + : __value_(nullptr) {} + + template <class _UArg> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg) + : __value_(_VSTD::addressof(__uarg)) + { + static_assert(__can_bind_reference<_UArg>(), + "Attempted to construct a reference element in tuple from a " + "possible temporary"); + } + + _LIBCPP_INLINE_VISIBILITY + void reset() noexcept { __value_ = nullptr; } + + _LIBCPP_INLINE_VISIBILITY + constexpr bool has_value() const noexcept + { return __value_ != nullptr; } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type& __get() const& noexcept + { return *__value_; } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type&& __get() const&& noexcept + { return _VSTD::forward<value_type>(*__value_); } + + template <class _UArg> + _LIBCPP_INLINE_VISIBILITY + void __construct(_UArg&& __val) + { + _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); + static_assert(__can_bind_reference<_UArg>(), + "Attempted to construct a reference element in tuple from a " + "possible temporary"); + __value_ = _VSTD::addressof(__val); + } + + template <class _That> + _LIBCPP_INLINE_VISIBILITY + void __construct_from(_That&& __opt) + { + if (__opt.has_value()) + __construct(_VSTD::forward<_That>(__opt).__get()); + } + + template <class _That> + _LIBCPP_INLINE_VISIBILITY + void __assign_from(_That&& __opt) + { + if (has_value() == __opt.has_value()) + { + if (has_value()) + *__value_ = _VSTD::forward<_That>(__opt).__get(); + } + else + { + if (has_value()) + reset(); + else + __construct(_VSTD::forward<_That>(__opt).__get()); + } + } +}; + +template <class _Tp, bool = is_trivially_copyable<_Tp>::value> +struct __optional_storage; + +template <class _Tp> +struct __optional_storage<_Tp, true> : __optional_storage_base<_Tp> +{ + using __optional_storage_base<_Tp>::__optional_storage_base; +}; + +template <class _Tp> +struct __optional_storage<_Tp, false> : __optional_storage_base<_Tp> +{ + using value_type = _Tp; + using __optional_storage_base<_Tp>::__optional_storage_base; + + _LIBCPP_INLINE_VISIBILITY + __optional_storage() = default; + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(const __optional_storage& __opt) + { + this->__construct_from(__opt); + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage(__optional_storage&& __opt) + noexcept(is_nothrow_move_constructible_v<value_type>) + { + this->__construct_from(_VSTD::move(__opt)); + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage& operator=(const __optional_storage& __opt) + { + this->__assign_from(__opt); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + __optional_storage& operator=(__optional_storage&& __opt) + noexcept(is_nothrow_move_assignable_v<value_type> && + is_nothrow_move_constructible_v<value_type>) + { + this->__assign_from(_VSTD::move(__opt)); + return *this; + } +}; + +template <class _Tp> +using __optional_sfinae_ctor_base_t = __sfinae_ctor_base< + is_copy_constructible<_Tp>::value, + is_move_constructible<_Tp>::value +>; + +template <class _Tp> +using __optional_sfinae_assign_base_t = __sfinae_assign_base< + (is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value), + (is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value) +>; + +template <class _Tp> +class optional + : private __optional_storage<_Tp> + , private __optional_sfinae_ctor_base_t<_Tp> + , private __optional_sfinae_assign_base_t<_Tp> +{ + using __base = __optional_storage<_Tp>; +public: + using value_type = _Tp; + +private: + // Disable the reference extension using this static assert. + static_assert(!is_same_v<value_type, in_place_t>, + "instantiation of optional with in_place_t is ill-formed"); + static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>, + "instantiation of optional with nullopt_t is ill-formed"); + static_assert(!is_reference_v<value_type>, + "instantiation of optional with a reference type is ill-formed"); + static_assert(is_destructible_v<value_type>, + "instantiation of optional with a non-destructible type is ill-formed"); + + // LWG2756: conditionally explicit conversion from _Up + struct _CheckOptionalArgsConstructor { + template <class _Up> + static constexpr bool __enable_implicit() { + return is_constructible_v<_Tp, _Up&&> && + is_convertible_v<_Up&&, _Tp>; + } + + template <class _Up> + static constexpr bool __enable_explicit() { + return is_constructible_v<_Tp, _Up&&> && + !is_convertible_v<_Up&&, _Tp>; + } + }; + template <class _Up> + using _CheckOptionalArgsCtor = conditional_t< + !is_same_v<in_place_t, _Up> && + !is_same_v<decay_t<_Up>, optional>, + _CheckOptionalArgsConstructor, + __check_tuple_constructor_fail + >; + template <class _QualUp> + struct _CheckOptionalLikeConstructor { + template <class _Up, class _Opt = optional<_Up>> + using __check_constructible_from_opt = __lazy_or< + is_constructible<_Tp, _Opt&>, + is_constructible<_Tp, _Opt const&>, + is_constructible<_Tp, _Opt&&>, + is_constructible<_Tp, _Opt const&&>, + is_convertible<_Opt&, _Tp>, + is_convertible<_Opt const&, _Tp>, + is_convertible<_Opt&&, _Tp>, + is_convertible<_Opt const&&, _Tp> + >; + template <class _Up, class _Opt = optional<_Up>> + using __check_assignable_from_opt = __lazy_or< + is_assignable<_Tp&, _Opt&>, + is_assignable<_Tp&, _Opt const&>, + is_assignable<_Tp&, _Opt&&>, + is_assignable<_Tp&, _Opt const&&> + >; + template <class _Up, class _QUp = _QualUp> + static constexpr bool __enable_implicit() { + return is_convertible<_QUp, _Tp>::value && + !__check_constructible_from_opt<_Up>::value; + } + template <class _Up, class _QUp = _QualUp> + static constexpr bool __enable_explicit() { + return !is_convertible<_QUp, _Tp>::value && + !__check_constructible_from_opt<_Up>::value; + } + template <class _Up, class _QUp = _QualUp> + static constexpr bool __enable_assign() { + // Construction and assignability of _Qup to _Tp has already been + // checked. + return !__check_constructible_from_opt<_Up>::value && + !__check_assignable_from_opt<_Up>::value; + } + }; + + template <class _Up, class _QualUp> + using _CheckOptionalLikeCtor = conditional_t< + __lazy_and< + __lazy_not<is_same<_Up, _Tp>>, + is_constructible<_Tp, _QualUp> + >::value, + _CheckOptionalLikeConstructor<_QualUp>, + __check_tuple_constructor_fail + >; + template <class _Up, class _QualUp> + using _CheckOptionalLikeAssign = conditional_t< + __lazy_and< + __lazy_not<is_same<_Up, _Tp>>, + is_constructible<_Tp, _QualUp>, + is_assignable<_Tp&, _QualUp> + >::value, + _CheckOptionalLikeConstructor<_QualUp>, + __check_tuple_constructor_fail + >; +public: + + _LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {} + _LIBCPP_INLINE_VISIBILITY optional(const optional&) = default; + _LIBCPP_INLINE_VISIBILITY optional(optional&&) = default; + _LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {} + + template <class... _Args, class = enable_if_t< + is_constructible_v<value_type, _Args...>> + > + _LIBCPP_INLINE_VISIBILITY + constexpr explicit optional(in_place_t, _Args&&... __args) + : __base(in_place, _VSTD::forward<_Args>(__args)...) {} + + template <class _Up, class... _Args, class = enable_if_t< + is_constructible_v<value_type, initializer_list<_Up>&, _Args...>> + > + _LIBCPP_INLINE_VISIBILITY + constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args) + : __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {} + + template <class _Up = value_type, enable_if_t< + _CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + constexpr optional(_Up&& __v) + : __base(in_place, _VSTD::forward<_Up>(__v)) {} + + template <class _Up, enable_if_t< + _CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + constexpr explicit optional(_Up&& __v) + : __base(in_place, _VSTD::forward<_Up>(__v)) {} + + // LWG2756: conditionally explicit conversion from const optional<_Up>& + template <class _Up, enable_if_t< + _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + optional(const optional<_Up>& __v) + { + this->__construct_from(__v); + } + template <class _Up, enable_if_t< + _CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + explicit optional(const optional<_Up>& __v) + { + this->__construct_from(__v); + } + + // LWG2756: conditionally explicit conversion from optional<_Up>&& + template <class _Up, enable_if_t< + _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + optional(optional<_Up>&& __v) + { + this->__construct_from(_VSTD::move(__v)); + } + template <class _Up, enable_if_t< + _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + explicit optional(optional<_Up>&& __v) + { + this->__construct_from(_VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + optional& operator=(nullopt_t) noexcept + { + reset(); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default; + _LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default; + + // LWG2756 + template <class _Up = value_type, + class = enable_if_t + <__lazy_and< + integral_constant<bool, + !is_same_v<decay_t<_Up>, optional> && + !(is_same_v<_Up, value_type> && is_scalar_v<value_type>) + >, + is_constructible<value_type, _Up>, + is_assignable<value_type&, _Up> + >::value> + > + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(_Up&& __v) + { + if (this->has_value()) + this->__get() = _VSTD::forward<_Up>(__v); + else + this->__construct(_VSTD::forward<_Up>(__v)); + return *this; + } + + // LWG2756 + template <class _Up, enable_if_t< + _CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(const optional<_Up>& __v) + { + this->__assign_from(__v); + return *this; + } + + // LWG2756 + template <class _Up, enable_if_t< + _CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>() + , int> = 0> + _LIBCPP_INLINE_VISIBILITY + optional& + operator=(optional<_Up>&& __v) + { + this->__assign_from(_VSTD::move(__v)); + return *this; + } + + template <class... _Args, + class = enable_if_t + < + is_constructible_v<value_type, _Args...> + > + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(_Args&&... __args) + { + reset(); + this->__construct(_VSTD::forward<_Args>(__args)...); + } + + template <class _Up, class... _Args, + class = enable_if_t + < + is_constructible_v<value_type, initializer_list<_Up>&, _Args...> + > + > + _LIBCPP_INLINE_VISIBILITY + void + emplace(initializer_list<_Up> __il, _Args&&... __args) + { + reset(); + this->__construct(__il, _VSTD::forward<_Args>(__args)...); + } + + _LIBCPP_INLINE_VISIBILITY + void swap(optional& __opt) + noexcept(is_nothrow_move_constructible_v<value_type> && + is_nothrow_swappable_v<value_type>) + { + if (this->has_value() == __opt.has_value()) + { + using _VSTD::swap; + if (this->has_value()) + swap(this->__get(), __opt.__get()); + } + else + { + if (this->has_value()) + { + __opt.__construct(_VSTD::move(this->__get())); + reset(); + } + else + { + this->__construct(_VSTD::move(__opt.__get())); + __opt.reset(); + } + } + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + add_pointer_t<value_type const> + operator->() const + { + _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF + return _VSTD::addressof(this->__get()); +#else + return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + add_pointer_t<value_type> + operator->() + { + _LIBCPP_ASSERT(this->has_value(), "optional operator-> called for disengaged value"); +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF + return _VSTD::addressof(this->__get()); +#else + return __operator_arrow(__has_operator_addressof<value_type>{}, this->__get()); +#endif + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + const value_type& + operator*() const& + { + _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); + return this->__get(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type& + operator*() & + { + _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); + return this->__get(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + value_type&& + operator*() && + { + _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); + return _VSTD::move(this->__get()); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr + const value_type&& + operator*() const&& + { + _LIBCPP_ASSERT(this->has_value(), "optional operator* called for disengaged value"); + return _VSTD::move(this->__get()); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr explicit operator bool() const noexcept { return has_value(); } + + using __base::has_value; + using __base::__get; + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const& value() const& + { + if (!this->has_value()) + __throw_bad_optional_access(); + return this->__get(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type& value() & + { + if (!this->has_value()) + __throw_bad_optional_access(); + return this->__get(); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type&& value() && + { + if (!this->has_value()) + __throw_bad_optional_access(); + return _VSTD::move(this->__get()); + } + + _LIBCPP_INLINE_VISIBILITY + constexpr value_type const&& value() const&& + { + if (!this->has_value()) + __throw_bad_optional_access(); + return _VSTD::move(this->__get()); + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + constexpr value_type value_or(_Up&& __v) const& + { + static_assert(is_copy_constructible_v<value_type>, + "optional<T>::value_or: T must be copy constructible"); + static_assert(is_convertible_v<_Up, value_type>, + "optional<T>::value_or: U must be convertible to T"); + return this->has_value() ? this->__get() : + static_cast<value_type>(_VSTD::forward<_Up>(__v)); + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + value_type value_or(_Up&& __v) && + { + static_assert(is_move_constructible_v<value_type>, + "optional<T>::value_or: T must be move constructible"); + static_assert(is_convertible_v<_Up, value_type>, + "optional<T>::value_or: U must be convertible to T"); + return this->has_value() ? _VSTD::move(this->__get()) : + static_cast<value_type>(_VSTD::forward<_Up>(__v)); + } + + using __base::reset; + +private: + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static _Up* + __operator_arrow(true_type, _Up& __x) + { + return _VSTD::addressof(__x); + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static constexpr _Up* + __operator_arrow(false_type, _Up& __x) + { + return &__x; + } +}; + +// Comparisons between optionals +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator==(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast<bool>(__x) != static_cast<bool>(__y)) + return false; + if (!static_cast<bool>(__x)) + return true; + return *__x == *__y; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator!=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (static_cast<bool>(__x) != static_cast<bool>(__y)) + return true; + if (!static_cast<bool>(__x)) + return false; + return *__x != *__y; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator<(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast<bool>(__y)) + return false; + if (!static_cast<bool>(__x)) + return true; + return *__x < *__y; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator>(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast<bool>(__x)) + return false; + if (!static_cast<bool>(__y)) + return true; + return *__x > *__y; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator<=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast<bool>(__x)) + return true; + if (!static_cast<bool>(__y)) + return false; + return *__x <= *__y; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator>=(const optional<_Tp>& __x, const optional<_Tp>& __y) +{ + if (!static_cast<bool>(__y)) + return true; + if (!static_cast<bool>(__x)) + return false; + return *__x >= *__y; +} + +// Comparisons with nullopt +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator==(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator==(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator!=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator!=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator<(const optional<_Tp>&, nullopt_t) noexcept +{ + return false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator<(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator<=(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return !static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator<=(nullopt_t, const optional<_Tp>&) noexcept +{ + return true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator>(const optional<_Tp>& __x, nullopt_t) noexcept +{ + return static_cast<bool>(__x); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator>(nullopt_t, const optional<_Tp>&) noexcept +{ + return false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator>=(const optional<_Tp>&, nullopt_t) noexcept +{ + return true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +bool +operator>=(nullopt_t, const optional<_Tp>& __x) noexcept +{ + return !static_cast<bool>(__x); +} + +// Comparisons with T +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator==(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x == __v : false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() == + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator==(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? __v == *__x : false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator!=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x != __v : true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() != + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator!=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? __v != *__x : true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator<(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x < __v : true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() < + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator<(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? __v < *__x : false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator<=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x <= __v : true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() <= + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator<=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? __v <= *__x : false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator>(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x > __v : false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() > + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator>(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? __v > *__x : true; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator>=(const optional<_Tp>& __x, const _Tp& __v) +{ + return static_cast<bool>(__x) ? *__x >= __v : false; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t< + is_convertible_v<decltype(_VSTD::declval<const _Tp&>() >= + _VSTD::declval<const _Tp&>()), bool>, + bool +> +operator>=(const _Tp& __v, const optional<_Tp>& __x) +{ + return static_cast<bool>(__x) ? __v >= *__x : true; +} + + +template <class _Tp> +inline _LIBCPP_INLINE_VISIBILITY +enable_if_t< + is_move_constructible_v<_Tp> && is_swappable_v<_Tp>, + void +> +swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y))) +{ + __x.swap(__y); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY constexpr +optional<decay_t<_Tp>> make_optional(_Tp&& __v) +{ + return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v)); +} + +template <class _Tp, class... _Args> +_LIBCPP_INLINE_VISIBILITY constexpr +optional<_Tp> make_optional(_Args&&... __args) +{ + return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...); +} + +template <class _Tp, class _Up, class... _Args> +_LIBCPP_INLINE_VISIBILITY constexpr +optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args) +{ + return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...); +} + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY hash<optional<_Tp> > +{ + typedef optional<_Tp> argument_type; + typedef size_t result_type; + + _LIBCPP_INLINE_VISIBILITY + result_type operator()(const argument_type& __opt) const _NOEXCEPT + { + return static_cast<bool>(__opt) ? hash<_Tp>()(*__opt) : 0; + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 14 + +#endif // _LIBCPP_OPTIONAL diff --git a/include/ostream b/include/ostream index f55fd40856ec..cf2051433a61 100644 --- a/include/ostream +++ b/include/ostream @@ -160,20 +160,24 @@ public: typedef typename traits_type::off_type off_type; // 27.7.2.2 Constructor/destructor: - explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit basic_ostream(basic_streambuf<char_type, traits_type>* __sb) + { this->init(__sb); } virtual ~basic_ostream(); protected: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY basic_ostream(basic_ostream&& __rhs); #endif // 27.7.2.3 Assign/swap #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_INLINE_VISIBILITY basic_ostream& operator=(basic_ostream&& __rhs); #endif - void swap(basic_ostream& __rhs); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void swap(basic_ostream& __rhs) + { basic_ios<char_type, traits_type>::swap(__rhs); } #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS basic_ostream (const basic_ostream& __rhs) = delete; @@ -188,10 +192,19 @@ public: class _LIBCPP_TYPE_VIS_ONLY sentry; // 27.7.2.6 Formatted output: - basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&)) + { return __pf(*this); } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream& operator<<(basic_ios<char_type, traits_type>& - (*__pf)(basic_ios<char_type,traits_type>&)); - basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)); + (*__pf)(basic_ios<char_type,traits_type>&)) + { __pf(*this); return *this; } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_ostream& operator<<(ios_base& (*__pf)(ios_base&)) + { __pf(*this); return *this; } + basic_ostream& operator<<(bool __n); basic_ostream& operator<<(short __n); basic_ostream& operator<<(unsigned short __n); @@ -213,8 +226,11 @@ public: basic_ostream& flush(); // 27.7.2.5 seeks: + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY pos_type tellp(); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream& seekp(pos_type __pos); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY basic_ostream& seekp(off_type __off, ios_base::seekdir __dir); protected: @@ -274,24 +290,15 @@ basic_ostream<_CharT, _Traits>::sentry::~sentry() } } -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>::basic_ostream(basic_streambuf<char_type, traits_type>* __sb) -{ - this->init(__sb); -} - #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>::basic_ostream(basic_ostream&& __rhs) { this->move(__rhs); } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator=(basic_ostream&& __rhs) { @@ -307,41 +314,6 @@ basic_ostream<_CharT, _Traits>::~basic_ostream() } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_ostream<_CharT, _Traits>::swap(basic_ostream& __rhs) -{ - basic_ios<char_type, traits_type>::swap(__rhs); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -basic_ostream<_CharT, _Traits>::operator<<(basic_ostream& (*__pf)(basic_ostream&)) -{ - return __pf(*this); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -basic_ostream<_CharT, _Traits>::operator<<(basic_ios<char_type, traits_type>& - (*__pf)(basic_ios<char_type,traits_type>&)) -{ - __pf(*this); - return *this; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_ostream<_CharT, _Traits>& -basic_ostream<_CharT, _Traits>::operator<<(ios_base& (*__pf)(ios_base&)) -{ - __pf(*this); - return *this; -} - -template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb) { @@ -989,7 +961,6 @@ basic_ostream<_CharT, _Traits>::flush() } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY typename basic_ostream<_CharT, _Traits>::pos_type basic_ostream<_CharT, _Traits>::tellp() { @@ -999,7 +970,6 @@ basic_ostream<_CharT, _Traits>::tellp() } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) { @@ -1013,7 +983,6 @@ basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::seekp(off_type __off, ios_base::seekdir __dir) { @@ -1080,6 +1049,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, return _VSTD::__put_character_sequence(__os, __str.data(), __str.size()); } +template<class _CharT, class _Traits> +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const basic_string_view<_CharT, _Traits> __sv) +{ + return _VSTD::__put_character_sequence(__os, __sv.data(), __sv.size()); +} + template <class _CharT, class _Traits> inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& @@ -1105,8 +1082,8 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) use_facet<ctype<_CharT> >(__os.getloc()).widen('1')); } -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ostream<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>) _LIBCPP_END_NAMESPACE_STD diff --git a/include/queue b/include/queue index c657b52f8038..01247a29da2b 100644 --- a/include/queue +++ b/include/queue @@ -63,7 +63,7 @@ public: void push(const value_type& v); void push(value_type&& v); - template <class... Args> void emplace(Args&&... args); + template <class... Args> reference emplace(Args&&... args); void pop(); void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>) @@ -292,8 +292,8 @@ public: #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args> _LIBCPP_INLINE_VISIBILITY - void emplace(_Args&&... __args) - {c.emplace_back(_VSTD::forward<_Args>(__args)...);} + reference emplace(_Args&&... __args) + { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} #endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY diff --git a/include/random b/include/random index 794bf7b3fd15..4e11f9e70771 100644 --- a/include/random +++ b/include/random @@ -2817,6 +2817,7 @@ class _LIBCPP_TYPE_VIS_ONLY discard_block_engine static_assert( 0 < __r, "discard_block_engine invalid parameters"); static_assert(__r <= __p, "discard_block_engine invalid parameters"); + static_assert(__r <= INT_MAX, "discard_block_engine invalid parameters"); public: // types typedef typename _Engine::result_type result_type; @@ -2918,7 +2919,7 @@ template<class _Engine, size_t __p, size_t __r> typename discard_block_engine<_Engine, __p, __r>::result_type discard_block_engine<_Engine, __p, __r>::operator()() { - if (__n_ >= __r) + if (__n_ >= static_cast<int>(__r)) { __e_.discard(__p - __r); __n_ = 0; diff --git a/include/ratio b/include/ratio index 8f708ce478d3..08eb774df665 100644 --- a/include/ratio +++ b/include/ratio @@ -300,18 +300,18 @@ public: >::type type; }; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _R1, class _R2> using ratio_multiply = typename __ratio_multiply<_R1, _R2>::type; -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#else // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct _LIBCPP_TYPE_VIS_ONLY ratio_multiply : public __ratio_multiply<_R1, _R2>::type {}; -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct __ratio_divide @@ -327,18 +327,18 @@ public: >::type type; }; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _R1, class _R2> using ratio_divide = typename __ratio_divide<_R1, _R2>::type; -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#else // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct _LIBCPP_TYPE_VIS_ONLY ratio_divide : public __ratio_divide<_R1, _R2>::type {}; -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct __ratio_add @@ -362,18 +362,18 @@ public: >::type type; }; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _R1, class _R2> using ratio_add = typename __ratio_add<_R1, _R2>::type; -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#else // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct _LIBCPP_TYPE_VIS_ONLY ratio_add : public __ratio_add<_R1, _R2>::type {}; -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct __ratio_subtract @@ -397,18 +397,18 @@ public: >::type type; }; -#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#ifndef _LIBCPP_CXX03_LANG template <class _R1, class _R2> using ratio_subtract = typename __ratio_subtract<_R1, _R2>::type; -#else // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#else // _LIBCPP_CXX03_LANG template <class _R1, class _R2> struct _LIBCPP_TYPE_VIS_ONLY ratio_subtract : public __ratio_subtract<_R1, _R2>::type {}; -#endif // _LIBCPP_HAS_NO_TEMPLATE_ALIASES +#endif // _LIBCPP_CXX03_LANG // ratio_equal diff --git a/include/regex b/include/regex index 1139d8fb2a90..5a6c7fbb8e0a 100644 --- a/include/regex +++ b/include/regex @@ -127,6 +127,8 @@ class basic_regex public: // types: typedef charT value_type; + typedef traits traits_type; + typedef typename traits::string_type string_type; typedef regex_constants::syntax_option_type flag_type; typedef typename traits::locale_type locale_type; @@ -145,7 +147,7 @@ public: // construct/copy/destroy: basic_regex(); explicit basic_regex(const charT* p, flag_type f = regex_constants::ECMAScript); - basic_regex(const charT* p, size_t len, flag_type f); + basic_regex(const charT* p, size_t len, flag_type f = regex_constants::ECMAScript); basic_regex(const basic_regex&); basic_regex(basic_regex&&) noexcept; template <class ST, class SA> @@ -762,7 +764,6 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; #include <memory> #include <vector> #include <deque> -#include <cassert> #include <__undef_min_max> @@ -864,7 +865,8 @@ enum match_flag_type format_sed = 1 << 8, format_no_copy = 1 << 9, format_first_only = 1 << 10, - __no_update_pos = 1 << 11 + __no_update_pos = 1 << 11, + __full_match = 1 << 12 }; inline _LIBCPP_INLINE_VISIBILITY @@ -957,13 +959,13 @@ public: }; template <regex_constants::error_type _Ev> -_LIBCPP_ALWAYS_INLINE +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE void __throw_regex_error() { #ifndef _LIBCPP_NO_EXCEPTIONS throw regex_error(_Ev); #else - assert(!"regex_error"); + _VSTD::abort(); #endif } @@ -2475,6 +2477,8 @@ class _LIBCPP_TYPE_VIS_ONLY basic_regex public: // types: typedef _CharT value_type; + typedef _Traits traits_type; + typedef typename _Traits::string_type string_type; typedef regex_constants::syntax_option_type flag_type; typedef typename _Traits::locale_type locale_type; @@ -2515,7 +2519,7 @@ public: __end_(0) {__parse(__p, __p + __traits_.length(__p));} _LIBCPP_INLINE_VISIBILITY - basic_regex(const value_type* __p, size_t __len, flag_type __f) + basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript) : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0), __end_(0) {__parse(__p, __p + __len);} @@ -2981,10 +2985,12 @@ __lookahead<_CharT, _Traits>::__exec(__state& __s) const { match_results<const _CharT*> __m; __m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_); - bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_, - __m, - __s.__flags_ | regex_constants::match_continuous, - __s.__at_first_ && __s.__current_ == __s.__first_); + bool __matched = __exp_.__match_at_start_ecma( + __s.__current_, __s.__last_, + __m, + (__s.__flags_ | regex_constants::match_continuous) & + ~regex_constants::__full_match, + __s.__at_first_ && __s.__current_ == __s.__first_); if (__matched != __invert_) { __s.__do_ = __state::__accept_but_not_consume; @@ -4308,7 +4314,8 @@ basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first, else if ('1' <= *__first && *__first <= '9') { unsigned __v = *__first - '0'; - for (++__first; '0' <= *__first && *__first <= '9'; ++__first) + for (++__first; + __first != __last && '0' <= *__first && *__first <= '9'; ++__first) __v = 10 * __v + *__first - '0'; if (__v > mark_count()) __throw_regex_error<regex_constants::error_backref>(); @@ -5552,6 +5559,18 @@ basic_regex<_CharT, _Traits>::__match_at_start_ecma( switch (__s.__do_) { case __state::__end_state: + if ((__flags & regex_constants::match_not_null) && + __s.__current_ == __first) + { + __states.pop_back(); + break; + } + if ((__flags & regex_constants::__full_match) && + __s.__current_ != __last) + { + __states.pop_back(); + break; + } __m.__matches_[0].first = __first; __m.__matches_[0].second = _VSTD::next(__first, __s.__current_ - __first); __m.__matches_[0].matched = true; @@ -5615,6 +5634,18 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs( switch (__s.__do_) { case __state::__end_state: + if ((__flags & regex_constants::match_not_null) && + __s.__current_ == __first) + { + __states.pop_back(); + break; + } + if ((__flags & regex_constants::__full_match) && + __s.__current_ != __last) + { + __states.pop_back(); + break; + } if (!__matched || __highest_j < __s.__current_ - __s.__first_) __highest_j = __s.__current_ - __s.__first_; __matched = true; @@ -5700,6 +5731,18 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs( switch (__s.__do_) { case __state::__end_state: + if ((__flags & regex_constants::match_not_null) && + __s.__current_ == __first) + { + __states.pop_back(); + break; + } + if ((__flags & regex_constants::__full_match) && + __s.__current_ != __last) + { + __states.pop_back(); + break; + } if (!__matched || __highest_j < __s.__current_ - __s.__first_) { __highest_j = __s.__current_ - __s.__first_; @@ -5930,8 +5973,10 @@ regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last, const basic_regex<_CharT, _Traits>& __e, regex_constants::match_flag_type __flags = regex_constants::match_default) { - bool __r = _VSTD::regex_search(__first, __last, __m, __e, - __flags | regex_constants::match_continuous); + bool __r = _VSTD::regex_search( + __first, __last, __m, __e, + __flags | regex_constants::match_continuous | + regex_constants::__full_match); if (__r) { __r = !__m.suffix().matched; @@ -6142,7 +6187,7 @@ private: _Position __position_; const value_type* __result_; value_type __suffix_; - ptrdiff_t _N_; + ptrdiff_t __n_; vector<int> __subs_; public: @@ -6225,10 +6270,10 @@ public: private: void __init(_BidirectionalIterator __a, _BidirectionalIterator __b); void __establish_result () { - if (__subs_[_N_] == -1) + if (__subs_[__n_] == -1) __result_ = &__position_->prefix(); else - __result_ = &(*__position_)[__subs_[_N_]]; + __result_ = &(*__position_)[__subs_[__n_]]; } }; @@ -6237,7 +6282,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: regex_token_iterator() : __result_(nullptr), __suffix_(), - _N_(0) + __n_(0) { } @@ -6248,7 +6293,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: { if (__position_ != _Position()) __establish_result (); - else if (__subs_[_N_] == -1) + else if (__subs_[__n_] == -1) { __suffix_.matched = true; __suffix_.first = __a; @@ -6265,7 +6310,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: const regex_type& __re, int __submatch, regex_constants::match_flag_type __m) : __position_(__a, __b, __re, __m), - _N_(0), + __n_(0), __subs_(1, __submatch) { __init(__a, __b); @@ -6277,7 +6322,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: const regex_type& __re, const vector<int>& __submatches, regex_constants::match_flag_type __m) : __position_(__a, __b, __re, __m), - _N_(0), + __n_(0), __subs_(__submatches) { __init(__a, __b); @@ -6292,7 +6337,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: initializer_list<int> __submatches, regex_constants::match_flag_type __m) : __position_(__a, __b, __re, __m), - _N_(0), + __n_(0), __subs_(__submatches) { __init(__a, __b); @@ -6308,7 +6353,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: const int (&__submatches)[_Np], regex_constants::match_flag_type __m) : __position_(__a, __b, __re, __m), - _N_(0), + __n_(0), __subs_(__submatches, __submatches + _Np) { __init(__a, __b); @@ -6320,7 +6365,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: : __position_(__x.__position_), __result_(__x.__result_), __suffix_(__x.__suffix_), - _N_(__x._N_), + __n_(__x.__n_), __subs_(__x.__subs_) { if (__x.__result_ == &__x.__suffix_) @@ -6342,7 +6387,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: else __result_ = __x.__result_; __suffix_ = __x.__suffix_; - _N_ = __x._N_; + __n_ = __x.__n_; __subs_ = __x.__subs_; if ( __result_ != nullptr && __result_ != &__suffix_ ) @@ -6365,7 +6410,7 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>:: return false; if (__result_ == &__suffix_ || __x.__result_ == &__x.__suffix_) return false; - return __position_ == __x.__position_ && _N_ == __x._N_ && + return __position_ == __x.__position_ && __n_ == __x.__n_ && __subs_ == __x.__subs_; } @@ -6376,14 +6421,14 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++() _Position __prev = __position_; if (__result_ == &__suffix_) __result_ = nullptr; - else if (_N_ + 1 < __subs_.size()) + else if (static_cast<size_t>(__n_ + 1) < __subs_.size()) { - ++_N_; + ++__n_; __establish_result(); } else { - _N_ = 0; + __n_ = 0; ++__position_; if (__position_ != _Position()) __establish_result(); diff --git a/include/scoped_allocator b/include/scoped_allocator index 9436dac9c199..605f70b472f1 100644 --- a/include/scoped_allocator +++ b/include/scoped_allocator @@ -115,7 +115,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs> _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) +#if !defined(_LIBCPP_CXX03_LANG) // scoped_allocator_adaptor @@ -498,8 +498,58 @@ public: template <class _Tp, class... _Args> _LIBCPP_INLINE_VISIBILITY void construct(_Tp* __p, _Args&& ...__args) - {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type, _Args...>(), + {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(), __p, _VSTD::forward<_Args>(__args)...);} + + template <class _T1, class _T2, class... _Args1, class... _Args2> + void construct(pair<_T1, _T2>* __p, piecewise_construct_t, + tuple<_Args1...> __x, tuple<_Args2...> __y) + { + typedef __outermost<outer_allocator_type> _OM; + allocator_traits<typename _OM::type>::construct( + _OM()(outer_allocator()), __p, piecewise_construct + , __transform_tuple( + typename __uses_alloc_ctor< + _T1, inner_allocator_type&, _Args1... + >::type() + , _VSTD::move(__x) + , typename __make_tuple_indices<sizeof...(_Args1)>::type{} + ) + , __transform_tuple( + typename __uses_alloc_ctor< + _T2, inner_allocator_type&, _Args2... + >::type() + , _VSTD::move(__y) + , typename __make_tuple_indices<sizeof...(_Args2)>::type{} + ) + ); + } + + template <class _T1, class _T2> + void construct(pair<_T1, _T2>* __p) + { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); } + + template <class _T1, class _T2, class _Up, class _Vp> + void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { + construct(__p, piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)), + _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y))); + } + + template <class _T1, class _T2, class _Up, class _Vp> + void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { + construct(__p, piecewise_construct, + _VSTD::forward_as_tuple(__x.first), + _VSTD::forward_as_tuple(__x.second)); + } + + template <class _T1, class _T2, class _Up, class _Vp> + void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { + construct(__p, piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)), + _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second))); + } + template <class _Tp> _LIBCPP_INLINE_VISIBILITY void destroy(_Tp* __p) @@ -515,6 +565,7 @@ public: private: + template <class _OuterA2, class = typename enable_if< is_constructible<outer_allocator_type, _OuterA2>::value @@ -545,9 +596,7 @@ private: allocator_traits<typename _OM::type>::construct ( _OM()(outer_allocator()), - __p, - allocator_arg, - inner_allocator(), + __p, allocator_arg, inner_allocator(), _VSTD::forward<_Args>(__args)... ); } @@ -566,6 +615,36 @@ private: ); } + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&...> + __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, + __tuple_indices<_Idx...>) + { + return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<allocator_arg_t, inner_allocator_type&, _Args&&...> + __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) + { + using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>; + return _Tup(allocator_arg, inner_allocator(), + _VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&..., inner_allocator_type&> + __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) + { + using _Tup = tuple<_Args&&..., inner_allocator_type&>; + return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator()); + } + template <class...> friend class __scoped_allocator_storage; }; @@ -597,7 +676,7 @@ operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a, return !(__a == __b); } -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_ADVANCED_SFINAE) +#endif // !defined(_LIBCPP_CXX03_LANG) _LIBCPP_END_NAMESPACE_STD diff --git a/include/set b/include/set index ac69e085241f..8e4c2ae6a604 100644 --- a/include/set +++ b/include/set @@ -672,7 +672,7 @@ public: template <typename _K2> _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type - count(const _K2& __k) {return __tree_.__count_unique(__k);} + count(const _K2& __k) const {return __tree_.__count_unique(__k);} #endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) @@ -1023,7 +1023,7 @@ public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_multi(_VSTD::move(__v));} + {return __tree_.__insert_multi(__p, _VSTD::move(__v));} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY diff --git a/include/sstream b/include/sstream index 27ae78f9d45f..18bccf6ac6c7 100644 --- a/include/sstream +++ b/include/sstream @@ -207,7 +207,9 @@ private: public: // 27.8.1.1 Constructors: + inline _LIBCPP_INLINE_VISIBILITY explicit basic_stringbuf(ios_base::openmode __wch = ios_base::in | ios_base::out); + inline _LIBCPP_INLINE_VISIBILITY explicit basic_stringbuf(const string_type& __s, ios_base::openmode __wch = ios_base::in | ios_base::out); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -231,12 +233,12 @@ protected: virtual int_type overflow (int_type __c = traits_type::eof()); virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __wch = ios_base::in | ios_base::out); + inline _LIBCPP_INLINE_VISIBILITY virtual pos_type seekpos(pos_type __sp, ios_base::openmode __wch = ios_base::in | ios_base::out); }; template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(ios_base::openmode __wch) : __hm_(0), __mode_(__wch) @@ -245,7 +247,6 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(ios_base::openmode } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(const string_type& __s, ios_base::openmode __wch) : __hm_(0), @@ -607,7 +608,6 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY typename basic_stringbuf<_CharT, _Traits, _Allocator>::pos_type basic_stringbuf<_CharT, _Traits, _Allocator>::seekpos(pos_type __sp, ios_base::openmode __wch) @@ -636,25 +636,31 @@ private: public: // 27.8.2.1 Constructors: + inline _LIBCPP_INLINE_VISIBILITY explicit basic_istringstream(ios_base::openmode __wch = ios_base::in); + inline _LIBCPP_INLINE_VISIBILITY explicit basic_istringstream(const string_type& __s, ios_base::openmode __wch = ios_base::in); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY basic_istringstream(basic_istringstream&& __rhs); // 27.8.2.2 Assign and swap: basic_istringstream& operator=(basic_istringstream&& __rhs); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY void swap(basic_istringstream& __rhs); // 27.8.2.3 Members: + inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; + inline _LIBCPP_INLINE_VISIBILITY string_type str() const; + inline _LIBCPP_INLINE_VISIBILITY void str(const string_type& __s); }; template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(ios_base::openmode __wch) : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) @@ -662,7 +668,6 @@ basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(ios_base:: } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(const string_type& __s, ios_base::openmode __wch) : basic_istream<_CharT, _Traits>(&__sb_), @@ -673,7 +678,6 @@ basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(const stri #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_istringstream<_CharT, _Traits, _Allocator>::basic_istringstream(basic_istringstream&& __rhs) : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -693,9 +697,7 @@ basic_istringstream<_CharT, _Traits, _Allocator>::operator=(basic_istringstream& #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_istringstream<_CharT, _Traits, _Allocator>::swap(basic_istringstream& __rhs) +void basic_istringstream<_CharT, _Traits, _Allocator>::swap(basic_istringstream& __rhs) { basic_istream<char_type, traits_type>::swap(__rhs); __sb_.swap(__rhs.__sb_); @@ -711,7 +713,6 @@ swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<_CharT, _Traits, _Allocator>* basic_istringstream<_CharT, _Traits, _Allocator>::rdbuf() const { @@ -719,7 +720,6 @@ basic_istringstream<_CharT, _Traits, _Allocator>::rdbuf() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_string<_CharT, _Traits, _Allocator> basic_istringstream<_CharT, _Traits, _Allocator>::str() const { @@ -727,9 +727,7 @@ basic_istringstream<_CharT, _Traits, _Allocator>::str() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_istringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s) +void basic_istringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s) { __sb_.str(__s); } @@ -755,25 +753,31 @@ private: public: // 27.8.2.1 Constructors: + inline _LIBCPP_INLINE_VISIBILITY explicit basic_ostringstream(ios_base::openmode __wch = ios_base::out); + inline _LIBCPP_INLINE_VISIBILITY explicit basic_ostringstream(const string_type& __s, ios_base::openmode __wch = ios_base::out); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY basic_ostringstream(basic_ostringstream&& __rhs); // 27.8.2.2 Assign and swap: basic_ostringstream& operator=(basic_ostringstream&& __rhs); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY void swap(basic_ostringstream& __rhs); // 27.8.2.3 Members: + inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; + inline _LIBCPP_INLINE_VISIBILITY string_type str() const; + inline _LIBCPP_INLINE_VISIBILITY void str(const string_type& __s); }; template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(ios_base::openmode __wch) : basic_ostream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::out) @@ -781,7 +785,6 @@ basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(ios_base:: } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(const string_type& __s, ios_base::openmode __wch) : basic_ostream<_CharT, _Traits>(&__sb_), @@ -792,7 +795,6 @@ basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(const stri #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_ostringstream<_CharT, _Traits, _Allocator>::basic_ostringstream(basic_ostringstream&& __rhs) : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -812,7 +814,6 @@ basic_ostringstream<_CharT, _Traits, _Allocator>::operator=(basic_ostringstream& #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY void basic_ostringstream<_CharT, _Traits, _Allocator>::swap(basic_ostringstream& __rhs) { @@ -830,7 +831,6 @@ swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<_CharT, _Traits, _Allocator>* basic_ostringstream<_CharT, _Traits, _Allocator>::rdbuf() const { @@ -838,7 +838,6 @@ basic_ostringstream<_CharT, _Traits, _Allocator>::rdbuf() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_string<_CharT, _Traits, _Allocator> basic_ostringstream<_CharT, _Traits, _Allocator>::str() const { @@ -846,7 +845,6 @@ basic_ostringstream<_CharT, _Traits, _Allocator>::str() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY void basic_ostringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s) { @@ -874,25 +872,31 @@ private: public: // 27.8.2.1 Constructors: + inline _LIBCPP_INLINE_VISIBILITY explicit basic_stringstream(ios_base::openmode __wch = ios_base::in | ios_base::out); + inline _LIBCPP_INLINE_VISIBILITY explicit basic_stringstream(const string_type& __s, ios_base::openmode __wch = ios_base::in | ios_base::out); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY basic_stringstream(basic_stringstream&& __rhs); // 27.8.2.2 Assign and swap: basic_stringstream& operator=(basic_stringstream&& __rhs); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + inline _LIBCPP_INLINE_VISIBILITY void swap(basic_stringstream& __rhs); // 27.8.2.3 Members: + inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; + inline _LIBCPP_INLINE_VISIBILITY string_type str() const; + inline _LIBCPP_INLINE_VISIBILITY void str(const string_type& __s); }; template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(ios_base::openmode __wch) : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) @@ -900,7 +904,6 @@ basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(ios_base::op } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(const string_type& __s, ios_base::openmode __wch) : basic_iostream<_CharT, _Traits>(&__sb_), @@ -911,7 +914,6 @@ basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(const string #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringstream<_CharT, _Traits, _Allocator>::basic_stringstream(basic_stringstream&& __rhs) : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -931,7 +933,6 @@ basic_stringstream<_CharT, _Traits, _Allocator>::operator=(basic_stringstream&& #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY void basic_stringstream<_CharT, _Traits, _Allocator>::swap(basic_stringstream& __rhs) { @@ -949,7 +950,6 @@ swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_stringbuf<_CharT, _Traits, _Allocator>* basic_stringstream<_CharT, _Traits, _Allocator>::rdbuf() const { @@ -957,7 +957,6 @@ basic_stringstream<_CharT, _Traits, _Allocator>::rdbuf() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY basic_string<_CharT, _Traits, _Allocator> basic_stringstream<_CharT, _Traits, _Allocator>::str() const { @@ -965,7 +964,6 @@ basic_stringstream<_CharT, _Traits, _Allocator>::str() const } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY void basic_stringstream<_CharT, _Traits, _Allocator>::str(const string_type& __s) { diff --git a/include/stack b/include/stack index 48b3b0d16ec2..ee3fac8c4548 100644 --- a/include/stack +++ b/include/stack @@ -55,7 +55,7 @@ public: void push(const value_type& x); void push(value_type&& x); - template <class... Args> void emplace(Args&&... args); + template <class... Args> reference emplace(Args&&... args); void pop(); void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>) @@ -199,8 +199,8 @@ public: #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args> _LIBCPP_INLINE_VISIBILITY - void emplace(_Args&&... __args) - {c.emplace_back(_VSTD::forward<_Args>(__args)...);} + reference emplace(_Args&&... __args) + { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} #endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY diff --git a/include/stdexcept b/include/stdexcept index 4218b1398d85..d501d0916085 100644 --- a/include/stdexcept +++ b/include/stdexcept @@ -45,22 +45,31 @@ public: #include <__config> #include <exception> #include <iosfwd> // for string forward decl +#ifdef _LIBCPP_NO_EXCEPTIONS +#include <cstdlib> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -#ifndef _LIBCPP___REFSTRING _LIBCPP_BEGIN_NAMESPACE_STD -class _LIBCPP_HIDDEN __libcpp_refstring { -#ifdef __clang__ - const char *__imp_ __attribute__((__unused__)); // only clang emits a warning -#else - const char *__imp_; -#endif + +class _LIBCPP_HIDDEN __libcpp_refstring +{ + const char* __imp_; + + bool __uses_refcount() const; +public: + explicit __libcpp_refstring(const char* msg); + __libcpp_refstring(const __libcpp_refstring& s) _NOEXCEPT; + __libcpp_refstring& operator=(const __libcpp_refstring& s) _NOEXCEPT; + ~__libcpp_refstring(); + + const char* c_str() const _NOEXCEPT {return __imp_;} }; + _LIBCPP_END_NAMESPACE_STD -#endif namespace std // purposefully not using versioning namespace { @@ -171,4 +180,99 @@ public: } // std +_LIBCPP_BEGIN_NAMESPACE_STD + +// in the dylib +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_logic_error(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw logic_error(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_domain_error(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw domain_error(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_invalid_argument(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw invalid_argument(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_length_error(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw length_error(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_out_of_range(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw out_of_range(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_range_error(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw range_error(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_overflow_error(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw overflow_error(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_underflow_error(const char*__msg) +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw underflow_error(__msg); +#else + ((void)__msg); + _VSTD::abort(); +#endif +} + +_LIBCPP_END_NAMESPACE_STD + #endif // _LIBCPP_STDEXCEPT diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 000000000000..468f6cd97c23 --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,121 @@ +// -*- C++ -*- +//===---------------------------- stdint.h --------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_STDINT_H +#define _LIBCPP_STDINT_H + +/* + stdint.h synopsis + +Macros: + + INT8_MIN + INT16_MIN + INT32_MIN + INT64_MIN + + INT8_MAX + INT16_MAX + INT32_MAX + INT64_MAX + + UINT8_MAX + UINT16_MAX + UINT32_MAX + UINT64_MAX + + INT_LEAST8_MIN + INT_LEAST16_MIN + INT_LEAST32_MIN + INT_LEAST64_MIN + + INT_LEAST8_MAX + INT_LEAST16_MAX + INT_LEAST32_MAX + INT_LEAST64_MAX + + UINT_LEAST8_MAX + UINT_LEAST16_MAX + UINT_LEAST32_MAX + UINT_LEAST64_MAX + + INT_FAST8_MIN + INT_FAST16_MIN + INT_FAST32_MIN + INT_FAST64_MIN + + INT_FAST8_MAX + INT_FAST16_MAX + INT_FAST32_MAX + INT_FAST64_MAX + + UINT_FAST8_MAX + UINT_FAST16_MAX + UINT_FAST32_MAX + UINT_FAST64_MAX + + INTPTR_MIN + INTPTR_MAX + UINTPTR_MAX + + INTMAX_MIN + INTMAX_MAX + + UINTMAX_MAX + + PTRDIFF_MIN + PTRDIFF_MAX + + SIG_ATOMIC_MIN + SIG_ATOMIC_MAX + + SIZE_MAX + + WCHAR_MIN + WCHAR_MAX + + WINT_MIN + WINT_MAX + + INT8_C(value) + INT16_C(value) + INT32_C(value) + INT64_C(value) + + UINT8_C(value) + UINT16_C(value) + UINT32_C(value) + UINT64_C(value) + + INTMAX_C(value) + UINTMAX_C(value) + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +/* C99 stdlib (e.g. glibc < 2.18) does not provide macros needed + for C++11 unless __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS + are defined +*/ +#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS +#endif +#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS +#endif + +#include_next <stdint.h> + +#endif // _LIBCPP_STDINT_H diff --git a/include/streambuf b/include/streambuf index 7544aaf179bd..6c478384d769 100644 --- a/include/streambuf +++ b/include/streambuf @@ -132,32 +132,96 @@ public: virtual ~basic_streambuf(); // 27.6.2.2.1 locales: - locale pubimbue(const locale& __loc); - locale getloc() const; + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + locale pubimbue(const locale& __loc) { + imbue(__loc); + locale __r = __loc_; + __loc_ = __loc; + return __r; + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + locale getloc() const { return __loc_; } // 27.6.2.2.2 buffer and positioning: - basic_streambuf* pubsetbuf(char_type* __s, streamsize __n); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + basic_streambuf* pubsetbuf(char_type* __s, streamsize __n) + { return setbuf(__s, __n); } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY pos_type pubseekoff(off_type __off, ios_base::seekdir __way, - ios_base::openmode __which = ios_base::in | ios_base::out); + ios_base::openmode __which = ios_base::in | ios_base::out) + { return seekoff(__off, __way, __which); } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY pos_type pubseekpos(pos_type __sp, - ios_base::openmode __which = ios_base::in | ios_base::out); - int pubsync(); + ios_base::openmode __which = ios_base::in | ios_base::out) + { return seekpos(__sp, __which); } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int pubsync() { return sync(); } // Get and put areas: // 27.6.2.2.3 Get area: - streamsize in_avail(); - int_type snextc(); - int_type sbumpc(); - int_type sgetc(); - streamsize sgetn(char_type* __s, streamsize __n); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + streamsize in_avail() { + if (__ninp_ < __einp_) + return static_cast<streamsize>(__einp_ - __ninp_); + return showmanyc(); + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int_type snextc() { + if (sbumpc() == traits_type::eof()) + return traits_type::eof(); + return sgetc(); + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int_type sbumpc() { + if (__ninp_ == __einp_) + return uflow(); + return traits_type::to_int_type(*__ninp_++); + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int_type sgetc() { + if (__ninp_ == __einp_) + return underflow(); + return traits_type::to_int_type(*__ninp_); + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + streamsize sgetn(char_type* __s, streamsize __n) + { return xsgetn(__s, __n); } // 27.6.2.2.4 Putback: - int_type sputbackc(char_type __c); - int_type sungetc(); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int_type sputbackc(char_type __c) { + if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1])) + return pbackfail(traits_type::to_int_type(__c)); + return traits_type::to_int_type(*--__ninp_); + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int_type sungetc() { + if (__binp_ == __ninp_) + return pbackfail(); + return traits_type::to_int_type(*--__ninp_); + } // 27.6.2.2.5 Put area: - int_type sputc(char_type __c); - streamsize sputn(const char_type* __s, streamsize __n); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + int_type sputc(char_type __c) { + if (__nout_ == __eout_) + return overflow(traits_type::to_int_type(__c)); + *__nout_++ = __c; + return traits_type::to_int_type(__c); + } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + streamsize sputn(const char_type* __s, streamsize __n) + { return xsputn(__s, __n); } protected: basic_streambuf(); @@ -169,15 +233,30 @@ protected: _LIBCPP_ALWAYS_INLINE char_type* eback() const {return __binp_;} _LIBCPP_ALWAYS_INLINE char_type* gptr() const {return __ninp_;} _LIBCPP_ALWAYS_INLINE char_type* egptr() const {return __einp_;} - void gbump(int __n); - void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend); + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void gbump(int __n) { __ninp_ += __n; } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void setg(char_type* __gbeg, char_type* __gnext, char_type* __gend) { + __binp_ = __gbeg; + __ninp_ = __gnext; + __einp_ = __gend; + } // 27.6.2.3.3 Put area: _LIBCPP_ALWAYS_INLINE char_type* pbase() const {return __bout_;} _LIBCPP_ALWAYS_INLINE char_type* pptr() const {return __nout_;} _LIBCPP_ALWAYS_INLINE char_type* epptr() const {return __eout_;} - void pbump(int __n); - void setp(char_type* __pbeg, char_type* __pend); + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void pbump(int __n) { __nout_ += __n; } + + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + void setp(char_type* __pbeg, char_type* __pend) { + __bout_ = __nout_ = __pbeg; + __eout_ = __pend; + } // 27.6.2.4 virtual functions: // 27.6.2.4.1 Locales: @@ -220,147 +299,6 @@ basic_streambuf<_CharT, _Traits>::~basic_streambuf() } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -locale -basic_streambuf<_CharT, _Traits>::pubimbue(const locale& __loc) -{ - imbue(__loc); - locale __r = __loc_; - __loc_ = __loc; - return __r; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -locale -basic_streambuf<_CharT, _Traits>::getloc() const -{ - return __loc_; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -basic_streambuf<_CharT, _Traits>* -basic_streambuf<_CharT, _Traits>::pubsetbuf(char_type* __s, streamsize __n) -{ - return setbuf(__s, __n); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::pos_type -basic_streambuf<_CharT, _Traits>::pubseekoff(off_type __off, - ios_base::seekdir __way, - ios_base::openmode __which) -{ - return seekoff(__off, __way, __which); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::pos_type -basic_streambuf<_CharT, _Traits>::pubseekpos(pos_type __sp, - ios_base::openmode __which) -{ - return seekpos(__sp, __which); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -int -basic_streambuf<_CharT, _Traits>::pubsync() -{ - return sync(); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -streamsize -basic_streambuf<_CharT, _Traits>::in_avail() -{ - if (__ninp_ < __einp_) - return static_cast<streamsize>(__einp_ - __ninp_); - return showmanyc(); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::int_type -basic_streambuf<_CharT, _Traits>::snextc() -{ - if (sbumpc() == traits_type::eof()) - return traits_type::eof(); - return sgetc(); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::int_type -basic_streambuf<_CharT, _Traits>::sbumpc() -{ - if (__ninp_ == __einp_) - return uflow(); - return traits_type::to_int_type(*__ninp_++); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::int_type -basic_streambuf<_CharT, _Traits>::sgetc() -{ - if (__ninp_ == __einp_) - return underflow(); - return traits_type::to_int_type(*__ninp_); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -streamsize -basic_streambuf<_CharT, _Traits>::sgetn(char_type* __s, streamsize __n) -{ - return xsgetn(__s, __n); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::int_type -basic_streambuf<_CharT, _Traits>::sputbackc(char_type __c) -{ - if (__binp_ == __ninp_ || !traits_type::eq(__c, __ninp_[-1])) - return pbackfail(traits_type::to_int_type(__c)); - return traits_type::to_int_type(*--__ninp_); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::int_type -basic_streambuf<_CharT, _Traits>::sungetc() -{ - if (__binp_ == __ninp_) - return pbackfail(); - return traits_type::to_int_type(*--__ninp_); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -typename basic_streambuf<_CharT, _Traits>::int_type -basic_streambuf<_CharT, _Traits>::sputc(char_type __c) -{ - if (__nout_ == __eout_) - return overflow(traits_type::to_int_type(__c)); - *__nout_++ = __c; - return traits_type::to_int_type(__c); -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -streamsize -basic_streambuf<_CharT, _Traits>::sputn(const char_type* __s, streamsize __n) -{ - return xsputn(__s, __n); -} - -template <class _CharT, class _Traits> basic_streambuf<_CharT, _Traits>::basic_streambuf() : __binp_(0), __ninp_(0), @@ -411,42 +349,6 @@ basic_streambuf<_CharT, _Traits>::swap(basic_streambuf& __sb) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::gbump(int __n) -{ - __ninp_ += __n; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::setg(char_type* __gbeg, char_type* __gnext, - char_type* __gend) -{ - __binp_ = __gbeg; - __ninp_ = __gnext; - __einp_ = __gend; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::pbump(int __n) -{ - __nout_ += __n; -} - -template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY -void -basic_streambuf<_CharT, _Traits>::setp(char_type* __pbeg, char_type* __pend) -{ - __bout_ = __nout_ = __pbeg; - __eout_ = __pend; -} - -template <class _CharT, class _Traits> void basic_streambuf<_CharT, _Traits>::imbue(const locale&) { @@ -574,11 +476,11 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type) return traits_type::eof(); } -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_streambuf<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_ios<wchar_t>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>) _LIBCPP_END_NAMESPACE_STD diff --git a/include/string b/include/string index 786735f970f8..98f538c38a0e 100644 --- a/include/string +++ b/include/string @@ -101,7 +101,10 @@ public: basic_string(const basic_string& str, size_type pos, const allocator_type& a = allocator_type()); basic_string(const basic_string& str, size_type pos, size_type n, - const Allocator& a = Allocator()); + const Allocator& a = Allocator()); + template<class T> + basic_string(const T& t, size_type pos, size_type n, const Allocator& a = Allocator()); // C++17 + explicit basic_string(const basic_string_view<charT, traits> sv, const Allocator& a = Allocator()); basic_string(const value_type* s, const allocator_type& a = allocator_type()); basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); @@ -114,7 +117,10 @@ public: ~basic_string(); + operator basic_string_view<charT, traits>() const noexcept; + basic_string& operator=(const basic_string& str); + basic_string& operator=(basic_string_view<charT, traits> sv); basic_string& operator=(basic_string&& str) noexcept( allocator_type::propagate_on_container_move_assignment::value || @@ -158,12 +164,16 @@ public: reference at(size_type n); basic_string& operator+=(const basic_string& str); + basic_string& operator+=(basic_string_view<charT, traits> sv); basic_string& operator+=(const value_type* s); basic_string& operator+=(value_type c); basic_string& operator+=(initializer_list<value_type>); basic_string& append(const basic_string& str); + basic_string& append(basic_string_view<charT, traits> sv); basic_string& append(const basic_string& str, size_type pos, size_type n=npos); //C++14 + template <class T> + basic_string& append(const T& t, size_type pos, size_type n=npos); // C++17 basic_string& append(const value_type* s, size_type n); basic_string& append(const value_type* s); basic_string& append(size_type n, value_type c); @@ -179,8 +189,11 @@ public: const_reference back() const; basic_string& assign(const basic_string& str); + basic_string& assign(basic_string_view<charT, traits> sv); basic_string& assign(basic_string&& str); basic_string& assign(const basic_string& str, size_type pos, size_type n=npos); // C++14 + template <class T> + basic_string& assign(const T& t, size_type pos, size_type n=npos); // C++17 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); @@ -189,8 +202,11 @@ public: basic_string& assign(initializer_list<value_type>); basic_string& insert(size_type pos1, const basic_string& str); + basic_string& insert(size_type pos1, basic_string_view<charT, traits> sv); basic_string& insert(size_type pos1, const basic_string& str, size_type pos2, size_type n); + template <class T> + basic_string& insert(size_type pos1, const T& t, size_type pos2, size_type n); // C++17 basic_string& insert(size_type pos, const value_type* s, size_type n=npos); //C++14 basic_string& insert(size_type pos, const value_type* s); basic_string& insert(size_type pos, size_type n, value_type c); @@ -205,12 +221,17 @@ public: iterator erase(const_iterator first, const_iterator last); basic_string& replace(size_type pos1, size_type n1, const basic_string& str); + basic_string& replace(size_type pos1, size_type n1, basic_string_view<charT, traits> sv); basic_string& replace(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos); // C++14 + template <class T> + basic_string& replace(size_type pos1, size_type n1, const T& t, + size_type pos2, size_type n); // C++17 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); basic_string& replace(size_type pos, size_type n1, size_type n2, value_type c); basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str); + basic_string& replace(const_iterator i1, const_iterator i2, basic_string_view<charT, traits> sv); basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s, size_type n); basic_string& replace(const_iterator i1, const_iterator i2, const value_type* s); basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); @@ -232,39 +253,50 @@ public: allocator_type get_allocator() const noexcept; size_type find(const basic_string& str, size_type pos = 0) const noexcept; + size_type find(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find(const value_type* s, size_type pos, size_type n) const noexcept; size_type find(const value_type* s, size_type pos = 0) const noexcept; size_type find(value_type c, size_type pos = 0) const noexcept; size_type rfind(const basic_string& str, size_type pos = npos) const noexcept; + size_type ffind(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type rfind(const value_type* s, size_type pos, size_type n) const noexcept; size_type rfind(const value_type* s, size_type pos = npos) const noexcept; size_type rfind(value_type c, size_type pos = npos) const noexcept; size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_first_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_last_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_of(value_type c, size_type pos = npos) const noexcept; size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_first_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_first_not_of(const value_type* s, size_type pos = 0) const noexcept; size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept; size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept; + size_type find_last_not_of(basic_string_view<charT, traits> sv, size_type pos = 0) const noexcept; size_type find_last_not_of(const value_type* s, size_type pos, size_type n) const noexcept; size_type find_last_not_of(const value_type* s, size_type pos = npos) const noexcept; size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept; int compare(const basic_string& str) const noexcept; + int compare(basic_string_view<charT, traits> sv) const noexcept; int compare(size_type pos1, size_type n1, const basic_string& str) const; + int compare(size_type pos1, size_type n1, basic_string_view<charT, traits> sv) const; int compare(size_type pos1, size_type n1, const basic_string& str, size_type pos2, size_type n2=npos) const; // C++14 + template <class T> + int compare(size_type pos1, size_type n1, const T& t, + size_type pos2, size_type n2=npos) const; // C++17 int compare(const value_type* s) const noexcept; int compare(size_type pos1, size_type n1, const value_type* s) const; int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const; @@ -435,6 +467,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 */ #include <__config> +#include <string_view> #include <iosfwd> #include <cstring> #include <cstdio> // For EOF. @@ -450,9 +483,6 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++1 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS #include <cstdint> #endif -#if defined(_LIBCPP_NO_EXCEPTIONS) -#include <cassert> -#endif #include <__undef_min_max> @@ -501,647 +531,6 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) {return streamoff(__x) != streamoff(__y);} -// char_traits - -template <class _CharT> -struct _LIBCPP_TYPE_VIS_ONLY char_traits -{ - typedef _CharT char_type; - typedef int int_type; - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - static int compare(const char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static size_t length(const char_type* __s); - _LIBCPP_INLINE_VISIBILITY - static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(EOF);} -}; - -template <class _CharT> -int -char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) -{ - for (; __n; --__n, ++__s1, ++__s2) - { - if (lt(*__s1, *__s2)) - return -1; - if (lt(*__s2, *__s1)) - return 1; - } - return 0; -} - -template <class _CharT> -inline -size_t -char_traits<_CharT>::length(const char_type* __s) -{ - size_t __len = 0; - for (; !eq(*__s, char_type(0)); ++__s) - ++__len; - return __len; -} - -template <class _CharT> -inline -const _CharT* -char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) -{ - for (; __n; --__n) - { - if (eq(*__s, __a)) - return __s; - ++__s; - } - return 0; -} - -template <class _CharT> -_CharT* -char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) -{ - char_type* __r = __s1; - if (__s1 < __s2) - { - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - } - else if (__s2 < __s1) - { - __s1 += __n; - __s2 += __n; - for (; __n; --__n) - assign(*--__s1, *--__s2); - } - return __r; -} - -template <class _CharT> -inline -_CharT* -char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) -{ - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - char_type* __r = __s1; - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - return __r; -} - -template <class _CharT> -inline -_CharT* -char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) -{ - char_type* __r = __s; - for (; __n; --__n, ++__s) - assign(*__s, __a); - return __r; -} - -// char_traits<char> - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<char> -{ - typedef char char_type; - typedef int int_type; - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return (unsigned char)__c1 < (unsigned char)__c2;} - - static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? 0 : memcmp(__s1, __s2, __n);} - static inline size_t length(const char_type* __s) {return strlen(__s);} - static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) - {return __n == 0 ? NULL : (const char_type*) memchr(__s, to_int_type(__a), __n);} - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) - { - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n); - } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) - {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);} - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type((unsigned char)__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(EOF);} -}; - -// char_traits<wchar_t> - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<wchar_t> -{ - typedef wchar_t char_type; - typedef wint_t int_type; - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - static inline int compare(const char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? 0 : wmemcmp(__s1, __s2, __n);} - static inline size_t length(const char_type* __s) - {return wcslen(__s);} - static inline const char_type* find(const char_type* __s, size_t __n, const char_type& __a) - {return __n == 0 ? NULL : (const char_type*)wmemchr(__s, __a, __n);} - static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) - {return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);} - static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) - { - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n); - } - static inline char_type* assign(char_type* __s, size_t __n, char_type __a) - {return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);} - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(WEOF);} -}; - -#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<char16_t> -{ - typedef char16_t char_type; - typedef uint_least16_t int_type; - typedef streamoff off_type; - typedef u16streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - _LIBCPP_INLINE_VISIBILITY - static int compare(const char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static size_t length(const char_type* __s); - _LIBCPP_INLINE_VISIBILITY - static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - _LIBCPP_INLINE_VISIBILITY - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(0xFFFF);} -}; - -inline -int -char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) -{ - for (; __n; --__n, ++__s1, ++__s2) - { - if (lt(*__s1, *__s2)) - return -1; - if (lt(*__s2, *__s1)) - return 1; - } - return 0; -} - -inline -size_t -char_traits<char16_t>::length(const char_type* __s) -{ - size_t __len = 0; - for (; !eq(*__s, char_type(0)); ++__s) - ++__len; - return __len; -} - -inline -const char16_t* -char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) -{ - for (; __n; --__n) - { - if (eq(*__s, __a)) - return __s; - ++__s; - } - return 0; -} - -inline -char16_t* -char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) -{ - char_type* __r = __s1; - if (__s1 < __s2) - { - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - } - else if (__s2 < __s1) - { - __s1 += __n; - __s2 += __n; - for (; __n; --__n) - assign(*--__s1, *--__s2); - } - return __r; -} - -inline -char16_t* -char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) -{ - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - char_type* __r = __s1; - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - return __r; -} - -inline -char16_t* -char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) -{ - char_type* __r = __s; - for (; __n; --__n, ++__s) - assign(*__s, __a); - return __r; -} - -template <> -struct _LIBCPP_TYPE_VIS_ONLY char_traits<char32_t> -{ - typedef char32_t char_type; - typedef uint_least32_t int_type; - typedef streamoff off_type; - typedef u32streampos pos_type; - typedef mbstate_t state_type; - - static inline void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT - {__c1 = __c2;} - static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT - {return __c1 < __c2;} - - _LIBCPP_INLINE_VISIBILITY - static int compare(const char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static size_t length(const char_type* __s); - _LIBCPP_INLINE_VISIBILITY - static const char_type* find(const char_type* __s, size_t __n, const char_type& __a); - _LIBCPP_INLINE_VISIBILITY - static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); - _LIBCPP_INLINE_VISIBILITY - static char_type* assign(char_type* __s, size_t __n, char_type __a); - - static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT - {return eq_int_type(__c, eof()) ? ~eof() : __c;} - static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT - {return char_type(__c);} - static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT - {return int_type(__c);} - static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT - {return __c1 == __c2;} - static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT - {return int_type(0xFFFFFFFF);} -}; - -inline -int -char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) -{ - for (; __n; --__n, ++__s1, ++__s2) - { - if (lt(*__s1, *__s2)) - return -1; - if (lt(*__s2, *__s1)) - return 1; - } - return 0; -} - -inline -size_t -char_traits<char32_t>::length(const char_type* __s) -{ - size_t __len = 0; - for (; !eq(*__s, char_type(0)); ++__s) - ++__len; - return __len; -} - -inline -const char32_t* -char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) -{ - for (; __n; --__n) - { - if (eq(*__s, __a)) - return __s; - ++__s; - } - return 0; -} - -inline -char32_t* -char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) -{ - char_type* __r = __s1; - if (__s1 < __s2) - { - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - } - else if (__s2 < __s1) - { - __s1 += __n; - __s2 += __n; - for (; __n; --__n) - assign(*--__s1, *--__s2); - } - return __r; -} - -inline -char32_t* -char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) -{ - _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); - char_type* __r = __s1; - for (; __n; --__n, ++__s1, ++__s2) - assign(*__s1, *__s2); - return __r; -} - -inline -char32_t* -char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) -{ - char_type* __r = __s; - for (; __n; --__n, ++__s) - assign(*__s, __a); - return __r; -} - -#endif // _LIBCPP_HAS_NO_UNICODE_CHARS - -// helper fns for basic_string - -// __str_find -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__pos >= __sz) - return __npos; - const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c); - if (__r == 0) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos > __sz || __sz - __pos < __n) - return __npos; - if (__n == 0) - return __pos; - const _CharT* __r = - _VSTD::__search(__p + __pos, __p + __sz, - __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()).first; - if (__r == __p + __sz) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - - -// __str_rfind - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_rfind(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__sz < 1) - return __npos; - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - { - if (_Traits::eq(*--__ps, __c)) - return static_cast<_SizeT>(__ps - __p); - } - return __npos; -} - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_rfind(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - __pos = _VSTD::min(__pos, __sz); - if (__n < __sz - __pos) - __pos += __n; - else - __pos = __sz; - const _CharT* __r = _VSTD::__find_end( - __p, __p + __pos, __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()); - if (__n > 0 && __r == __p + __pos) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - -// __str_find_first_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_first_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos >= __sz || __n == 0) - return __npos; - const _CharT* __r = _VSTD::__find_first_of_ce - (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq ); - if (__r == __p + __sz) - return __npos; - return static_cast<_SizeT>(__r - __p); -} - - -// __str_find_last_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_last_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT - { - if (__n != 0) - { - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - { - const _CharT* __r = _Traits::find(__s, __n, *--__ps); - if (__r) - return static_cast<_SizeT>(__ps - __p); - } - } - return __npos; -} - - -// __str_find_first_not_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_first_not_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos < __sz) - { - const _CharT* __pe = __p + __sz; - for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) - if (_Traits::find(__s, __n, *__ps) == 0) - return static_cast<_SizeT>(__ps - __p); - } - return __npos; -} - - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_first_not_of(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__pos < __sz) - { - const _CharT* __pe = __p + __sz; - for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps) - if (!_Traits::eq(*__ps, __c)) - return static_cast<_SizeT>(__ps - __p); - } - return __npos; -} - - -// __str_find_last_not_of -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_last_not_of(const _CharT *__p, _SizeT __sz, - const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT -{ - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - if (_Traits::find(__s, __n, *--__ps) == 0) - return static_cast<_SizeT>(__ps - __p); - return __npos; -} - - -template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY -__str_find_last_not_of(const _CharT *__p, _SizeT __sz, - _CharT __c, _SizeT __pos) _NOEXCEPT -{ - if (__pos < __sz) - ++__pos; - else - __pos = __sz; - for (const _CharT* __ps = __p + __pos; __ps != __p;) - if (!_Traits::eq(*--__ps, __c)) - return static_cast<_SizeT>(__ps - __p); - return __npos; -} - -template<class _Ptr> -size_t _LIBCPP_INLINE_VISIBILITY __do_string_hash(_Ptr __p, _Ptr __e) -{ - typedef typename iterator_traits<_Ptr>::value_type value_type; - return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type)); -} - // basic_string template<class _CharT, class _Traits, class _Allocator> @@ -1169,37 +558,29 @@ template <bool> class _LIBCPP_TYPE_VIS_ONLY __basic_string_common { protected: - void __throw_length_error() const; - void __throw_out_of_range() const; + _LIBCPP_NORETURN void __throw_length_error() const; + _LIBCPP_NORETURN void __throw_out_of_range() const; }; template <bool __b> void __basic_string_common<__b>::__throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw length_error("basic_string"); -#else - assert(!"basic_string length_error"); -#endif + _VSTD::__throw_length_error("basic_string"); } template <bool __b> void __basic_string_common<__b>::__throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("basic_string"); -#else - assert(!"basic_string out_of_range"); -#endif + _VSTD::__throw_out_of_range("basic_string"); } #ifdef _LIBCPP_MSVC #pragma warning( push ) #pragma warning( disable: 4231 ) #endif // _LIBCPP_MSVC -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __basic_string_common<true>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __basic_string_common<true>) #ifdef _LIBCPP_MSVC #pragma warning( pop ) #endif // _LIBCPP_MSVC @@ -1228,6 +609,11 @@ template <class _Iter> 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)) {}; + #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT template <class _CharT, size_t = sizeof(_CharT)> @@ -1249,6 +635,7 @@ class _LIBCPP_TYPE_VIS_ONLY basic_string { public: typedef basic_string __self; + typedef basic_string_view<_CharT, _Traits> __self_view; typedef _Traits traits_type; typedef typename traits_type::char_type value_type; typedef _Allocator allocator_type; @@ -1404,6 +791,14 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string(const basic_string& __str, size_type __pos, const allocator_type& __a = allocator_type()); + template<class _Tp> + basic_string(const _Tp& __t, size_type __pos, size_type __n, + const allocator_type& __a = allocator_type(), + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0); + _LIBCPP_INLINE_VISIBILITY explicit + basic_string(__self_view __sv); + _LIBCPP_INLINE_VISIBILITY + basic_string(__self_view __sv, const allocator_type& __a); template<class _InputIterator> _LIBCPP_INLINE_VISIBILITY basic_string(_InputIterator __first, _InputIterator __last); @@ -1417,9 +812,14 @@ public: basic_string(initializer_list<value_type> __il, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS - ~basic_string(); + inline ~basic_string(); + + _LIBCPP_INLINE_VISIBILITY + operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } basic_string& operator=(const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& operator=(__self_view __sv) {return assign(__sv);} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY basic_string& operator=(basic_string&& __str) @@ -1503,14 +903,15 @@ public: void clear() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return size() == 0;} - _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const; - _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos); + _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __pos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __pos) _NOEXCEPT; const_reference at(size_type __n) const; reference at(size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const basic_string& __str) {return append(__str);} - _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(const value_type* __s) {return append(__s);} + _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(__self_view __sv) {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;} #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY basic_string& operator+=(initializer_list<value_type> __il) {return append(__il);} @@ -1518,10 +919,21 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& append(const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& append(__self_view __sv) { return append(__sv.data(), __sv.size()); } basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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); basic_string& append(size_type __n, value_type __c); + template <class _ForwardIterator> + inline basic_string& __append_forward_unsafe(_ForwardIterator, _ForwardIterator); template<class _InputIterator> typename enable_if < @@ -1529,7 +941,12 @@ public: || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, basic_string& >::type - append(_InputIterator __first, _InputIterator __last); + _LIBCPP_INLINE_VISIBILITY + append(_InputIterator __first, _InputIterator __last) { + const basic_string __temp (__first, __last, __alloc()); + append(__temp.data(), __temp.size()); + return *this; + } template<class _ForwardIterator> typename enable_if < @@ -1537,7 +954,11 @@ public: && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, basic_string& >::type - append(_ForwardIterator __first, _ForwardIterator __last); + _LIBCPP_INLINE_VISIBILITY + append(_ForwardIterator __first, _ForwardIterator __last) { + return __append_forward_unsafe(__first, __last); + } + #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());} @@ -1552,6 +973,8 @@ public: _LIBCPP_INLINE_VISIBILITY const_reference back() const; _LIBCPP_INLINE_VISIBILITY + basic_string& assign(__self_view __sv) { return assign(__sv.data(), __sv.size()); } + _LIBCPP_INLINE_VISIBILITY basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -1560,6 +983,13 @@ public: {*this = _VSTD::move(str); return *this;} #endif basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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); @@ -1586,6 +1016,15 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& insert(size_type __pos1, const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& insert(size_type __pos1, __self_view __sv) { return insert(__pos1, __sv.data(), __sv.size()); } + template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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); basic_string& insert(size_type __pos, const value_type* __s); @@ -1623,13 +1062,24 @@ public: _LIBCPP_INLINE_VISIBILITY basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str); + _LIBCPP_INLINE_VISIBILITY + basic_string& replace(size_type __pos1, size_type __n1, __self_view __sv) { 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> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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); basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const basic_string& __str); _LIBCPP_INLINE_VISIBILITY + basic_string& replace(const_iterator __i1, const_iterator __i2, __self_view __sv) { return replace(__i1 - begin(), __i2 - __i1, __sv); } + _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n); _LIBCPP_INLINE_VISIBILITY basic_string& replace(const_iterator __i1, const_iterator __i2, const value_type* __s); @@ -1655,9 +1105,9 @@ public: _LIBCPP_INLINE_VISIBILITY void swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; + _NOEXCEPT_DEBUG; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif @@ -1675,6 +1125,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1682,6 +1134,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type rfind(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type rfind(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1689,6 +1143,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_first_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1697,6 +1153,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_last_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1705,6 +1163,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_first_not_of(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; @@ -1713,6 +1173,8 @@ public: _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(__self_view __sv, size_type __pos = 0) const _NOEXCEPT; size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type find_last_not_of(const value_type* __s, size_type __pos = npos) const _NOEXCEPT; @@ -1722,8 +1184,20 @@ public: _LIBCPP_INLINE_VISIBILITY int compare(const basic_string& __str) const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY + int compare(__self_view __sv) const _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, __self_view __sv) const; + _LIBCPP_INLINE_VISIBILITY int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos) const; + template <class _Tp> + inline _LIBCPP_INLINE_VISIBILITY + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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; int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; @@ -1847,11 +1321,15 @@ private: __align_it<sizeof(value_type) < __alignment ? __alignment/sizeof(value_type) : 1 > (__s+1)) - 1;} + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void __init(const value_type* __s, size_type __sz, size_type __reserve); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void __init(const value_type* __s, size_type __sz); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY void __init(size_type __n, value_type __c); template <class _InputIterator> + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_exactly_input_iterator<_InputIterator>::value, @@ -1860,6 +1338,7 @@ private: __init(_InputIterator __first, _InputIterator __last); template <class _ForwardIterator> + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY typename enable_if < __is_forward_iterator<_ForwardIterator>::value, @@ -2008,8 +1487,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const allocator_type& __ } template <class _CharT, class _Traits, class _Allocator> -void -basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz, size_type __reserve) +void basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, + size_type __sz, + size_type __reserve) { if (__reserve > max_size()) this->__throw_length_error(); @@ -2243,6 +1723,41 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +basic_string<_CharT, _Traits, _Allocator>::basic_string( + const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a, + typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type *) + : __r_(__a) +{ + __self_view __sv = __self_view(__t).substr(__pos, __n); + __init(__sv.data(), __sv.size()); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv) +{ + __init(__sv.data(), __sv.size()); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const allocator_type& __a) + : __r_(__a) +{ + __init(__sv.data(), __sv.size()); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> typename enable_if < @@ -2550,7 +2065,7 @@ typename enable_if >::type basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) { - basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc()); assign(__temp.data(), __temp.size()); return *this; } @@ -2593,6 +2108,23 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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; + size_type __sz = __sv.size(); + if (__pos > __sz) + this->__throw_out_of_range(); + return assign(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); +} + + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) { @@ -2681,43 +2213,46 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) traits_type::assign(*++__p, value_type()); } -template <class _CharT, class _Traits, class _Allocator> -template<class _InputIterator> -typename enable_if -< - __is_exactly_input_iterator<_InputIterator>::value - || !__libcpp_string_gets_noexcept_iterator<_InputIterator>::value, - basic_string<_CharT, _Traits, _Allocator>& ->::type -basic_string<_CharT, _Traits, _Allocator>::append(_InputIterator __first, _InputIterator __last) +template <class _Tp> +bool __ptr_in_range (const _Tp* __p, const _Tp* __first, const _Tp* __last) { - basic_string __temp (__first, __last, __alloc()); - append(__temp.data(), __temp.size()); - return *this; + return __first <= __p && __p < __last; +} + +template <class _Tp1, class _Tp2> +bool __ptr_in_range (const _Tp1*, const _Tp2*, const _Tp2*) +{ + return false; } template <class _CharT, class _Traits, class _Allocator> template<class _ForwardIterator> -typename enable_if -< - __is_forward_iterator<_ForwardIterator>::value - && __libcpp_string_gets_noexcept_iterator<_ForwardIterator>::value, - basic_string<_CharT, _Traits, _Allocator>& ->::type -basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) +basic_string<_CharT, _Traits, _Allocator>& +basic_string<_CharT, _Traits, _Allocator>::__append_forward_unsafe( + _ForwardIterator __first, _ForwardIterator __last) { + static_assert(__is_forward_iterator<_ForwardIterator>::value, + "function requires a ForwardIterator"); size_type __sz = size(); size_type __cap = capacity(); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) { - if (__cap - __sz < __n) - __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); - pointer __p = __get_pointer() + __sz; - for (; __first != __last; ++__p, ++__first) - traits_type::assign(*__p, *__first); - traits_type::assign(*__p, value_type()); - __set_size(__sz + __n); + if ( __ptr_in_range(&*__first, data(), data() + size())) + { + const basic_string __temp (__first, __last, __alloc()); + append(__temp.data(), __temp.size()); + } + else + { + if (__cap - __sz < __n) + __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); + pointer __p = __get_pointer() + __sz; + for (; __first != __last; ++__p, ++__first) + traits_type::assign(*__p, *__first); + traits_type::assign(*__p, value_type()); + __set_size(__sz + __n); + } } return *this; } @@ -2741,6 +2276,22 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> + typename enable_if + < + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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; + size_type __sz = __sv.size(); + if (__pos > __sz) + this->__throw_out_of_range(); + return append(__sv.data() + __pos, _VSTD::min(__n, __sz - __pos)); +} + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) { @@ -2828,7 +2379,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIt "string::insert(iterator, range) called with an iterator not" " referring to this string"); #endif - basic_string __temp(__first, __last, __alloc()); + const basic_string __temp(__first, __last, __alloc()); return insert(__pos, __temp.data(), __temp.data() + __temp.size()); } @@ -2848,11 +2399,17 @@ basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _Forward " referring to this string"); #endif size_type __ip = static_cast<size_type>(__pos - begin()); - size_type __sz = size(); - size_type __cap = capacity(); size_type __n = static_cast<size_type>(_VSTD::distance(__first, __last)); if (__n) { + if ( __ptr_in_range(&*__first, data(), data() + size())) + { + const basic_string __temp(__first, __last, __alloc()); + return insert(__pos, __temp.data(), __temp.data() + __temp.size()); + } + + size_type __sz = size(); + size_type __cap = capacity(); value_type* __p; if (__cap - __sz >= __n) { @@ -2895,6 +2452,23 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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) +{ + __self_view __sv = __t; + size_type __str_sz = __sv.size(); + if (__pos2 > __str_sz) + this->__throw_out_of_range(); + return insert(__pos1, __sv.data() + __pos2, _VSTD::min(__n, __str_sz - __pos2)); +} + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) { @@ -3040,7 +2614,7 @@ typename enable_if basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) { - basic_string __temp(__j1, __j2, __alloc()); + const basic_string __temp(__j1, __j2, __alloc()); return this->replace(__i1, __i2, __temp); } @@ -3064,6 +2638,23 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::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) +{ + __self_view __sv = __t; + size_type __str_sz = __sv.size(); + if (__pos2 > __str_sz) + this->__throw_out_of_range(); + return replace(__pos1, __n1, __sv.data() + __pos2, _VSTD::min(__n2, __str_sz - __pos2)); +} + +template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) { @@ -3311,7 +2902,7 @@ basic_string<_CharT, _Traits, _Allocator>::reserve(size_type __res_arg) template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::const_reference -basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const +basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); return *(data() + __pos); @@ -3320,7 +2911,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::reference -basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) +basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT { _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); return *(__get_pointer() + __pos); @@ -3405,9 +2996,9 @@ inline _LIBCPP_INLINE_VISIBILITY void basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT_DEBUG #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -3418,6 +3009,10 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) __get_db()->__invalidate_all(&__str); __get_db()->swap(this, &__str); #endif + _LIBCPP_ASSERT( + __alloc_traits::propagate_on_container_swap::value || + __alloc_traits::is_always_equal::value || + __alloc() == __str.__alloc(), "swapping non-equal allocators"); _VSTD::swap(__r_.first(), __str.__r_.first()); __swap_allocator(__alloc(), __str.__alloc()); } @@ -3440,7 +3035,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3450,18 +3045,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3470,7 +3075,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find<value_type, size_type, traits_type, npos> + return __str_find<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3483,7 +3088,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3493,18 +3098,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::rfind(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_rfind<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3513,7 +3128,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::rfind(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> + return __str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3526,7 +3141,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> + return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3536,18 +3151,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> + return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_first_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_first_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); - return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> + return __str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3569,7 +3194,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> + return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3579,18 +3204,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> + return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_last_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_last_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); - return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> + return __str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3612,7 +3247,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3622,18 +3257,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_first_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3643,7 +3288,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> + return __str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3656,7 +3301,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ size_type __n) const _NOEXCEPT { _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -3666,18 +3311,28 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& __str, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __str.data(), __pos, __str.size()); } template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY typename basic_string<_CharT, _Traits, _Allocator>::size_type +basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(__self_view __sv, + size_type __pos) const _NOEXCEPT +{ + return __str_find_last_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __sv.data(), __pos, __sv.size()); +} + +template<class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT { _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -3687,7 +3342,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size_type __pos) const _NOEXCEPT { - return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> + return __str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __c, __pos); } @@ -3696,11 +3351,11 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY int -basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT +basic_string<_CharT, _Traits, _Allocator>::compare(__self_view __sv) const _NOEXCEPT { size_t __lhs_sz = size(); - size_t __rhs_sz = __str.size(); - int __result = traits_type::compare(data(), __str.data(), + size_t __rhs_sz = __sv.size(); + int __result = traits_type::compare(data(), __sv.data(), _VSTD::min(__lhs_sz, __rhs_sz)); if (__result != 0) return __result; @@ -3714,6 +3369,47 @@ basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) co template <class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY int +basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT +{ + return compare(__self_view(__str)); +} + +template <class _CharT, class _Traits, class _Allocator> +int +basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, + size_type __n1, + const value_type* __s, + size_type __n2) const +{ + _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); + size_type __sz = size(); + if (__pos1 > __sz || __n2 == npos) + this->__throw_out_of_range(); + size_type __rlen = _VSTD::min(__n1, __sz - __pos1); + int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); + if (__r == 0) + { + if (__rlen < __n2) + __r = -1; + else if (__rlen > __n2) + __r = 1; + } + return __r; +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +int +basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, + size_type __n1, + __self_view __sv) const +{ + return compare(__pos1, __n1, __sv.data(), __sv.size()); +} + +template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const @@ -3722,6 +3418,23 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, } template <class _CharT, class _Traits, class _Allocator> +template <class _Tp> +typename enable_if +< + __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, + size_type __pos2, + size_type __n2) const +{ + __self_view __sv = __t; + return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); +} + +template <class _CharT, class _Traits, class _Allocator> int basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, @@ -3729,11 +3442,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __pos2, size_type __n2) const { - size_type __sz = __str.size(); - if (__pos2 > __sz) - this->__throw_out_of_range(); - return compare(__pos1, __n1, __str.data() + __pos2, _VSTD::min(__n2, - __sz - __pos2)); + return compare(__pos1, __n1, __self_view(__str), __pos2, __n2); } template <class _CharT, class _Traits, class _Allocator> @@ -3754,29 +3463,6 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, return compare(__pos1, __n1, __s, traits_type::length(__s)); } -template <class _CharT, class _Traits, class _Allocator> -int -basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, - size_type __n1, - const value_type* __s, - size_type __n2) const -{ - _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); - size_type __sz = size(); - if (__pos1 > __sz || __n2 == npos) - this->__throw_out_of_range(); - size_type __rlen = _VSTD::min(__n1, __sz - __pos1); - int __r = traits_type::compare(data() + __pos1, __s, _VSTD::min(__rlen, __n2)); - if (__r == 0) - { - if (__rlen < __n2) - __r = -1; - else if (__rlen > __n2) - __r = 1; - } - return __r; -} - // __invariants template<class _CharT, class _Traits, class _Allocator> @@ -3854,8 +3540,6 @@ operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; } -// operator!= - template<class _CharT, class _Traits, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY bool @@ -4307,8 +3991,8 @@ inline namespace literals } #endif -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<char>) -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS basic_string<wchar_t>) +_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>) _LIBCPP_EXTERN_TEMPLATE(string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&)) _LIBCPP_END_NAMESPACE_STD diff --git a/include/string_view b/include/string_view new file mode 100644 index 000000000000..e66ac40d3e2f --- /dev/null +++ b/include/string_view @@ -0,0 +1,754 @@ +// -*- C++ -*- +//===------------------------ string_view ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_STRING_VIEW +#define _LIBCPP_STRING_VIEW + +/* +string_view synopsis + +namespace std { + + // 7.2, Class template basic_string_view + template<class charT, class traits = char_traits<charT>> + class basic_string_view; + + // 7.9, basic_string_view non-member comparison functions + template<class charT, class traits> + constexpr bool operator==(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> + constexpr bool operator!=(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> + constexpr bool operator< (basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> + constexpr bool operator> (basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> + constexpr bool operator<=(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + template<class charT, class traits> + constexpr bool operator>=(basic_string_view<charT, traits> x, + basic_string_view<charT, traits> y) noexcept; + // see below, sufficient additional overloads of comparison functions + + // 7.10, Inserters and extractors + template<class charT, class traits> + basic_ostream<charT, traits>& + operator<<(basic_ostream<charT, traits>& os, + basic_string_view<charT, traits> str); + + // basic_string_view typedef names + typedef basic_string_view<char> string_view; + typedef basic_string_view<char16_t> u16string_view; + typedef basic_string_view<char32_t> u32string_view; + typedef basic_string_view<wchar_t> wstring_view; + + template<class charT, class traits = char_traits<charT>> + class basic_string_view { + public: + // types + typedef traits traits_type; + typedef charT value_type; + typedef charT* pointer; + typedef const charT* const_pointer; + typedef charT& reference; + typedef const charT& const_reference; + typedef implementation-defined const_iterator; + typedef const_iterator iterator; + typedef reverse_iterator<const_iterator> const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static constexpr size_type npos = size_type(-1); + + // 7.3, basic_string_view constructors and assignment operators + constexpr basic_string_view() noexcept; + constexpr basic_string_view(const basic_string_view&) noexcept = default; + basic_string_view& operator=(const basic_string_view&) noexcept = default; + template<class Allocator> + constexpr basic_string_view(const charT* str); + constexpr basic_string_view(const charT* str, size_type len); + + // 7.4, basic_string_view iterator support + constexpr const_iterator begin() const noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator rend() const noexcept; + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + + // 7.5, basic_string_view capacity + constexpr size_type size() const noexcept; + constexpr size_type length() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + + // 7.6, basic_string_view element access + constexpr const_reference operator[](size_type pos) const; + constexpr const_reference at(size_type pos) const; + constexpr const_reference front() const; + constexpr const_reference back() const; + constexpr const_pointer data() const noexcept; + + // 7.7, basic_string_view modifiers + constexpr void clear() noexcept; + constexpr void remove_prefix(size_type n); + constexpr void remove_suffix(size_type n); + constexpr void swap(basic_string_view& s) noexcept; + + size_type copy(charT* s, size_type n, size_type pos = 0) const; + + constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; + constexpr int compare(basic_string_view s) const noexcept; + constexpr int compare(size_type pos1, size_type n1, basic_string_view s) const; + constexpr int compare(size_type pos1, size_type n1, + basic_string_view s, size_type pos2, size_type n2) const; + constexpr int compare(const charT* s) const; + constexpr int compare(size_type pos1, size_type n1, const charT* s) const; + constexpr int compare(size_type pos1, size_type n1, + const charT* s, size_type n2) const; + constexpr size_type find(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find(charT c, size_type pos = 0) const noexcept; + constexpr size_type find(const charT* s, size_type pos, size_type n) const; + constexpr size_type find(const charT* s, size_type pos = 0) const; + constexpr size_type rfind(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type rfind(charT c, size_type pos = npos) const noexcept; + constexpr size_type rfind(const charT* s, size_type pos, size_type n) const; + constexpr size_type rfind(const charT* s, size_type pos = npos) const; + constexpr size_type find_first_of(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find_first_of(charT c, size_type pos = 0) const noexcept; + constexpr size_type find_first_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_first_of(const charT* s, size_type pos = 0) const; + constexpr size_type find_last_of(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type find_last_of(charT c, size_type pos = npos) const noexcept; + constexpr size_type find_last_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_last_of(const charT* s, size_type pos = npos) const; + constexpr size_type find_first_not_of(basic_string_view s, size_type pos = 0) const noexcept; + constexpr size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; + constexpr size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_first_not_of(const charT* s, size_type pos = 0) const; + constexpr size_type find_last_not_of(basic_string_view s, size_type pos = npos) const noexcept; + constexpr size_type find_last_not_of(charT c, size_type pos = npos) const noexcept; + constexpr size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; + constexpr size_type find_last_not_of(const charT* s, size_type pos = npos) const; + + private: + const_pointer data_; // exposition only + size_type size_; // exposition only + }; + + // 7.11, Hash support + template <class T> struct hash; + template <> struct hash<string_view>; + template <> struct hash<u16string_view>; + template <> struct hash<u32string_view>; + template <> struct hash<wstring_view>; + +} // namespace std + + +*/ + +#include <__config> + +#include <__string> +#include <algorithm> +#include <iterator> +#include <limits> +#include <stdexcept> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template<class _CharT, class _Traits = char_traits<_CharT> > +class _LIBCPP_TYPE_VIS_ONLY basic_string_view { +public: + // types + typedef _Traits traits_type; + typedef _CharT value_type; + typedef const _CharT* pointer; + typedef const _CharT* const_pointer; + typedef const _CharT& reference; + typedef const _CharT& const_reference; + typedef const_pointer const_iterator; // See [string.view.iterators] + typedef const_iterator iterator; + typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; + typedef const_reverse_iterator reverse_iterator; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + static _LIBCPP_CONSTEXPR const size_type npos = -1; // size_type(-1); + + // [string.view.cons], construct/copy + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view() _NOEXCEPT : __data (nullptr), __size(0) {} + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view(const basic_string_view&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + basic_string_view& operator=(const basic_string_view&) _NOEXCEPT = default; + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view(const _CharT* __s, size_type __len) + : __data(__s), __size(__len) + { +// #if _LIBCPP_STD_VER > 11 +// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); +// #endif + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view(const _CharT* __s) + : __data(__s), __size(_Traits::length(__s)) {} + + // [string.view.iterators], iterators + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator begin() const _NOEXCEPT { return cbegin(); } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator end() const _NOEXCEPT { return cend(); } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator cbegin() const _NOEXCEPT { return __data; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_iterator cend() const _NOEXCEPT { return __data + __size; } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } + + _LIBCPP_INLINE_VISIBILITY + const_reverse_iterator crend() const _NOEXCEPT { return const_reverse_iterator(cbegin()); } + + // [string.view.capacity], capacity + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT { return __size; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + size_type length() const _NOEXCEPT { return __size; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + size_type max_size() const _NOEXCEPT { return numeric_limits<size_type>::max(); } + + _LIBCPP_CONSTEXPR bool _LIBCPP_INLINE_VISIBILITY + empty() const _NOEXCEPT { return __size == 0; } + + // [string.view.access], element access + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference operator[](size_type __pos) const _NOEXCEPT { return __data[__pos]; } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference at(size_type __pos) const + { + return __pos >= size() + ? (__throw_out_of_range("string_view::at"), __data[0]) + : __data[__pos]; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference front() const + { + return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data[0]; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_reference back() const + { + return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data[__size-1]; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + const_pointer data() const _NOEXCEPT { return __data; } + + // [string.view.modifiers], modifiers: + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT + { + __data = nullptr; + __size = 0; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void remove_prefix(size_type __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); + __data += __n; + __size -= __n; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void remove_suffix(size_type __n) _NOEXCEPT + { + _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); + __size -= __n; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + void swap(basic_string_view& __other) _NOEXCEPT + { + const value_type *__p = __data; + __data = __other.__data; + __other.__data = __p; + + size_type __sz = __size; + __size = __other.__size; + __other.__size = __sz; + } + + _LIBCPP_INLINE_VISIBILITY + size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const + { + if (__pos > size()) + __throw_out_of_range("string_view::copy"); + size_type __rlen = _VSTD::min(__n, size() - __pos); + _Traits::copy(__s, data() + __pos, __rlen); + return __rlen; + } + + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + basic_string_view substr(size_type __pos = 0, size_type __n = npos) const + { + return __pos > size() + ? (__throw_out_of_range("string_view::substr"), basic_string_view()) + : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 int compare(basic_string_view __sv) const _NOEXCEPT + { + size_type __rlen = _VSTD::min( size(), __sv.size()); + int __retval = _Traits::compare(data(), __sv.data(), __rlen); + if ( __retval == 0 ) // first __rlen chars matched + __retval = size() == __sv.size() ? 0 : ( size() < __sv.size() ? -1 : 1 ); + return __retval; + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, basic_string_view __sv) const + { + return substr(__pos1, __n1).compare(__sv); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare( size_type __pos1, size_type __n1, + basic_string_view _sv, size_type __pos2, size_type __n2) const + { + return substr(__pos1, __n1).compare(_sv.substr(__pos2, __n2)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(const _CharT* __s) const _NOEXCEPT + { + return compare(basic_string_view(__s)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, const _CharT* __s) const + { + return substr(__pos1, __n1).compare(basic_string_view(__s)); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + int compare(size_type __pos1, size_type __n1, const _CharT* __s, size_type __n2) const + { + return substr(__pos1, __n1).compare(basic_string_view(__s, __n2)); + } + + // find + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); + return __str_find<value_type, size_type, traits_type, npos> + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(_CharT __c, size_type __pos = 0) const _NOEXCEPT + { + return __str_find<value_type, size_type, traits_type, npos> + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); + return __str_find<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find(const _CharT* __s, size_type __pos = 0) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); + return __str_find<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // rfind + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); + return __str_rfind<value_type, size_type, traits_type, npos> + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(_CharT __c, size_type __pos = npos) const _NOEXCEPT + { + return __str_rfind<value_type, size_type, traits_type, npos> + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); + return __str_rfind<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type rfind(const _CharT* __s, size_type __pos=npos) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); + return __str_rfind<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_first_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); + return __str_find_first_of<value_type, size_type, traits_type, npos> + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(_CharT __c, size_type __pos = 0) const _NOEXCEPT + { return find(__c, __pos); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); + return __str_find_first_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_of(const _CharT* __s, size_type __pos=0) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); + return __str_find_first_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_last_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); + return __str_find_last_of<value_type, size_type, traits_type, npos> + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(_CharT __c, size_type __pos = npos) const _NOEXCEPT + { return rfind(__c, __pos); } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); + return __str_find_last_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_of(const _CharT* __s, size_type __pos=npos) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); + return __str_find_last_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_first_not_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); + return __str_find_first_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(_CharT __c, size_type __pos=0) const _NOEXCEPT + { + return __str_find_first_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); + return __str_find_first_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); + return __str_find_first_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, traits_type::length(__s)); + } + + // find_last_not_of + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT + { + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); + return __str_find_last_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __s.data(), __pos, __s.size()); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(_CharT __c, size_type __pos=npos) const _NOEXCEPT + { + return __str_find_last_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __c, __pos); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const + { + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); + return __str_find_last_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, __n); + } + + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const + { + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); + return __str_find_last_not_of<value_type, size_type, traits_type, npos> + (data(), size(), __s, __pos, traits_type::length(__s)); + } + +private: + const value_type* __data; + size_type __size; +}; + + +// [string.view.comparison] +// operator == +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator==(basic_string_view<_CharT, _Traits> __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + if ( __lhs.size() != __rhs.size()) return false; + return __lhs.compare(__rhs) == 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator==(basic_string_view<_CharT, _Traits> __lhs, + typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT +{ + if ( __lhs.size() != __rhs.size()) return false; + return __lhs.compare(__rhs) == 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator==(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + if ( __lhs.size() != __rhs.size()) return false; + return __lhs.compare(__rhs) == 0; +} + + +// operator != +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator!=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + if ( __lhs.size() != __rhs.size()) + return true; + return __lhs.compare(__rhs) != 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator!=(basic_string_view<_CharT, _Traits> __lhs, + typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT +{ + if ( __lhs.size() != __rhs.size()) + return true; + return __lhs.compare(__rhs) != 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator!=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + if ( __lhs.size() != __rhs.size()) + return true; + return __lhs.compare(__rhs) != 0; +} + + +// operator < +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator<(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) < 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator<(basic_string_view<_CharT, _Traits> __lhs, + typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) < 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator<(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) < 0; +} + + +// operator > +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator> (basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) > 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator>(basic_string_view<_CharT, _Traits> __lhs, + typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) > 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator>(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) > 0; +} + + +// operator <= +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator<=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) <= 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator<=(basic_string_view<_CharT, _Traits> __lhs, + typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) <= 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator<=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) <= 0; +} + + +// operator >= +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator>=(basic_string_view<_CharT, _Traits> __lhs, basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) >= 0; +} + + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator>=(basic_string_view<_CharT, _Traits> __lhs, + typename common_type<basic_string_view<_CharT, _Traits> >::type __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) >= 0; +} + +template<class _CharT, class _Traits> +_LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +bool operator>=(typename common_type<basic_string_view<_CharT, _Traits> >::type __lhs, + basic_string_view<_CharT, _Traits> __rhs) _NOEXCEPT +{ + return __lhs.compare(__rhs) >= 0; +} + +typedef basic_string_view<char> string_view; +typedef basic_string_view<char16_t> u16string_view; +typedef basic_string_view<char32_t> u32string_view; +typedef basic_string_view<wchar_t> wstring_view; + +// [string.view.hash] +template<class _CharT, class _Traits> +struct _LIBCPP_TYPE_VIS_ONLY hash<basic_string_view<_CharT, _Traits> > + : public unary_function<basic_string_view<_CharT, _Traits>, size_t> +{ + size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT; +}; + +template<class _CharT, class _Traits> +size_t +hash<basic_string_view<_CharT, _Traits> >::operator()( + const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT +{ + return __do_string_hash(__val.data(), __val.data() + __val.size()); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STRING_VIEW diff --git a/include/support/android/locale_bionic.h b/include/support/android/locale_bionic.h index 1365563ee481..482e23433585 100644 --- a/include/support/android/locale_bionic.h +++ b/include/support/android/locale_bionic.h @@ -11,7 +11,7 @@ #ifndef _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H #define _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H -#if defined(__ANDROID__) +#if defined(__BIONIC__) #ifdef __cplusplus extern "C" { @@ -27,5 +27,5 @@ extern "C" { #include <support/xlocale/__posix_l_fallback.h> #include <support/xlocale/__strtonum_fallback.h> -#endif // defined(__ANDROID__) +#endif // defined(__BIONIC__) #endif // _LIBCPP_SUPPORT_ANDROID_LOCALE_BIONIC_H diff --git a/include/support/win32/locale_win32.h b/include/support/win32/locale_win32.h index 7f3710ecc188..0f5527e570ab 100644 --- a/include/support/win32/locale_win32.h +++ b/include/support/win32/locale_win32.h @@ -17,7 +17,6 @@ extern "C" unsigned short __declspec(dllimport) _ctype[]; #include "support/win32/support.h" #include "support/win32/locale_mgmt_win32.h" #include <stdio.h> -#include <memory> lconv *localeconv_l( locale_t loc ); size_t mbrlen_l( const char *__restrict s, size_t n, @@ -34,21 +33,19 @@ size_t wcsnrtombs_l( char *__restrict dst, const wchar_t **__restrict src, size_t nwc, size_t len, mbstate_t *__restrict ps, locale_t loc); wint_t btowc_l( int c, locale_t loc ); int wctob_l( wint_t c, locale_t loc ); -typedef _VSTD::remove_pointer<locale_t>::type __locale_struct; -typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; inline _LIBCPP_ALWAYS_INLINE decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l ) { - __locale_raii __current( uselocale(__l), uselocale ); - return MB_CUR_MAX; + return ___mb_cur_max_l_func(__l); } // the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+ #define mbtowc_l _mbtowc_l #define strtoll_l _strtoi64_l #define strtoull_l _strtoui64_l -// FIXME: current msvcrt does not know about long double -#define strtold_l _strtod_l +#define strtof_l _strtof_l +#define strtod_l _strtod_l +#define strtold_l _strtold_l inline _LIBCPP_INLINE_VISIBILITY int diff --git a/include/support/win32/math_win32.h b/include/support/win32/math_win32.h deleted file mode 100644 index 0d6b422a165c..000000000000 --- a/include/support/win32/math_win32.h +++ /dev/null @@ -1,117 +0,0 @@ -// -*- C++ -*- -//===---------------------- support/win32/math_win32.h --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H -#define _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H - -#if !defined(_LIBCPP_MSVCRT) -#error "This header complements Microsoft's C Runtime library, and should not be included otherwise." -#else - -#include <math.h> -#include <float.h> // _FPCLASS_PN etc. -#include <crtversion.h> - -#if ((_VC_CRT_MAJOR_VERSION-0) < 12) -// Necessary? -typedef float float_t; -typedef double double_t; - -_LIBCPP_ALWAYS_INLINE bool isfinite( double num ) -{ - return _finite(num) != 0; -} -_LIBCPP_ALWAYS_INLINE bool isinf( double num ) -{ - return !isfinite(num) && !_isnan(num); -} -_LIBCPP_ALWAYS_INLINE bool isnan( double num ) -{ - return _isnan(num) != 0; -} -_LIBCPP_ALWAYS_INLINE bool isnormal( double num ) -{ - int class_ = _fpclass(num); - return class_ == _FPCLASS_NN || class_ == _FPCLASS_PN; -} - -_LIBCPP_ALWAYS_INLINE bool isgreater( double x, double y ) -{ - if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false; - else return x > y; -} - -_LIBCPP_ALWAYS_INLINE bool isgreaterequal( double x, double y ) -{ - if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false; - else return x >= y; -} - -_LIBCPP_ALWAYS_INLINE bool isless( double x, double y ) -{ - if(_fpclass(x) == _FPCLASS_SNAN || _fpclass(y) == _FPCLASS_SNAN) return false; - else return x < y; -} - -_LIBCPP_ALWAYS_INLINE bool islessequal( double x, double y ) -{ - if(::_fpclass(x) == _FPCLASS_SNAN || ::_fpclass(y) == _FPCLASS_SNAN) return false; - else return x <= y; -} - -_LIBCPP_ALWAYS_INLINE bool islessgreater( double x, double y ) -{ - if(::_fpclass(x) == _FPCLASS_SNAN || ::_fpclass(y) == _FPCLASS_SNAN) return false; - else return x < y || x > y; -} - -_LIBCPP_ALWAYS_INLINE bool isunordered( double x, double y ) -{ - return isnan(x) || isnan(y); -} -_LIBCPP_ALWAYS_INLINE bool signbit( double num ) -{ - switch(_fpclass(num)) - { - case _FPCLASS_SNAN: - case _FPCLASS_QNAN: - case _FPCLASS_NINF: - case _FPCLASS_NN: - case _FPCLASS_ND: - case _FPCLASS_NZ: - return true; - case _FPCLASS_PZ: - case _FPCLASS_PD: - case _FPCLASS_PN: - case _FPCLASS_PINF: - return false; - } - return false; -} -_LIBCPP_ALWAYS_INLINE float copysignf( float x, float y ) -{ - return (signbit (x) != signbit (y) ? - x : x); -} -_LIBCPP_ALWAYS_INLINE double copysign( double x, double y ) -{ - return ::_copysign(x,y); -} -_LIBCPP_ALWAYS_INLINE double copysignl( long double x, long double y ) -{ - return ::_copysignl(x,y); -} -_LIBCPP_ALWAYS_INLINE int fpclassify( double num ) -{ - return _fpclass(num); -} -#endif -#endif // _LIBCPP_MSVCRT - -#endif // _LIBCPP_SUPPORT_WIN32_MATH_WIN32_H diff --git a/include/support/win32/support.h b/include/support/win32/support.h index 5765babcd13b..6a5763b5e49b 100644 --- a/include/support/win32/support.h +++ b/include/support/win32/support.h @@ -22,7 +22,7 @@ #include <intrin.h> #endif #if defined(_LIBCPP_MSVCRT) -#include <xlocinfo.h> +#include <crtversion.h> #endif #define swprintf _snwprintf #define vswprintf _vsnwprintf @@ -44,26 +44,8 @@ size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, } #endif // __MINGW32__ -#if defined(_LIBCPP_MSVCRT) +#if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14 #define snprintf _snprintf -#define atoll _atoi64 -#define strtoll _strtoi64 -#define strtoull _strtoui64 -#define wcstoll _wcstoi64 -#define wcstoull _wcstoui64 -_LIBCPP_ALWAYS_INLINE float strtof(const char *nptr, char **endptr) -{ - return _Stof(nptr, endptr, 0); -} -_LIBCPP_ALWAYS_INLINE double strtod(const char *nptr, char **endptr) -{ - return _Stod(nptr, endptr, 0); -} -_LIBCPP_ALWAYS_INLINE long double strtold(const char *nptr, char **endptr) -{ - return _Stold(nptr, endptr, 0); -} - #define _Exit _exit #endif diff --git a/include/support/xlocale/__posix_l_fallback.h b/include/support/xlocale/__posix_l_fallback.h index 8bf9567ffc25..c893a67313cc 100644 --- a/include/support/xlocale/__posix_l_fallback.h +++ b/include/support/xlocale/__posix_l_fallback.h @@ -124,11 +124,11 @@ inline _LIBCPP_ALWAYS_INLINE int tolower_l(int c, locale_t) { return ::tolower(c); } -inline _LIBCPP_ALWAYS_INLINE int towupper_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE wint_t towupper_l(wint_t c, locale_t) { return ::towupper(c); } -inline _LIBCPP_ALWAYS_INLINE int towlower_l(int c, locale_t) { +inline _LIBCPP_ALWAYS_INLINE wint_t towlower_l(wint_t c, locale_t) { return ::towlower(c); } diff --git a/include/system_error b/include/system_error index 134bb3274031..c7e73d4ab82b 100644 --- a/include/system_error +++ b/include/system_error @@ -46,6 +46,12 @@ template <class T> struct is_error_code_enum template <class T> struct is_error_condition_enum : public false_type {}; +template <class _Tp> +constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; // C++17 + +template <class _Tp> +constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; // C++17 + class error_code { public: @@ -213,6 +219,7 @@ bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; template <> struct hash<std::error_code>; +template <> struct hash<std::error_condition>; } // std @@ -236,12 +243,22 @@ template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_error_code_enum : public false_type {}; +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t is_error_code_enum_v = is_error_code_enum<_Tp>::value; +#endif + // is_error_condition_enum template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_error_condition_enum : public false_type {}; +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; +#endif + // Some error codes are not present on all platforms, so we provide equivalents // for them: @@ -613,6 +630,17 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<error_code> } }; +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash<error_condition> + : public unary_function<error_condition, size_t> +{ + _LIBCPP_INLINE_VISIBILITY + size_t operator()(const error_condition& __ec) const _NOEXCEPT + { + return static_cast<size_t>(__ec.value()); + } +}; + // system_error class _LIBCPP_TYPE_VIS system_error @@ -635,7 +663,8 @@ private: static string __init(const error_code&, string); }; -_LIBCPP_FUNC_VIS void __throw_system_error(int ev, const char* what_arg); +_LIBCPP_NORETURN _LIBCPP_FUNC_VIS +void __throw_system_error(int ev, const char* what_arg); _LIBCPP_END_NAMESPACE_STD diff --git a/include/thread b/include/thread index 022021c5adde..7fe4c77e1b10 100644 --- a/include/thread +++ b/include/thread @@ -99,6 +99,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #include <tuple> #endif #include <__threading_support> +#include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -136,7 +137,7 @@ public: template <class _Tp> class __thread_specific_ptr { - __libcpp_tl_key __key_; + __libcpp_tls_key __key_; // Only __thread_local_data() may construct a __thread_specific_ptr // and only with _Tp == __thread_struct. @@ -154,13 +155,12 @@ public: ~__thread_specific_ptr(); _LIBCPP_INLINE_VISIBILITY - pointer get() const {return static_cast<_Tp*>(__libcpp_tl_get(__key_));} + pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));} _LIBCPP_INLINE_VISIBILITY pointer operator*() const {return *get();} _LIBCPP_INLINE_VISIBILITY pointer operator->() const {return get();} - pointer release(); - void reset(pointer __p = nullptr); + void set_pointer(pointer __p); }; template <class _Tp> @@ -173,7 +173,7 @@ __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) template <class _Tp> __thread_specific_ptr<_Tp>::__thread_specific_ptr() { - int __ec = __libcpp_tl_create( + int __ec = __libcpp_tls_create( &__key_, &__thread_specific_ptr::__at_thread_exit); if (__ec) @@ -191,21 +191,12 @@ __thread_specific_ptr<_Tp>::~__thread_specific_ptr() } template <class _Tp> -typename __thread_specific_ptr<_Tp>::pointer -__thread_specific_ptr<_Tp>::release() -{ - pointer __p = get(); - __libcpp_tl_set(__key_, nullptr); - return __p; -} - -template <class _Tp> void -__thread_specific_ptr<_Tp>::reset(pointer __p) +__thread_specific_ptr<_Tp>::set_pointer(pointer __p) { - pointer __p_old = get(); - __libcpp_tl_set(__key_, __p); - delete __p_old; + _LIBCPP_ASSERT(get() == nullptr, + "Attempting to overwrite thread local data"); + __libcpp_tls_set(__key_, __p); } class _LIBCPP_TYPE_VIS thread; @@ -351,7 +342,7 @@ void* __thread_proxy(void* __vp) { // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...> std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); - __thread_local_data().reset(_VSTD::get<0>(*__p).release()); + __thread_local_data().set_pointer(_VSTD::get<0>(*__p).release()); typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; __thread_execute(*__p, _Index()); return nullptr; @@ -392,7 +383,7 @@ template <class _Fp> void* __thread_proxy_cxx03(void* __vp) { std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); - __thread_local_data().reset(__p->__tsp_.release()); + __thread_local_data().set_pointer(__p->__tsp_.release()); (__p->__fn_)(); return nullptr; } diff --git a/include/tuple b/include/tuple index 744a3ff032d0..553d8e546f89 100644 --- a/include/tuple +++ b/include/tuple @@ -84,7 +84,7 @@ template <class T, class Tuple> constexpr T make_from_tuple(Tuple&& t); // C++17 // 20.4.1.4, tuple helper classes: -template <class T> class tuple_size; // undefined +template <class T> class tuple_size; template <class... T> class tuple_size<tuple<T...>>; template <class T> constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 @@ -150,27 +150,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_VARIADICS -// tuple_size - -template <class ..._Tp> -class _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> > - : public integral_constant<size_t, sizeof...(_Tp)> -{ -}; - -// tuple_element - -template <size_t _Ip, class ..._Tp> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> > -{ -public: - typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; -}; - -#if _LIBCPP_STD_VER > 11 -template <size_t _Ip, class ..._Tp> -using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; -#endif // __tuple_leaf @@ -192,6 +171,20 @@ class __tuple_leaf { _Hp value; + template <class _Tp> + static constexpr bool __can_bind_reference() { + using _RawTp = typename remove_reference<_Tp>::type; + using _RawHp = typename remove_reference<_Hp>::type; + using _CheckLValueArg = integral_constant<bool, + is_lvalue_reference<_Tp>::value + || is_same<_RawTp, reference_wrapper<_RawHp>>::value + || is_same<_RawTp, reference_wrapper<typename remove_const<_RawHp>::type>>::value + >; + return !is_reference<_Hp>::value + || (is_lvalue_reference<_Hp>::value && _CheckLValueArg::value) + || (is_rvalue_reference<_Hp>::value && !is_lvalue_reference<_Tp>::value); + } + __tuple_leaf& operator=(const __tuple_leaf&); public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf() @@ -231,59 +224,29 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value)) : value(_VSTD::forward<_Tp>(__t)) - {static_assert(!is_reference<_Hp>::value || - (is_lvalue_reference<_Hp>::value && - (is_lvalue_reference<_Tp>::value || - is_same<typename remove_reference<_Tp>::type, - reference_wrapper< - typename remove_reference<_Hp>::type - > - >::value)) || - (is_rvalue_reference<_Hp>::value && - !is_lvalue_reference<_Tp>::value), + {static_assert(__can_bind_reference<_Tp>(), "Attempted to construct a reference element in a tuple with an rvalue");} template <class _Tp, class _Alloc> _LIBCPP_INLINE_VISIBILITY explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) : value(_VSTD::forward<_Tp>(__t)) - {static_assert(!is_lvalue_reference<_Hp>::value || - (is_lvalue_reference<_Hp>::value && - (is_lvalue_reference<_Tp>::value || - is_same<typename remove_reference<_Tp>::type, - reference_wrapper< - typename remove_reference<_Hp>::type - > - >::value)), + {static_assert(__can_bind_reference<_Tp>(), "Attempted to construct a reference element in a tuple with an rvalue");} template <class _Tp, class _Alloc> _LIBCPP_INLINE_VISIBILITY explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) - {static_assert(!is_lvalue_reference<_Hp>::value || - (is_lvalue_reference<_Hp>::value && - (is_lvalue_reference<_Tp>::value || - is_same<typename remove_reference<_Tp>::type, - reference_wrapper< - typename remove_reference<_Hp>::type - > - >::value)), - "Attempted to construct a reference element in a tuple with an rvalue");} + {static_assert(!is_reference<_Hp>::value, + "Attempted to uses-allocator construct a reference element in a tuple");} template <class _Tp, class _Alloc> _LIBCPP_INLINE_VISIBILITY explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) : value(_VSTD::forward<_Tp>(__t), __a) - {static_assert(!is_lvalue_reference<_Hp>::value || - (is_lvalue_reference<_Hp>::value && - (is_lvalue_reference<_Tp>::value || - is_same<typename remove_reference<_Tp>::type, - reference_wrapper< - typename remove_reference<_Hp>::type - > - >::value)), - "Attempted to construct a reference element in a tuple with an rvalue");} + {static_assert(!is_reference<_Hp>::value, + "Attempted to uses-allocator construct a reference element in a tuple");} __tuple_leaf(const __tuple_leaf& __t) = default; __tuple_leaf(__tuple_leaf&& __t) = default; @@ -505,27 +468,7 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> } }; -template <bool _IsTuple, class _SizeTrait, size_t _Expected> -struct __tuple_like_with_size_imp : false_type {}; - -template <class _SizeTrait, size_t _Expected> -struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected> - : integral_constant<bool, _SizeTrait::value == _Expected> {}; -template <class _Tuple, size_t _ExpectedSize, - class _RawTuple = typename __uncvref<_Tuple>::type> -using __tuple_like_with_size = __tuple_like_with_size_imp< - __tuple_like<_RawTuple>::value, - tuple_size<_RawTuple>, _ExpectedSize - >; - - -struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { - template <class ...> - static constexpr bool __enable_explicit() { return false; } - template <class ...> - static constexpr bool __enable_implicit() { return false; } -}; template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple @@ -534,6 +477,12 @@ class _LIBCPP_TYPE_VIS_ONLY tuple base base_; +#if defined(_LIBCPP_ENABLE_TUPLE_IMPLICIT_REDUCED_ARITY_EXTENSION) + static constexpr bool _EnableImplicitReducedArityExtension = true; +#else + static constexpr bool _EnableImplicitReducedArityExtension = false; +#endif + template <class ..._Args> struct _PackExpandsToThisTuple : false_type {}; @@ -548,6 +497,11 @@ class _LIBCPP_TYPE_VIS_ONLY tuple struct _CheckArgsConstructor<true, _Dummy> { template <class ..._Args> + static constexpr bool __enable_default() { + return __all<is_default_constructible<_Args>::value...>::value; + } + + template <class ..._Args> static constexpr bool __enable_explicit() { return __tuple_constructible< @@ -657,12 +611,15 @@ class _LIBCPP_TYPE_VIS_ONLY tuple public: template <bool _Dummy = true, class = typename enable_if< - __all<__dependent_type<is_default_constructible<_Tp>, _Dummy>::value...>::value + _CheckArgsConstructor<_Dummy>::template __enable_default<_Tp...>() >::type> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR tuple() _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} + tuple(tuple const&) = default; + tuple(tuple&&) = default; + template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if< __lazy_and< is_same<allocator_arg_t, _AllocArgT>, @@ -752,11 +709,17 @@ public: ) {} template <class ..._Up, + bool _PackIsTuple = _PackExpandsToThisTuple<_Up...>::value, typename enable_if < _CheckArgsConstructor< - sizeof...(_Up) <= sizeof...(_Tp) - && !_PackExpandsToThisTuple<_Up...>::value + sizeof...(_Up) == sizeof...(_Tp) + && !_PackIsTuple + >::template __enable_implicit<_Up...>() || + _CheckArgsConstructor< + _EnableImplicitReducedArityExtension + && sizeof...(_Up) < sizeof...(_Tp) + && !_PackIsTuple >::template __enable_implicit<_Up...>(), bool >::type = false @@ -784,7 +747,12 @@ public: _CheckArgsConstructor< sizeof...(_Up) <= sizeof...(_Tp) && !_PackExpandsToThisTuple<_Up...>::value - >::template __enable_explicit<_Up...>(), + >::template __enable_explicit<_Up...>() || + _CheckArgsConstructor< + !_EnableImplicitReducedArityExtension + && sizeof...(_Up) < sizeof...(_Tp) + && !_PackExpandsToThisTuple<_Up...>() + >::template __enable_implicit<_Up...>(), bool >::type = false > @@ -901,6 +869,25 @@ public: tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} + using _CanCopyAssign = __all<is_copy_assignable<_Tp>::value...>; + using _CanMoveAssign = __all<is_move_assignable<_Tp>::value...>; + + _LIBCPP_INLINE_VISIBILITY + tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, __nat>::type const& __t) + _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value)) + { + base_.operator=(__t.base_); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, __nat>::type&& __t) + _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value)) + { + base_.operator=(static_cast<base&&>(__t.base_)); + return *this; + } + template <class _Tuple, class = typename enable_if < @@ -1356,6 +1343,9 @@ template <class ..._Tp, class _Alloc> struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc> : true_type {}; +#endif // _LIBCPP_HAS_NO_VARIADICS + +#ifndef _LIBCPP_CXX03_LANG template <class _T1, class _T2> template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2> inline _LIBCPP_INLINE_VISIBILITY @@ -1366,8 +1356,7 @@ pair<_T1, _T2>::pair(piecewise_construct_t, second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...) { } - -#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // _LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER > 14 template <class _Tp> diff --git a/include/type_traits b/include/type_traits index 821a73c764dd..e2b537799dcc 100644 --- a/include/type_traits +++ b/include/type_traits @@ -425,7 +425,7 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp #endif // addressof -#if __has_builtin(__builtin_addressof) +#ifndef _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF template <class _Tp> inline _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -443,10 +443,11 @@ inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY _Tp* addressof(_Tp& __x) _NOEXCEPT { - return (_Tp*)&reinterpret_cast<const volatile char&>(__x); + return reinterpret_cast<_Tp *>( + const_cast<char *>(&reinterpret_cast<const volatile char &>(__x))); } -#endif // __has_builtin(__builtin_addressof) +#endif // _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF #if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF) // Objective-C++ Automatic Reference Counting uses qualified pointers @@ -488,6 +489,10 @@ addressof(__unsafe_unretained _Tp& __x) _NOEXCEPT } #endif +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_DELETED_FUNCTIONS) +template <class _Tp> _Tp* addressof(const _Tp&&) noexcept = delete; +#endif + struct __two {char __lx[2];}; // helper class: @@ -520,7 +525,7 @@ using bool_constant = integral_constant<bool, __b>; typedef _LIBCPP_BOOL_CONSTANT(true) true_type; typedef _LIBCPP_BOOL_CONSTANT(false) false_type; -#if !defined(_LIBCPP_HAS_NO_VARIADICS) +#if !defined(_LIBCPP_CXX03_LANG) // __lazy_and @@ -595,7 +600,7 @@ struct __or_<_B0, _B1, _B2, _Bn...> template<class _Tp> struct __not_ : conditional<_Tp::value, false_type, true_type>::type {}; -#endif // !defined(_LIBCPP_HAS_NO_VARIADICS) +#endif // !defined(_LIBCPP_CXX03_LANG) // is_const @@ -1122,6 +1127,11 @@ struct __unconstref { typedef typename remove_const<typename remove_reference<_Tp>::type>::type type; }; +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +using __uncvref_t = typename __uncvref<_Tp>::type; +#endif + // __is_same_uncvref template <class _Tp, class _Up> @@ -1670,10 +1680,10 @@ _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400); _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800); _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000); _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000); -// MSDN says that MSVC does not support alignment beyond 8192 (=0x2000) -#if !defined(_LIBCPP_MSVC) +// PE/COFF does not support alignment beyond 8192 (=0x2000) +#if !defined(_WIN32) _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000); -#endif // !_LIBCPP_MSVC +#endif // !_WIN32 #undef _CREATE_ALIGNED_STORAGE_SPECIALIZATION @@ -1987,10 +1997,10 @@ struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp> // bullet 3 - sizeof...(Tp) == 2 template <class _Tp, class _Up, class = void> -struct __common_type2 {}; +struct __common_type2_imp {}; template <class _Tp, class _Up> -struct __common_type2<_Tp, _Up, +struct __common_type2_imp<_Tp, _Up, typename __void_t<decltype( true ? _VSTD::declval<_Tp>() : _VSTD::declval<_Up>() )>::type> @@ -2000,6 +2010,16 @@ struct __common_type2<_Tp, _Up, )>::type type; }; +template <class _Tp, class _Up, + class _DTp = typename decay<_Tp>::type, + class _DUp = typename decay<_Up>::type> +using __common_type2 = + typename conditional< + is_same<_Tp, _DTp>::value && is_same<_Up, _DUp>::value, + __common_type2_imp<_Tp, _Up>, + common_type<_DTp, _DUp> + >::type; + template <class _Tp, class _Up> struct _LIBCPP_TYPE_VIS_ONLY common_type<_Tp, _Up> : __common_type2<_Tp, _Up> {}; @@ -2011,13 +2031,21 @@ template <class ...Tp> struct __common_types; template <class, class = void> struct __common_type_impl {}; +template <class _Tp, class _Up> +struct __common_type_impl< + __common_types<_Tp, _Up>, + typename __void_t<typename common_type<_Tp, _Up>::type>::type> +{ + typedef typename common_type<_Tp, _Up>::type type; +}; + template <class _Tp, class _Up, class ..._Vp> struct __common_type_impl<__common_types<_Tp, _Up, _Vp...>, typename __void_t<typename common_type<_Tp, _Up>::type>::type> + : __common_type_impl< + __common_types<typename common_type<_Tp, _Up>::type, _Vp...> > { - typedef typename common_type< - typename common_type<_Tp, _Up>::type, _Vp... - >::type type; + }; template <class _Tp, class _Up, class ..._Vp> @@ -2036,26 +2064,15 @@ template<typename, typename _Tp> struct __select_2nd { typedef _Tp type; }; template <class _Tp, class _Arg> typename __select_2nd<decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>())), true_type>::type -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -__is_assignable_test(_Tp&&, _Arg&&); -#else -__is_assignable_test(_Tp, _Arg&); -#endif +__is_assignable_test(int); + +template <class, class> +false_type __is_assignable_test(...); -template <class _Arg> -false_type -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -__is_assignable_test(__any, _Arg&&); -#else -__is_assignable_test(__any, _Arg&); -#endif template <class _Tp, class _Arg, bool = is_void<_Tp>::value || is_void<_Arg>::value> struct __is_assignable_imp - : public common_type - < - decltype(_VSTD::__is_assignable_test(declval<_Tp>(), declval<_Arg>())) - >::type {}; + : public decltype((_VSTD::__is_assignable_test<_Tp, _Arg>(0))) {}; template <class _Tp, class _Arg> struct __is_assignable_imp<_Tp, _Arg, true> @@ -2088,7 +2105,7 @@ template <class _Tp> _LIBCPP_CONSTEXPR bool is_copy_assignable_v template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_move_assignable #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES : public is_assignable<typename add_lvalue_reference<_Tp>::type, - const typename add_rvalue_reference<_Tp>::type> {}; + typename add_rvalue_reference<_Tp>::type> {}; #else : public is_copy_assignable<_Tp> {}; #endif @@ -2166,7 +2183,7 @@ template <class _Tp> _LIBCPP_CONSTEXPR bool is_destructible_v #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename remove_reference<_Tp>::type&& move(_Tp&& __t) _NOEXCEPT { @@ -2175,7 +2192,7 @@ move(_Tp&& __t) _NOEXCEPT } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&& forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT { @@ -2183,12 +2200,12 @@ forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp&& forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT { static_assert(!is_lvalue_reference<_Tp>::value, - "Can not forward an rvalue as an lvalue."); + "can not forward an rvalue as an lvalue"); return static_cast<_Tp&&>(__t); } @@ -2900,135 +2917,132 @@ namespace __is_construct struct __nat {}; } -#if __has_feature(is_constructible) +#if !defined(_LIBCPP_CXX03_LANG) && (!__has_feature(is_constructible) || \ + defined(_LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE)) -template <class _Tp, class ..._Args> -struct _LIBCPP_TYPE_VIS_ONLY is_constructible - : public integral_constant<bool, __is_constructible(_Tp, _Args...)> - {}; - -#else - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -// main is_constructible test - -template <class _Tp, class ..._Args> -typename __select_2nd<decltype(_VSTD::move(_Tp(_VSTD::declval<_Args>()...))), true_type>::type -__is_constructible_test(_Tp&&, _Args&& ...); - -template <class ..._Args> -false_type -__is_constructible_test(__any, _Args&& ...); - -template <bool, class _Tp, class... _Args> -struct __libcpp_is_constructible // false, _Tp is not a scalar - : public common_type - < - decltype(__is_constructible_test(declval<_Tp>(), declval<_Args>()...)) - >::type - {}; +template <class _Tp, class... _Args> +struct __libcpp_is_constructible; + +template <class _To, class _From> +struct __is_invalid_base_to_derived_cast { + static_assert(is_reference<_To>::value, "Wrong specialization"); + using _RawFrom = __uncvref_t<_From>; + using _RawTo = __uncvref_t<_To>; + static const bool value = __lazy_and< + __lazy_not<is_same<_RawFrom, _RawTo>>, + is_base_of<_RawFrom, _RawTo>, + __lazy_not<__libcpp_is_constructible<_RawTo, _From>> + >::value; +}; + +template <class _To, class _From> +struct __is_invalid_lvalue_to_rvalue_cast : false_type { + static_assert(is_reference<_To>::value, "Wrong specialization"); +}; + +template <class _ToRef, class _FromRef> +struct __is_invalid_lvalue_to_rvalue_cast<_ToRef&&, _FromRef&> { + using _RawFrom = __uncvref_t<_FromRef>; + using _RawTo = __uncvref_t<_ToRef>; + static const bool value = __lazy_and< + __lazy_not<is_function<_RawTo>>, + __lazy_or< + is_same<_RawFrom, _RawTo>, + is_base_of<_RawTo, _RawFrom>> + >::value; +}; + +struct __is_constructible_helper +{ + template <class _To> + static void __eat(_To); + + // This overload is needed to work around a Clang bug that disallows + // static_cast<T&&>(e) for non-reference-compatible types. + // Example: static_cast<int&&>(declval<double>()); + // NOTE: The static_cast implementation below is required to support + // classes with explicit conversion operators. + template <class _To, class _From, + class = decltype(__eat<_To>(_VSTD::declval<_From>()))> + static true_type __test_cast(int); + + template <class _To, class _From, + class = decltype(static_cast<_To>(_VSTD::declval<_From>()))> + static integral_constant<bool, + !__is_invalid_base_to_derived_cast<_To, _From>::value && + !__is_invalid_lvalue_to_rvalue_cast<_To, _From>::value + > __test_cast(long); -// function types are not constructible + template <class, class> + static false_type __test_cast(...); -template <class _Rp, class... _A1, class... _A2> -struct __libcpp_is_constructible<false, _Rp(_A1...), _A2...> - : public false_type - {}; + template <class _Tp, class ..._Args, + class = decltype(_Tp(_VSTD::declval<_Args>()...))> + static true_type __test_nary(int); + template <class _Tp, class...> + static false_type __test_nary(...); -// handle scalars and reference types + template <class _Tp, class _A0, class = decltype(::new _Tp(_VSTD::declval<_A0>()))> + static is_destructible<_Tp> __test_unary(int); + template <class, class> + static false_type __test_unary(...); +}; -// Scalars are default constructible, references are not +template <class _Tp, bool = is_void<_Tp>::value> +struct __is_default_constructible + : decltype(__is_constructible_helper::__test_nary<_Tp>(0)) +{}; template <class _Tp> -struct __libcpp_is_constructible<true, _Tp> - : public is_scalar<_Tp> - {}; - -// Scalars and references are constructible from one arg if that arg is -// implicitly convertible to the scalar or reference. +struct __is_default_constructible<_Tp, true> : false_type {}; template <class _Tp> -struct __is_constructible_ref -{ - true_type static __lxx(_Tp); - false_type static __lxx(...); -}; - -template <class _Tp, class _A0> -struct __libcpp_is_constructible<true, _Tp, _A0> - : public common_type - < - decltype(__is_constructible_ref<_Tp>::__lxx(declval<_A0>())) - >::type - {}; - -// Scalars and references are not constructible from multiple args. +struct __is_default_constructible<_Tp[], false> : false_type {}; -template <class _Tp, class _A0, class ..._Args> -struct __libcpp_is_constructible<true, _Tp, _A0, _Args...> - : public false_type - {}; - -// Treat scalars and reference types separately - -template <bool, class _Tp, class... _Args> -struct __is_constructible_void_check - : public __libcpp_is_constructible<is_scalar<_Tp>::value || is_reference<_Tp>::value, - _Tp, _Args...> - {}; - -// If any of T or Args is void, is_constructible should be false +template <class _Tp, size_t _Nx> +struct __is_default_constructible<_Tp[_Nx], false> + : __is_default_constructible<typename remove_all_extents<_Tp>::type> {}; template <class _Tp, class... _Args> -struct __is_constructible_void_check<true, _Tp, _Args...> - : public false_type - {}; - -template <class ..._Args> struct __contains_void; - -template <> struct __contains_void<> : false_type {}; - -template <class _A0, class ..._Args> -struct __contains_void<_A0, _Args...> +struct __libcpp_is_constructible { - static const bool value = is_void<_A0>::value || - __contains_void<_Args...>::value; + static_assert(sizeof...(_Args) > 1, "Wrong specialization"); + typedef decltype(__is_constructible_helper::__test_nary<_Tp, _Args...>(0)) + type; }; -// is_constructible entry point - -template <class _Tp, class... _Args> -struct _LIBCPP_TYPE_VIS_ONLY is_constructible - : public __is_constructible_void_check<__contains_void<_Tp, _Args...>::value - || is_abstract<_Tp>::value, - _Tp, _Args...> - {}; - -// Array types are default constructible if their element type -// is default constructible +template <class _Tp> +struct __libcpp_is_constructible<_Tp> : __is_default_constructible<_Tp> {}; -template <class _Ap, size_t _Np> -struct __libcpp_is_constructible<false, _Ap[_Np]> - : public is_constructible<typename remove_all_extents<_Ap>::type> - {}; +template <class _Tp, class _A0> +struct __libcpp_is_constructible<_Tp, _A0> + : public decltype(__is_constructible_helper::__test_unary<_Tp, _A0>(0)) +{}; -// Otherwise array types are not constructible by this syntax +template <class _Tp, class _A0> +struct __libcpp_is_constructible<_Tp&, _A0> + : public decltype(__is_constructible_helper:: + __test_cast<_Tp&, _A0>(0)) +{}; -template <class _Ap, size_t _Np, class ..._Args> -struct __libcpp_is_constructible<false, _Ap[_Np], _Args...> - : public false_type - {}; +template <class _Tp, class _A0> +struct __libcpp_is_constructible<_Tp&&, _A0> + : public decltype(__is_constructible_helper:: + __test_cast<_Tp&&, _A0>(0)) +{}; -// Incomplete array types are not constructible +#endif -template <class _Ap, class ..._Args> -struct __libcpp_is_constructible<false, _Ap[], _Args...> - : public false_type +#if __has_feature(is_constructible) +template <class _Tp, class ..._Args> +struct _LIBCPP_TYPE_VIS_ONLY is_constructible + : public integral_constant<bool, __is_constructible(_Tp, _Args...)> {}; - -#else // _LIBCPP_HAS_NO_VARIADICS - +#elif !defined(_LIBCPP_CXX03_LANG) +template <class _Tp, class... _Args> +struct _LIBCPP_TYPE_VIS_ONLY is_constructible + : public __libcpp_is_constructible<_Tp, _Args...>::type {}; +#else // template <class T> struct is_constructible0; // main is_constructible0 test @@ -3201,8 +3215,8 @@ struct __is_constructible2_imp<false, _Ap[], _A0, _A1> : public false_type {}; -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // __has_feature(is_constructible) +#endif // __has_feature(is_constructible) + #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(_LIBCPP_HAS_NO_VARIADICS) template <class _Tp, class ..._Args> _LIBCPP_CONSTEXPR bool is_constructible_v @@ -4406,7 +4420,7 @@ template <class _Tp> struct __is_nothrow_swappable; template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE +#ifndef _LIBCPP_CXX03_LANG typename enable_if < is_move_constructible<_Tp>::value && @@ -4614,7 +4628,7 @@ inline _LIBCPP_INLINE_VISIBILITY typename __sfinae_underlying_type<_Tp>::__promoted_type __convert_to_integral(_Tp __val) { return __val; } -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE +#ifndef _LIBCPP_CXX03_LANG template <class _Tp> struct __has_operator_addressof_member_imp @@ -4646,9 +4660,11 @@ struct __has_operator_addressof || __has_operator_addressof_free_imp<_Tp>::value> {}; -#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE +#endif // _LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER > 14 + +#define __cpp_lib_void_t 201411 template <class...> using void_t = void; # ifndef _LIBCPP_HAS_NO_VARIADICS diff --git a/include/typeinfo b/include/typeinfo index 14ef77b31c3f..9b14cb36048e 100644 --- a/include/typeinfo +++ b/include/typeinfo @@ -61,6 +61,9 @@ public: #include <exception> #include <cstddef> #include <cstdint> +#ifdef _LIBCPP_NO_EXCEPTIONS +#include <cstdlib> +#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -73,6 +76,7 @@ class _LIBCPP_EXCEPTION_ABI type_info { type_info& operator=(const type_info&); type_info(const type_info&); + protected: #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT const char* __type_name; @@ -113,7 +117,7 @@ public: _LIBCPP_INLINE_VISIBILITY size_t hash_code() const _NOEXCEPT #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT - {return *reinterpret_cast<const size_t*>(&__type_name);} + {return reinterpret_cast<size_t>(__type_name);} #else {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name; const char *__ptr = name(); @@ -165,4 +169,16 @@ public: } // std +_LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE +void __throw_bad_cast() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_cast(); +#else + _VSTD::abort(); +#endif +} +_LIBCPP_END_NAMESPACE_STD + #endif // __LIBCPP_TYPEINFO diff --git a/include/unordered_map b/include/unordered_map index 8d7edaf509c8..dc8db8085197 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -922,6 +922,8 @@ public: _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_map"); +#else + ((void)__p); #endif return insert(__x).first; } @@ -946,6 +948,8 @@ public: _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" " referring to this unordered_map"); +#else + ((void)__p); #endif return __table_.__insert_unique(_VSTD::move(__x)).first; } @@ -965,6 +969,8 @@ public: _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" " referring to this unordered_map"); +#else + ((void)__p); #endif return insert(_VSTD::forward<_Pp>(__x)).first; } @@ -982,6 +988,8 @@ public: _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" " referring to this unordered_map"); +#else + ((void)__p); #endif return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; } @@ -1012,11 +1020,13 @@ public: iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" " referring to this unordered_map"); +#else + ((void)__h); #endif - return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; + return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } template <class... _Args> @@ -1024,9 +1034,11 @@ public: iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { #if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__h) == this, "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" " referring to this unordered_map"); +#else + ((void)__h); #endif return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } @@ -1057,15 +1069,17 @@ public: template <class _Vp> _LIBCPP_INLINE_VISIBILITY - iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) + iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v) { + // FIXME: Add debug mode checking for the iterator input return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first; } template <class _Vp> _LIBCPP_INLINE_VISIBILITY - iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) + iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v) { + // FIXME: Add debug mode checking for the iterator input return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; } #endif @@ -1085,7 +1099,7 @@ public: _LIBCPP_INLINE_VISIBILITY void swap(unordered_map& __u) _NOEXCEPT_(__is_nothrow_swappable<__table>::value) - {__table_.swap(__u.__table_);} + { __table_.swap(__u.__table_);} _LIBCPP_INLINE_VISIBILITY hasher hash_function() const diff --git a/include/utility b/include/utility index 7b978ad30969..364221433a8a 100644 --- a/include/utility +++ b/include/utility @@ -171,6 +171,25 @@ template<class... T> template<class T, class U=T> T exchange(T& obj, U&& new_value); + +// 20.2.7, in-place construction // C++17 +struct in_place_t { + explicit in_place_t() = default; +}; +inline constexpr in_place_t in_place{}; +template <class T> + struct in_place_type_t { + explicit in_place_type_t() = default; + }; +template <class T> + inline constexpr in_place_type_t<T> in_place_type{}; +template <size_t I> + struct in_place_index_t { + explicit in_place_index_t() = default; + }; +template <size_t I> + inline constexpr in_place_index_t<I> in_place_index{}; + } // std */ @@ -179,6 +198,7 @@ template<class T, class U=T> #include <__tuple> #include <type_traits> #include <initializer_list> +#include <__debug> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -276,8 +296,20 @@ extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); #endif +#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +struct __non_trivially_copyable_base { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + __non_trivially_copyable_base() _NOEXCEPT {} + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} +}; +#endif + template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair +#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +: private __non_trivially_copyable_base +#endif { typedef _T1 first_type; typedef _T2 second_type; @@ -285,56 +317,179 @@ struct _LIBCPP_TYPE_VIS_ONLY pair _T1 first; _T2 second; -#ifndef _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS - template <bool _Dummy = true, class = typename enable_if< - __dependent_type<is_default_constructible<_T1>, _Dummy>::value && - __dependent_type<is_default_constructible<_T2>, _Dummy>::value - >::type> +#if !defined(_LIBCPP_CXX03_LANG) + pair(pair const&) = default; + pair(pair&&) = default; +#else + // Use the implicitly declared copy constructor in C++03 #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(const _T1& __x, const _T2& __y) - : first(__x), second(__y) {} - - template<class _U1, class _U2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(const pair<_U1, _U2>& __p -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE - ,typename enable_if<is_convertible<const _U1&, _T1>::value && - is_convertible<const _U2&, _T2>::value>::type* = 0 -#endif - ) - : first(__p.first), second(__p.second) {} +#ifdef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + pair() : first(), second() {} -#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) _LIBCPP_INLINE_VISIBILITY - pair(const pair& __p) - _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && - is_nothrow_copy_constructible<second_type>::value) - : first(__p.first), - second(__p.second) - { - } + pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {} -# ifndef _LIBCPP_CXX03_LANG + template <class _U1, class _U2> _LIBCPP_INLINE_VISIBILITY - pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value && - is_nothrow_move_constructible<second_type>::value) - : first(_VSTD::forward<first_type>(__p.first)), - second(_VSTD::forward<second_type>(__p.second)) - { + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} + + _LIBCPP_INLINE_VISIBILITY + pair& operator=(pair const& __p) { + first = __p.first; + second = __p.second; + return *this; } -# endif -#elif !defined(_LIBCPP_CXX03_LANG) - pair(pair const&) = default; - pair(pair&&) = default; #else - // Use the implicitly declared copy constructor in C++03 -#endif + template <bool _Val> + using _EnableB = typename enable_if<_Val, bool>::type; + + struct _CheckArgs { + template <class _U1, class _U2> + static constexpr bool __enable_default() { + return is_default_constructible<_U1>::value + && is_default_constructible<_U2>::value; + } + + template <class _U1, class _U2> + static constexpr bool __enable_explicit() { + return is_constructible<first_type, _U1>::value + && is_constructible<second_type, _U2>::value + && (!is_convertible<_U1, first_type>::value + || !is_convertible<_U2, second_type>::value); + } + + template <class _U1, class _U2> + static constexpr bool __enable_implicit() { + return is_constructible<first_type, _U1>::value + && is_constructible<second_type, _U2>::value + && is_convertible<_U1, first_type>::value + && is_convertible<_U2, second_type>::value; + } + }; + + template <bool _MaybeEnable> + using _CheckArgsDep = typename conditional< + _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type; + + struct _CheckTupleLikeConstructor { + template <class _Tuple> + static constexpr bool __enable_implicit() { + return __tuple_convertible<_Tuple, pair>::value; + } + + template <class _Tuple> + static constexpr bool __enable_explicit() { + return __tuple_constructible<_Tuple, pair>::value + && !__tuple_convertible<_Tuple, pair>::value; + } + + template <class _Tuple> + static constexpr bool __enable_assign() { + return __tuple_assignable<_Tuple, pair>::value; + } + }; + + template <class _Tuple> + using _CheckTLC = typename conditional< + __tuple_like_with_size<_Tuple, 2>::value + && !is_same<typename decay<_Tuple>::type, pair>::value, + _CheckTupleLikeConstructor, + __check_tuple_constructor_fail + >::type; + + template<bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + pair() : first(), second() {} + + template <bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(_T1 const& __t1, _T2 const& __t2) + : first(__t1), second(__t2) {} + + template<bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(_T1 const& __t1, _T2 const& __t2) + : first(__t1), second(__t2) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_explicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(_U1&& __u1, _U2&& __u2) + : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_implicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(_U1&& __u1, _U2&& __u2) + : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(pair<_U1, _U2> const& __p) + : first(__p.first), second(__p.second) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(pair<_U1, _U2> const& __p) + : first(__p.first), second(__p.second) {} + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_explicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(pair<_U1, _U2>&&__p) + : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_implicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(pair<_U1, _U2>&& __p) + : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} + + template<class _Tuple, _EnableB< + _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(_Tuple&& __p) + : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))), + second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {} + + template<class _Tuple, _EnableB< + _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(_Tuple&& __p) + : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))), + second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {} + + template <class... _Args1, class... _Args2> _LIBCPP_INLINE_VISIBILITY - pair& operator=(const pair& __p) + pair(piecewise_construct_t __pc, + tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) + : pair(__pc, __first_args, __second_args, + typename __make_tuple_indices<sizeof...(_Args1)>::type(), + typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} + + _LIBCPP_INLINE_VISIBILITY + pair& operator=(typename conditional< + is_copy_assignable<first_type>::value && + is_copy_assignable<second_type>::value, + pair, __nat>::type const& __p) _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value && is_nothrow_copy_assignable<second_type>::value) { @@ -343,75 +498,30 @@ struct _LIBCPP_TYPE_VIS_ONLY pair return *this; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - - template <class _U1, class _U2, - class = typename enable_if<is_convertible<_U1, first_type>::value && - is_convertible<_U2, second_type>::value>::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(_U1&& __u1, _U2&& __u2) - : first(_VSTD::forward<_U1>(__u1)), - second(_VSTD::forward<_U2>(__u2)) - {} - - template<class _U1, class _U2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(pair<_U1, _U2>&& __p, - typename enable_if<is_convertible<_U1, _T1>::value && - is_convertible<_U2, _T2>::value>::type* = 0) - : first(_VSTD::forward<_U1>(__p.first)), - second(_VSTD::forward<_U2>(__p.second)) {} - _LIBCPP_INLINE_VISIBILITY - pair& - operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && - is_nothrow_move_assignable<second_type>::value) + pair& operator=(typename conditional< + is_move_assignable<first_type>::value && + is_move_assignable<second_type>::value, + pair, __nat>::type&& __p) + _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && + is_nothrow_move_assignable<second_type>::value) { first = _VSTD::forward<first_type>(__p.first); second = _VSTD::forward<second_type>(__p.second); return *this; } -#ifndef _LIBCPP_HAS_NO_VARIADICS - - template<class _Tuple, - class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(_Tuple&& __p) - : first(_VSTD::forward<typename tuple_element<0, - typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<0>(__p))), - second(_VSTD::forward<typename tuple_element<1, - typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<1>(__p))) - {} - - - - template <class... _Args1, class... _Args2> - _LIBCPP_INLINE_VISIBILITY - pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, - tuple<_Args2...> __second_args) - : pair(__pc, __first_args, __second_args, - typename __make_tuple_indices<sizeof...(_Args1)>::type(), - typename __make_tuple_indices<sizeof...(_Args2) >::type()) - {} - - template <class _Tuple, - class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type> - _LIBCPP_INLINE_VISIBILITY - pair& - operator=(_Tuple&& __p) - { - typedef typename __make_tuple_types<_Tuple>::type _TupleRef; - typedef typename tuple_element<0, _TupleRef>::type _U0; - typedef typename tuple_element<1, _TupleRef>::type _U1; - first = _VSTD::forward<_U0>(_VSTD::get<0>(__p)); - second = _VSTD::forward<_U1>(_VSTD::get<1>(__p)); - return *this; - } - -#endif // _LIBCPP_HAS_NO_VARIADICS + template <class _Tuple, _EnableB< + _CheckTLC<_Tuple>::template __enable_assign<_Tuple>() + > = false> + _LIBCPP_INLINE_VISIBILITY + pair& operator=(_Tuple&& __p) { + first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p)); + second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p)); + return *this; + } +#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value && @@ -423,13 +533,13 @@ struct _LIBCPP_TYPE_VIS_ONLY pair } private: -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> _LIBCPP_INLINE_VISIBILITY pair(piecewise_construct_t, tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, __tuple_indices<_I1...>, __tuple_indices<_I2...>); -#endif // _LIBCPP_HAS_NO_VARIADICS +#endif }; template <class _T1, class _T2> @@ -782,6 +892,44 @@ _T1 exchange(_T1& __obj, _T2 && __new_value) } #endif // _LIBCPP_STD_VER > 11 +#if _LIBCPP_STD_VER > 14 + +struct _LIBCPP_TYPE_VIS in_place_t { + explicit in_place_t() = default; +}; +#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES +inline +#endif +constexpr in_place_t in_place{}; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS in_place_type_t { + explicit in_place_type_t() = default; +}; +template <class _Tp> +#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES +inline +#endif +constexpr in_place_type_t<_Tp> in_place_type{}; + +template <size_t _Idx> +struct _LIBCPP_TYPE_VIS in_place_index_t { + explicit in_place_index_t() = default; +}; +template <size_t _Idx> +#ifndef _LIBCPP_HAS_NO_INLINE_VARIABLES +inline +#endif +constexpr in_place_index_t<_Idx> in_place_index{}; + +template <class _Tp> struct __is_inplace_type_imp : false_type {}; +template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_type {}; + +template <class _Tp> +using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>; + +#endif // _LIBCPP_STD_VER > 14 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_UTILITY diff --git a/include/valarray b/include/valarray index bde644e8719b..2325c54f7c6d 100644 --- a/include/valarray +++ b/include/valarray @@ -802,8 +802,8 @@ public: // construct/destroy: _LIBCPP_INLINE_VISIBILITY valarray() : __begin_(0), __end_(0) {} - _LIBCPP_INLINE_VISIBILITY - inline explicit valarray(size_t __n); + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY + explicit valarray(size_t __n); _LIBCPP_INLINE_VISIBILITY valarray(const value_type& __x, size_t __n); valarray(const value_type* __p, size_t __n); @@ -819,7 +819,7 @@ public: valarray(const gslice_array<value_type>& __ga); valarray(const mask_array<value_type>& __ma); valarray(const indirect_array<value_type>& __ia); - inline _LIBCPP_INLINE_VISIBILITY + inline _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY ~valarray(); // assignment: diff --git a/include/variant b/include/variant new file mode 100644 index 000000000000..fcbad951f7d9 --- /dev/null +++ b/include/variant @@ -0,0 +1,1568 @@ +// -*- C++ -*- +//===------------------------------ variant -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_VARIANT +#define _LIBCPP_VARIANT + +/* + variant synopsis + +namespace std { + + // 20.7.2, class template variant + template <class... Types> + class variant { + public: + + // 20.7.2.1, constructors + constexpr variant() noexcept(see below); + variant(const variant&); + variant(variant&&) noexcept(see below); + + template <class T> constexpr variant(T&&) noexcept(see below); + + template <class T, class... Args> + constexpr explicit variant(in_place_type_t<T>, Args&&...); + + template <class T, class U, class... Args> + constexpr explicit variant( + in_place_type_t<T>, initializer_list<U>, Args&&...); + + template <size_t I, class... Args> + constexpr explicit variant(in_place_index_t<I>, Args&&...); + + template <size_t I, class U, class... Args> + constexpr explicit variant( + in_place_index_t<I>, initializer_list<U>, Args&&...); + + // 20.7.2.2, destructor + ~variant(); + + // 20.7.2.3, assignment + variant& operator=(const variant&); + variant& operator=(variant&&) noexcept(see below); + + template <class T> variant& operator=(T&&) noexcept(see below); + + // 20.7.2.4, modifiers + template <class T, class... Args> + void emplace(Args&&...); + + template <class T, class U, class... Args> + void emplace(initializer_list<U>, Args&&...); + + template <size_t I, class... Args> + void emplace(Args&&...); + + template <size_t I, class U, class... Args> + void emplace(initializer_list<U>, Args&&...); + + // 20.7.2.5, value status + constexpr bool valueless_by_exception() const noexcept; + constexpr size_t index() const noexcept; + + // 20.7.2.6, swap + void swap(variant&) noexcept(see below); + }; + + // 20.7.3, variant helper classes + template <class T> struct variant_size; // undefined + + template <class T> + constexpr size_t variant_size_v = variant_size<T>::value; + + template <class T> struct variant_size<const T>; + template <class T> struct variant_size<volatile T>; + template <class T> struct variant_size<const volatile T>; + + template <class... Types> + struct variant_size<variant<Types...>>; + + template <size_t I, class T> struct variant_alternative; // undefined + + template <size_t I, class T> + using variant_alternative_t = typename variant_alternative<I, T>::type; + + template <size_t I, class T> struct variant_alternative<I, const T>; + template <size_t I, class T> struct variant_alternative<I, volatile T>; + template <size_t I, class T> struct variant_alternative<I, const volatile T>; + + template <size_t I, class... Types> + struct variant_alternative<I, variant<Types...>>; + + constexpr size_t variant_npos = -1; + + // 20.7.4, value access + template <class T, class... Types> + constexpr bool holds_alternative(const variant<Types...>&) noexcept; + + template <size_t I, class... Types> + constexpr variant_alternative_t<I, variant<Types...>>& + get(variant<Types...>&); + + template <size_t I, class... Types> + constexpr variant_alternative_t<I, variant<Types...>>&& + get(variant<Types...>&&); + + template <size_t I, class... Types> + constexpr variant_alternative_t<I, variant<Types...>> const& + get(const variant<Types...>&); + + template <size_t I, class... Types> + constexpr variant_alternative_t<I, variant<Types...>> const&& + get(const variant<Types...>&&); + + template <class T, class... Types> + constexpr T& get(variant<Types...>&); + + template <class T, class... Types> + constexpr T&& get(variant<Types...>&&); + + template <class T, class... Types> + constexpr const T& get(const variant<Types...>&); + + template <class T, class... Types> + constexpr const T&& get(const variant<Types...>&&); + + template <size_t I, class... Types> + constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> + get_if(variant<Types...>*) noexcept; + + template <size_t I, class... Types> + constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> + get_if(const variant<Types...>*) noexcept; + + template <class T, class... Types> + constexpr add_pointer_t<T> + get_if(variant<Types...>*) noexcept; + + template <class T, class... Types> + constexpr add_pointer_t<const T> + get_if(const variant<Types...>*) noexcept; + + // 20.7.5, relational operators + template <class... Types> + constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); + + template <class... Types> + constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); + + template <class... Types> + constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); + + template <class... Types> + constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); + + template <class... Types> + constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); + + template <class... Types> + constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); + + // 20.7.6, visitation + template <class Visitor, class... Variants> + constexpr see below visit(Visitor&&, Variants&&...); + + // 20.7.7, class monostate + struct monostate; + + // 20.7.8, monostate relational operators + constexpr bool operator<(monostate, monostate) noexcept; + constexpr bool operator>(monostate, monostate) noexcept; + constexpr bool operator<=(monostate, monostate) noexcept; + constexpr bool operator>=(monostate, monostate) noexcept; + constexpr bool operator==(monostate, monostate) noexcept; + constexpr bool operator!=(monostate, monostate) noexcept; + + // 20.7.9, specialized algorithms + template <class... Types> + void swap(variant<Types...>&, variant<Types...>&) noexcept(see below); + + // 20.7.10, class bad_variant_access + class bad_variant_access; + + // 20.7.11, hash support + template <class T> struct hash; + template <class... Types> struct hash<variant<Types...>>; + template <> struct hash<monostate>; + +} // namespace std + +*/ + +#include <__config> +#include <__tuple> +#include <array> +#include <exception> +#include <functional> +#include <initializer_list> +#include <new> +#include <tuple> +#include <type_traits> +#include <utility> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +namespace std { // explicitly not using versioning namespace + +class _LIBCPP_EXCEPTION_ABI bad_variant_access : public exception { +public: + virtual const char* what() const _NOEXCEPT; +}; + +} // namespace std + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 14 + +_LIBCPP_NORETURN +inline _LIBCPP_INLINE_VISIBILITY +void __throw_bad_variant_access() { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_variant_access(); +#else + _VSTD::abort(); +#endif +} + +template <class... _Types> +class _LIBCPP_TYPE_VIS_ONLY variant; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_size; + +template <class _Tp> +constexpr size_t variant_size_v = variant_size<_Tp>::value; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_size<const _Tp> : variant_size<_Tp> {}; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_size<volatile _Tp> : variant_size<_Tp> {}; + +template <class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_size<const volatile _Tp> + : variant_size<_Tp> {}; + +template <class... _Types> +struct _LIBCPP_TYPE_VIS_ONLY variant_size<variant<_Types...>> + : integral_constant<size_t, sizeof...(_Types)> {}; + +template <size_t _Ip, class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_alternative; + +template <size_t _Ip, class _Tp> +using variant_alternative_t = typename variant_alternative<_Ip, _Tp>::type; + +template <size_t _Ip, class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, const _Tp> + : add_const<variant_alternative_t<_Ip, _Tp>> {}; + +template <size_t _Ip, class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, volatile _Tp> + : add_volatile<variant_alternative_t<_Ip, _Tp>> {}; + +template <size_t _Ip, class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, const volatile _Tp> + : add_cv<variant_alternative_t<_Ip, _Tp>> {}; + +template <size_t _Ip, class... _Types> +struct _LIBCPP_TYPE_VIS_ONLY variant_alternative<_Ip, variant<_Types...>> { + static_assert(_Ip < sizeof...(_Types)); + using type = __type_pack_element<_Ip, _Types...>; +}; + +constexpr size_t variant_npos = static_cast<size_t>(-1); +constexpr unsigned int __variant_npos = static_cast<unsigned int>(-1); + +namespace __find_detail { + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_index() { + constexpr bool __matches[] = {is_same_v<_Tp, _Types>...}; + size_t __result = __not_found; + for (size_t __i = 0; __i < sizeof...(_Types); ++__i) { + if (__matches[__i]) { + if (__result != __not_found) { + return __ambiguous; + } + __result = __i; + } + } + return __result; +} + +template <size_t _Index> +struct __find_unambiguous_index_sfinae_impl + : integral_constant<size_t, _Index> {}; + +template <> +struct __find_unambiguous_index_sfinae_impl<__not_found> {}; + +template <> +struct __find_unambiguous_index_sfinae_impl<__ambiguous> {}; + +template <class _Tp, class... _Types> +struct __find_unambiguous_index_sfinae + : __find_unambiguous_index_sfinae_impl<__find_index<_Tp, _Types...>()> {}; + +} // namespace __find_detail + +namespace __variant_detail { + +struct __valueless_t {}; + +enum class _Trait { _TriviallyAvailable, _Available, _Unavailable }; + +template <typename _Tp, + template <typename> class _IsTriviallyAvailable, + template <typename> class _IsAvailable> +constexpr _Trait __trait = + _IsTriviallyAvailable<_Tp>::value + ? _Trait::_TriviallyAvailable + : _IsAvailable<_Tp>::value ? _Trait::_Available : _Trait::_Unavailable; + +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Trait __common_trait(initializer_list<_Trait> __traits) { + _Trait __result = _Trait::_TriviallyAvailable; + for (_Trait __t : __traits) { + if (static_cast<int>(__t) > static_cast<int>(__result)) { + __result = __t; + } + } + return __result; +} + +template <typename... _Types> +struct __traits { + static constexpr _Trait __copy_constructible_trait = + __common_trait({__trait<_Types, + is_trivially_copy_constructible, + is_copy_constructible>...}); + + static constexpr _Trait __move_constructible_trait = + __common_trait({__trait<_Types, + is_trivially_move_constructible, + is_move_constructible>...}); + + static constexpr _Trait __copy_assignable_trait = __common_trait( + {__copy_constructible_trait, + __move_constructible_trait, + __trait<_Types, is_trivially_copy_assignable, is_copy_assignable>...}); + + static constexpr _Trait __move_assignable_trait = __common_trait( + {__move_constructible_trait, + __trait<_Types, is_trivially_move_assignable, is_move_assignable>...}); + + static constexpr _Trait __destructible_trait = __common_trait( + {__trait<_Types, is_trivially_destructible, is_destructible>...}); +}; + +namespace __access { + +struct __union { + template <class _Vp> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<0>) { + return _VSTD::forward<_Vp>(__v).__head; + } + + template <class _Vp, size_t _Ip> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto&& __get_alt(_Vp&& __v, in_place_index_t<_Ip>) { + return __get_alt(_VSTD::forward<_Vp>(__v).__tail, in_place_index<_Ip - 1>); + } +}; + +struct __base { + template <size_t _Ip, class _Vp> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto&& __get_alt(_Vp&& __v) { + return __union::__get_alt(_VSTD::forward<_Vp>(__v).__data, + in_place_index<_Ip>); + } +}; + +struct __variant { + template <size_t _Ip, class _Vp> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto&& __get_alt(_Vp&& __v) { + return __base::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v).__impl); + } +}; + +} // namespace __access + +namespace __visitation { + +struct __base { + template <class _Visitor, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr decltype(auto) + __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { + constexpr auto __fdiagonal = + __make_fdiagonal<_Visitor&&, + decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); + return __fdiagonal[__index](_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Vs>(__vs).__as_base()...); + } + + template <class _Visitor, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, + _Vs&&... __vs) { + constexpr auto __fmatrix = + __make_fmatrix<_Visitor&&, + decltype(_VSTD::forward<_Vs>(__vs).__as_base())...>(); + const size_t __indices[] = {__vs.index()...}; + return __at(__fmatrix, __indices)(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Vs>(__vs).__as_base()...); + } + +private: + template <class _Tp> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr const _Tp& __at_impl(const _Tp& __elem, const size_t*) { + return __elem; + } + + template <class _Tp, size_t _Np> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto&& __at_impl(const array<_Tp, _Np>& __elems, + const size_t* __index) { + return __at_impl(__elems[*__index], __index + 1); + } + + template <class _Tp, size_t _Np, size_t _Ip> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto&& __at(const array<_Tp, _Np>& __elems, + const size_t (&__indices)[_Ip]) { + return __at_impl(__elems, begin(__indices)); + } + + template <class _Fp, class... _Fs> + static constexpr void __std_visit_visitor_return_type_check() { + static_assert( + __all<is_same_v<_Fp, _Fs>...>::value, + "`std::visit` requires the visitor to have a single return type."); + } + + template <class... _Fs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_farray(_Fs&&... __fs) { + __std_visit_visitor_return_type_check<decay_t<_Fs>...>(); + using __result = array<common_type_t<decay_t<_Fs>...>, sizeof...(_Fs)>; + return __result{{_VSTD::forward<_Fs>(__fs)...}}; + } + + template <class _Fp, class... _Vs, size_t... _Is> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_dispatch(index_sequence<_Is...>) { + struct __dispatcher { + static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) { + return __invoke_constexpr( + static_cast<_Fp>(__f), + __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...); + } + }; + return _VSTD::addressof(__dispatcher::__dispatch); + } + + template <size_t _Ip, class _Fp, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_fdiagonal_impl() { + return __make_dispatch<_Fp, _Vs...>( + index_sequence<(__identity<_Vs>{}, _Ip)...>{}); + } + + template <class _Fp, class... _Vs, size_t... _Is> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_fdiagonal_impl(index_sequence<_Is...>) { + return __base::__make_farray(__make_fdiagonal_impl<_Is, _Fp, _Vs...>()...); + } + + template <class _Fp, class _Vp, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_fdiagonal() { + constexpr size_t _Np = decay_t<_Vp>::__size(); + static_assert(__all<(_Np == decay_t<_Vs>::__size())...>::value); + return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{}); + } + + template <class _Fp, class... _Vs, size_t... _Is> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_fmatrix_impl(index_sequence<_Is...> __is) { + return __make_dispatch<_Fp, _Vs...>(__is); + } + + template <class _Fp, class... _Vs, size_t... _Is, size_t... _Js, class... _Ls> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_fmatrix_impl(index_sequence<_Is...>, + index_sequence<_Js...>, + _Ls... __ls) { + return __base::__make_farray(__make_fmatrix_impl<_Fp, _Vs...>( + index_sequence<_Is..., _Js>{}, __ls...)...); + } + + template <class _Fp, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_fmatrix() { + return __make_fmatrix_impl<_Fp, _Vs...>( + index_sequence<>{}, make_index_sequence<decay_t<_Vs>::__size()>{}...); + } +}; + +struct __variant { + template <class _Visitor, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr decltype(auto) + __visit_alt_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { + return __base::__visit_alt_at(__index, + _VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Vs>(__vs).__impl...); + } + + template <class _Visitor, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr decltype(auto) __visit_alt(_Visitor&& __visitor, + _Vs&&... __vs) { + return __base::__visit_alt(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Vs>(__vs).__impl...); + } + + template <class _Visitor, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr decltype(auto) + __visit_value_at(size_t __index, _Visitor&& __visitor, _Vs&&... __vs) { + return __visit_alt_at( + __index, + __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)), + _VSTD::forward<_Vs>(__vs)...); + } + + template <class _Visitor, class... _Vs> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr decltype(auto) __visit_value(_Visitor&& __visitor, + _Vs&&... __vs) { + return __visit_alt( + __make_value_visitor(_VSTD::forward<_Visitor>(__visitor)), + _VSTD::forward<_Vs>(__vs)...); + } + +private: + template <class _Visitor, class... _Values> + static constexpr void __std_visit_exhaustive_visitor_check() { + static_assert(is_callable_v<_Visitor(_Values...)>, + "`std::visit` requires the visitor to be exhaustive."); + } + + template <class _Visitor> + struct __value_visitor { + template <class... _Alts> + inline _LIBCPP_INLINE_VISIBILITY + constexpr decltype(auto) operator()(_Alts&&... __alts) const { + __std_visit_exhaustive_visitor_check< + _Visitor, + decltype(_VSTD::forward<_Alts>(__alts).__value)...>(); + return __invoke_constexpr(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Alts>(__alts).__value...); + } + _Visitor&& __visitor; + }; + + template <class _Visitor> + inline _LIBCPP_INLINE_VISIBILITY + static constexpr auto __make_value_visitor(_Visitor&& __visitor) { + return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)}; + } +}; + +} // namespace __visitation + +template <size_t _Index, class _Tp> +struct _LIBCPP_TYPE_VIS_ONLY __alt { + using __value_type = _Tp; + + template <class... _Args> + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr __alt(in_place_t, _Args&&... __args) + : __value(_VSTD::forward<_Args>(__args)...) {} + + __value_type __value; +}; + +template <_Trait _DestructibleTrait, size_t _Index, class... _Types> +union _LIBCPP_TYPE_VIS_ONLY __union; + +template <_Trait _DestructibleTrait, size_t _Index> +union _LIBCPP_TYPE_VIS_ONLY __union<_DestructibleTrait, _Index> {}; + +#define _LIBCPP_VARIANT_UNION(destructible_trait, destructor) \ + template <size_t _Index, class _Tp, class... _Types> \ + union _LIBCPP_TYPE_VIS_ONLY __union<destructible_trait, \ + _Index, \ + _Tp, \ + _Types...> { \ + public: \ + inline _LIBCPP_INLINE_VISIBILITY \ + explicit constexpr __union(__valueless_t) noexcept : __dummy{} {} \ + \ + template <class... _Args> \ + inline _LIBCPP_INLINE_VISIBILITY \ + explicit constexpr __union(in_place_index_t<0>, _Args&&... __args) \ + : __head(in_place, _VSTD::forward<_Args>(__args)...) {} \ + \ + template <size_t _Ip, class... _Args> \ + inline _LIBCPP_INLINE_VISIBILITY \ + explicit constexpr __union(in_place_index_t<_Ip>, _Args&&... __args) \ + : __tail(in_place_index<_Ip - 1>, _VSTD::forward<_Args>(__args)...) {} \ + \ + __union(const __union&) = default; \ + __union(__union&&) = default; \ + \ + destructor \ + \ + __union& operator=(const __union&) = default; \ + __union& operator=(__union&&) = default; \ + \ + private: \ + char __dummy; \ + __alt<_Index, _Tp> __head; \ + __union<destructible_trait, _Index + 1, _Types...> __tail; \ + \ + friend struct __access::__union; \ + } + +_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;); +_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union() {}); +_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;); + +#undef _LIBCPP_VARIANT_UNION + +template <_Trait _DestructibleTrait, class... _Types> +class _LIBCPP_TYPE_VIS_ONLY __base { +public: + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr __base(__valueless_t tag) noexcept + : __data(tag), __index(__variant_npos) {} + + template <size_t _Ip, class... _Args> + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr __base(in_place_index_t<_Ip>, _Args&&... __args) + : + __data(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...), + __index(_Ip) {} + + inline _LIBCPP_INLINE_VISIBILITY + constexpr bool valueless_by_exception() const noexcept { + return index() == variant_npos; + } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr size_t index() const noexcept { + return __index == __variant_npos ? variant_npos : __index; + } + +protected: + inline _LIBCPP_INLINE_VISIBILITY + constexpr auto&& __as_base() & { return *this; } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr auto&& __as_base() && { return _VSTD::move(*this); } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr auto&& __as_base() const & { return *this; } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr auto&& __as_base() const && { return _VSTD::move(*this); } + + inline _LIBCPP_INLINE_VISIBILITY + static constexpr size_t __size() { return sizeof...(_Types); } + + __union<_DestructibleTrait, 0, _Types...> __data; + unsigned int __index; + + friend struct __access::__base; + friend struct __visitation::__base; +}; + +template <class _Traits, _Trait = _Traits::__destructible_trait> +class _LIBCPP_TYPE_VIS_ONLY __destructor; + +#define _LIBCPP_VARIANT_DESTRUCTOR(destructible_trait, destructor, destroy) \ + template <class... _Types> \ + class _LIBCPP_TYPE_VIS_ONLY __destructor<__traits<_Types...>, \ + destructible_trait> \ + : public __base<destructible_trait, _Types...> { \ + using __base_type = __base<destructible_trait, _Types...>; \ + \ + public: \ + using __base_type::__base_type; \ + using __base_type::operator=; \ + \ + __destructor(const __destructor&) = default; \ + __destructor(__destructor&&) = default; \ + destructor \ + __destructor& operator=(const __destructor&) = default; \ + __destructor& operator=(__destructor&&) = default; \ + \ + protected: \ + inline _LIBCPP_INLINE_VISIBILITY \ + destroy \ + } + +_LIBCPP_VARIANT_DESTRUCTOR( + _Trait::_TriviallyAvailable, + ~__destructor() = default;, + void __destroy() noexcept { this->__index = __variant_npos; }); + +_LIBCPP_VARIANT_DESTRUCTOR( + _Trait::_Available, + ~__destructor() { __destroy(); }, + void __destroy() noexcept { + if (!this->valueless_by_exception()) { + __visitation::__base::__visit_alt( + [](auto& __alt) noexcept { + using __alt_type = decay_t<decltype(__alt)>; + __alt.~__alt_type(); + }, + *this); + } + this->__index = __variant_npos; + }); + +_LIBCPP_VARIANT_DESTRUCTOR( + _Trait::_Unavailable, + ~__destructor() = delete;, + void __destroy() noexcept = delete;); + +#undef _LIBCPP_VARIANT_DESTRUCTOR + +template <class _Traits> +class _LIBCPP_TYPE_VIS_ONLY __constructor : public __destructor<_Traits> { + using __base_type = __destructor<_Traits>; + +public: + using __base_type::__base_type; + using __base_type::operator=; + +protected: + template <size_t _Ip, class _Tp, class... _Args> + inline _LIBCPP_INLINE_VISIBILITY + static void __construct_alt(__alt<_Ip, _Tp>& __a, _Args&&... __args) { + ::new (_VSTD::addressof(__a)) + __alt<_Ip, _Tp>(in_place, _VSTD::forward<_Args>(__args)...); + } + + template <class _Rhs> + inline _LIBCPP_INLINE_VISIBILITY + static void __generic_construct(__constructor& __lhs, _Rhs&& __rhs) { + __lhs.__destroy(); + if (!__rhs.valueless_by_exception()) { + __visitation::__base::__visit_alt_at( + __rhs.index(), + [](auto& __lhs_alt, auto&& __rhs_alt) { + __construct_alt( + __lhs_alt, + _VSTD::forward<decltype(__rhs_alt)>(__rhs_alt).__value); + }, + __lhs, _VSTD::forward<_Rhs>(__rhs)); + __lhs.__index = __rhs.index(); + } + } +}; + +template <class _Traits, _Trait = _Traits::__move_constructible_trait> +class _LIBCPP_TYPE_VIS_ONLY __move_constructor; + +#define _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(move_constructible_trait, \ + move_constructor) \ + template <class... _Types> \ + class _LIBCPP_TYPE_VIS_ONLY __move_constructor<__traits<_Types...>, \ + move_constructible_trait> \ + : public __constructor<__traits<_Types...>> { \ + using __base_type = __constructor<__traits<_Types...>>; \ + \ + public: \ + using __base_type::__base_type; \ + using __base_type::operator=; \ + \ + __move_constructor(const __move_constructor&) = default; \ + move_constructor \ + ~__move_constructor() = default; \ + __move_constructor& operator=(const __move_constructor&) = default; \ + __move_constructor& operator=(__move_constructor&&) = default; \ + } + +_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( + _Trait::_TriviallyAvailable, + __move_constructor(__move_constructor&& __that) = default;); + +_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( + _Trait::_Available, + __move_constructor(__move_constructor&& __that) noexcept( + __all<is_nothrow_move_constructible_v<_Types>...>::value) + : __move_constructor(__valueless_t{}) { + this->__generic_construct(*this, _VSTD::move(__that)); + }); + +_LIBCPP_VARIANT_MOVE_CONSTRUCTOR( + _Trait::_Unavailable, + __move_constructor(__move_constructor&&) = delete;); + +#undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR + +template <class _Traits, _Trait = _Traits::__copy_constructible_trait> +class _LIBCPP_TYPE_VIS_ONLY __copy_constructor; + +#define _LIBCPP_VARIANT_COPY_CONSTRUCTOR(copy_constructible_trait, \ + copy_constructor) \ + template <class... _Types> \ + class _LIBCPP_TYPE_VIS_ONLY __copy_constructor<__traits<_Types...>, \ + copy_constructible_trait> \ + : public __move_constructor<__traits<_Types...>> { \ + using __base_type = __move_constructor<__traits<_Types...>>; \ + \ + public: \ + using __base_type::__base_type; \ + using __base_type::operator=; \ + \ + copy_constructor \ + __copy_constructor(__copy_constructor&&) = default; \ + ~__copy_constructor() = default; \ + __copy_constructor& operator=(const __copy_constructor&) = default; \ + __copy_constructor& operator=(__copy_constructor&&) = default; \ + } + +_LIBCPP_VARIANT_COPY_CONSTRUCTOR( + _Trait::_TriviallyAvailable, + __copy_constructor(const __copy_constructor& __that) = default;); + +_LIBCPP_VARIANT_COPY_CONSTRUCTOR( + _Trait::_Available, + __copy_constructor(const __copy_constructor& __that) + : __copy_constructor(__valueless_t{}) { + this->__generic_construct(*this, __that); + }); + +_LIBCPP_VARIANT_COPY_CONSTRUCTOR( + _Trait::_Unavailable, + __copy_constructor(const __copy_constructor&) = delete;); + +#undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR + +template <class _Traits> +class _LIBCPP_TYPE_VIS_ONLY __assignment : public __copy_constructor<_Traits> { + using __base_type = __copy_constructor<_Traits>; + +public: + using __base_type::__base_type; + using __base_type::operator=; + + template <size_t _Ip, class... _Args> + inline _LIBCPP_INLINE_VISIBILITY + void __emplace(_Args&&... __args) { + this->__destroy(); + this->__construct_alt(__access::__base::__get_alt<_Ip>(*this), + _VSTD::forward<_Args>(__args)...); + this->__index = _Ip; + } + +protected: + template <bool _CopyAssign, size_t _Ip, class _Tp, class _Arg> + inline _LIBCPP_INLINE_VISIBILITY + void __assign_alt(__alt<_Ip, _Tp>& __a, + _Arg&& __arg, + bool_constant<_CopyAssign> __tag) { + if (this->index() == _Ip) { + __a.__value = _VSTD::forward<_Arg>(__arg); + } else { + struct { + void operator()(true_type) const { + __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg))); + } + void operator()(false_type) const { + __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg)); + } + __assignment* __this; + _Arg&& __arg; + } __impl{this, _VSTD::forward<_Arg>(__arg)}; + __impl(__tag); + } + } + + template <class _That> + inline _LIBCPP_INLINE_VISIBILITY + void __generic_assign(_That&& __that) { + if (this->valueless_by_exception() && __that.valueless_by_exception()) { + // do nothing. + } else if (__that.valueless_by_exception()) { + this->__destroy(); + } else { + __visitation::__base::__visit_alt_at( + __that.index(), + [this](auto& __this_alt, auto&& __that_alt) { + this->__assign_alt( + __this_alt, + _VSTD::forward<decltype(__that_alt)>(__that_alt).__value, + is_lvalue_reference<_That>{}); + }, + *this, _VSTD::forward<_That>(__that)); + } + } +}; + +template <class _Traits, _Trait = _Traits::__move_assignable_trait> +class _LIBCPP_TYPE_VIS_ONLY __move_assignment; + +#define _LIBCPP_VARIANT_MOVE_ASSIGNMENT(move_assignable_trait, \ + move_assignment) \ + template <class... _Types> \ + class _LIBCPP_TYPE_VIS_ONLY __move_assignment<__traits<_Types...>, \ + move_assignable_trait> \ + : public __assignment<__traits<_Types...>> { \ + using __base_type = __assignment<__traits<_Types...>>; \ + \ + public: \ + using __base_type::__base_type; \ + using __base_type::operator=; \ + \ + __move_assignment(const __move_assignment&) = default; \ + __move_assignment(__move_assignment&&) = default; \ + ~__move_assignment() = default; \ + __move_assignment& operator=(const __move_assignment&) = default; \ + move_assignment \ + } + +_LIBCPP_VARIANT_MOVE_ASSIGNMENT( + _Trait::_TriviallyAvailable, + __move_assignment& operator=(__move_assignment&& __that) = default;); + +_LIBCPP_VARIANT_MOVE_ASSIGNMENT( + _Trait::_Available, + __move_assignment& operator=(__move_assignment&& __that) noexcept( + __all<(is_nothrow_move_constructible_v<_Types> && + is_nothrow_move_assignable_v<_Types>)...>::value) { + this->__generic_assign(_VSTD::move(__that)); + return *this; + }); + +_LIBCPP_VARIANT_MOVE_ASSIGNMENT( + _Trait::_Unavailable, + __move_assignment& operator=(__move_assignment&&) = delete;); + +#undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT + +template <class _Traits, _Trait = _Traits::__copy_assignable_trait> +class _LIBCPP_TYPE_VIS_ONLY __copy_assignment; + +#define _LIBCPP_VARIANT_COPY_ASSIGNMENT(copy_assignable_trait, \ + copy_assignment) \ + template <class... _Types> \ + class _LIBCPP_TYPE_VIS_ONLY __copy_assignment<__traits<_Types...>, \ + copy_assignable_trait> \ + : public __move_assignment<__traits<_Types...>> { \ + using __base_type = __move_assignment<__traits<_Types...>>; \ + \ + public: \ + using __base_type::__base_type; \ + using __base_type::operator=; \ + \ + __copy_assignment(const __copy_assignment&) = default; \ + __copy_assignment(__copy_assignment&&) = default; \ + ~__copy_assignment() = default; \ + copy_assignment \ + __copy_assignment& operator=(__copy_assignment&&) = default; \ + } + +_LIBCPP_VARIANT_COPY_ASSIGNMENT( + _Trait::_TriviallyAvailable, + __copy_assignment& operator=(const __copy_assignment& __that) = default;); + +_LIBCPP_VARIANT_COPY_ASSIGNMENT( + _Trait::_Available, + __copy_assignment& operator=(const __copy_assignment& __that) { + this->__generic_assign(__that); + return *this; + }); + +_LIBCPP_VARIANT_COPY_ASSIGNMENT( + _Trait::_Unavailable, + __copy_assignment& operator=(const __copy_assignment&) = delete;); + +#undef _LIBCPP_VARIANT_COPY_ASSIGNMENT + +template <class... _Types> +class _LIBCPP_TYPE_VIS_ONLY __impl + : public __copy_assignment<__traits<_Types...>> { + using __base_type = __copy_assignment<__traits<_Types...>>; + +public: + using __base_type::__base_type; + using __base_type::operator=; + + template <size_t _Ip, class _Arg> + inline _LIBCPP_INLINE_VISIBILITY + void __assign(_Arg&& __arg) { + this->__assign_alt(__access::__base::__get_alt<_Ip>(*this), + _VSTD::forward<_Arg>(__arg), + false_type{}); + } + + inline _LIBCPP_INLINE_VISIBILITY + void __swap(__impl& __that) { + if (this->valueless_by_exception() && __that.valueless_by_exception()) { + // do nothing. + } else if (this->index() == __that.index()) { + __visitation::__base::__visit_alt_at( + this->index(), + [](auto& __this_alt, auto& __that_alt) { + using _VSTD::swap; + swap(__this_alt.__value, __that_alt.__value); + }, + *this, + __that); + } else { + __impl* __lhs = this; + __impl* __rhs = _VSTD::addressof(__that); + if (__lhs->__move_nothrow() && !__rhs->__move_nothrow()) { + _VSTD::swap(__lhs, __rhs); + } + __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 guarentee. + try { + this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); + } catch (...) { + if (__tmp.__move_nothrow()) { + this->__generic_construct(*__rhs, _VSTD::move(__tmp)); + } + throw; + } +#else + this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); +#endif + this->__generic_construct(*__lhs, _VSTD::move(__tmp)); + } + } + +private: + inline _LIBCPP_INLINE_VISIBILITY + bool __move_nothrow() const { + constexpr bool __results[] = {is_nothrow_move_constructible_v<_Types>...}; + return this->valueless_by_exception() || __results[this->index()]; + } +}; + +template <class... _Types> +struct __overload; + +template <> +struct __overload<> { void operator()() const; }; + +template <class _Tp, class... _Types> +struct __overload<_Tp, _Types...> : __overload<_Types...> { + using __overload<_Types...>::operator(); + __identity<_Tp> operator()(_Tp) const; +}; + +template <class _Tp, class... _Types> +using __best_match_t = typename result_of_t<__overload<_Types...>(_Tp&&)>::type; + +} // __variant_detail + +template <class... _Types> +class _LIBCPP_TYPE_VIS_ONLY variant + : private __sfinae_ctor_base< + __all<is_copy_constructible_v<_Types>...>::value, + __all<is_move_constructible_v<_Types>...>::value>, + private __sfinae_assign_base< + __all<(is_copy_constructible_v<_Types> && + is_move_constructible_v<_Types> && + is_copy_assignable_v<_Types>)...>::value, + __all<(is_move_constructible_v<_Types> && + is_move_assignable_v<_Types>)...>::value> { + static_assert(0 < sizeof...(_Types), + "variant must consist of at least one alternative."); + + static_assert(__all<!is_array_v<_Types>...>::value, + "variant can not have an array type as an alternative."); + + static_assert(__all<!is_reference_v<_Types>...>::value, + "variant can not have a reference type as an alternative."); + + static_assert(__all<!is_void_v<_Types>...>::value, + "variant can not have a void type as an alternative."); + + using __first_type = variant_alternative_t<0, variant>; + +public: + template <bool _Dummy = true, + enable_if_t<__dependent_type<is_default_constructible<__first_type>, + _Dummy>::value, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) + : __impl(in_place_index<0>) {} + + variant(const variant&) = default; + variant(variant&&) = default; + + template < + class _Arg, + enable_if_t<!is_same_v<decay_t<_Arg>, variant>, int> = 0, + class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, + size_t _Ip = + __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, + enable_if_t<is_constructible_v<_Tp, _Arg>, int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + constexpr variant(_Arg&& __arg) noexcept( + is_nothrow_constructible_v<_Tp, _Arg>) + : __impl(in_place_index<_Ip>, _VSTD::forward<_Arg>(__arg)) {} + + template <size_t _Ip, class... _Args, + enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, + class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, + enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr variant( + in_place_index_t<_Ip>, + _Args&&... __args) noexcept(is_nothrow_constructible_v<_Tp, _Args...>) + : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {} + + template < + size_t _Ip, + class _Up, + class... _Args, + enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, + class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, + enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr variant( + in_place_index_t<_Ip>, + initializer_list<_Up> __il, + _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) + : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} + + template < + class _Tp, + class... _Args, + size_t _Ip = + __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, + enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr variant(in_place_type_t<_Tp>, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, _Args...>) + : __impl(in_place_index<_Ip>, _VSTD::forward<_Args>(__args)...) {} + + template < + class _Tp, + class _Up, + class... _Args, + size_t _Ip = + __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, + enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + explicit constexpr variant( + in_place_type_t<_Tp>, + initializer_list<_Up> __il, + _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>) + : __impl(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} + + ~variant() = default; + + variant& operator=(const variant&) = default; + variant& operator=(variant&&) = default; + + template < + class _Arg, + enable_if_t<!is_same_v<decay_t<_Arg>, variant>, int> = 0, + class _Tp = __variant_detail::__best_match_t<_Arg, _Types...>, + size_t _Ip = + __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, + enable_if_t<is_assignable_v<_Tp&, _Arg> && is_constructible_v<_Tp, _Arg>, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + variant& operator=(_Arg&& __arg) noexcept( + is_nothrow_assignable_v<_Tp&, _Arg> && + is_nothrow_constructible_v<_Tp, _Arg>) { + __impl.template __assign<_Ip>(_VSTD::forward<_Arg>(__arg)); + return *this; + } + + template < + size_t _Ip, + class... _Args, + enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, + class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, + enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + void emplace(_Args&&... __args) { + __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...); + } + + template < + size_t _Ip, + class _Up, + class... _Args, + enable_if_t<(_Ip < sizeof...(_Types)), int> = 0, + class _Tp = variant_alternative_t<_Ip, variant<_Types...>>, + enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + void emplace(initializer_list<_Up> __il, _Args&&... __args) { + __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...); + } + + template < + class _Tp, + class... _Args, + size_t _Ip = + __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, + enable_if_t<is_constructible_v<_Tp, _Args...>, int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + void emplace(_Args&&... __args) { + __impl.template __emplace<_Ip>(_VSTD::forward<_Args>(__args)...); + } + + template < + class _Tp, + class _Up, + class... _Args, + size_t _Ip = + __find_detail::__find_unambiguous_index_sfinae<_Tp, _Types...>::value, + enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&, _Args...>, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + void emplace(initializer_list<_Up> __il, _Args&&... __args) { + __impl.template __emplace<_Ip>(__il, _VSTD::forward<_Args>(__args)...); + } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr bool valueless_by_exception() const noexcept { + return __impl.valueless_by_exception(); + } + + inline _LIBCPP_INLINE_VISIBILITY + constexpr size_t index() const noexcept { return __impl.index(); } + + template < + bool _Dummy = true, + enable_if_t< + __all<( + __dependent_type<is_move_constructible<_Types>, _Dummy>::value && + __dependent_type<is_swappable<_Types>, _Dummy>::value)...>::value, + int> = 0> + inline _LIBCPP_INLINE_VISIBILITY + void swap(variant& __that) noexcept( + __all<(is_nothrow_move_constructible_v<_Types> && + is_nothrow_swappable_v<_Types>)...>::value) { + __impl.__swap(__that.__impl); + } + +private: + __variant_detail::__impl<_Types...> __impl; + + friend struct __variant_detail::__access::__variant; + friend struct __variant_detail::__visitation::__variant; +}; + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool __holds_alternative(const variant<_Types...>& __v) noexcept { + return __v.index() == _Ip; +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool holds_alternative(const variant<_Types...>& __v) noexcept { + return __holds_alternative<__find_exactly_one_t<_Tp, _Types...>::value>(__v); +} + +template <size_t _Ip, class _Vp> +inline _LIBCPP_INLINE_VISIBILITY +static constexpr auto&& __generic_get(_Vp&& __v) { + using __variant_detail::__access::__variant; + if (!__holds_alternative<_Ip>(__v)) { + __throw_bad_variant_access(); + } + return __variant::__get_alt<_Ip>(_VSTD::forward<_Vp>(__v)).__value; +} + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr variant_alternative_t<_Ip, variant<_Types...>>& get( + variant<_Types...>& __v) { + static_assert(_Ip < sizeof...(_Types)); + static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); + return __generic_get<_Ip>(__v); +} + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr variant_alternative_t<_Ip, variant<_Types...>>&& get( + variant<_Types...>&& __v) { + static_assert(_Ip < sizeof...(_Types)); + static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); + return __generic_get<_Ip>(_VSTD::move(__v)); +} + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr const variant_alternative_t<_Ip, variant<_Types...>>& get( + const variant<_Types...>& __v) { + static_assert(_Ip < sizeof...(_Types)); + static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); + return __generic_get<_Ip>(__v); +} + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr const variant_alternative_t<_Ip, variant<_Types...>>&& get( + const variant<_Types...>&& __v) { + static_assert(_Ip < sizeof...(_Types)); + static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); + return __generic_get<_Ip>(_VSTD::move(__v)); +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp& get(variant<_Types...>& __v) { + static_assert(!is_void_v<_Tp>); + return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp&& get(variant<_Types...>&& __v) { + static_assert(!is_void_v<_Tp>); + return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( + _VSTD::move(__v)); +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr const _Tp& get(const variant<_Types...>& __v) { + static_assert(!is_void_v<_Tp>); + return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr const _Tp&& get(const variant<_Types...>&& __v) { + static_assert(!is_void_v<_Tp>); + return _VSTD::get<__find_exactly_one_t<_Tp, _Types...>::value>( + _VSTD::move(__v)); +} + +template <size_t _Ip, class _Vp> +inline _LIBCPP_INLINE_VISIBILITY +constexpr auto* __generic_get_if(_Vp* __v) noexcept { + using __variant_detail::__access::__variant; + return __v && __holds_alternative<_Ip>(*__v) + ? _VSTD::addressof(__variant::__get_alt<_Ip>(*__v).__value) + : nullptr; +} + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr add_pointer_t<variant_alternative_t<_Ip, variant<_Types...>>> +get_if(variant<_Types...>* __v) noexcept { + static_assert(_Ip < sizeof...(_Types)); + static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); + return __generic_get_if<_Ip>(__v); +} + +template <size_t _Ip, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr add_pointer_t<const variant_alternative_t<_Ip, variant<_Types...>>> +get_if(const variant<_Types...>* __v) noexcept { + static_assert(_Ip < sizeof...(_Types)); + static_assert(!is_void_v<variant_alternative_t<_Ip, variant<_Types...>>>); + return __generic_get_if<_Ip>(__v); +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr add_pointer_t<_Tp> +get_if(variant<_Types...>* __v) noexcept { + static_assert(!is_void_v<_Tp>); + return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); +} + +template <class _Tp, class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr add_pointer_t<const _Tp> +get_if(const variant<_Types...>* __v) noexcept { + static_assert(!is_void_v<_Tp>); + return _VSTD::get_if<__find_exactly_one_t<_Tp, _Types...>::value>(__v); +} + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(const variant<_Types...>& __lhs, + const variant<_Types...>& __rhs) { + using __variant_detail::__visitation::__variant; + if (__lhs.index() != __rhs.index()) return false; + if (__lhs.valueless_by_exception()) return true; + return __variant::__visit_value_at(__lhs.index(), equal_to<>{}, __lhs, __rhs); +} + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(const variant<_Types...>& __lhs, + const variant<_Types...>& __rhs) { + using __variant_detail::__visitation::__variant; + if (__lhs.index() != __rhs.index()) return true; + if (__lhs.valueless_by_exception()) return false; + return __variant::__visit_value_at( + __lhs.index(), not_equal_to<>{}, __lhs, __rhs); +} + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator<(const variant<_Types...>& __lhs, + const variant<_Types...>& __rhs) { + using __variant_detail::__visitation::__variant; + if (__rhs.valueless_by_exception()) return false; + if (__lhs.valueless_by_exception()) return true; + if (__lhs.index() < __rhs.index()) return true; + if (__lhs.index() > __rhs.index()) return false; + return __variant::__visit_value_at(__lhs.index(), less<>{}, __lhs, __rhs); +} + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator>(const variant<_Types...>& __lhs, + const variant<_Types...>& __rhs) { + using __variant_detail::__visitation::__variant; + if (__lhs.valueless_by_exception()) return false; + if (__rhs.valueless_by_exception()) return true; + if (__lhs.index() > __rhs.index()) return true; + if (__lhs.index() < __rhs.index()) return false; + return __variant::__visit_value_at(__lhs.index(), greater<>{}, __lhs, __rhs); +} + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(const variant<_Types...>& __lhs, + const variant<_Types...>& __rhs) { + using __variant_detail::__visitation::__variant; + if (__lhs.valueless_by_exception()) return true; + if (__rhs.valueless_by_exception()) return false; + if (__lhs.index() < __rhs.index()) return true; + if (__lhs.index() > __rhs.index()) return false; + return __variant::__visit_value_at( + __lhs.index(), less_equal<>{}, __lhs, __rhs); +} + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(const variant<_Types...>& __lhs, + const variant<_Types...>& __rhs) { + using __variant_detail::__visitation::__variant; + if (__rhs.valueless_by_exception()) return true; + if (__lhs.valueless_by_exception()) return false; + if (__lhs.index() > __rhs.index()) return true; + if (__lhs.index() < __rhs.index()) return false; + return __variant::__visit_value_at( + __lhs.index(), greater_equal<>{}, __lhs, __rhs); +} + +template <class _Visitor, class... _Vs> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) { + using __variant_detail::__visitation::__variant; + bool __results[] = {__vs.valueless_by_exception()...}; + for (bool __result : __results) { + if (__result) { + __throw_bad_variant_access(); + } + } + return __variant::__visit_value(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Vs>(__vs)...); +} + +struct _LIBCPP_TYPE_VIS_ONLY monostate {}; + +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator<(monostate, monostate) noexcept { return false; } + +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator>(monostate, monostate) noexcept { return false; } + +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator<=(monostate, monostate) noexcept { return true; } + +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator>=(monostate, monostate) noexcept { return true; } + +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator==(monostate, monostate) noexcept { return true; } + +inline _LIBCPP_INLINE_VISIBILITY +constexpr bool operator!=(monostate, monostate) noexcept { return false; } + +template <class... _Types> +inline _LIBCPP_INLINE_VISIBILITY +auto swap(variant<_Types...>& __lhs, + variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) + -> decltype(__lhs.swap(__rhs)) { + __lhs.swap(__rhs); +} + +template <class... _Types> +struct _LIBCPP_TYPE_VIS_ONLY hash<variant<_Types...>> { + using argument_type = variant<_Types...>; + using result_type = size_t; + + inline _LIBCPP_INLINE_VISIBILITY + result_type operator()(const argument_type& __v) const { + using __variant_detail::__visitation::__variant; + size_t __res = + __v.valueless_by_exception() + ? 299792458 // Random value chosen by the universe upon creation + : __variant::__visit_alt( + [](const auto& __alt) { + using __alt_type = decay_t<decltype(__alt)>; + using __value_type = typename __alt_type::__value_type; + return hash<__value_type>{}(__alt.__value); + }, + __v); + return __hash_combine(__res, hash<size_t>{}(__v.index())); + } +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash<monostate> { + using argument_type = monostate; + using result_type = size_t; + + inline _LIBCPP_INLINE_VISIBILITY + result_type operator()(const argument_type&) const { + return 66740831; // return a fundamentally attractive random value. + } +}; + +#endif // _LIBCPP_STD_VER > 14 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_VARIANT diff --git a/include/vector b/include/vector index 021bbfb6643e..0e014d4bed13 100644 --- a/include/vector +++ b/include/vector @@ -99,7 +99,7 @@ public: void push_back(const value_type& x); void push_back(value_type&& x); template <class... Args> - void emplace_back(Args&&... args); + reference emplace_back(Args&&... args); void pop_back(); template <class... Args> iterator emplace(const_iterator position, Args&&... args); @@ -218,7 +218,7 @@ public: const_reference back() const; void push_back(const value_type& x); - template <class... Args> void emplace_back(Args&&... args); // C++14 + template <class... Args> reference emplace_back(Args&&... args); // C++14 void pop_back(); template <class... Args> iterator emplace(const_iterator position, Args&&... args); // C++14 @@ -290,37 +290,29 @@ class __vector_base_common { protected: _LIBCPP_ALWAYS_INLINE __vector_base_common() {} - void __throw_length_error() const; - void __throw_out_of_range() const; + _LIBCPP_NORETURN void __throw_length_error() const; + _LIBCPP_NORETURN void __throw_out_of_range() const; }; template <bool __b> void __vector_base_common<__b>::__throw_length_error() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw length_error("vector"); -#else - assert(!"vector length_error"); -#endif + _VSTD::__throw_length_error("vector"); } template <bool __b> void __vector_base_common<__b>::__throw_out_of_range() const { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw out_of_range("vector"); -#else - assert(!"vector out_of_range"); -#endif + _VSTD::__throw_out_of_range("vector"); } #ifdef _LIBCPP_MSVC #pragma warning( push ) #pragma warning( disable: 4231 ) #endif // _LIBCPP_MSVC -_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>) +_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __vector_base_common<true>) #ifdef _LIBCPP_MSVC #pragma warning( pop ) #endif // _LIBCPP_MSVC @@ -687,7 +679,7 @@ public: #ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args> _LIBCPP_INLINE_VISIBILITY - void emplace_back(_Args&&... __args); + reference emplace_back(_Args&&... __args); #endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -746,9 +738,9 @@ public: void swap(vector&) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT; + _NOEXCEPT_DEBUG; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif @@ -765,6 +757,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); + _LIBCPP_INLINE_VISIBILITY void __invalidate_iterators_past(pointer __new_last); void allocate(size_type __n); void deallocate() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY size_type __recommend(size_type __new_size) const; @@ -794,21 +787,7 @@ private: _LIBCPP_INLINE_VISIBILITY void __destruct_at_end(pointer __new_last) _NOEXCEPT { -#if _LIBCPP_DEBUG_LEVEL >= 2 - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); - if (__i->base() > __new_last) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif + __invalidate_iterators_past(__new_last); size_type __old_size = size(); __base::__destruct_at_end(__new_last); __annotate_shrink(__old_size); @@ -829,30 +808,40 @@ private: // We call annotatations only for the default Allocator because other allocators // may not meet the AddressSanitizer alignment constraints. // See the documentation for __sanitizer_annotate_contiguous_container for more details. - void __annotate_contiguous_container - (const void *__beg, const void *__end, const void *__old_mid, const void *__new_mid) const - { #ifndef _LIBCPP_HAS_NO_ASAN + void __annotate_contiguous_container(const void *__beg, const void *__end, + const void *__old_mid, + const void *__new_mid) const + { + if (__beg && is_same<allocator_type, __default_allocator_type>::value) __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); -#endif } - - void __annotate_new(size_type __current_size) const - { +#else + _LIBCPP_INLINE_VISIBILITY + void __annotate_contiguous_container(const void*, const void*, const void*, + const void*) const {} +#endif + _LIBCPP_INLINE_VISIBILITY + void __annotate_new(size_type __current_size) const { __annotate_contiguous_container(data(), data() + capacity(), data() + capacity(), data() + __current_size); } - void __annotate_delete() const - { + + _LIBCPP_INLINE_VISIBILITY + void __annotate_delete() const { __annotate_contiguous_container(data(), data() + capacity(), data() + size(), data() + capacity()); } + + _LIBCPP_INLINE_VISIBILITY void __annotate_increase(size_type __n) const { __annotate_contiguous_container(data(), data() + capacity(), data() + size(), data() + size() + __n); } + + _LIBCPP_INLINE_VISIBILITY void __annotate_shrink(size_type __old_size) const { __annotate_contiguous_container(data(), data() + capacity(), @@ -877,8 +866,9 @@ private: }; #else struct __RAII_IncreaseAnnotator { - inline __RAII_IncreaseAnnotator(const vector &, size_type __n = 1) {} - inline void __done() {} + _LIBCPP_INLINE_VISIBILITY + __RAII_IncreaseAnnotator(const vector &, size_type = 1) {} + _LIBCPP_INLINE_VISIBILITY void __done() {} }; #endif @@ -949,7 +939,8 @@ template <class _Tp, class _Allocator> typename vector<_Tp, _Allocator>::size_type vector<_Tp, _Allocator>::max_size() const _NOEXCEPT { - return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), numeric_limits<size_type>::max() / 2); // end() >= begin(), always + return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), + numeric_limits<difference_type>::max()); } // Precondition: __new_size > capacity() @@ -1411,6 +1402,7 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las allocate(__recommend(__new_size)); __construct_at_end(__first, __last, __new_size); } + __invalidate_all_iterators(); } template <class _Tp, class _Allocator> @@ -1432,6 +1424,7 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) allocate(__recommend(static_cast<size_type>(__n))); __construct_at_end(__n, __u); } + __invalidate_all_iterators(); } template <class _Tp, class _Allocator> @@ -1632,7 +1625,7 @@ vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) template <class _Tp, class _Allocator> template <class... _Args> inline -void +typename vector<_Tp, _Allocator>::reference vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) { if (this->__end_ < this->__end_cap()) @@ -1646,6 +1639,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) } else __emplace_back_slow_path(_VSTD::forward<_Args>(__args)...); + return this->back(); } #endif // _LIBCPP_HAS_NO_VARIADICS @@ -1674,8 +1668,9 @@ vector<_Tp, _Allocator>::erase(const_iterator __position) "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); pointer __p = this->__begin_ + __ps; - iterator __r = __make_iter(__p); this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p)); + this->__invalidate_iterators_past(__p-1); + iterator __r = __make_iter(__p); return __r; } @@ -1687,12 +1682,17 @@ vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, "vector::erase(iterator, iterator) called with an iterator not" " referring to this vector"); + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__last) == this, + "vector::erase(iterator, iterator) called with an iterator not" + " referring to this vector"); #endif _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); - iterator __r = __make_iter(__p); - if (__first != __last) + if (__first != __last) { this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p)); + this->__invalidate_iterators_past(__p - 1); + } + iterator __r = __make_iter(__p); return __r; } @@ -2013,9 +2013,9 @@ template <class _Tp, class _Allocator> void vector<_Tp, _Allocator>::swap(vector& __x) #if _LIBCPP_STD_VER >= 14 - _NOEXCEPT + _NOEXCEPT_DEBUG #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { @@ -2098,6 +2098,28 @@ vector<_Tp, _Allocator>::__invalidate_all_iterators() #endif // _LIBCPP_DEBUG_LEVEL >= 2 } + +template <class _Tp, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +void +vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) { + --__p; + const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); + if (__i->base() > __new_last) { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#else + ((void)__new_last); +#endif +} + // vector<bool> template <class _Allocator> class vector<bool, _Allocator>; @@ -2314,8 +2336,10 @@ public: void push_back(const value_type& __x); #if _LIBCPP_STD_VER > 11 template <class... _Args> - _LIBCPP_INLINE_VISIBILITY void emplace_back(_Args&&... __args) - { push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); } + _LIBCPP_INLINE_VISIBILITY reference emplace_back(_Args&&... __args) { + push_back ( value_type ( _VSTD::forward<_Args>(__args)... )); + return this->back(); + } #endif _LIBCPP_INLINE_VISIBILITY void pop_back() {--__size_;} @@ -2360,7 +2384,7 @@ public: #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value); #endif static void swap(reference __x, reference __y) _NOEXCEPT { _VSTD::swap(__x, __y); } @@ -2891,6 +2915,7 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x) } _VSTD::fill_n(begin(), __n, __x); } + __invalidate_all_iterators(); } template <class _Allocator> @@ -2918,7 +2943,9 @@ typename enable_if vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) { clear(); - difference_type __n = _VSTD::distance(__first, __last); + difference_type __ns = _VSTD::distance(__first, __last); + _LIBCPP_ASSERT(__ns >= 0, "invalid range specified"); + const size_t __n = static_cast<size_type>(__ns); if (__n) { if (__n > capacity()) @@ -3097,7 +3124,9 @@ typename enable_if >::type vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { - difference_type __n = _VSTD::distance(__first, __last); + const difference_type __n_signed = _VSTD::distance(__first, __last); + _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified"); + const size_type __n = static_cast<size_type>(__n_signed); iterator __r; size_type __c = capacity(); if (__n <= __c && size() <= __c - __n) @@ -3148,7 +3177,7 @@ vector<bool, _Allocator>::swap(vector& __x) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else - _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || + _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<allocator_type>::value) #endif { |