diff options
Diffstat (limited to 'contrib/libc++/include')
77 files changed, 8623 insertions, 2892 deletions
diff --git a/contrib/libc++/include/__bsd_locale_defaults.h b/contrib/libc++/include/__bsd_locale_defaults.h new file mode 100644 index 0000000..f315ca2 --- /dev/null +++ b/contrib/libc++/include/__bsd_locale_defaults.h @@ -0,0 +1,33 @@ +// -*- C++ -*- +//===---------------------- __bsd_locale_defaults.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. +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. We don't want to define those symbols +// on other platforms though, for fear of conflicts with user code. So here, +// we will define the mapping from an internal macro to the real BSD symbol. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_BSD_LOCALE_DEFAULTS_H +#define _LIBCPP_BSD_LOCALE_DEFAULTS_H + +#define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) +#define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc) +#define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc) +#define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc) +#define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc) +#define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc) +#define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l) +#define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l) +#define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l) +#define __libcpp_localeconv_l(l) localeconv_l(l) +#define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l) +#define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__) +#define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) +#define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) + +#endif // _LIBCPP_BSD_LOCALE_DEFAULTS_H diff --git a/contrib/libc++/include/__bsd_locale_fallbacks.h b/contrib/libc++/include/__bsd_locale_fallbacks.h new file mode 100644 index 0000000..cbc8ad2 --- /dev/null +++ b/contrib/libc++/include/__bsd_locale_fallbacks.h @@ -0,0 +1,138 @@ +// -*- C++ -*- +//===---------------------- __bsd_locale_fallbacks.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. +// +//===----------------------------------------------------------------------===// +// The BSDs have lots of *_l functions. This file provides reimplementations +// of those functions for non-BSD platforms. +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H +#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H + +#include <stdlib.h> +#include <memory> + +_LIBCPP_BEGIN_NAMESPACE_STD + +typedef _VSTD::remove_pointer<locale_t>::type __use_locale_struct; +typedef _VSTD::unique_ptr<__use_locale_struct, decltype(&uselocale)> __locale_raii; + +inline _LIBCPP_ALWAYS_INLINE +decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return MB_CUR_MAX; +} + +inline _LIBCPP_ALWAYS_INLINE +wint_t __libcpp_btowc_l(int __c, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return btowc(__c); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_wctob_l(wint_t __c, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return wctob(__c); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, + size_t __len, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return wcsnrtombs(__dest, __src, __nwc, __len, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return wcrtomb(__s, __wc, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, + size_t __len, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbsnrtowcs(__dest, __src, __nms, __len, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, + mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbrtowc(__pwc, __s, __n, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbtowc(__pwc, __pmb, __max); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbrlen(__s, __n, __ps); +} + +inline _LIBCPP_ALWAYS_INLINE +lconv *__libcpp_localeconv_l(locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return localeconv(); +} + +inline _LIBCPP_ALWAYS_INLINE +size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, + mbstate_t *__ps, locale_t __l) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return mbsrtowcs(__dest, __src, __len, __ps); +} + +inline +int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_raii __current( uselocale(__l), uselocale ); + int __res = vsnprintf(__s, __n, __format, __va); + va_end(__va); + return __res; +} + +inline +int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_raii __current( uselocale(__l), uselocale ); + int __res = vasprintf(__s, __format, __va); + va_end(__va); + return __res; +} + +inline +int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { + va_list __va; + va_start(__va, __format); + __locale_raii __current( uselocale(__l), uselocale ); + int __res = vsscanf(__s, __format, __va); + va_end(__va); + return __res; +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H diff --git a/contrib/libc++/include/__config b/contrib/libc++/include/__config index e574bf0..3edb9de 100644 --- a/contrib/libc++/include/__config +++ b/contrib/libc++/include/__config @@ -27,7 +27,7 @@ #define _GNUC_VER 0 #endif -#define _LIBCPP_VERSION 3800 +#define _LIBCPP_VERSION 3900 #ifndef _LIBCPP_ABI_VERSION #define _LIBCPP_ABI_VERSION 1 @@ -41,6 +41,22 @@ #define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE // Fix undefined behavior in how std::list stores it's linked nodes. #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 +#define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB +#define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE +#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#elif _LIBCPP_ABI_VERSION == 1 +// Feature macros for disabling pre ABI v1 features. All of these options +// are deprecated. +#if defined(__FreeBSD__) +#define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +#endif +#endif + +#ifdef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR +#error "_LIBCPP_TRIVIAL_PAIR_COPY_CTOR" is no longer supported. \ + use _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR instead #endif #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y @@ -178,6 +194,12 @@ # endif #endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) +#if __has_attribute(__no_sanitize__) +#define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +#else +#define _LIBCPP_NO_CFI +#endif + #ifdef _WIN32 // only really useful for a DLL @@ -236,6 +258,12 @@ # 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 @@ -283,7 +311,7 @@ typedef __char16_t char16_t; typedef __char32_t char32_t; #endif -#if !(__has_feature(cxx_exceptions)) +#if !(__has_feature(cxx_exceptions)) && !defined(_LIBCPP_NO_EXCEPTIONS) #define _LIBCPP_NO_EXCEPTIONS #endif @@ -305,8 +333,6 @@ typedef __char32_t char32_t; # define _LIBCPP_NORETURN __attribute__ ((noreturn)) #endif -#define _LIBCPP_UNUSED __attribute__((__unused__)) - #if !(__has_feature(cxx_default_function_template_args)) #define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #endif @@ -434,8 +460,8 @@ namespace std { #endif // Allow for build-time disabling of unsigned integer sanitization -#ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute((no_sanitize("unsigned-integer-overflow"))) +#if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize) +#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) #endif #elif defined(__GNUC__) @@ -445,8 +471,6 @@ namespace std { #define _LIBCPP_NORETURN __attribute__((noreturn)) -#define _LIBCPP_UNUSED __attribute__((__unused__)) - #if _GNUC_VER >= 407 #define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) #define _LIBCPP_IS_LITERAL(T) __is_literal_type(T) @@ -461,8 +485,6 @@ namespace std { #define _LIBCPP_NO_EXCEPTIONS #endif -#define _LIBCPP_HAS_NO_TEMPLATE_ALIASES - // constexpr was added to GCC in 4.6. #if _GNUC_VER < 406 #define _LIBCPP_HAS_NO_CONSTEXPR @@ -494,6 +516,7 @@ namespace std { #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__ @@ -517,6 +540,7 @@ 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 @@ -552,7 +576,6 @@ using namespace _LIBCPP_NAMESPACE __attribute__((__strong__)); #define _LIBCPP_HAS_NO_NOEXCEPT #define __alignof__ __alignof #define _LIBCPP_NORETURN __declspec(noreturn) -#define _LIBCPP_UNUSED #define _ALIGNAS(x) __declspec(align(x)) #define _LIBCPP_HAS_NO_VARIADICS @@ -574,7 +597,6 @@ namespace std { #define _ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) #define _ATTRIBUTE(x) __attribute__((x)) #define _LIBCPP_NORETURN __attribute__((noreturn)) -#define _LIBCPP_UNUSED #define _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS #define _LIBCPP_HAS_NO_TEMPLATE_ALIASES @@ -655,6 +677,12 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_DEFAULT = default; #endif +#ifdef _LIBCPP_HAS_NO_DELETED_FUNCTIONS +#define _LIBCPP_EQUAL_DELETE +#else +#define _LIBCPP_EQUAL_DELETE = delete +#endif + #ifdef __GNUC__ #define _NOALIAS __attribute__((__malloc__)) #else @@ -712,10 +740,12 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_LOCALE__L_EXTENSIONS 1 #endif -#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(_NEWLIB_VERSION) && \ - !defined(__CloudABI__) +#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) #define _LIBCPP_HAS_CATOPEN 1 #endif +#endif #ifdef __FreeBSD__ #define _DECLARE_C99_LDBL_MATH 1 @@ -729,24 +759,13 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_WCTYPE_IS_MASK #endif -#ifndef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR -# if defined(__FreeBSD__) -// Making the std::pair copy constructor trivial breaks ABI compatibility with -// earlier versions of libc++ shipped by FreeBSD, so turn it off by default. -// See also http://svnweb.freebsd.org/changeset/base/261801 -# define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 0 -# else -# define _LIBCPP_TRIVIAL_PAIR_COPY_CTOR 1 -# endif -#endif - #ifndef _LIBCPP_STD_VER # if __cplusplus <= 201103L # define _LIBCPP_STD_VER 11 # elif __cplusplus <= 201402L # define _LIBCPP_STD_VER 14 # else -# define _LIBCPP_STD_VER 15 // current year, or date of c++17 ratification +# define _LIBCPP_STD_VER 16 // current year, or date of c++17 ratification # endif #endif // _LIBCPP_STD_VER @@ -770,6 +789,12 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_CONSTEXPR_AFTER_CXX11 #endif +#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr +#else +#define _LIBCPP_CONSTEXPR_AFTER_CXX14 +#endif + #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES # define _LIBCPP_EXPLICIT_MOVE(x) _VSTD::move(x) #else @@ -797,6 +822,25 @@ extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_WEAK __attribute__((__weak__)) #endif +// Thread API +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# if defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__linux__) || \ + defined(__APPLE__) || \ + defined(__CloudABI__) || \ + defined(__sun__) +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# else +# error "No thread API" +# endif // _LIBCPP_HAS_THREAD_API +#endif // _LIBCPP_HAS_NO_THREADS + +#if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +# error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ + _LIBCPP_HAS_NO_THREADS is not defined. +#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. @@ -840,7 +884,20 @@ extern "C" void __sanitizer_annotate_contiguous_container( #ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -#endif +#endif + +#if __cplusplus < 201103L +#define _LIBCPP_CXX03_LANG +#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. +#endif +#endif + +#if (defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) && defined(__clang__) \ + && __has_attribute(acquire_capability)) +#define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +#endif #endif // __cplusplus diff --git a/contrib/libc++/include/__functional_base b/contrib/libc++/include/__functional_base index 52c535a..1a08ea2 100644 --- a/contrib/libc++/include/__functional_base +++ b/contrib/libc++/include/__functional_base @@ -38,8 +38,6 @@ struct _LIBCPP_TYPE_VIS_ONLY binary_function typedef _Result result_type; }; -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash; - template <class _Tp> struct __has_result_type { @@ -306,75 +304,19 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> #endif // _LIBCPP_HAS_NO_VARIADICS -// __invoke - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -// bullets 1 and 2 - -template <class _Fp, class _A0, class ..._Args, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) -{ - return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...); -} - -template <class _Fp, class _A0, class ..._Args, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) -{ - return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...); -} - -// bullets 3 and 4 +#ifndef _LIBCPP_CXX03_LANG -template <class _Fp, class _A0, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype(_VSTD::forward<_A0>(__a0).*__f) -{ - return _VSTD::forward<_A0>(__a0).*__f; -} - -template <class _Fp, class _A0, - class> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype((*_VSTD::forward<_A0>(__a0)).*__f) -{ - return (*_VSTD::forward<_A0>(__a0)).*__f; -} - -// bullet 5 - -template <class _Fp, class ..._Args> -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _Args&& ...__args) - -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) -{ - return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...); -} template <class _Tp, class ..._Args> struct __invoke_return { typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; }; -#else // _LIBCPP_HAS_NO_VARIADICS +#else // defined(_LIBCPP_CXX03_LANG) #include <__functional_base_03> -#endif // _LIBCPP_HAS_NO_VARIADICS +#endif // !defined(_LIBCPP_CXX03_LANG) template <class _Ret> @@ -577,10 +519,6 @@ public: #endif // _LIBCPP_HAS_NO_VARIADICS }; -template <class _Tp> struct __is_reference_wrapper_impl : public false_type {}; -template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {}; -template <class _Tp> struct __is_reference_wrapper - : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {}; template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY diff --git a/contrib/libc++/include/__hash_table b/contrib/libc++/include/__hash_table index c7d1ef3..08bc519 100644 --- a/contrib/libc++/include/__hash_table +++ b/contrib/libc++/include/__hash_table @@ -17,6 +17,7 @@ #include <iterator> #include <algorithm> #include <cmath> +#include <utility> #include <__undef_min_max> #include <__undef___deallocate> @@ -29,6 +30,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD + +#ifndef _LIBCPP_CXX03_LANG +template <class _Key, class _Tp> +union __hash_value_type; +#else +template <class _Key, class _Tp> +struct __hash_value_type; +#endif + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +struct __is_hash_value_type_imp : false_type {}; + +template <class _Key, class _Value> +struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value>> : true_type {}; + +template <class ..._Args> +struct __is_hash_value_type : false_type {}; + +template <class _One> +struct __is_hash_value_type<_One> : __is_hash_value_type_imp<typename __uncvref<_One>::type> {}; +#endif + _LIBCPP_FUNC_VIS size_t __next_prime(size_t __n); @@ -49,10 +73,10 @@ struct __hash_node typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, _VoidPtr> >::type > { - typedef _Tp value_type; + typedef _Tp __node_value_type; size_t __hash_; - value_type __value_; + __node_value_type __value_; }; inline _LIBCPP_INLINE_VISIBILITY @@ -66,7 +90,8 @@ inline _LIBCPP_INLINE_VISIBILITY size_t __constrain_hash(size_t __h, size_t __bc) { - return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : __h % __bc; + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : + (__h < __bc ? __h : __h % __bc); } inline _LIBCPP_INLINE_VISIBILITY @@ -76,24 +101,173 @@ __next_hash_pow2(size_t __n) return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1)); } + template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table; + +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator; template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator; +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator; +template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator; template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; +template <class _Tp> +struct __hash_key_value_types { + static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +#endif +}; + +template <class _Key, class _Tp> +struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __hash_value_type<_Key, _Tp> __node_value_type; + typedef pair<const _Key, _Tp> __container_value_type; + typedef pair<_Key, _Tp> __nc_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(__container_value_type const& __v) { + return __v.first; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __node_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t.__cc; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__cc); + } +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __nc_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v.__nc); + } +#endif + +}; + +template <class _Tp, class _AllocPtr, class _KVTypes = __hash_key_value_types<_Tp>, + bool = _KVTypes::__is_map> +struct __hash_map_pointer_types {}; + +template <class _Tp, class _AllocPtr, class _KVTypes> +struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + __map_value_type_pointer; + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + __const_map_value_type_pointer; +}; + +template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> +struct __hash_node_types; + +template <class _NodePtr, class _Tp, class _VoidPtr> +struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > + : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> + +{ + typedef __hash_key_value_types<_Tp> __base; + +public: + typedef ptrdiff_t difference_type; + typedef size_t size_type; + + typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; + + typedef __hash_node_base<__node_pointer> __node_base_type; + typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type + __node_base_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"); + static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); + static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; + + + +template <class _HashIterator> +struct __hash_node_types_from_iterator; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; +template <class _NodePtr> +struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; + + +template <class _NodeValueTp, class _VoidPtr> +struct __make_hash_node_types { + typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; + typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; + typedef __hash_node_types<_NodePtr> type; +}; + template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator { - typedef _NodePtr __node_pointer; + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; __node_pointer __node_; public: - typedef forward_iterator_tag iterator_category; - typedef typename pointer_traits<__node_pointer>::element_type::value_type value_type; - typedef typename pointer_traits<__node_pointer>::difference_type difference_type; - typedef value_type& reference; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -202,25 +376,24 @@ private: template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; }; -template <class _ConstNodePtr> +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator { - typedef _ConstNodePtr __node_pointer; - - __node_pointer __node_; + static_assert(!is_const<typename pointer_traits<_NodePtr>::element_type>::value, ""); + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; - typedef typename remove_const< - typename pointer_traits<__node_pointer>::element_type - >::type __node; + __node_pointer __node_; public: - typedef forward_iterator_tag iterator_category; - typedef typename __node::value_type value_type; - typedef typename pointer_traits<__node_pointer>::difference_type difference_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type pointer; - typedef typename __rebind_pointer<__node_pointer, __node>::type __non_const_node_pointer; - typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator; + typedef __hash_iterator<_NodePtr> __non_const_iterator; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -336,24 +509,22 @@ private: template <class, class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY unordered_multimap; }; -template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator; - template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator { - typedef _NodePtr __node_pointer; + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; __node_pointer __node_; size_t __bucket_; size_t __bucket_count_; - typedef pointer_traits<__node_pointer> __pointer_traits; public: typedef forward_iterator_tag iterator_category; - typedef typename __pointer_traits::element_type::value_type value_type; - typedef typename __pointer_traits::difference_type difference_type; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; typedef value_type& reference; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT { @@ -476,7 +647,8 @@ private: template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator { - typedef _ConstNodePtr __node_pointer; + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; + typedef _ConstNodePtr __node_pointer; __node_pointer __node_; size_t __bucket_; @@ -487,18 +659,15 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator typedef typename remove_const<__node>::type __non_const_node; typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type __non_const_node_pointer; - +public: typedef __hash_local_iterator<__non_const_node_pointer> __non_const_iterator; -public: - typedef forward_iterator_tag iterator_category; - typedef typename remove_const< - typename __pointer_traits::element_type::value_type - >::type value_type; - typedef typename __pointer_traits::difference_type difference_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type - pointer; + + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT @@ -686,10 +855,11 @@ class __hash_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + public: typedef typename __alloc_traits::pointer pointer; private: + typedef __hash_node_types<pointer> _NodeTypes; allocator_type& __na_; @@ -709,7 +879,7 @@ public: void operator()(pointer __p) _NOEXCEPT { if (__value_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_)); + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); if (__p) __alloc_traits::deallocate(__na_, __p, 1); } @@ -728,23 +898,47 @@ public: private: typedef allocator_traits<allocator_type> __alloc_traits; + typedef typename + __make_hash_node_types<value_type, typename __alloc_traits::void_pointer>::type + _NodeTypes; public: + + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename _NodeTypes::key_type key_type; typedef value_type& reference; typedef const value_type& const_reference; typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; +#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; +#else + typedef typename _NodeTypes::size_type size_type; +#endif + typedef typename _NodeTypes::difference_type difference_type; public: // Create __node - typedef __hash_node<value_type, typename __alloc_traits::void_pointer> __node; + + typedef typename _NodeTypes::__node_type __node; typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; typedef allocator_traits<__node_allocator> __node_traits; - typedef typename __node_traits::pointer __node_pointer; - typedef typename __node_traits::pointer __node_const_pointer; - typedef __hash_node_base<__node_pointer> __first_node; - typedef typename __rebind_pointer<__node_pointer, __first_node>::type - __node_base_pointer; + typedef typename _NodeTypes::__void_pointer __void_pointer; + typedef typename _NodeTypes::__node_pointer __node_pointer; + 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; + +private: + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type + __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); private: @@ -755,10 +949,10 @@ private: typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; // --- Member data begin --- - __bucket_list __bucket_list_; - __compressed_pair<__first_node, __node_allocator> __p1_; - __compressed_pair<size_type, hasher> __p2_; - __compressed_pair<float, key_equal> __p3_; + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair<size_type, hasher> __p2_; + __compressed_pair<float, key_equal> __p3_; // --- Member data end --- _LIBCPP_INLINE_VISIBILITY @@ -809,7 +1003,7 @@ public: explicit __hash_table(const allocator_type& __a); __hash_table(const __hash_table& __u); __hash_table(const __hash_table& __u, const allocator_type& __a); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG __hash_table(__hash_table&& __u) _NOEXCEPT_( is_nothrow_move_constructible<__bucket_list>::value && @@ -818,11 +1012,11 @@ public: is_nothrow_move_constructible<hasher>::value && is_nothrow_move_constructible<key_equal>::value); __hash_table(__hash_table&& __u, const allocator_type& __a); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG ~__hash_table(); __hash_table& operator=(const __hash_table& __u); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY __hash_table& operator=(__hash_table&& __u) _NOEXCEPT_( @@ -848,41 +1042,103 @@ public: iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - template <class... _Args> - pair<iterator, bool> __emplace_unique(_Args&&... __args); - template <class... _Args> - iterator __emplace_multi(_Args&&... __args); +#ifndef _LIBCPP_CXX03_LANG + template <class _Key, class ..._Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args); + template <class... _Args> - iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _ValueTp> + template <class _Pp> _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> __insert_unique_value(_ValueTp&& __x); -#else + pair<iterator, bool> __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class _First, class _Second> _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> __insert_unique_value(const value_type& __x); -#endif + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + pair<iterator, bool> + >::type __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } - pair<iterator, bool> __insert_unique(const value_type& __x); + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - pair<iterator, bool> __insert_unique(value_type&& __x); template <class _Pp> - pair<iterator, bool> __insert_unique(_Pp&& __x); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_multi(_Args&&... __args); + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __insert_unique(__container_value_type&& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); + } + + template <class _Pp, class = typename enable_if< + !__is_same_uncvref<_Pp, __container_value_type>::value + >::type> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(_Pp&& __x) { + return __emplace_unique(_VSTD::forward<_Pp>(__x)); + } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Pp> - iterator __insert_multi(_Pp&& __x); + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Pp&& __x) { + return __emplace_multi(_VSTD::forward<_Pp>(__x)); + } + template <class _Pp> - iterator __insert_multi(const_iterator __p, _Pp&& __x); -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - iterator __insert_multi(const value_type& __x); - iterator __insert_multi(const_iterator __p, const value_type& __x); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Pp&& __x) { + return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); + } + +#else // !defined(_LIBCPP_CXX03_LANG) + template <class _Key, class _Args> + pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); + + iterator __insert_multi(const __container_value_type& __x); + iterator __insert_multi(const_iterator __p, const __container_value_type& __x); +#endif + + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(const __container_value_type& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); + } void clear() _NOEXCEPT; void rehash(size_type __n); @@ -1042,16 +1298,17 @@ public: private: void __rehash(size_type __n); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - __node_holder __construct_node(_Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS - __node_holder __construct_node(value_type&& __v, size_t __hash); -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(const value_type& __v); + __node_holder __construct_node(_Args&& ...__args); + + template <class _First, class ..._Rest> + __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); +#else // _LIBCPP_CXX03_LANG + __node_holder __construct_node(const __container_value_type& __v); + __node_holder __construct_node_hash(size_t __hash, const __container_value_type& __v); #endif - __node_holder __construct_node(const value_type& __v, size_t __hash); + _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __hash_table& __u) @@ -1061,6 +1318,7 @@ private: _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __hash_table&, false_type) {} +#ifndef _LIBCPP_CXX03_LANG void __move_assign(__hash_table& __u, false_type); void __move_assign(__hash_table& __u, true_type) _NOEXCEPT_( @@ -1087,6 +1345,7 @@ private: } _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} +#endif // _LIBCPP_CXX03_LANG void __deallocate(__node_pointer __np) _NOEXCEPT; __node_pointer __detach() _NOEXCEPT; @@ -1163,7 +1422,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, { } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) @@ -1212,11 +1471,15 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, } } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() { + static_assert((is_copy_constructible<key_equal>::value), + "Predicate must be copy-constructible."); + static_assert((is_copy_constructible<hasher>::value), + "Hasher must be copy-constructible."); __deallocate(__p1_.first().__next_); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__erase_c(this); @@ -1277,7 +1540,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) } __get_db()->unlock(); #endif - __node_traits::destroy(__na, _VSTD::addressof(__np->__value_)); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__np->__value_)); __node_traits::deallocate(__na, __np, 1); __np = __next; } @@ -1296,7 +1559,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT return __cache; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> void @@ -1369,8 +1632,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( const_iterator __i = __u.begin(); while (__u.size() != 0) { - __node_holder __h = - __construct_node(_VSTD::move(__u.remove(__i++)->__value_)); + __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); __node_insert_multi(__h.get()); __h.release(); } @@ -1392,7 +1654,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) return *this; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class _InputIterator> @@ -1400,6 +1662,11 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + if (bucket_count() != 0) { __node_pointer __cache = __detach(); @@ -1434,6 +1701,12 @@ void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); if (bucket_count() != 0) { __node_pointer __cache = __detach(); @@ -1459,7 +1732,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, __deallocate(__cache); } for (; __first != __last; ++__first) - __insert_multi(*__first); + __insert_multi(_NodeTypes::__get_value(*__first)); } template <class _Tp, class _Hash, class _Equal, class _Alloc> @@ -1685,31 +1958,24 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( return __node_insert_multi(__cp); } -template <class _Tp, class _Hash, class _Equal, class _Alloc> -pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(const value_type& __x) -{ - return __insert_unique_value(__x); -} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _ValueTp> +template <class _Key, class ..._Args> _LIBCPP_INLINE_VISIBILITY pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(_ValueTp&& __x) +__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>::__insert_unique_value(const value_type& __x) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args& __args) #endif { -#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) - typedef const value_type& _ValueTp; -#endif - size_t __hash = hash_function()(__x); + + size_t __hash = hash_function()(__k); size_type __bc = bucket_count(); bool __inserted = false; __node_pointer __nd; @@ -1724,13 +1990,17 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type __constrain_hash(__nd->__hash_, __bc) == __chash; __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __x)) + if (key_eq()(__nd->__value_, __k)) goto __done; } } } { - __node_holder __h = __construct_node(_VSTD::forward<_ValueTp>(__x), __hash); +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node_hash(__hash, __args); +#endif if (size()+1 > __bc * max_load_factor() || __bc == 0) { rehash(_VSTD::max<size_type>(2 * __bc + !__is_hash_power2(__bc), @@ -1742,7 +2012,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique_value(const value_type __node_pointer __pn = __bucket_list_[__chash]; if (__pn == nullptr) { - __pn = static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first())); + __pn = static_cast<__node_pointer>(static_cast<__void_pointer>(pointer_traits<__node_base_pointer>::pointer_to(__p1_.first()))); __h->__next_ = __pn->__next_; __pn->__next_ = __h.get(); // fix up __bucket_list_ @@ -1768,13 +2038,12 @@ __done: #endif } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class... _Args> pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); pair<iterator, bool> __r = __node_insert_unique(__h.get()); @@ -1811,64 +2080,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( return __r; } -#endif // _LIBCPP_HAS_NO_VARIADICS +#else // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> -pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(value_type&& __x) -{ - return __insert_unique_value(_VSTD::move(__x)); -} - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _Pp> -pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_unique(_Pp&& __x) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); - pair<iterator, bool> __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _Pp> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(_Pp&& __x) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); - iterator __r = __node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -template <class _Pp> -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, - _Pp&& __x) -{ -#if _LIBCPP_DEBUG_LEVEL >= 2 - _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, - "unordered container::insert(const_iterator, rvalue) called with an iterator not" - " referring to this unordered container"); -#endif - __node_holder __h = __construct_node(_VSTD::forward<_Pp>(__x)); - iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); - return __r; -} - -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Tp, class _Hash, class _Equal, class _Alloc> -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const __container_value_type& __x) { __node_holder __h = __construct_node(__x); iterator __r = __node_insert_multi(__h.get()); @@ -1879,7 +2095,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const value_type& __x) template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, - const value_type& __x) + const __container_value_type& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, @@ -1892,7 +2108,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p, return __r; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> void @@ -1986,10 +2202,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) 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 ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return iterator(__nd, this); #else @@ -2015,10 +2232,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const if (__nd != nullptr) { for (__nd = __nd->__next_; __nd != nullptr && - __constrain_hash(__nd->__hash_, __bc) == __chash; + (__hash == __nd->__hash_ || __constrain_hash(__nd->__hash_, __bc) == __chash); __nd = __nd->__next_) { - if (key_eq()(__nd->__value_, __k)) + if ((__nd->__hash_ == __hash) && key_eq()(__nd->__value_, __k)) #if _LIBCPP_DEBUG_LEVEL >= 2 return const_iterator(__nd, this); #else @@ -2031,70 +2248,74 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const return end(); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> template <class ..._Args> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder __hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) { + static_assert(!__is_hash_value_type<_Args...>::value, + "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; __h->__hash_ = hash_function()(__h->__value_); __h->__next_ = nullptr; return __h; } -#endif // _LIBCPP_HAS_NO_VARIADICS - template <class _Tp, class _Hash, class _Equal, class _Alloc> +template <class _First, class ..._Rest> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(value_type&& __v, - size_t __hash) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( + size_t __hash, _First&& __f, _Rest&& ...__rest) { + static_assert(!__is_hash_value_type<_First, _Rest...>::value, + "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), + _VSTD::forward<_First>(__f), + _VSTD::forward<_Rest>(__rest)...); __h.get_deleter().__value_constructed = true; __h->__hash_ = __hash; __h->__next_ = nullptr; return __h; } -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#else // _LIBCPP_CXX03_LANG template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; __h->__hash_ = hash_function()(__h->__value_); __h->__next_ = nullptr; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _Tp, class _Hash, class _Equal, class _Alloc> typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(const value_type& __v, - size_t __hash) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, + const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; __h->__hash_ = __hash; __h->__next_ = nullptr; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } +#endif // _LIBCPP_CXX03_LANG + 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) diff --git a/contrib/libc++/include/__mutex_base b/contrib/libc++/include/__mutex_base index b019b47..38a76ac 100644 --- a/contrib/libc++/include/__mutex_base +++ b/contrib/libc++/include/__mutex_base @@ -14,9 +14,7 @@ #include <__config> #include <chrono> #include <system_error> -#ifndef _LIBCPP_HAS_NO_THREADS -#include <pthread.h> -#endif +#include <__threading_support> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -26,29 +24,41 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_THREADS -class _LIBCPP_TYPE_VIS mutex +#ifndef _LIBCPP_THREAD_SAFETY_ANNOTATION +# ifdef _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) __attribute__((x)) +# else +# define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) +# endif +#endif // _LIBCPP_THREAD_SAFETY_ANNOTATION + +class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex { - pthread_mutex_t __m_; +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; +#else + __libcpp_mutex_t __m_; +#endif public: _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_HAS_NO_CONSTEXPR - constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {} + constexpr mutex() _NOEXCEPT _LIBCPP_DEFAULT #else - mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;} + mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;} #endif - ~mutex(); + ~mutex(); private: mutex(const mutex&);// = delete; mutex& operator=(const mutex&);// = delete; public: - void lock(); - bool try_lock() _NOEXCEPT; - void unlock() _NOEXCEPT; + void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); + bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); + void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); - typedef pthread_mutex_t* native_handle_type; + typedef __libcpp_mutex_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} }; @@ -70,8 +80,21 @@ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); #endif + +// Forward declare lock_guard as a variadic template even in C++03 to keep +// the mangling consistent between dialects. +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) +template <class ..._Mutexes> +class _LIBCPP_TYPE_VIS_ONLY lock_guard; +#endif + template <class _Mutex> -class _LIBCPP_TYPE_VIS_ONLY lock_guard +class _LIBCPP_TYPE_VIS_ONLY _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) +#if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) +lock_guard +#else +lock_guard<_Mutex> +#endif { public: typedef _Mutex mutex_type; @@ -81,17 +104,17 @@ private: public: _LIBCPP_INLINE_VISIBILITY - explicit lock_guard(mutex_type& __m) + explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) : __m_(__m) {__m_.lock();} _LIBCPP_INLINE_VISIBILITY - lock_guard(mutex_type& __m, adopt_lock_t) + lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) : __m_(__m) {} _LIBCPP_INLINE_VISIBILITY - ~lock_guard() {__m_.unlock();} + ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();} private: - lock_guard(lock_guard const&);// = delete; - lock_guard& operator=(lock_guard const&);// = delete; + lock_guard(lock_guard const&) _LIBCPP_EQUAL_DELETE; + lock_guard& operator=(lock_guard const&) _LIBCPP_EQUAL_DELETE; }; template <class _Mutex> @@ -109,24 +132,24 @@ public: unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY explicit unique_lock(mutex_type& __m) - : __m_(&__m), __owns_(true) {__m_->lock();} + : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), __owns_(false) {} + : __m_(_VSTD::addressof(__m)), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), __owns_(__m.try_lock()) {} + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {} _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), __owns_(true) {} + : __m_(_VSTD::addressof(__m)), __owns_(true) {} template <class _Clock, class _Duration> _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) - : __m_(&__m), __owns_(__m.try_lock_until(__t)) {} + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {} template <class _Rep, class _Period> _LIBCPP_INLINE_VISIBILITY unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) - : __m_(&__m), __owns_(__m.try_lock_for(__d)) {} + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {} _LIBCPP_INLINE_VISIBILITY ~unique_lock() { @@ -268,13 +291,18 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) class _LIBCPP_TYPE_VIS condition_variable { - pthread_cond_t __cv_; +#ifndef _LIBCPP_HAS_NO_CONSTEXPR + __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; +#else + __libcpp_condvar_t __cv_; +#endif + public: _LIBCPP_INLINE_VISIBILITY #ifndef _LIBCPP_HAS_NO_CONSTEXPR - constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {} + constexpr condition_variable() _NOEXCEPT _LIBCPP_DEFAULT #else - condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;} + condition_variable() _NOEXCEPT {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;} #endif ~condition_variable(); @@ -313,7 +341,7 @@ public: const chrono::duration<_Rep, _Period>& __d, _Predicate __pred); - typedef pthread_cond_t* native_handle_type; + typedef __libcpp_condvar_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} private: diff --git a/contrib/libc++/include/__threading_support b/contrib/libc++/include/__threading_support new file mode 100644 index 0000000..c9a4ea9 --- /dev/null +++ b/contrib/libc++/include/__threading_support @@ -0,0 +1,205 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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_THREADING_SUPPORT +#define _LIBCPP_THREADING_SUPPORT + +#include <__config> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +#ifndef _LIBCPP_HAS_NO_THREADS + +#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) +#include <pthread.h> +#include <sched.h> +#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; + +inline _LIBCPP_ALWAYS_INLINE +int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m) +{ + pthread_mutexattr_t attr; + int __ec = pthread_mutexattr_init(&attr); + if (__ec) return __ec; + __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + if (__ec) + { + pthread_mutexattr_destroy(&attr); + return __ec; + } + __ec = pthread_mutex_init(__m, &attr); + if (__ec) + { + pthread_mutexattr_destroy(&attr); + return __ec; + } + __ec = pthread_mutexattr_destroy(&attr); + if (__ec) + { + pthread_mutex_destroy(__m); + return __ec; + } + 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*)) +{ + return pthread_key_create(__key, __at_exit); +} + +inline _LIBCPP_ALWAYS_INLINE +void* __libcpp_tl_get(__libcpp_tl_key __key) +{ + return pthread_getspecific(__key); +} + +inline _LIBCPP_ALWAYS_INLINE +void __libcpp_tl_set(__libcpp_tl_key __key, void* __p) +{ + pthread_setspecific(__key, __p); +} + +#else // !_LIBCPP_HAS_THREAD_API_PTHREAD + #error "No thread API selected." +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_NO_THREADS + +#endif // _LIBCPP_THREADING_SUPPORT diff --git a/contrib/libc++/include/__tree b/contrib/libc++/include/__tree index 94565bc..b560bf0 100644 --- a/contrib/libc++/include/__tree +++ b/contrib/libc++/include/__tree @@ -29,6 +29,22 @@ template <class _Tp, class _NodePtr, class _DiffType> template <class _Tp, class _ConstNodePtr, class _DiffType> class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; +template <class _Pointer> class __tree_end_node; +template <class _VoidPtr> class __tree_node_base; +template <class _Tp, class _VoidPtr> class __tree_node; + +#ifndef _LIBCPP_CXX03_LANG +template <class _Key, class _Value> +union __value_type; +#else +template <class _Key, class _Value> +struct __value_type; +#endif + +template <class _Allocator> class __map_node_destructor; +template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator; +template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; + /* _NodePtr algorithms @@ -149,21 +165,36 @@ __tree_next(_NodePtr __x) _NOEXCEPT if (__x->__right_ != nullptr) return __tree_min(__x->__right_); while (!__tree_is_left_child(__x)) - __x = __x->__parent_; - return __x->__parent_; + __x = __x->__parent_unsafe(); + return __x->__parent_unsafe(); +} + +template <class _EndNodePtr, class _NodePtr> +inline _LIBCPP_INLINE_VISIBILITY +_EndNodePtr +__tree_next_iter(_NodePtr __x) _NOEXCEPT +{ + if (__x->__right_ != nullptr) + return static_cast<_EndNodePtr>(__tree_min(__x->__right_)); + while (!__tree_is_left_child(__x)) + __x = __x->__parent_unsafe(); + return static_cast<_EndNodePtr>(__x->__parent_); } // Returns: pointer to the previous in-order node before __x. // Precondition: __x != nullptr. -template <class _NodePtr> +// Note: __x may be the end node. +template <class _NodePtr, class _EndNodePtr> +inline _LIBCPP_INLINE_VISIBILITY _NodePtr -__tree_prev(_NodePtr __x) _NOEXCEPT +__tree_prev_iter(_EndNodePtr __x) _NOEXCEPT { if (__x->__left_ != nullptr) return __tree_max(__x->__left_); - while (__tree_is_left_child(__x)) - __x = __x->__parent_; - return __x->__parent_; + _NodePtr __xx = static_cast<_NodePtr>(__x); + while (__tree_is_left_child(__xx)) + __xx = __xx->__parent_unsafe(); + return __xx->__parent_unsafe(); } // Returns: pointer to a node which has no children @@ -199,14 +230,14 @@ __tree_left_rotate(_NodePtr __x) _NOEXCEPT _NodePtr __y = __x->__right_; __x->__right_ = __y->__left_; if (__x->__right_ != nullptr) - __x->__right_->__parent_ = __x; + __x->__right_->__set_parent(__x); __y->__parent_ = __x->__parent_; if (__tree_is_left_child(__x)) __x->__parent_->__left_ = __y; else - __x->__parent_->__right_ = __y; + __x->__parent_unsafe()->__right_ = __y; __y->__left_ = __x; - __x->__parent_ = __y; + __x->__set_parent(__y); } // Effects: Makes __x->__left_ the subtree root with __x as its right child @@ -219,14 +250,14 @@ __tree_right_rotate(_NodePtr __x) _NOEXCEPT _NodePtr __y = __x->__left_; __x->__left_ = __y->__right_; if (__x->__left_ != nullptr) - __x->__left_->__parent_ = __x; + __x->__left_->__set_parent(__x); __y->__parent_ = __x->__parent_; if (__tree_is_left_child(__x)) __x->__parent_->__left_ = __y; else - __x->__parent_->__right_ = __y; + __x->__parent_unsafe()->__right_ = __y; __y->__right_ = __x; - __x->__parent_ = __y; + __x->__set_parent(__y); } // Effects: Rebalances __root after attaching __x to a leaf. @@ -242,17 +273,17 @@ void __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { __x->__is_black_ = __x == __root; - while (__x != __root && !__x->__parent_->__is_black_) + while (__x != __root && !__x->__parent_unsafe()->__is_black_) { // __x->__parent_ != __root because __x->__parent_->__is_black == false - if (__tree_is_left_child(__x->__parent_)) + if (__tree_is_left_child(__x->__parent_unsafe())) { - _NodePtr __y = __x->__parent_->__parent_->__right_; + _NodePtr __y = __x->__parent_unsafe()->__parent_unsafe()->__right_; if (__y != nullptr && !__y->__is_black_) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = __x == __root; __y->__is_black_ = true; } @@ -260,12 +291,12 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { if (!__tree_is_left_child(__x)) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __tree_left_rotate(__x); } - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = false; __tree_right_rotate(__x); break; @@ -273,12 +304,12 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT } else { - _NodePtr __y = __x->__parent_->__parent_->__left_; + _NodePtr __y = __x->__parent_unsafe()->__parent_->__left_; if (__y != nullptr && !__y->__is_black_) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = __x == __root; __y->__is_black_ = true; } @@ -286,12 +317,12 @@ __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT { if (__tree_is_left_child(__x)) { - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __tree_right_rotate(__x); } - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = true; - __x = __x->__parent_; + __x = __x->__parent_unsafe(); __x->__is_black_ = false; __tree_left_rotate(__x); break; @@ -328,13 +359,13 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT { __y->__parent_->__left_ = __x; if (__y != __root) - __w = __y->__parent_->__right_; + __w = __y->__parent_unsafe()->__right_; else __root = __x; // __w == nullptr } else { - __y->__parent_->__right_ = __x; + __y->__parent_unsafe()->__right_ = __x; // __y can't be root if it is a right child __w = __y->__parent_->__left_; } @@ -348,12 +379,12 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT if (__tree_is_left_child(__z)) __y->__parent_->__left_ = __y; else - __y->__parent_->__right_ = __y; + __y->__parent_unsafe()->__right_ = __y; __y->__left_ = __z->__left_; - __y->__left_->__parent_ = __y; + __y->__left_->__set_parent(__y); __y->__right_ = __z->__right_; if (__y->__right_ != nullptr) - __y->__right_->__parent_ = __y; + __y->__right_->__set_parent(__y); __y->__is_black_ = __z->__is_black_; if (__root == __z) __root = __y; @@ -390,8 +421,8 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT if (!__w->__is_black_) { __w->__is_black_ = true; - __w->__parent_->__is_black_ = false; - __tree_left_rotate(__w->__parent_); + __w->__parent_unsafe()->__is_black_ = false; + __tree_left_rotate(__w->__parent_unsafe()); // __x is still valid // reset __root only if necessary if (__root == __w->__left_) @@ -404,7 +435,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT (__w->__right_ == nullptr || __w->__right_->__is_black_)) { __w->__is_black_ = false; - __x = __w->__parent_; + __x = __w->__parent_unsafe(); // __x can no longer be null if (__x == __root || !__x->__is_black_) { @@ -413,7 +444,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT } // reset sibling, and it still can't be null __w = __tree_is_left_child(__x) ? - __x->__parent_->__right_ : + __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; // continue; } @@ -427,13 +458,13 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT __tree_right_rotate(__w); // __w is known not to be root, so root hasn't changed // reset sibling, and it still can't be null - __w = __w->__parent_; + __w = __w->__parent_unsafe(); } // __w has a right red child, left child may be null - __w->__is_black_ = __w->__parent_->__is_black_; - __w->__parent_->__is_black_ = true; + __w->__is_black_ = __w->__parent_unsafe()->__is_black_; + __w->__parent_unsafe()->__is_black_ = true; __w->__right_->__is_black_ = true; - __tree_left_rotate(__w->__parent_); + __tree_left_rotate(__w->__parent_unsafe()); break; } } @@ -442,8 +473,8 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT if (!__w->__is_black_) { __w->__is_black_ = true; - __w->__parent_->__is_black_ = false; - __tree_right_rotate(__w->__parent_); + __w->__parent_unsafe()->__is_black_ = false; + __tree_right_rotate(__w->__parent_unsafe()); // __x is still valid // reset __root only if necessary if (__root == __w->__right_) @@ -456,7 +487,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT (__w->__right_ == nullptr || __w->__right_->__is_black_)) { __w->__is_black_ = false; - __x = __w->__parent_; + __x = __w->__parent_unsafe(); // __x can no longer be null if (!__x->__is_black_ || __x == __root) { @@ -465,7 +496,7 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT } // reset sibling, and it still can't be null __w = __tree_is_left_child(__x) ? - __x->__parent_->__right_ : + __x->__parent_unsafe()->__right_ : __x->__parent_->__left_; // continue; } @@ -479,13 +510,13 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT __tree_left_rotate(__w); // __w is known not to be root, so root hasn't changed // reset sibling, and it still can't be null - __w = __w->__parent_; + __w = __w->__parent_unsafe(); } // __w has a left red child, right child may be null - __w->__is_black_ = __w->__parent_->__is_black_; - __w->__parent_->__is_black_ = true; + __w->__is_black_ = __w->__parent_unsafe()->__is_black_; + __w->__parent_unsafe()->__is_black_ = true; __w->__left_->__is_black_ = true; - __tree_right_rotate(__w->__parent_); + __tree_right_rotate(__w->__parent_unsafe()); break; } } @@ -494,41 +525,182 @@ __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT } } -template <class _Allocator> class __map_node_destructor; +// node traits + + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp> +struct __is_tree_value_type_imp : false_type {}; + +template <class _Key, class _Value> +struct __is_tree_value_type_imp<__value_type<_Key, _Value>> : true_type {}; + +template <class ..._Args> +struct __is_tree_value_type : false_type {}; + +template <class _One> +struct __is_tree_value_type<_One> : __is_tree_value_type_imp<typename __uncvref<_One>::type> {}; +#endif + +template <class _Tp> +struct __tree_key_value_types { + typedef _Tp key_type; + typedef _Tp __node_value_type; + typedef _Tp __container_value_type; + static const bool __is_map = false; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& __get_key(_Tp const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& __get_value(__node_value_type const& __v) { + return __v; + } + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n); + } + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __container_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v); + } +#endif +}; + +template <class _Key, class _Tp> +struct __tree_key_value_types<__value_type<_Key, _Tp> > { + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __value_type<_Key, _Tp> __node_value_type; + typedef pair<const _Key, _Tp> __container_value_type; + typedef pair<_Key, _Tp> __nc_value_type; + typedef __container_value_type __map_value_type; + static const bool __is_map = true; + + _LIBCPP_INLINE_VISIBILITY + static key_type const& + __get_key(__node_value_type const& __t) { + return __t.__cc.first; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + key_type const&>::type + __get_key(_Up& __t) { + return __t.first; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type const& + __get_value(__node_value_type const& __t) { + return __t.__cc; + } + + template <class _Up> + _LIBCPP_INLINE_VISIBILITY + static typename enable_if<__is_same_uncvref<_Up, __container_value_type>::value, + __container_value_type const&>::type + __get_value(_Up& __t) { + return __t; + } + + _LIBCPP_INLINE_VISIBILITY + static __container_value_type* __get_ptr(__node_value_type& __n) { + return _VSTD::addressof(__n.__cc); + } + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + static __nc_value_type&& __move(__node_value_type& __v) { + return _VSTD::move(__v.__nc); + } +#endif +}; + +template <class _VoidPtr> +struct __tree_node_base_types { + typedef _VoidPtr __void_pointer; + + typedef __tree_node_base<__void_pointer> __node_base_type; + typedef typename __rebind_pointer<_VoidPtr, __node_base_type>::type + __node_base_pointer; + + typedef __tree_end_node<__node_base_pointer> __end_node_type; + typedef typename __rebind_pointer<_VoidPtr, __end_node_type>::type + __end_node_pointer; +#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) + typedef __end_node_pointer __parent_pointer; +#else + typedef typename conditional< + is_pointer<__end_node_pointer>::value, + __end_node_pointer, + __node_base_pointer>::type __parent_pointer; +#endif -template <class _Allocator> -class __tree_node_destructor -{ - typedef _Allocator allocator_type; - typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; -public: - typedef typename __alloc_traits::pointer pointer; private: + static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, void>::value), + "_VoidPtr does not point to unqualified void type"); +}; - allocator_type& __na_; +template <class _Tp, class _AllocPtr, class _KVTypes = __tree_key_value_types<_Tp>, + bool = _KVTypes::__is_map> +struct __tree_map_pointer_types {}; + +template <class _Tp, class _AllocPtr, class _KVTypes> +struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { + typedef typename _KVTypes::__map_value_type _Mv; + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type + __map_value_type_pointer; + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type + __const_map_value_type_pointer; +}; - __tree_node_destructor& operator=(const __tree_node_destructor&); +template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type> +struct __tree_node_types; +template <class _NodePtr, class _Tp, class _VoidPtr> +struct __tree_node_types<_NodePtr, __tree_node<_Tp, _VoidPtr> > + : public __tree_node_base_types<_VoidPtr>, + __tree_key_value_types<_Tp>, + __tree_map_pointer_types<_Tp, _VoidPtr> +{ + typedef __tree_node_base_types<_VoidPtr> __base; + typedef __tree_key_value_types<_Tp> __key_base; + typedef __tree_map_pointer_types<_Tp, _VoidPtr> __map_pointer_base; public: - bool __value_constructed; - _LIBCPP_INLINE_VISIBILITY - explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT - : __na_(__na), - __value_constructed(__val) - {} - - _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) _NOEXCEPT - { - if (__value_constructed) - __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_)); - if (__p) - __alloc_traits::deallocate(__na_, __p, 1); - } + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_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; +#if defined(_LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB) + typedef typename __base::__end_node_pointer __iter_pointer; +#else + typedef typename conditional< + is_pointer<__node_pointer>::value, + typename __base::__end_node_pointer, + __node_pointer>::type __iter_pointer; +#endif +private: + static_assert(!is_const<__node_type>::value, + "_NodePtr should never be a pointer to const"); + static_assert((is_same<typename __rebind_pointer<_VoidPtr, __node_type>::type, + _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); +}; - template <class> friend class __map_node_destructor; +template <class _ValueTp, class _VoidPtr> +struct __make_tree_node_types { + typedef typename __rebind_pointer<_VoidPtr, __tree_node<_ValueTp, _VoidPtr> >::type + _NodePtr; + typedef __tree_node_types<_NodePtr> type; }; // node @@ -546,26 +718,30 @@ public: template <class _VoidPtr> class __tree_node_base - : public __tree_end_node - < - typename __rebind_pointer<_VoidPtr, __tree_node_base<_VoidPtr> >::type - > + : public __tree_node_base_types<_VoidPtr>::__end_node_type { - __tree_node_base(const __tree_node_base&); - __tree_node_base& operator=(const __tree_node_base&); -public: - typedef typename __rebind_pointer<_VoidPtr, __tree_node_base>::type pointer; - typedef typename __rebind_pointer<_VoidPtr, const __tree_node_base>::type const_pointer; + typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes; - typedef __tree_end_node<pointer> base; +public: + typedef typename _NodeBaseTypes::__node_base_pointer pointer; + typedef typename _NodeBaseTypes::__parent_pointer __parent_pointer; - pointer __right_; - pointer __parent_; + pointer __right_; + __parent_pointer __parent_; bool __is_black_; _LIBCPP_INLINE_VISIBILITY - __tree_node_base() _NOEXCEPT - : __right_(), __parent_(), __is_black_(false) {} + pointer __parent_unsafe() const { return static_cast<pointer>(__parent_);} + + _LIBCPP_INLINE_VISIBILITY + void __set_parent(pointer __p) { + __parent_ = static_cast<__parent_pointer>(__p); + } + +private: + ~__tree_node_base() _LIBCPP_EQUAL_DELETE; + __tree_node_base(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; + __tree_node_base& operator=(__tree_node_base const&) _LIBCPP_EQUAL_DELETE; }; template <class _Tp, class _VoidPtr> @@ -573,41 +749,71 @@ class __tree_node : public __tree_node_base<_VoidPtr> { public: - typedef __tree_node_base<_VoidPtr> base; - typedef _Tp value_type; + typedef _Tp __node_value_type; - value_type __value_; + __node_value_type __value_; + +private: + ~__tree_node() _LIBCPP_EQUAL_DELETE; + __tree_node(__tree_node const&) _LIBCPP_EQUAL_DELETE; + __tree_node& operator=(__tree_node const&) _LIBCPP_EQUAL_DELETE; +}; + + +template <class _Allocator> +class __tree_node_destructor +{ + typedef _Allocator allocator_type; + typedef allocator_traits<allocator_type> __alloc_traits; + +public: + typedef typename __alloc_traits::pointer pointer; +private: + typedef __tree_node_types<pointer> _NodeTypes; + allocator_type& __na_; + + __tree_node_destructor& operator=(const __tree_node_destructor&); + +public: + bool __value_constructed; -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - template <class ..._Args> - _LIBCPP_INLINE_VISIBILITY - explicit __tree_node(_Args&& ...__args) - : __value_(_VSTD::forward<_Args>(__args)...) {} -#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) _LIBCPP_INLINE_VISIBILITY - explicit __tree_node(const value_type& __v) - : __value_(__v) {} -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) + explicit __tree_node_destructor(allocator_type& __na, bool __val = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__val) + {} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT + { + if (__value_constructed) + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } + + template <class> friend class __map_node_destructor; }; -template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator; -template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; template <class _Tp, class _NodePtr, class _DiffType> class _LIBCPP_TYPE_VIS_ONLY __tree_iterator { - typedef _NodePtr __node_pointer; - typedef typename pointer_traits<__node_pointer>::element_type __node; + typedef __tree_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + typedef pointer_traits<__node_pointer> __pointer_traits; - __node_pointer __ptr_; + __iter_pointer __ptr_; - typedef pointer_traits<__node_pointer> __pointer_traits; public: - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _DiffType difference_type; - typedef value_type& reference; - typedef typename __rebind_pointer<__node_pointer, value_type>::type pointer; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -615,14 +821,15 @@ public: #endif {} - _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY reference operator*() const + {return __get_np()->__value_;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const - {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} _LIBCPP_INLINE_VISIBILITY __tree_iterator& operator++() { - __ptr_ = static_cast<__node_pointer>( - __tree_next(static_cast<typename __node::base::pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>( + __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -631,8 +838,8 @@ public: _LIBCPP_INLINE_VISIBILITY __tree_iterator& operator--() { - __ptr_ = static_cast<__node_pointer>( - __tree_prev(static_cast<typename __node::base::pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( + static_cast<__end_node_pointer>(__ptr_))); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -649,6 +856,10 @@ public: private: _LIBCPP_INLINE_VISIBILITY explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + explicit __tree_iterator(__end_node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } template <class, class, class> friend class __tree; template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator; @@ -658,21 +869,24 @@ private: template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset; }; -template <class _Tp, class _ConstNodePtr, class _DiffType> +template <class _Tp, class _NodePtr, class _DiffType> class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator { - typedef _ConstNodePtr __node_pointer; - typedef typename pointer_traits<__node_pointer>::element_type __node; + typedef __tree_node_types<_NodePtr> _NodeTypes; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__end_node_pointer __end_node_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; + typedef pointer_traits<__node_pointer> __pointer_traits; - __node_pointer __ptr_; + __iter_pointer __ptr_; - typedef pointer_traits<__node_pointer> __pointer_traits; public: - typedef bidirectional_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _DiffType difference_type; - typedef const value_type& reference; - typedef typename __rebind_pointer<__node_pointer, const value_type>::type pointer; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _DiffType difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT #if _LIBCPP_STD_VER > 11 @@ -681,26 +895,22 @@ public: {} private: - typedef typename remove_const<__node>::type __non_const_node; - typedef typename __rebind_pointer<__node_pointer, __non_const_node>::type - __non_const_node_pointer; - typedef __tree_iterator<value_type, __non_const_node_pointer, difference_type> - __non_const_iterator; + typedef __tree_iterator<value_type, __node_pointer, difference_type> + __non_const_iterator; public: _LIBCPP_INLINE_VISIBILITY __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {} - _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __ptr_->__value_;} + _LIBCPP_INLINE_VISIBILITY reference operator*() const + {return __get_np()->__value_;} _LIBCPP_INLINE_VISIBILITY pointer operator->() const - {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + {return pointer_traits<pointer>::pointer_to(__get_np()->__value_);} _LIBCPP_INLINE_VISIBILITY __tree_const_iterator& operator++() { - typedef typename __rebind_pointer<__node_pointer, typename __node::base>::type - __node_base_pointer; - __ptr_ = static_cast<__node_pointer>( - __tree_next(static_cast<__node_base_pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>( + __tree_next_iter<__end_node_pointer>(static_cast<__node_base_pointer>(__ptr_))); return *this; } @@ -710,10 +920,8 @@ public: _LIBCPP_INLINE_VISIBILITY __tree_const_iterator& operator--() { - typedef typename __rebind_pointer<__node_pointer, typename __node::base>::type - __node_base_pointer; - __ptr_ = static_cast<__node_pointer>( - __tree_prev(static_cast<__node_base_pointer>(__ptr_))); + __ptr_ = static_cast<__iter_pointer>(__tree_prev_iter<__node_base_pointer>( + static_cast<__end_node_pointer>(__ptr_))); return *this; } @@ -732,12 +940,19 @@ private: _LIBCPP_INLINE_VISIBILITY explicit __tree_const_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + explicit __tree_const_iterator(__end_node_pointer __p) _NOEXCEPT + : __ptr_(__p) {} + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_np() const { return static_cast<__node_pointer>(__ptr_); } + template <class, class, class> friend class __tree; template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map; template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap; template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set; template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset; template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator; + }; template <class _Tp, class _Compare, class _Allocator> @@ -747,48 +962,73 @@ public: typedef _Tp value_type; typedef _Compare value_compare; typedef _Allocator allocator_type; + +private: typedef allocator_traits<allocator_type> __alloc_traits; + typedef typename __make_tree_node_types<value_type, + typename __alloc_traits::void_pointer>::type + _NodeTypes; + typedef typename _NodeTypes::key_type key_type; +public: + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; typedef typename __alloc_traits::size_type size_type; typedef typename __alloc_traits::difference_type difference_type; - typedef typename __alloc_traits::void_pointer __void_pointer; +public: + typedef typename _NodeTypes::__void_pointer __void_pointer; + + typedef typename _NodeTypes::__node_type __node; + typedef typename _NodeTypes::__node_pointer __node_pointer; + + typedef typename _NodeTypes::__node_base_type __node_base; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + + typedef typename _NodeTypes::__end_node_type __end_node_t; + typedef typename _NodeTypes::__end_node_pointer __end_node_ptr; + + typedef typename _NodeTypes::__parent_pointer __parent_pointer; + typedef typename _NodeTypes::__iter_pointer __iter_pointer; - typedef __tree_node<value_type, __void_pointer> __node; - typedef __tree_node_base<__void_pointer> __node_base; typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type __node_allocator; - typedef allocator_traits<__node_allocator> __node_traits; - typedef typename __node_traits::pointer __node_pointer; - typedef typename __node_traits::pointer __node_const_pointer; - typedef typename __node_base::pointer __node_base_pointer; - typedef typename __node_base::pointer __node_base_const_pointer; + typedef allocator_traits<__node_allocator> __node_traits; + private: - typedef typename __node_base::base __end_node_t; - typedef typename __rebind_pointer<__node_pointer, __end_node_t>::type - __end_node_ptr; - typedef __end_node_ptr __end_node_const_ptr; + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); + typedef typename __rebind_alloc_helper<__node_traits, __node_base>::type + __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), + "Allocator does not rebind pointers in a sane manner."); - __node_pointer __begin_node_; +private: + __iter_pointer __begin_node_; __compressed_pair<__end_node_t, __node_allocator> __pair1_; __compressed_pair<size_type, value_compare> __pair3_; public: _LIBCPP_INLINE_VISIBILITY - __node_pointer __end_node() _NOEXCEPT + __iter_pointer __end_node() _NOEXCEPT { - return static_cast<__node_pointer> - ( - pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) - ); + return static_cast<__iter_pointer>( + pointer_traits<__end_node_ptr>::pointer_to(__pair1_.first()) + ); } _LIBCPP_INLINE_VISIBILITY - __node_const_pointer __end_node() const _NOEXCEPT + __iter_pointer __end_node() const _NOEXCEPT { - return static_cast<__node_const_pointer> - ( - pointer_traits<__end_node_const_ptr>::pointer_to(const_cast<__end_node_t&>(__pair1_.first())) - ); + return static_cast<__iter_pointer>( + pointer_traits<__end_node_ptr>::pointer_to( + const_cast<__end_node_t&>(__pair1_.first()) + ) + ); } _LIBCPP_INLINE_VISIBILITY __node_allocator& __node_alloc() _NOEXCEPT {return __pair1_.second();} @@ -797,9 +1037,9 @@ private: const __node_allocator& __node_alloc() const _NOEXCEPT {return __pair1_.second();} _LIBCPP_INLINE_VISIBILITY - __node_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} + __iter_pointer& __begin_node() _NOEXCEPT {return __begin_node_;} _LIBCPP_INLINE_VISIBILITY - const __node_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} + const __iter_pointer& __begin_node() const _NOEXCEPT {return __begin_node_;} public: _LIBCPP_INLINE_VISIBILITY allocator_type __alloc() const _NOEXCEPT @@ -816,12 +1056,14 @@ public: const value_compare& value_comp() const _NOEXCEPT {return __pair3_.second();} public: + _LIBCPP_INLINE_VISIBILITY - __node_pointer __root() _NOEXCEPT - {return static_cast<__node_pointer> (__end_node()->__left_);} - _LIBCPP_INLINE_VISIBILITY - __node_const_pointer __root() const _NOEXCEPT - {return static_cast<__node_const_pointer>(__end_node()->__left_);} + __node_pointer __root() const _NOEXCEPT + {return static_cast<__node_pointer>(__end_node()->__left_);} + + __node_base_pointer* __root_ptr() const _NOEXCEPT { + return _VSTD::addressof(__end_node()->__left_); + } typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator; typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator; @@ -877,45 +1119,195 @@ public: #endif ); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS + +#ifndef _LIBCPP_CXX03_LANG + template <class _Key, class ..._Args> + pair<iterator, bool> + __emplace_unique_key_args(_Key const&, _Args&&... __args); + template <class _Key, class ..._Args> + iterator + __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); + template <class... _Args> - pair<iterator, bool> - __emplace_unique(_Args&&... __args); + pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); + template <class... _Args> - iterator - __emplace_multi(_Args&&... __args); + iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); template <class... _Args> - iterator - __emplace_hint_unique(const_iterator __p, _Args&&... __args); + iterator __emplace_multi(_Args&&... __args); + template <class... _Args> + iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class _First, class _Second> + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, + pair<iterator, bool> + >::type __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { + return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class _First, class _Second> + _LIBCPP_INLINE_VISIBILITY + typename enable_if< + __can_extract_map_key<_First, key_type, __container_value_type>::value, iterator - __emplace_hint_multi(const_iterator __p, _Args&&... __args); -#endif // _LIBCPP_HAS_NO_VARIADICS + >::type __emplace_hint_unique(const_iterator __p, _First&& __f, _Second&& __s) { + return __emplace_hint_unique_key_args(__p, __f, + _VSTD::forward<_First>(__f), + _VSTD::forward<_Second>(__s)); + } - template <class _Vp> - pair<iterator, bool> __insert_unique(_Vp&& __v); - template <class _Vp> - iterator __insert_unique(const_iterator __p, _Vp&& __v); - template <class _Vp> - iterator __insert_multi(_Vp&& __v); - template <class _Vp> - iterator __insert_multi(const_iterator __p, _Vp&& __v); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); + } - pair<iterator, bool> __insert_unique(const value_type& __v); - iterator __insert_unique(const_iterator __p, const value_type& __v); - iterator __insert_multi(const value_type& __v); - iterator __insert_multi(const_iterator __p, const value_type& __v); + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); + } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - pair<iterator, bool> __insert_unique( value_type&& __v); - iterator __insert_unique(const_iterator __p, value_type&& __v); - iterator __insert_multi( value_type&& __v); - iterator __insert_multi(const_iterator __p, value_type&& __v); + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { + return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { + return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); + } + +#else + template <class _Key, class _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique_key_args(_Key const&, _Args& __args); + template <class _Key, class _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&); #endif + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(const __container_value_type& __v) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__v), __v); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, const __container_value_type& __v) { + return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), __v); + } + +#ifdef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const __container_value_type& __v); + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, const __container_value_type& __v); +#else + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(__container_value_type&& __v) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__v), _VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, __container_value_type&& __v) { + return __emplace_hint_unique_key_args(__p, _NodeTypes::__get_key(__v), _VSTD::move(__v)); + } + + template <class _Vp, class = typename enable_if< + !is_same<typename __unconstref<_Vp>::type, + __container_value_type + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __insert_unique(_Vp&& __v) { + return __emplace_unique(_VSTD::forward<_Vp>(__v)); + } + + template <class _Vp, class = typename enable_if< + !is_same<typename __unconstref<_Vp>::type, + __container_value_type + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_unique(const_iterator __p, _Vp&& __v) { + return __emplace_hint_unique(__p, _VSTD::forward<_Vp>(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(__container_value_type&& __v) { + return __emplace_multi(_VSTD::move(__v)); + } + + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, __container_value_type&& __v) { + return __emplace_hint_multi(__p, _VSTD::move(__v)); + } + + template <class _Vp> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(_Vp&& __v) { + return __emplace_multi(_VSTD::forward<_Vp>(__v)); + } + + template <class _Vp> + _LIBCPP_INLINE_VISIBILITY + iterator __insert_multi(const_iterator __p, _Vp&& __v) { + return __emplace_hint_multi(__p, _VSTD::forward<_Vp>(__v)); + } + +#endif // !_LIBCPP_CXX03_LANG + pair<iterator, bool> __node_insert_unique(__node_pointer __nd); iterator __node_insert_unique(const_iterator __p, __node_pointer __nd); @@ -930,7 +1322,7 @@ public: template <class _Key> size_type __erase_multi(const _Key& __k); - void __insert_node_at(__node_base_pointer __parent, + void __insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node); @@ -951,15 +1343,15 @@ public: template <class _Key> iterator __lower_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result); + __iter_pointer __result); template <class _Key> _LIBCPP_INLINE_VISIBILITY const_iterator lower_bound(const _Key& __v) const {return __lower_bound(__v, __root(), __end_node());} template <class _Key> const_iterator __lower_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const; + __node_pointer __root, + __iter_pointer __result) const; template <class _Key> _LIBCPP_INLINE_VISIBILITY iterator upper_bound(const _Key& __v) @@ -967,15 +1359,15 @@ public: template <class _Key> iterator __upper_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result); + __iter_pointer __result); template <class _Key> _LIBCPP_INLINE_VISIBILITY const_iterator upper_bound(const _Key& __v) const {return __upper_bound(__v, __root(), __end_node());} template <class _Key> const_iterator __upper_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const; + __node_pointer __root, + __iter_pointer __result) const; template <class _Key> pair<iterator, iterator> __equal_range_unique(const _Key& __k); @@ -995,26 +1387,27 @@ public: __node_holder remove(const_iterator __p) _NOEXCEPT; private: - typename __node_base::pointer& - __find_leaf_low(typename __node_base::pointer& __parent, const value_type& __v); - typename __node_base::pointer& - __find_leaf_high(typename __node_base::pointer& __parent, const value_type& __v); - typename __node_base::pointer& + __node_base_pointer& + __find_leaf_low(__parent_pointer& __parent, const key_type& __v); + __node_base_pointer& + __find_leaf_high(__parent_pointer& __parent, const key_type& __v); + __node_base_pointer& __find_leaf(const_iterator __hint, - typename __node_base::pointer& __parent, const value_type& __v); + __parent_pointer& __parent, const key_type& __v); template <class _Key> - typename __node_base::pointer& - __find_equal(typename __node_base::pointer& __parent, const _Key& __v); + __node_base_pointer& + __find_equal(__parent_pointer& __parent, const _Key& __v); template <class _Key> - typename __node_base::pointer& - __find_equal(const_iterator __hint, typename __node_base::pointer& __parent, + __node_base_pointer& + __find_equal(const_iterator __hint, __parent_pointer& __parent, + __node_base_pointer& __dummy, const _Key& __v); -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - __node_holder __construct_node(_Args&& ...__args); -#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - __node_holder __construct_node(const value_type& __v); + __node_holder __construct_node(_Args&& ...__args); +#else + __node_holder __construct_node(const __container_value_type& __v); #endif void destroy(__node_pointer __nd) _NOEXCEPT; @@ -1026,7 +1419,11 @@ private: _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __tree& __t, true_type) - {__node_alloc() = __t.__node_alloc();} + { + if (__node_alloc() != __t.__node_alloc()) + clear(); + __node_alloc() = __t.__node_alloc(); + } _LIBCPP_INLINE_VISIBILITY void __copy_assign_alloc(const __tree& __t, false_type) {} @@ -1069,7 +1466,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp) template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) - : __begin_node_(__node_pointer()), + : __begin_node_(__iter_pointer()), __pair1_(__node_allocator(__a)), __pair3_(0) { @@ -1079,7 +1476,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(const allocator_type& __a) template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(const value_compare& __comp, const allocator_type& __a) - : __begin_node_(__node_pointer()), + : __begin_node_(__iter_pointer()), __pair1_(__node_allocator(__a)), __pair3_(0, __comp) { @@ -1091,7 +1488,7 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::__node_pointer __tree<_Tp, _Compare, _Allocator>::__detach() { - __node_pointer __cache = __begin_node(); + __node_pointer __cache = static_cast<__node_pointer>(__begin_node()); __begin_node() = __end_node(); __end_node()->__left_->__parent_ = nullptr; __end_node()->__left_ = nullptr; @@ -1123,7 +1520,7 @@ __tree<_Tp, _Compare, _Allocator>::__detach(__node_pointer __cache) return static_cast<__node_pointer>(__tree_leaf(__cache->__right_)); } // __cache is right child - __cache->__parent_->__right_ = nullptr; + __cache->__parent_unsafe()->__right_ = nullptr; __cache = static_cast<__node_pointer>(__cache->__parent_); if (__cache->__left_ == nullptr) return __cache; @@ -1148,6 +1545,11 @@ template <class _InputIterator> void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value), + "__assign_unique may only be called with the containers value type"); + if (size() != 0) { __node_pointer __cache = __detach(); @@ -1188,6 +1590,12 @@ template <class _InputIterator> void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert((is_same<_ItValueType, __container_value_type>::value || + is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); if (size() != 0) { __node_pointer __cache = __detach(); @@ -1220,12 +1628,12 @@ __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _Input } } for (; __first != __last; ++__first) - __insert_multi(*__first); + __insert_multi(_NodeTypes::__get_value(*__first)); } template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::__tree(const __tree& __t) - : __begin_node_(__node_pointer()), + : __begin_node_(__iter_pointer()), __pair1_(__node_traits::select_on_container_copy_construction(__t.__node_alloc())), __pair3_(0, __t.value_comp()) { @@ -1247,7 +1655,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t) __begin_node() = __end_node(); else { - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; @@ -1267,7 +1675,7 @@ __tree<_Tp, _Compare, _Allocator>::__tree(__tree&& __t, const allocator_type& __ { __begin_node() = __t.__begin_node(); __end_node()->__left_ = __t.__end_node()->__left_; - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); size() = __t.size(); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; @@ -1295,7 +1703,7 @@ __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, true_type) __begin_node() = __end_node(); else { - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); __t.__begin_node() = __t.__end_node(); __t.__end_node()->__left_ = nullptr; __t.size() = 0; @@ -1344,7 +1752,7 @@ __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) } } while (__t.size() != 0) - __insert_multi(__e, _VSTD::move(__t.remove(__t.begin())->__value_)); + __insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_)); } } @@ -1367,6 +1775,8 @@ __tree<_Tp, _Compare, _Allocator>::operator=(__tree&& __t) template <class _Tp, class _Compare, class _Allocator> __tree<_Tp, _Compare, _Allocator>::~__tree() { + static_assert((is_copy_constructible<value_compare>::value), + "Comparator must be copy-constructible."); destroy(__root()); } @@ -1379,7 +1789,7 @@ __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT destroy(static_cast<__node_pointer>(__nd->__left_)); destroy(static_cast<__node_pointer>(__nd->__right_)); __node_allocator& __na = __node_alloc(); - __node_traits::destroy(__na, _VSTD::addressof(__nd->__value_)); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_)); __node_traits::deallocate(__na, __nd, 1); } } @@ -1403,11 +1813,11 @@ __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) if (size() == 0) __begin_node() = __end_node(); else - __end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__end_node()); + __end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__end_node()); if (__t.size() == 0) __t.__begin_node() = __t.__end_node(); else - __t.__end_node()->__left_->__parent_ = static_cast<__node_base_pointer>(__t.__end_node()); + __t.__end_node()->__left_->__parent_ = static_cast<__parent_pointer>(__t.__end_node()); } template <class _Tp, class _Compare, class _Allocator> @@ -1424,9 +1834,9 @@ __tree<_Tp, _Compare, _Allocator>::clear() _NOEXCEPT // Set __parent to parent of null leaf // Return reference to null leaf template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& -__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer& __parent, - const value_type& __v) +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_low(__parent_pointer& __parent, + const key_type& __v) { __node_pointer __nd = __root(); if (__nd != nullptr) @@ -1439,8 +1849,8 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer __nd = static_cast<__node_pointer>(__nd->__right_); else { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; } } else @@ -1449,13 +1859,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer __nd = static_cast<__node_pointer>(__nd->__left_); else { - __parent = static_cast<__node_base_pointer>(__nd); + __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } } } - __parent = static_cast<__node_base_pointer>(__end_node()); + __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } @@ -1463,9 +1873,9 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_low(typename __node_base::pointer // Set __parent to parent of null leaf // Return reference to null leaf template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& -__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointer& __parent, - const value_type& __v) +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_leaf_high(__parent_pointer& __parent, + const key_type& __v) { __node_pointer __nd = __root(); if (__nd != nullptr) @@ -1478,7 +1888,7 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointe __nd = static_cast<__node_pointer>(__nd->__left_); else { - __parent = static_cast<__node_base_pointer>(__nd); + __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } @@ -1488,13 +1898,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointe __nd = static_cast<__node_pointer>(__nd->__right_); else { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; } } } } - __parent = static_cast<__node_base_pointer>(__end_node()); + __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } @@ -1505,10 +1915,10 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf_high(typename __node_base::pointe // Set __parent to parent of null leaf // Return reference to null leaf template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, - typename __node_base::pointer& __parent, - const value_type& __v) + __parent_pointer& __parent, + const key_type& __v) { if (__hint == end() || !value_comp()(*__hint, __v)) // check before { @@ -1519,13 +1929,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, // *prev(__hint) <= __v <= *__hint if (__hint.__ptr_->__left_ == nullptr) { - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + __parent = static_cast<__parent_pointer>(__hint.__ptr_); return __parent->__left_; } else { - __parent = static_cast<__node_base_pointer>(__prior.__ptr_); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__prior.__ptr_); + return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; } } // __v < *prev(__hint) @@ -1541,43 +1951,44 @@ __tree<_Tp, _Compare, _Allocator>::__find_leaf(const_iterator __hint, // If __v exists, set parent to node of __v and return reference to node of __v template <class _Tp, class _Compare, class _Allocator> template <class _Key> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& -__tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& __parent, +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& +__tree<_Tp, _Compare, _Allocator>::__find_equal(__parent_pointer& __parent, const _Key& __v) { __node_pointer __nd = __root(); + __node_base_pointer* __nd_ptr = __root_ptr(); if (__nd != nullptr) { while (true) { if (value_comp()(__v, __nd->__value_)) { - if (__nd->__left_ != nullptr) + if (__nd->__left_ != nullptr) { + __nd_ptr = _VSTD::addressof(__nd->__left_); __nd = static_cast<__node_pointer>(__nd->__left_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); + } else { + __parent = static_cast<__parent_pointer>(__nd); return __parent->__left_; } } else if (value_comp()(__nd->__value_, __v)) { - if (__nd->__right_ != nullptr) + if (__nd->__right_ != nullptr) { + __nd_ptr = _VSTD::addressof(__nd->__right_); __nd = static_cast<__node_pointer>(__nd->__right_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; + } else { + __parent = static_cast<__parent_pointer>(__nd); + return __nd->__right_; } } else { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent; + __parent = static_cast<__parent_pointer>(__nd); + return *__nd_ptr; } } } - __parent = static_cast<__node_base_pointer>(__end_node()); + __parent = static_cast<__parent_pointer>(__end_node()); return __parent->__left_; } @@ -1590,9 +2001,10 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(typename __node_base::pointer& _ // If __v exists, set parent to node of __v and return reference to node of __v template <class _Tp, class _Compare, class _Allocator> template <class _Key> -typename __tree<_Tp, _Compare, _Allocator>::__node_base::pointer& +typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, - typename __node_base::pointer& __parent, + __parent_pointer& __parent, + __node_base_pointer& __dummy, const _Key& __v) { if (__hint == end() || value_comp()(__v, *__hint)) // check before @@ -1604,13 +2016,13 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, // *prev(__hint) < __v < *__hint if (__hint.__ptr_->__left_ == nullptr) { - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); + __parent = static_cast<__parent_pointer>(__hint.__ptr_); return __parent->__left_; } else { - __parent = static_cast<__node_base_pointer>(__prior.__ptr_); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__prior.__ptr_); + return static_cast<__node_base_pointer>(__prior.__ptr_)->__right_; } } // __v <= *prev(__hint) @@ -1623,14 +2035,14 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, if (__next == end() || value_comp()(__v, *__next)) { // *__hint < __v < *_VSTD::next(__hint) - if (__hint.__ptr_->__right_ == nullptr) + if (__hint.__get_np()->__right_ == nullptr) { - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); - return __parent->__right_; + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + return static_cast<__node_base_pointer>(__hint.__ptr_)->__right_; } else { - __parent = static_cast<__node_base_pointer>(__next.__ptr_); + __parent = static_cast<__parent_pointer>(__next.__ptr_); return __parent->__left_; } } @@ -1638,48 +2050,115 @@ __tree<_Tp, _Compare, _Allocator>::__find_equal(const_iterator __hint, return __find_equal(__parent, __v); } // else __v == *__hint - __parent = static_cast<__node_base_pointer>(__hint.__ptr_); - return __parent; + __parent = static_cast<__parent_pointer>(__hint.__ptr_); + __dummy = static_cast<__node_base_pointer>(__hint.__ptr_); + return __dummy; } template <class _Tp, class _Compare, class _Allocator> void -__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__node_base_pointer __parent, +__tree<_Tp, _Compare, _Allocator>::__insert_node_at(__parent_pointer __parent, __node_base_pointer& __child, - __node_base_pointer __new_node) + __node_base_pointer __new_node) { __new_node->__left_ = nullptr; __new_node->__right_ = nullptr; __new_node->__parent_ = __parent; + // __new_node->__is_black_ is initialized in __tree_balance_after_insert __child = __new_node; if (__begin_node()->__left_ != nullptr) - __begin_node() = static_cast<__node_pointer>(__begin_node()->__left_); + __begin_node() = static_cast<__iter_pointer>(__begin_node()->__left_); __tree_balance_after_insert(__end_node()->__left_, __child); ++size(); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class... _Args> +pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) +#else +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class _Args> +pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const& __k, _Args& __args) +#endif +{ + __parent_pointer __parent; + __node_base_pointer& __child = __find_equal(__parent, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + bool __inserted = false; + if (__child == nullptr) + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node(__args); +#endif + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + __inserted = true; + } + return pair<iterator, bool>(iterator(__r), __inserted); +} + + +#ifndef _LIBCPP_CXX03_LANG +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class... _Args> +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( + const_iterator __p, _Key const& __k, _Args&&... __args) +#else +template <class _Tp, class _Compare, class _Allocator> +template <class _Key, class _Args> +typename __tree<_Tp, _Compare, _Allocator>::iterator +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args( + const_iterator __p, _Key const& __k, _Args& __args) +#endif +{ + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __k); + __node_pointer __r = static_cast<__node_pointer>(__child); + if (__child == nullptr) + { +#ifndef _LIBCPP_CXX03_LANG + __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); +#else + __node_holder __h = __construct_node(__args); +#endif + __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); + __r = __h.release(); + } + return iterator(__r); +} + + +#ifndef _LIBCPP_CXX03_LANG template <class _Tp, class _Compare, class _Allocator> template <class ..._Args> typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) { + static_assert(!__is_tree_value_type<_Args...>::value, + "Cannot construct from __value_type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; return __h; } + template <class _Tp, class _Compare, class _Allocator> template <class... _Args> pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; + __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __h->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; @@ -1695,11 +2174,12 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) template <class _Tp, class _Compare, class _Allocator> template <class... _Args> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal(__p, __parent, __h->__value_); + __parent_pointer __parent; + __node_base_pointer __dummy; + __node_base_pointer& __child = __find_equal(__p, __parent, __dummy, __h->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) { @@ -1715,8 +2195,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__emplace_multi(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__h->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(static_cast<__node_pointer>(__h.release())); } @@ -1728,161 +2208,35 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__h->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(static_cast<__node_pointer>(__h.release())); } -#endif // _LIBCPP_HAS_NO_VARIADICS - -template <class _Tp, class _Compare, class _Allocator> -pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__insert_unique(value_type&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - pair<iterator, bool> __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, value_type&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - iterator __r = __node_insert_unique(__p, __h.get()); - if (__r.__ptr_ == __h.get()) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__insert_unique(_Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - pair<iterator, bool> __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, _Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - iterator __r = __node_insert_unique(__p, __h.get()); - if (__r.__ptr_ == __h.get()) - __h.release(); - return __r; -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(value_type&& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __v); - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, value_type&& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __v); - __node_holder __h = __construct_node(_VSTD::forward<value_type>(__v)); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(_Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __h->__value_); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -template <class _Tp, class _Compare, class _Allocator> -template <class _Vp> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, _Vp&& __v) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Vp>(__v)); - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __h->__value_); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - return iterator(__h.release()); -} - -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#else // _LIBCPP_CXX03_LANG template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::__node_holder -__tree<_Tp, _Compare, _Allocator>::__construct_node(const value_type& __v) +__tree<_Tp, _Compare, _Allocator>::__construct_node(const __container_value_type& __v) { __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), __v); + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), __v); __h.get_deleter().__value_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Tp, class _Compare, class _Allocator> -pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const value_type& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal(__parent, __v); - __node_pointer __r = static_cast<__node_pointer>(__child); - bool __inserted = false; - if (__child == nullptr) - { - __node_holder __h = __construct_node(__v); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - __r = __h.release(); - __inserted = true; - } - return pair<iterator, bool>(iterator(__r), __inserted); -} - -template <class _Tp, class _Compare, class _Allocator> -typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_unique(const_iterator __p, const value_type& __v) -{ - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal(__p, __parent, __v); - __node_pointer __r = static_cast<__node_pointer>(__child); - if (__child == nullptr) - { - __node_holder __h = __construct_node(__v); - __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - __r = __h.release(); - } - return iterator(__r); -} +#endif // _LIBCPP_CXX03_LANG +#ifdef _LIBCPP_CXX03_LANG template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v) +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const __container_value_type& __v) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __v); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__v)); __node_holder __h = __construct_node(__v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(__h.release()); @@ -1890,20 +2244,21 @@ __tree<_Tp, _Compare, _Allocator>::__insert_multi(const value_type& __v) template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const value_type& __v) +__tree<_Tp, _Compare, _Allocator>::__insert_multi(const_iterator __p, const __container_value_type& __v) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __v); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__v)); __node_holder __h = __construct_node(__v); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); return iterator(__h.release()); } +#endif template <class _Tp, class _Compare, class _Allocator> pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> __tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd) { - __node_base_pointer __parent; + __parent_pointer __parent; __node_base_pointer& __child = __find_equal(__parent, __nd->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); bool __inserted = false; @@ -1921,7 +2276,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_unique(const_iterator __p, __node_pointer __nd) { - __node_base_pointer __parent; + __parent_pointer __parent; + __node_base_pointer __dummy; __node_base_pointer& __child = __find_equal(__p, __parent, __nd->__value_); __node_pointer __r = static_cast<__node_pointer>(__child); if (__child == nullptr) @@ -1936,8 +2292,8 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(__node_pointer __nd) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf_high(__parent, __nd->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf_high(__parent, _NodeTypes::__get_key(__nd->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); return iterator(__nd); } @@ -1947,8 +2303,8 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__node_insert_multi(const_iterator __p, __node_pointer __nd) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_leaf(__p, __parent, __nd->__value_); + __parent_pointer __parent; + __node_base_pointer& __child = __find_leaf(__p, __parent, _NodeTypes::__get_key(__nd->__value_)); __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd)); return iterator(__nd); } @@ -1957,16 +2313,17 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::erase(const_iterator __p) { - __node_pointer __np = __p.__ptr_; - iterator __r(__np); + __node_pointer __np = __p.__get_np(); + iterator __r(__p.__ptr_); ++__r; - if (__begin_node() == __np) + if (__begin_node() == __p.__ptr_) __begin_node() = __r.__ptr_; --size(); __node_allocator& __na = __node_alloc(); __tree_remove(__end_node()->__left_, static_cast<__node_base_pointer>(__np)); - __node_traits::destroy(__na, const_cast<value_type*>(_VSTD::addressof(*__p))); + __node_traits::destroy(__na, _NodeTypes::__get_ptr( + const_cast<__node_value_type&>(*__p))); __node_traits::deallocate(__na, __np, 1); return __r; } @@ -2031,17 +2388,15 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__count_unique(const _Key& __k) const { - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else return 1; } @@ -2053,21 +2408,21 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::size_type __tree<_Tp, _Compare, _Allocator>::__count_multi(const _Key& __k) const { - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else return _VSTD::distance( - __lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt), - __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result) + __lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result) ); } return 0; @@ -2078,13 +2433,13 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result) + __iter_pointer __result) { while (__root != nullptr) { if (!value_comp()(__root->__value_, __v)) { - __result = __root; + __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else @@ -2097,18 +2452,18 @@ template <class _Tp, class _Compare, class _Allocator> template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__lower_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const + __node_pointer __root, + __iter_pointer __result) const { while (__root != nullptr) { if (!value_comp()(__root->__value_, __v)) { - __result = __root; - __root = static_cast<__node_const_pointer>(__root->__left_); + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); } else - __root = static_cast<__node_const_pointer>(__root->__right_); + __root = static_cast<__node_pointer>(__root->__right_); } return const_iterator(__result); } @@ -2118,13 +2473,13 @@ template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, __node_pointer __root, - __node_pointer __result) + __iter_pointer __result) { while (__root != nullptr) { if (value_comp()(__v, __root->__value_)) { - __result = __root; + __result = static_cast<__iter_pointer>(__root); __root = static_cast<__node_pointer>(__root->__left_); } else @@ -2137,18 +2492,18 @@ template <class _Tp, class _Compare, class _Allocator> template <class _Key> typename __tree<_Tp, _Compare, _Allocator>::const_iterator __tree<_Tp, _Compare, _Allocator>::__upper_bound(const _Key& __v, - __node_const_pointer __root, - __node_const_pointer __result) const + __node_pointer __root, + __iter_pointer __result) const { while (__root != nullptr) { if (value_comp()(__v, __root->__value_)) { - __result = __root; - __root = static_cast<__node_const_pointer>(__root->__left_); + __result = static_cast<__iter_pointer>(__root); + __root = static_cast<__node_pointer>(__root->__left_); } else - __root = static_cast<__node_const_pointer>(__root->__right_); + __root = static_cast<__node_pointer>(__root->__right_); } return const_iterator(__result); } @@ -2160,13 +2515,13 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) { typedef pair<iterator, iterator> _Pp; - __node_pointer __result = __end_node(); + __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; + __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) @@ -2175,7 +2530,7 @@ __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) return _Pp(iterator(__rt), iterator( __rt->__right_ != nullptr ? - static_cast<__node_pointer>(__tree_min(__rt->__right_)) + static_cast<__iter_pointer>(__tree_min(__rt->__right_)) : __result)); } return _Pp(iterator(__result), iterator(__result)); @@ -2188,22 +2543,22 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_unique(const _Key& __k) const { typedef pair<const_iterator, const_iterator> _Pp; - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else return _Pp(const_iterator(__rt), const_iterator( __rt->__right_ != nullptr ? - static_cast<__node_const_pointer>(__tree_min(__rt->__right_)) + static_cast<__iter_pointer>(__tree_min(__rt->__right_)) : __result)); } return _Pp(const_iterator(__result), const_iterator(__result)); @@ -2216,19 +2571,19 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) { typedef pair<iterator, iterator> _Pp; - __node_pointer __result = __end_node(); + __iter_pointer __result = __end_node(); __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; + __result = static_cast<__iter_pointer>(__rt); __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) __rt = static_cast<__node_pointer>(__rt->__right_); else - return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), __rt), + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); } return _Pp(iterator(__result), iterator(__result)); @@ -2241,20 +2596,20 @@ pair<typename __tree<_Tp, _Compare, _Allocator>::const_iterator, __tree<_Tp, _Compare, _Allocator>::__equal_range_multi(const _Key& __k) const { typedef pair<const_iterator, const_iterator> _Pp; - __node_const_pointer __result = __end_node(); - __node_const_pointer __rt = __root(); + __iter_pointer __result = __end_node(); + __node_pointer __rt = __root(); while (__rt != nullptr) { if (value_comp()(__k, __rt->__value_)) { - __result = __rt; - __rt = static_cast<__node_const_pointer>(__rt->__left_); + __result = static_cast<__iter_pointer>(__rt); + __rt = static_cast<__node_pointer>(__rt->__left_); } else if (value_comp()(__rt->__value_, __k)) - __rt = static_cast<__node_const_pointer>(__rt->__right_); + __rt = static_cast<__node_pointer>(__rt->__right_); else - return _Pp(__lower_bound(__k, static_cast<__node_const_pointer>(__rt->__left_), __rt), - __upper_bound(__k, static_cast<__node_const_pointer>(__rt->__right_), __result)); + return _Pp(__lower_bound(__k, static_cast<__node_pointer>(__rt->__left_), static_cast<__iter_pointer>(__rt)), + __upper_bound(__k, static_cast<__node_pointer>(__rt->__right_), __result)); } return _Pp(const_iterator(__result), const_iterator(__result)); } @@ -2263,13 +2618,13 @@ template <class _Tp, class _Compare, class _Allocator> typename __tree<_Tp, _Compare, _Allocator>::__node_holder __tree<_Tp, _Compare, _Allocator>::remove(const_iterator __p) _NOEXCEPT { - __node_pointer __np = __p.__ptr_; - if (__begin_node() == __np) + __node_pointer __np = __p.__get_np(); + if (__begin_node() == __p.__ptr_) { if (__np->__right_ != nullptr) - __begin_node() = static_cast<__node_pointer>(__np->__right_); + __begin_node() = static_cast<__iter_pointer>(__np->__right_); else - __begin_node() = static_cast<__node_pointer>(__np->__parent_); + __begin_node() = static_cast<__iter_pointer>(__np->__parent_); } --size(); __tree_remove(__end_node()->__left_, diff --git a/contrib/libc++/include/__tuple b/contrib/libc++/include/__tuple index 8c31759..cc9fbbe 100644 --- a/contrib/libc++/include/__tuple +++ b/contrib/libc++/include/__tuple @@ -68,6 +68,80 @@ template <class _Tp> struct __tuple_like<const volatile _Tp> : public __tuple_li // tuple specializations #if !defined(_LIBCPP_HAS_NO_VARIADICS) + +template <size_t...> struct __tuple_indices {}; + +template <class _IdxType, _IdxType... _Values> +struct __integer_sequence { + template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> + using __convert = _ToIndexSeq<_ToIndexType, _Values...>; + + template <size_t _Sp> + using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; +}; + +#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) +namespace __detail { + +template<typename _Tp, size_t ..._Extra> struct __repeat; +template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { + typedef __integer_sequence<_Tp, + _Np..., + sizeof...(_Np) + _Np..., + 2 * sizeof...(_Np) + _Np..., + 3 * sizeof...(_Np) + _Np..., + 4 * sizeof...(_Np) + _Np..., + 5 * sizeof...(_Np) + _Np..., + 6 * sizeof...(_Np) + _Np..., + 7 * sizeof...(_Np) + _Np..., + _Extra...> type; +}; + +template<size_t _Np> struct __parity; +template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; + +template<> struct __make<0> { typedef __integer_sequence<size_t> type; }; +template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; }; +template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; }; +template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; }; +template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; }; +template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; +template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; +template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; + +template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; +template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; +template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; + +} // namespace detail + +#endif // !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) + +#if __has_builtin(__make_integer_seq) +template <size_t _Ep, size_t _Sp> +using __make_indices_imp = + typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template + __to_tuple_indices<_Sp>; +#else +template <size_t _Ep, size_t _Sp> +using __make_indices_imp = + typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; + +#endif + +template <size_t _Ep, size_t _Sp = 0> +struct __make_tuple_indices +{ + static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); + typedef __make_indices_imp<_Ep, _Sp> type; +}; + + template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple; template <class... _Tp> struct __tuple_like<tuple<_Tp...> > : true_type {}; @@ -95,8 +169,6 @@ get(const tuple<_Tp...>&&) _NOEXCEPT; // pair specializations -template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; - template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; template <size_t _Ip, class _T1, class _T2> @@ -151,58 +223,49 @@ get(const array<_Tp, _Size>&&) _NOEXCEPT; #if !defined(_LIBCPP_HAS_NO_VARIADICS) -// __make_tuple_indices -template <size_t...> struct __tuple_indices {}; +// __tuple_types -template <size_t _Sp, class _IntTuple, size_t _Ep> -struct __make_indices_imp; +template <class ..._Tp> struct __tuple_types {}; -template <size_t _Sp, size_t ..._Indices, size_t _Ep> -struct __make_indices_imp<_Sp, __tuple_indices<_Indices...>, _Ep> -{ - typedef typename __make_indices_imp<_Sp+1, __tuple_indices<_Indices..., _Sp>, _Ep>::type type; -}; +#if !__has_builtin(__type_pack_element) -template <size_t _Ep, size_t ..._Indices> -struct __make_indices_imp<_Ep, __tuple_indices<_Indices...>, _Ep> -{ - typedef __tuple_indices<_Indices...> type; -}; +namespace __indexer_detail { -template <size_t _Ep, size_t _Sp = 0> -struct __make_tuple_indices -{ - static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); - typedef typename __make_indices_imp<_Sp, __tuple_indices<>, _Ep>::type type; -}; +template <size_t _Idx, class _Tp> +struct __indexed { using type = _Tp; }; -// __tuple_types +template <class _Types, class _Indexes> struct __indexer; -template <class ..._Tp> struct __tuple_types {}; +template <class ..._Types, size_t ..._Idx> +struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> + : __indexed<_Idx, _Types>... +{}; -template <size_t _Ip> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<> > -{ -public: - static_assert(_Ip == 0, "tuple_element index out of range"); - static_assert(_Ip != 0, "tuple_element index out of range"); -}; +template <size_t _Idx, class _Tp> +__indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); -template <class _Hp, class ..._Tp> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<0, __tuple_types<_Hp, _Tp...> > -{ -public: - typedef _Hp type; -}; +} // namespace __indexer_detail + +template <size_t _Idx, class ..._Types> +using __type_pack_element = typename decltype( + __indexer_detail::__at_index<_Idx>( + __indexer_detail::__indexer< + __tuple_types<_Types...>, + typename __make_tuple_indices<sizeof...(_Types)>::type + >{}) + )::type; +#endif -template <size_t _Ip, class _Hp, class ..._Tp> -class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Hp, _Tp...> > +template <size_t _Ip, class ..._Types> +class _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, __tuple_types<_Types...>> { public: - typedef typename tuple_element<_Ip-1, __tuple_types<_Tp...> >::type type; + static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); + typedef __type_pack_element<_Ip, _Types...> type; }; + template <class ..._Tp> class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > : public integral_constant<size_t, sizeof...(_Tp)> @@ -211,6 +274,46 @@ class _LIBCPP_TYPE_VIS_ONLY tuple_size<__tuple_types<_Tp...> > template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type {}; +template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile> +struct __apply_cv_mf; +template <> +struct __apply_cv_mf<false, false, false> { + template <class _Tp> using __apply = _Tp; +}; +template <> +struct __apply_cv_mf<false, true, false> { + template <class _Tp> using __apply = const _Tp; +}; +template <> +struct __apply_cv_mf<false, false, true> { + template <class _Tp> using __apply = volatile _Tp; +}; +template <> +struct __apply_cv_mf<false, true, true> { + template <class _Tp> using __apply = const volatile _Tp; +}; +template <> +struct __apply_cv_mf<true, false, false> { + template <class _Tp> using __apply = _Tp&; +}; +template <> +struct __apply_cv_mf<true, true, false> { + template <class _Tp> using __apply = const _Tp&; +}; +template <> +struct __apply_cv_mf<true, false, true> { + template <class _Tp> using __apply = volatile _Tp&; +}; +template <> +struct __apply_cv_mf<true, true, true> { + template <class _Tp> using __apply = const volatile _Tp&; +}; +template <class _Tp, class _RawTp = typename remove_reference<_Tp>::type> +using __apply_cv_t = __apply_cv_mf< + is_lvalue_reference<_Tp>::value, + is_const<_RawTp>::value, + is_volatile<_RawTp>::value>; + // __make_tuple_types // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a @@ -218,58 +321,72 @@ template <class... _Tp> struct __tuple_like<__tuple_types<_Tp...> > : true_type // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a // lvalue_reference type, then __tuple_types<_Types&...> is the result. -template <class _TupleTypes, class _Tp, size_t _Sp, size_t _Ep> -struct __make_tuple_types_imp; +template <class _TupleTypes, class _TupleIndices> +struct __make_tuple_types_flat; -template <class ..._Types, class _Tp, size_t _Sp, size_t _Ep> -struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Sp, _Ep> -{ - typedef typename remove_reference<_Tp>::type _Tpr; - typedef typename __make_tuple_types_imp<__tuple_types<_Types..., - typename conditional<is_lvalue_reference<_Tp>::value, - typename tuple_element<_Sp, _Tpr>::type&, - typename tuple_element<_Sp, _Tpr>::type>::type>, - _Tp, _Sp+1, _Ep>::type type; +template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx> +struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { + // Specialization for pair, tuple, and __tuple_types + template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> + using __apply_quals = __tuple_types< + typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>... + >; }; -template <class ..._Types, class _Tp, size_t _Ep> -struct __make_tuple_types_imp<__tuple_types<_Types...>, _Tp, _Ep, _Ep> -{ - typedef __tuple_types<_Types...> type; +template <class _Vt, size_t _Np, size_t ..._Idx> +struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { + template <size_t> + using __value_type = _Vt; + template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> + using __apply_quals = __tuple_types< + typename _ApplyFn::template __apply<__value_type<_Idx>>... + >; }; -template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, size_t _Sp = 0> +template <class _Tp, size_t _Ep = tuple_size<typename remove_reference<_Tp>::type>::value, + size_t _Sp = 0, + bool _SameSize = (_Ep == tuple_size<typename remove_reference<_Tp>::type>::value)> struct __make_tuple_types { static_assert(_Sp <= _Ep, "__make_tuple_types input error"); - typedef typename __make_tuple_types_imp<__tuple_types<>, _Tp, _Sp, _Ep>::type type; + using _RawTp = typename remove_cv<typename remove_reference<_Tp>::type>::type; + using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; + using type = typename _Maker::template __apply_quals<_Tp>; }; -// __tuple_convertible - -template <class, class> -struct __tuple_convertible_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_convertible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > - : public integral_constant<bool, - is_convertible<_Tp0, _Up0>::value && - __tuple_convertible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; +template <class ..._Types, size_t _Ep> +struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> { + typedef __tuple_types<_Types...> type; +}; -template <> -struct __tuple_convertible_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; +template <class ..._Types, size_t _Ep> +struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> { + typedef __tuple_types<_Types...> type; +}; -template <bool, class, class> -struct __tuple_convertible_apply : public false_type {}; +template <bool ..._Preds> +struct __all_dummy; + +template <bool ..._Pred> +using __all = is_same<__all_dummy<_Pred...>, __all_dummy<(_Pred, true)...>>; + +struct __tuple_sfinae_base { + template <template <class, class...> class _Trait, + class ..._LArgs, class ..._RArgs> + static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>) + -> __all<typename enable_if<_Trait<_LArgs, _RArgs>::value, bool>::type{true}...>; + template <template <class...> class> + static auto __do_test(...) -> false_type; + + template <class _FromArgs, class _ToArgs> + using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); + template <class _FromArgs, class _ToArgs> + using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{})); + template <class _FromArgs, class _ToArgs> + using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{})); +}; -template <class _Tp, class _Up> -struct __tuple_convertible_apply<true, _Tp, _Up> - : public __tuple_convertible_imp< - typename __make_tuple_types<_Tp>::type - , typename __make_tuple_types<_Up>::type - > -{}; +// __tuple_convertible template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> @@ -278,36 +395,14 @@ struct __tuple_convertible template <class _Tp, class _Up> struct __tuple_convertible<_Tp, _Up, true, true> - : public __tuple_convertible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> -{}; - -// __tuple_constructible - -template <class, class> -struct __tuple_constructible_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_constructible_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > - : public integral_constant<bool, - is_constructible<_Up0, _Tp0>::value && - __tuple_constructible_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; - -template <> -struct __tuple_constructible_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; - -template <bool _SameSize, class, class> -struct __tuple_constructible_apply : public false_type {}; - -template <class _Tp, class _Up> -struct __tuple_constructible_apply<true, _Tp, _Up> - : public __tuple_constructible_imp< + : public __tuple_sfinae_base::__convertible< typename __make_tuple_types<_Tp>::type , typename __make_tuple_types<_Up>::type > {}; +// __tuple_constructible + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_constructible @@ -315,36 +410,14 @@ struct __tuple_constructible template <class _Tp, class _Up> struct __tuple_constructible<_Tp, _Up, true, true> - : public __tuple_constructible_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> -{}; - -// __tuple_assignable - -template <class, class> -struct __tuple_assignable_imp : public false_type {}; - -template <class _Tp0, class ..._Tp, class _Up0, class ..._Up> -struct __tuple_assignable_imp<__tuple_types<_Tp0, _Tp...>, __tuple_types<_Up0, _Up...> > - : public integral_constant<bool, - is_assignable<_Up0&, _Tp0>::value && - __tuple_assignable_imp<__tuple_types<_Tp...>, __tuple_types<_Up...> >::value> {}; - -template <> -struct __tuple_assignable_imp<__tuple_types<>, __tuple_types<> > - : public true_type {}; - -template <bool, class, class> -struct __tuple_assignable_apply : public false_type {}; - -template <class _Tp, class _Up> -struct __tuple_assignable_apply<true, _Tp, _Up> - : __tuple_assignable_imp< + : public __tuple_sfinae_base::__constructible< typename __make_tuple_types<_Tp>::type , typename __make_tuple_types<_Up>::type > {}; +// __tuple_assignable + template <class _Tp, class _Up, bool = __tuple_like<typename remove_reference<_Tp>::type>::value, bool = __tuple_like<_Up>::value> struct __tuple_assignable @@ -352,8 +425,10 @@ struct __tuple_assignable template <class _Tp, class _Up> struct __tuple_assignable<_Tp, _Up, true, true> - : public __tuple_assignable_apply<tuple_size<typename remove_reference<_Tp>::type>::value == - tuple_size<_Up>::value, _Tp, _Up> + : public __tuple_sfinae_base::__assignable< + typename __make_tuple_types<_Tp>::type + , typename __make_tuple_types<_Up&>::type + > {}; #endif // _LIBCPP_HAS_NO_VARIADICS diff --git a/contrib/libc++/include/__undef___deallocate b/contrib/libc++/include/__undef___deallocate index 2b4ad99..52f4d99 100644 --- a/contrib/libc++/include/__undef___deallocate +++ b/contrib/libc++/include/__undef___deallocate @@ -9,10 +9,12 @@ //===----------------------------------------------------------------------===// #ifdef __deallocate +#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) #if defined(_MSC_VER) && !defined(__clang__) _LIBCPP_WARNING("macro __deallocate is incompatible with C++. #undefining __deallocate") #else #warning: macro __deallocate is incompatible with C++. #undefining __deallocate #endif +#endif #undef __deallocate #endif diff --git a/contrib/libc++/include/__undef_min_max b/contrib/libc++/include/__undef_min_max index 5df9412..d3c3138 100644 --- a/contrib/libc++/include/__undef_min_max +++ b/contrib/libc++/include/__undef_min_max @@ -9,21 +9,25 @@ //===----------------------------------------------------------------------===// #ifdef min +#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) #if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING("macro min is incompatible with C++. Try #define NOMINMAX " "before any Windows header. #undefing min") #else #warning: macro min is incompatible with C++. #undefing min #endif +#endif #undef min #endif #ifdef max +#if !defined(_LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS) #if defined(_MSC_VER) && ! defined(__clang__) _LIBCPP_WARNING("macro max is incompatible with C++. Try #define NOMINMAX " "before any Windows header. #undefing max") #else #warning: macro max is incompatible with C++. #undefing max #endif +#endif #undef max #endif diff --git a/contrib/libc++/include/algorithm b/contrib/libc++/include/algorithm index 71e5df3..7a6db7a 100644 --- a/contrib/libc++/include/algorithm +++ b/contrib/libc++/include/algorithm @@ -543,6 +543,12 @@ template<class T, class Compare> T min(initializer_list<T> t, Compare comp); // constexpr in C++14 +template<class T> + constexpr const T& clamp( const T& v, const T& lo, const T& hi ); // C++17 + +template<class T, class Compare> + constexpr const T& clamp( const T& v, const T& lo, const T& hi, Compare comp ); // C++17 + template <class ForwardIterator> ForwardIterator max_element(ForwardIterator first, ForwardIterator last); // constexpr in C++14 @@ -624,7 +630,7 @@ template <class BidirectionalIterator, class Compare> #include <initializer_list> #include <type_traits> #include <cstring> -#include <utility> +#include <utility> // needed to provide swap_ranges. #include <memory> #include <iterator> #include <cstddef> @@ -1415,20 +1421,20 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, // search template <class _BinaryPredicate, class _ForwardIterator1, class _ForwardIterator2> -_ForwardIterator1 +pair<_ForwardIterator1, _ForwardIterator1> __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred, forward_iterator_tag, forward_iterator_tag) { if (__first2 == __last2) - return __first1; // Everything matches an empty sequence + return make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { // Find first element in sequence 1 that matchs *__first2, with a mininum of loop checks while (true) { if (__first1 == __last1) // return __last1 if no element matches *__first2 - return __last1; + return make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -1439,9 +1445,9 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, while (true) { if (++__m2 == __last2) // If pattern exhausted, __first1 is the answer (works for 1 element pattern) - return __first1; + return make_pair(__first1, __m1); if (++__m1 == __last1) // Otherwise if source exhaused, pattern not found - return __last1; + return make_pair(__last1, __last1); if (!__pred(*__m1, *__m2)) // if there is a mismatch, restart with a new __first1 { ++__first1; @@ -1452,20 +1458,21 @@ __search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> -_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 +_LIBCPP_CONSTEXPR_AFTER_CXX11 +pair<_RandomAccessIterator1, _RandomAccessIterator1> __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _D1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _D2; + typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - _D2 __len2 = __last2 - __first2; + const _D2 __len2 = __last2 - __first2; if (__len2 == 0) - return __first1; - _D1 __len1 = __last1 - __first1; + return make_pair(__first1, __first1); + const _D1 __len1 = __last1 - __first1; if (__len1 < __len2) - return __last1; + return make_pair(__last1, __last1); const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here while (true) { @@ -1473,7 +1480,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (__first1 == __s) - return __last1; + return make_pair(__last1, __last1); if (__pred(*__first1, *__first2)) break; ++__first1; @@ -1505,7 +1512,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, if (__pred(*__first1, *__first2)) break; case 0: - return __last1; + return make_pair(__last1, __last1); } __phase2: #endif // !_LIBCPP_UNROLL_LOOPS @@ -1515,7 +1522,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, while (true) { if (++__m2 == __last2) - return __first1; + return make_pair(__first1, __first1 + __len2); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source if (!__pred(*__m1, *__m2)) { @@ -1555,7 +1562,7 @@ __search(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, if (!__pred(*__m1, *__m2)) break; case 0: - return __first1; + return make_pair(__first1, __first1 + __len2); } __continue: ++__first1; @@ -1571,8 +1578,9 @@ search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, { return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type> (__first1, __last1, __first2, __last2, __pred, - typename std::iterator_traits<_ForwardIterator1>::iterator_category(), - typename std::iterator_traits<_ForwardIterator2>::iterator_category()); + typename iterator_traits<_ForwardIterator1>::iterator_category(), + typename iterator_traits<_ForwardIterator2>::iterator_category()) + .first; } template <class _ForwardIterator1, class _ForwardIterator2> @@ -1581,8 +1589,8 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - typedef typename std::iterator_traits<_ForwardIterator1>::value_type __v1; - typedef typename std::iterator_traits<_ForwardIterator2>::value_type __v2; + typedef typename iterator_traits<_ForwardIterator1>::value_type __v1; + typedef typename iterator_traits<_ForwardIterator2>::value_type __v2; return _VSTD::search(__first1, __last1, __first2, __last2, __equal_to<__v1, __v2>()); } @@ -2657,6 +2665,27 @@ max(initializer_list<_Tp> __t) #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#if _LIBCPP_STD_VER > 14 +// clamp +template<class _Tp, class _Compare> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) +{ + _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); + return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; + +} + +template<class _Tp> +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +const _Tp& +clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) +{ + return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); +} +#endif + // minmax_element template <class _ForwardIterator, class _Compare> @@ -5725,34 +5754,6 @@ prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); } -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - _Tp ->::type -__rotate_left(_Tp __t, _Tp __n = 1) -{ - const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1); - __n &= __bits; - return static_cast<_Tp>((__t << __n) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> (__bits - __n))); -} - -template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value, - _Tp ->::type -__rotate_right(_Tp __t, _Tp __n = 1) -{ - const unsigned __bits = static_cast<unsigned>(sizeof(_Tp) * __CHAR_BIT__ - 1); - __n &= __bits; - return static_cast<_Tp>((__t << (__bits - __n)) | (static_cast<typename make_unsigned<_Tp>::type>(__t) >> __n)); -} - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_ALGORITHM diff --git a/contrib/libc++/include/array b/contrib/libc++/include/array index 8866eaf..719286d 100644 --- a/contrib/libc++/include/array +++ b/contrib/libc++/include/array @@ -34,7 +34,7 @@ struct array // No explicit construct/copy/destroy for aggregate type void fill(const T& u); - void swap(array& a) noexcept(noexcept(swap(declval<T&>(), declval<T&>()))); + void swap(array& a) noexcept(is_nothrow_swappable_v<T>); // iterators: iterator begin() noexcept; @@ -141,8 +141,15 @@ struct _LIBCPP_TYPE_VIS_ONLY array _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) {_VSTD::fill_n(__elems_, _Size, __u);} _LIBCPP_INLINE_VISIBILITY - void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) - {_VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} + void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) + { __swap_dispatch((std::integral_constant<bool, _Size == 0>()), __a); } + + _LIBCPP_INLINE_VISIBILITY + void __swap_dispatch(std::true_type, array&) {} + + _LIBCPP_INLINE_VISIBILITY + void __swap_dispatch(std::false_type, array& __a) + { _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} // iterators: _LIBCPP_INLINE_VISIBILITY @@ -276,11 +283,12 @@ template <class _Tp, size_t _Size> inline _LIBCPP_INLINE_VISIBILITY typename enable_if < + _Size == 0 || __is_swappable<_Tp>::value, void >::type -swap(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) - _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) +swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) + _NOEXCEPT_(noexcept(__x.swap(__y))) { __x.swap(__y); } diff --git a/contrib/libc++/include/atomic b/contrib/libc++/include/atomic index abec2a0..11f2152 100644 --- a/contrib/libc++/include/atomic +++ b/contrib/libc++/include/atomic @@ -17,6 +17,10 @@ namespace std { +// feature test macro + +#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10 + // order and consistency typedef enum memory_order @@ -89,6 +93,7 @@ void template <class T> struct atomic { + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; @@ -127,6 +132,7 @@ struct atomic template <> struct atomic<integral> { + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; @@ -202,6 +208,7 @@ struct atomic<integral> template <class T> struct atomic<T*> { + static constexpr bool is_always_lock_free; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; @@ -508,6 +515,15 @@ typedef atomic<uint_fast32_t> atomic_uint_fast32_t; typedef atomic<int_fast64_t> atomic_int_fast64_t; typedef atomic<uint_fast64_t> atomic_uint_fast64_t; +typedef atomic<int8_t> atomic_int8_t; +typedef atomic<uint8_t> atomic_uint8_t; +typedef atomic<int16_t> atomic_int16_t; +typedef atomic<uint16_t> atomic_uint16_t; +typedef atomic<int32_t> atomic_int32_t; +typedef atomic<uint32_t> atomic_uint32_t; +typedef atomic<int64_t> atomic_int64_t; +typedef atomic<uint64_t> atomic_uint64_t; + typedef atomic<intptr_t> atomic_intptr_t; typedef atomic<uintptr_t> atomic_uintptr_t; typedef atomic<size_t> atomic_size_t; @@ -540,6 +556,11 @@ void atomic_signal_fence(memory_order m) noexcept; #error <atomic> is not implemented #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 + _LIBCPP_BEGIN_NAMESPACE_STD typedef enum memory_order @@ -825,6 +846,17 @@ kill_dependency(_Tp __y) _NOEXCEPT return __y; } +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE + // general atomic<T> template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> @@ -832,6 +864,10 @@ struct __atomic_base // false { mutable _Atomic(_Tp) __a_; +#if defined(__cpp_lib_atomic_is_always_lock_free) + static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); +#endif + _LIBCPP_INLINE_VISIBILITY bool is_lock_free() const volatile _NOEXCEPT { @@ -920,6 +956,11 @@ private: #endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS }; +#if defined(__cpp_lib_atomic_is_always_lock_free) +template <class _Tp, bool __b> +_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; +#endif + // atomic<Integral> template <class _Tp> @@ -1657,7 +1698,7 @@ typedef struct atomic_flag #endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS _LIBCPP_INLINE_VISIBILITY - atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} + atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS atomic_flag(const atomic_flag&) = delete; @@ -1779,6 +1820,15 @@ typedef atomic<uint_fast32_t> atomic_uint_fast32_t; typedef atomic<int_fast64_t> atomic_int_fast64_t; typedef atomic<uint_fast64_t> atomic_uint_fast64_t; +typedef atomic< int8_t> atomic_int8_t; +typedef atomic<uint8_t> atomic_uint8_t; +typedef atomic< int16_t> atomic_int16_t; +typedef atomic<uint16_t> atomic_uint16_t; +typedef atomic< int32_t> atomic_int32_t; +typedef atomic<uint32_t> atomic_uint32_t; +typedef atomic< int64_t> atomic_int64_t; +typedef atomic<uint64_t> atomic_uint64_t; + typedef atomic<intptr_t> atomic_intptr_t; typedef atomic<uintptr_t> atomic_uintptr_t; typedef atomic<size_t> atomic_size_t; @@ -1789,17 +1839,6 @@ typedef atomic<uintmax_t> atomic_uintmax_t; #define ATOMIC_FLAG_INIT {false} #define ATOMIC_VAR_INIT(__v) {__v} -#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE -#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE -#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE -#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE -#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE -#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE -#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE -#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE -#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE -#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE - _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_ATOMIC diff --git a/contrib/libc++/include/bitset b/contrib/libc++/include/bitset index 87d7afc..593b884 100644 --- a/contrib/libc++/include/bitset +++ b/contrib/libc++/include/bitset @@ -262,7 +262,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 @@ -656,7 +656,7 @@ __bitset<0, 0>::__bitset(unsigned long long) _NOEXCEPT } template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset; -template <size_t _Size> struct _LIBCPP_TYPE_VIS_ONLY hash<bitset<_Size> >; +template <size_t _Size> struct hash<bitset<_Size> >; template <size_t _Size> class _LIBCPP_TYPE_VIS_ONLY bitset diff --git a/contrib/libc++/include/cctype b/contrib/libc++/include/cctype index a68c2a0..7fc8134 100644 --- a/contrib/libc++/include/cctype +++ b/contrib/libc++/include/cctype @@ -44,6 +44,63 @@ int toupper(int c); _LIBCPP_BEGIN_NAMESPACE_STD +#ifdef isalnum +#undef isalnum +#endif + +#ifdef isalpha +#undef isalpha +#endif + +#ifdef isblank +#undef isblank +#endif + +#ifdef iscntrl +#undef iscntrl +#endif + +#ifdef isdigit +#undef isdigit +#endif + +#ifdef isgraph +#undef isgraph +#endif + +#ifdef islower +#undef islower +#endif + +#ifdef isprint +#undef isprint +#endif + +#ifdef ispunct +#undef ispunct +#endif + +#ifdef isspace +#undef isspace +#endif + +#ifdef isupper +#undef isupper +#endif + +#ifdef isxdigit +#undef isxdigit +#endif + +#ifdef tolower +#undef tolower +#endif + +#ifdef toupper +#undef toupper +#endif + + using ::isalnum; using ::isalpha; using ::isblank; diff --git a/contrib/libc++/include/cmath b/contrib/libc++/include/cmath index ebbde18..b3e9594 100644 --- a/contrib/libc++/include/cmath +++ b/contrib/libc++/include/cmath @@ -209,6 +209,10 @@ floating_point hypot (arithmetic x, arithmetic y); float hypotf(float x, float y); long double hypotl(long double x, long double y); +double hypot(double x, double y, double z); // C++17 +float hypot(float x, float y, float z); // C++17 +long double hypot(long double x, long double y, long double z); // C++17 + int ilogb (arithmetic x); int ilogbf(float x); int ilogbl(long double x); @@ -548,6 +552,30 @@ 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); } +inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double x, long double y, long double z ) { return sqrt(x*x + y*y + z*z); } + +template <class _A1, class _A2, class _A3> +inline _LIBCPP_INLINE_VISIBILITY +typename std::__lazy_enable_if +< + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value && + std::is_arithmetic<_A3>::value, + std::__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)), ""); + return hypot((__result_type)__lcpp_x, (__result_type)__lcpp_y, (__result_type)__lcpp_z); +} +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_CMATH diff --git a/contrib/libc++/include/complex b/contrib/libc++/include/complex index 2943da1..f56138f 100644 --- a/contrib/libc++/include/complex +++ b/contrib/libc++/include/complex @@ -332,7 +332,9 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(float __re = 0.0f, float __im = 0.0f) : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR complex(const complex<double>& __c); + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR float real() const {return __re_;} @@ -388,7 +390,9 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(double __re = 0.0, double __im = 0.0) : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(const complex<float>& __c); + _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR complex(const complex<long double>& __c); _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR double real() const {return __re_;} @@ -444,7 +448,9 @@ public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(long double __re = 0.0L, long double __im = 0.0L) : __re_(__re), __im_(__im) {} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(const complex<float>& __c); + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR complex(const complex<double>& __c); _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR long double real() const {return __re_;} @@ -490,32 +496,32 @@ public: } }; -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<long double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<double>::complex(const complex<long double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<float>& __c) : __re_(__c.real()), __im_(__c.imag()) {} -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR complex<long double>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} @@ -1399,7 +1405,7 @@ acos(const complex<_Tp>& __x) } if (isinf(__x.imag())) return complex<_Tp>(__pi/_Tp(2), -__x.imag()); - if (__x.real() == 0) + if (__x.real() == 0 && (__x.imag() == 0 || isnan(__x.imag()))) return complex<_Tp>(__pi/_Tp(2), -__x.imag()); complex<_Tp> __z = log(__x + sqrt(pow(__x, _Tp(2)) - _Tp(1))); if (signbit(__x.imag())) diff --git a/contrib/libc++/include/cstring b/contrib/libc++/include/cstring index d60b992..d550695 100644 --- a/contrib/libc++/include/cstring +++ b/contrib/libc++/include/cstring @@ -78,30 +78,13 @@ using ::strcmp; using ::strncmp; using ::strcoll; using ::strxfrm; - using ::memchr; - using ::strchr; - using ::strcspn; - using ::strpbrk; - using ::strrchr; - using ::strspn; - using ::strstr; - -// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus -#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) -inline _LIBCPP_INLINE_VISIBILITY char* strchr( char* __s, int __c) {return ::strchr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY char* strpbrk( char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);} -inline _LIBCPP_INLINE_VISIBILITY char* strrchr( char* __s, int __c) {return ::strrchr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY void* memchr( void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);} -inline _LIBCPP_INLINE_VISIBILITY char* strstr( char* __s1, const char* __s2) {return ::strstr(__s1, __s2);} -#endif - #ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS using ::strtok; #endif diff --git a/contrib/libc++/include/cwchar b/contrib/libc++/include/cwchar index ef4806d..52dde9e 100644 --- a/contrib/libc++/include/cwchar +++ b/contrib/libc++/include/cwchar @@ -157,30 +157,11 @@ using ::wcscmp; using ::wcscoll; using ::wcsncmp; using ::wcsxfrm; - -#ifdef _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS using ::wcschr; using ::wcspbrk; using ::wcsrchr; using ::wcsstr; using ::wmemchr; -#else -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcschr( wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcspbrk( wchar_t* __s1, const wchar_t* __s2) {return ::wcspbrk(__s1, __s2);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcsrchr( wchar_t* __s, wchar_t __c) {return ::wcsrchr(__s, __c);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wcsstr( wchar_t* __s1, const wchar_t* __s2) {return ::wcsstr(__s1, __s2);} - -inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);} -inline _LIBCPP_INLINE_VISIBILITY wchar_t* wmemchr( wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);} -#endif - using ::wcscspn; using ::wcslen; using ::wcsspn; diff --git a/contrib/libc++/include/deque b/contrib/libc++/include/deque index c6fbd51..5765042 100644 --- a/contrib/libc++/include/deque +++ b/contrib/libc++/include/deque @@ -2026,7 +2026,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); iterator __b = __base::begin(); iterator __bm1 = _VSTD::prev(__b); __alloc_traits::construct(__a, _VSTD::addressof(*__bm1), _VSTD::move(*__b)); @@ -2034,7 +2034,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) ++__base::size(); if (__pos > 1) __b = _VSTD::move(_VSTD::next(__b), __b + __pos, __b); - *__b = _VSTD::move(__tmp); + *__b = _VSTD::move(__tmp.get()); } } else @@ -2050,14 +2050,14 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); iterator __e = __base::end(); iterator __em1 = _VSTD::prev(__e); __alloc_traits::construct(__a, _VSTD::addressof(*__e), _VSTD::move(*__em1)); ++__base::size(); if (__de > 1) __e = _VSTD::move_backward(__e - __de, __em1, __e); - *--__e = _VSTD::move(__tmp); + *--__e = _VSTD::move(__tmp.get()); } } return __base::begin() + __pos; diff --git a/contrib/libc++/include/exception b/contrib/libc++/include/exception index 686e4ecd0..186d379 100644 --- a/contrib/libc++/include/exception +++ b/contrib/libc++/include/exception @@ -80,6 +80,10 @@ 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 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -251,4 +255,19 @@ 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/contrib/libc++/include/experimental/__config b/contrib/libc++/include/experimental/__config index f64a3a9..9a7bbe8 100644 --- a/contrib/libc++/include/experimental/__config +++ b/contrib/libc++/include/experimental/__config @@ -25,8 +25,26 @@ #define _LIBCPP_END_NAMESPACE_LFTS } } } #define _VSTD_LFTS _VSTD_EXPERIMENTAL::fundamentals_v1 +#define _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v2 { +#define _LIBCPP_END_NAMESPACE_LFTS_V2 } } } +#define _VSTD_LFTS_V2 _VSTD_EXPERIMENTAL::fundamentals_v2 + +#define _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR _LIBCPP_BEGIN_NAMESPACE_LFTS namespace pmr { +#define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS } +#define _VSTD_LFTS_PMR _VSTD_LFTS::pmr + #define _LIBCPP_BEGIN_NAMESPACE_CHRONO_LFTS _LIBCPP_BEGIN_NAMESPACE_STD \ namespace chrono { namespace experimental { inline namespace fundamentals_v1 { #define _LIBCPP_END_NAMESPACE_CHRONO_LFTS _LIBCPP_END_NAMESPACE_STD } } } +#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace filesystem { \ + inline namespace v1 { + +#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM \ + } } _LIBCPP_END_NAMESPACE_EXPERIMENTAL + + +#define _VSTD_FS ::std::experimental::filesystem::v1 + #endif diff --git a/contrib/libc++/include/experimental/__memory b/contrib/libc++/include/experimental/__memory new file mode 100644 index 0000000..229fea6 --- /dev/null +++ b/contrib/libc++/include/experimental/__memory @@ -0,0 +1,90 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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___MEMORY +#define _LIBCPP_EXPERIMENTAL___MEMORY + +#include <experimental/__config> +#include <experimental/utility> // for erased_type +#include <__functional_base> +#include <type_traits> + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +template < + class _Tp, class _Alloc + , bool = uses_allocator<_Tp, _Alloc>::value + , bool = __has_allocator_type<_Tp>::value + > +struct __lfts_uses_allocator : public false_type {}; + +template <class _Tp, class _Alloc> +struct __lfts_uses_allocator<_Tp, _Alloc, false, false> : public false_type {}; + +template <class _Tp, class _Alloc, bool HasAlloc> +struct __lfts_uses_allocator<_Tp, _Alloc, true, HasAlloc> : public true_type {}; + +template <class _Tp, class _Alloc> +struct __lfts_uses_allocator<_Tp, _Alloc, false, true> + : public integral_constant<bool + , is_convertible<_Alloc, typename _Tp::allocator_type>::value + || is_same<erased_type, typename _Tp::allocator_type>::value + > +{}; + +template <bool _UsesAlloc, class _Tp, class _Alloc, class ..._Args> +struct __lfts_uses_alloc_ctor_imp +{ + static const int value = 0; +}; + +template <class _Tp, class _Alloc, class ..._Args> +struct __lfts_uses_alloc_ctor_imp<true, _Tp, _Alloc, _Args...> +{ + static const bool __ic_first + = is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; + + static const bool __ic_second = + conditional< + __ic_first, + false_type, + is_constructible<_Tp, _Args..., _Alloc> + >::type::value; + + static_assert(__ic_first || __ic_second, + "Request for uses allocator construction is ill-formed"); + + static const int value = __ic_first ? 1 : 2; +}; + +template <class _Tp, class _Alloc, class ..._Args> +struct __lfts_uses_alloc_ctor + : integral_constant<int, + __lfts_uses_alloc_ctor_imp< + __lfts_uses_allocator<_Tp, _Alloc>::value + , _Tp, _Alloc, _Args... + >::value + > +{}; + +template <class _Tp, class _Alloc, class ..._Args> +inline _LIBCPP_INLINE_VISIBILITY +void __lfts_user_alloc_construct( + _Tp * __store, const _Alloc & __a, _Args &&... __args) +{ + _VSTD::__user_alloc_construct_impl( + typename __lfts_uses_alloc_ctor<_Tp, _Alloc, _Args...>::type() + , __store, __a, _VSTD::forward<_Args>(__args)... + ); +} + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_EXPERIMENTAL___MEMORY */ diff --git a/contrib/libc++/include/experimental/algorithm b/contrib/libc++/include/experimental/algorithm index ffaa793..3902111 100644 --- a/contrib/libc++/include/experimental/algorithm +++ b/contrib/libc++/include/experimental/algorithm @@ -53,7 +53,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS template <class _ForwardIterator, class _Searcher> _LIBCPP_INLINE_VISIBILITY _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) -{ return __s(__f, __l); } +{ return __s(__f, __l).first; } template <class _PopulationIterator, class _SampleIterator, class _Distance, diff --git a/contrib/libc++/include/experimental/any b/contrib/libc++/include/experimental/any index 6037884..4c73249 100644 --- a/contrib/libc++/include/experimental/any +++ b/contrib/libc++/include/experimental/any @@ -113,10 +113,12 @@ class any; template <class _ValueType> typename add_pointer<typename add_const<_ValueType>::type>::type +_LIBCPP_INLINE_VISIBILITY any_cast(any const *) _NOEXCEPT; template <class _ValueType> typename add_pointer<_ValueType>::type +_LIBCPP_INLINE_VISIBILITY any_cast(any *) _NOEXCEPT; namespace __any_imp @@ -185,6 +187,7 @@ public: class _ValueType , class = __any_imp::_EnableIfNotAny<_ValueType> > + _LIBCPP_INLINE_VISIBILITY any(_ValueType && __value); _LIBCPP_INLINE_VISIBILITY @@ -212,6 +215,7 @@ public: class _ValueType , class = __any_imp::_EnableIfNotAny<_ValueType> > + _LIBCPP_INLINE_VISIBILITY any & operator=(_ValueType && __rhs); // 6.3.3 any modifiers @@ -221,6 +225,7 @@ public: if (__h) this->__call(_Action::_Destroy); } + _LIBCPP_INLINE_VISIBILITY void swap(any & __rhs) _NOEXCEPT; // 6.3.4 any observers @@ -457,7 +462,6 @@ namespace __any_imp template <class _ValueType, class> -_LIBCPP_INLINE_VISIBILITY any::any(_ValueType && __v) : __h(nullptr) { typedef typename decay<_ValueType>::type _Tp; @@ -468,7 +472,6 @@ any::any(_ValueType && __v) : __h(nullptr) } template <class _ValueType, class> -_LIBCPP_INLINE_VISIBILITY any & any::operator=(_ValueType && __v) { typedef typename decay<_ValueType>::type _Tp; @@ -478,7 +481,7 @@ any & any::operator=(_ValueType && __v) return *this; } -inline _LIBCPP_INLINE_VISIBILITY +inline void any::swap(any & __rhs) _NOEXCEPT { if (__h && __rhs.__h) { @@ -550,7 +553,7 @@ _ValueType any_cast(any && __v) } template <class _ValueType> -inline _LIBCPP_INLINE_VISIBILITY +inline typename add_pointer<typename add_const<_ValueType>::type>::type any_cast(any const * __any) _NOEXCEPT { @@ -560,7 +563,6 @@ any_cast(any const * __any) _NOEXCEPT } template <class _ValueType> -_LIBCPP_INLINE_VISIBILITY typename add_pointer<_ValueType>::type any_cast(any * __any) _NOEXCEPT { diff --git a/contrib/libc++/include/experimental/deque b/contrib/libc++/include/experimental/deque new file mode 100644 index 0000000..f849574 --- /dev/null +++ b/contrib/libc++/include/experimental/deque @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- deque ------------------------------------===// +// +// 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_DEQUE +#define _LIBCPP_EXPERIMENTAL_DEQUE +/* + experimental/deque synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using deque = std::deque<T,polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <deque> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using deque = _VSTD::deque<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_DEQUE */ diff --git a/contrib/libc++/include/experimental/dynarray b/contrib/libc++/include/experimental/dynarray index f40a6ca..4a06908 100644 --- a/contrib/libc++/include/experimental/dynarray +++ b/contrib/libc++/include/experimental/dynarray @@ -159,9 +159,13 @@ private: public: + _LIBCPP_INLINE_VISIBILITY explicit dynarray(size_type __c); + _LIBCPP_INLINE_VISIBILITY dynarray(size_type __c, const value_type& __v); + _LIBCPP_INLINE_VISIBILITY dynarray(const dynarray& __d); + _LIBCPP_INLINE_VISIBILITY dynarray(initializer_list<value_type>); // We're not implementing these right now. @@ -176,6 +180,7 @@ public: // dynarray(allocator_arg_t, const _Alloc& __alloc, initializer_list<value_type>); dynarray& operator=(const dynarray&) = delete; + _LIBCPP_INLINE_VISIBILITY ~dynarray(); // iterators: @@ -219,7 +224,7 @@ public: }; template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(size_type __c) : dynarray () { __base_ = __allocate (__c); @@ -229,7 +234,7 @@ dynarray<_Tp>::dynarray(size_type __c) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () { __base_ = __allocate (__c); @@ -239,7 +244,7 @@ dynarray<_Tp>::dynarray(size_type __c, const value_type& __v) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () { size_t sz = __il.size(); @@ -251,7 +256,7 @@ dynarray<_Tp>::dynarray(initializer_list<value_type> __il) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () { size_t sz = __d.size(); @@ -263,7 +268,7 @@ dynarray<_Tp>::dynarray(const dynarray& __d) : dynarray () } template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline dynarray<_Tp>::~dynarray() { value_type *__data = data () + __size_; diff --git a/contrib/libc++/include/experimental/filesystem b/contrib/libc++/include/experimental/filesystem new file mode 100644 index 0000000..7de93fd --- /dev/null +++ b/contrib/libc++/include/experimental/filesystem @@ -0,0 +1,2052 @@ +// -*- C++ -*- +//===--------------------------- filesystem -------------------------------===// +// +// 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_FILESYSTEM +#define _LIBCPP_EXPERIMENTAL_FILESYSTEM +/* + filesystem synopsis + + namespace std { namespace experimental { namespace filesystem { inline namespace v1 { + + class path; + + void swap(path& lhs, path& rhs) _NOEXCEPT; + size_t hash_value(const path& p) _NOEXCEPT; + + bool operator==(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator!=(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator< (const path& lhs, const path& rhs) _NOEXCEPT; + bool operator<=(const path& lhs, const path& rhs) _NOEXCEPT; + bool operator> (const path& lhs, const path& rhs) _NOEXCEPT; + bool operator>=(const path& lhs, const path& rhs) _NOEXCEPT; + + path operator/ (const path& lhs, const path& rhs); + + template <class charT, class traits> + basic_ostream<charT, traits>& + operator<<(basic_ostream<charT, traits>& os, const path& p); + + template <class charT, class traits> + basic_istream<charT, traits>& + operator>>(basic_istream<charT, traits>& is, path& p); + + template <class Source> + path u8path(const Source& source); + template <class InputIterator> + path u8path(InputIterator first, InputIterator last); + + class filesystem_error; + class directory_entry; + + class directory_iterator; + + // enable directory_iterator range-based for statements + directory_iterator begin(directory_iterator iter) noexcept; + directory_iterator end(const directory_iterator&) noexcept; + + class recursive_directory_iterator; + + // enable recursive_directory_iterator range-based for statements + recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; + recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; + + class file_status; + + struct space_info + { + uintmax_t capacity; + uintmax_t free; + uintmax_t available; + }; + + enum class file_type; + enum class perms; + enum class copy_options; + enum class directory_options; + + typedef chrono::time_point<trivial-clock> file_time_type; + + // operational functions + + path absolute(const path& p, const path& base=current_path()); + + path canonical(const path& p, const path& base = current_path()); + path canonical(const path& p, error_code& ec); + path canonical(const path& p, const path& base, error_code& ec); + + void copy(const path& from, const path& to); + void copy(const path& from, const path& to, error_code& ec) _NOEXCEPT; + void copy(const path& from, const path& to, copy_options options); + void copy(const path& from, const path& to, copy_options options, + error_code& ec) _NOEXCEPT; + + bool copy_file(const path& from, const path& to); + bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT; + bool copy_file(const path& from, const path& to, copy_options option); + bool copy_file(const path& from, const path& to, copy_options option, + error_code& ec) _NOEXCEPT; + + void copy_symlink(const path& existing_symlink, const path& new_symlink); + void copy_symlink(const path& existing_symlink, const path& new_symlink, + error_code& ec) _NOEXCEPT; + + bool create_directories(const path& p); + bool create_directories(const path& p, error_code& ec) _NOEXCEPT; + + bool create_directory(const path& p); + bool create_directory(const path& p, error_code& ec) _NOEXCEPT; + + bool create_directory(const path& p, const path& attributes); + bool create_directory(const path& p, const path& attributes, + error_code& ec) _NOEXCEPT; + + void create_directory_symlink(const path& to, const path& new_symlink); + void create_directory_symlink(const path& to, const path& new_symlink, + error_code& ec) _NOEXCEPT; + + void create_hard_link(const path& to, const path& new_hard_link); + void create_hard_link(const path& to, const path& new_hard_link, + error_code& ec) _NOEXCEPT; + + void create_symlink(const path& to, const path& new_symlink); + void create_symlink(const path& to, const path& new_symlink, + error_code& ec) _NOEXCEPT; + + path current_path(); + path current_path(error_code& ec); + void current_path(const path& p); + void current_path(const path& p, error_code& ec) _NOEXCEPT; + + bool exists(file_status s) _NOEXCEPT; + bool exists(const path& p); + bool exists(const path& p, error_code& ec) _NOEXCEPT; + + bool equivalent(const path& p1, const path& p2); + bool equivalent(const path& p1, const path& p2, error_code& ec) _NOEXCEPT; + + uintmax_t file_size(const path& p); + uintmax_t file_size(const path& p, error_code& ec) _NOEXCEPT; + + uintmax_t hard_link_count(const path& p); + uintmax_t hard_link_count(const path& p, error_code& ec) _NOEXCEPT; + + bool is_block_file(file_status s) _NOEXCEPT; + bool is_block_file(const path& p); + bool is_block_file(const path& p, error_code& ec) _NOEXCEPT; + + bool is_character_file(file_status s) _NOEXCEPT; + bool is_character_file(const path& p); + bool is_character_file(const path& p, error_code& ec) _NOEXCEPT; + + bool is_directory(file_status s) _NOEXCEPT; + bool is_directory(const path& p); + bool is_directory(const path& p, error_code& ec) _NOEXCEPT; + + bool is_empty(const path& p); + bool is_empty(const path& p, error_code& ec) _NOEXCEPT; + + bool is_fifo(file_status s) _NOEXCEPT; + bool is_fifo(const path& p); + bool is_fifo(const path& p, error_code& ec) _NOEXCEPT; + + bool is_other(file_status s) _NOEXCEPT; + bool is_other(const path& p); + bool is_other(const path& p, error_code& ec) _NOEXCEPT; + + bool is_regular_file(file_status s) _NOEXCEPT; + bool is_regular_file(const path& p); + bool is_regular_file(const path& p, error_code& ec) _NOEXCEPT; + + bool is_socket(file_status s) _NOEXCEPT; + bool is_socket(const path& p); + bool is_socket(const path& p, error_code& ec) _NOEXCEPT; + + bool is_symlink(file_status s) _NOEXCEPT; + bool is_symlink(const path& p); + bool is_symlink(const path& p, error_code& ec) _NOEXCEPT; + + file_time_type last_write_time(const path& p); + file_time_type last_write_time(const path& p, error_code& ec) _NOEXCEPT; + void last_write_time(const path& p, file_time_type new_time); + void last_write_time(const path& p, file_time_type new_time, + error_code& ec) _NOEXCEPT; + + void permissions(const path& p, perms prms); + void permissions(const path& p, perms prms, error_code& ec) _NOEXCEPT; + + path read_symlink(const path& p); + path read_symlink(const path& p, error_code& ec); + + bool remove(const path& p); + bool remove(const path& p, error_code& ec) _NOEXCEPT; + + uintmax_t remove_all(const path& p); + uintmax_t remove_all(const path& p, error_code& ec) _NOEXCEPT; + + void rename(const path& from, const path& to); + void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT; + + void resize_file(const path& p, uintmax_t size); + void resize_file(const path& p, uintmax_t size, error_code& ec) _NOEXCEPT; + + space_info space(const path& p); + space_info space(const path& p, error_code& ec) _NOEXCEPT; + + file_status status(const path& p); + file_status status(const path& p, error_code& ec) _NOEXCEPT; + + bool status_known(file_status s) _NOEXCEPT; + + file_status symlink_status(const path& p); + file_status symlink_status(const path& p, error_code& ec) _NOEXCEPT; + + path system_complete(const path& p); + path system_complete(const path& p, error_code& ec); + + path temp_directory_path(); + path temp_directory_path(error_code& ec); + +} } } } // namespaces std::experimental::filesystem::v1 + +*/ + +#include <experimental/__config> +#include <cstddef> +#include <chrono> +#include <iterator> +#include <iosfwd> +#include <locale> +#include <memory> +#include <stack> +#include <string> +#include <system_error> +#include <utility> +#include <iomanip> // for quoted +#include <experimental/string_view> + +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#define __cpp_lib_experimental_filesystem 201406 + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +typedef chrono::time_point<std::chrono::system_clock> file_time_type; + +struct _LIBCPP_TYPE_VIS space_info +{ + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; + +enum class _LIBCPP_TYPE_VIS file_type : signed char +{ + none = 0, + not_found = -1, + regular = 1, + directory = 2, + symlink = 3, + block = 4, + character = 5, + fifo = 6, + socket = 7, + unknown = 8 +}; + +enum class _LIBCPP_TYPE_VIS perms : unsigned +{ + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + mask = 07777, + unknown = 0xFFFF, + + add_perms = 0x10000, + remove_perms = 0x20000, + symlink_nofollow = 0x40000 +}; + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator&(perms _LHS, perms _RHS) +{ return static_cast<perms>(static_cast<unsigned>(_LHS) & static_cast<unsigned>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator|(perms _LHS, perms _RHS) +{ return static_cast<perms>(static_cast<unsigned>(_LHS) | static_cast<unsigned>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator^(perms _LHS, perms _RHS) +{ return static_cast<perms>(static_cast<unsigned>(_LHS) ^ static_cast<unsigned>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR perms operator~(perms _LHS) +{ return static_cast<perms>(~static_cast<unsigned>(_LHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator&=(perms& _LHS, perms _RHS) +{ return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator|=(perms& _LHS, perms _RHS) +{ return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline perms& operator^=(perms& _LHS, perms _RHS) +{ return _LHS = _LHS ^ _RHS; } + +enum class _LIBCPP_TYPE_VIS copy_options : unsigned short +{ + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, + __in_recursive_copy = 512, +}; + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator&(copy_options _LHS, copy_options _RHS) +{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) & static_cast<unsigned short>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator|(copy_options _LHS, copy_options _RHS) +{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) | static_cast<unsigned short>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator^(copy_options _LHS, copy_options _RHS) +{ return static_cast<copy_options>(static_cast<unsigned short>(_LHS) ^ static_cast<unsigned short>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR copy_options operator~(copy_options _LHS) +{ return static_cast<copy_options>(~static_cast<unsigned short>(_LHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator&=(copy_options& _LHS, copy_options _RHS) +{ return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator|=(copy_options& _LHS, copy_options _RHS) +{ return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline copy_options& operator^=(copy_options& _LHS, copy_options _RHS) +{ return _LHS = _LHS ^ _RHS; } + + +enum class directory_options : unsigned char +{ + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2 +}; + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator&(directory_options _LHS, directory_options _RHS) +{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) & static_cast<unsigned char>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator|(directory_options _LHS, directory_options _RHS) +{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) | static_cast<unsigned char>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator^(directory_options _LHS, directory_options _RHS) +{ return static_cast<directory_options>(static_cast<unsigned char>(_LHS) ^ static_cast<unsigned char>(_RHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR directory_options operator~(directory_options _LHS) +{ return static_cast<directory_options>(~static_cast<unsigned char>(_LHS)); } + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator&=(directory_options& _LHS, directory_options _RHS) +{ return _LHS = _LHS & _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator|=(directory_options& _LHS, directory_options _RHS) +{ return _LHS = _LHS | _RHS; } + +_LIBCPP_INLINE_VISIBILITY +inline directory_options& operator^=(directory_options& _LHS, directory_options _RHS) +{ return _LHS = _LHS ^ _RHS; } + + +class _LIBCPP_TYPE_VIS file_status +{ +public: + // constructors + _LIBCPP_INLINE_VISIBILITY + explicit file_status(file_type __ft = file_type::none, + perms __prms = perms::unknown) _NOEXCEPT + : __ft_(__ft), __prms_(__prms) + {} + + file_status(const file_status&) _NOEXCEPT = default; + file_status(file_status&&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + ~file_status() {} + + file_status& operator=(const file_status&) _NOEXCEPT = default; + file_status& operator=(file_status&&) _NOEXCEPT = default; + + // observers + _LIBCPP_ALWAYS_INLINE + file_type type() const _NOEXCEPT { + return __ft_; + } + + _LIBCPP_ALWAYS_INLINE + perms permissions() const _NOEXCEPT { + return __prms_; + } + + // modifiers + _LIBCPP_ALWAYS_INLINE + void type(file_type __ft) _NOEXCEPT { + __ft_ = __ft; + } + + _LIBCPP_ALWAYS_INLINE + void permissions(perms __p) _NOEXCEPT { + __prms_ = __p; + } +private: + file_type __ft_; + perms __prms_; +}; + +class _LIBCPP_TYPE_VIS directory_entry; + +template <class _Tp> struct __can_convert_char { + static const bool value = false; +}; +template <> struct __can_convert_char<char> { + static const bool value = true; + using __char_type = char; +}; +template <> struct __can_convert_char<wchar_t> { + static const bool value = true; + using __char_type = wchar_t; +}; +template <> struct __can_convert_char<char16_t> { + static const bool value = true; + using __char_type = char16_t; +}; +template <> struct __can_convert_char<char32_t> { + static const bool value = true; + using __char_type = char32_t; +}; + +template <class _ECharT> +typename enable_if<__can_convert_char<_ECharT>::value, bool>::type +__is_separator(_ECharT __e) { + return __e == _ECharT('/'); +}; + +struct _NullSentinal {}; + +template <class _Tp> +using _Void = void; + +template <class _Tp, class = void> +struct __is_pathable_string : public false_type {}; + +template <class _ECharT, class _Traits, class _Alloc> +struct __is_pathable_string<basic_string<_ECharT, _Traits, _Alloc>, + _Void<typename __can_convert_char<_ECharT>::__char_type>> +: public __can_convert_char<_ECharT> +{ + using _Str = basic_string<_ECharT, _Traits, _Alloc>; + 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< + typename remove_pointer<_DS>::type>::type, + bool _IsCharPtr = is_pointer<_DS>::value && + __can_convert_char<_UnqualPtrType>::value + > +struct __is_pathable_char_array : false_type {}; + +template <class _Source, class _ECharT, class _UPtr> +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> + : __can_convert_char<typename remove_const<_ECharT>::type> +{ + using _Base = __can_convert_char<typename remove_const<_ECharT>::type>; + + static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } + static _ECharT const* __range_end(const _ECharT* __b) + { + using _Iter = const _ECharT*; + const _ECharT __sentinal = _ECharT{}; + _Iter __e = __b; + for (; *__e != __sentinal; ++__e) + ; + return __e; + } + + static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } +}; + +template <class _Iter, bool _IsIt = __is_input_iterator<_Iter>::value, class = void> +struct __is_pathable_iter : false_type {}; + +template <class _Iter> +struct __is_pathable_iter<_Iter, true, + _Void<typename __can_convert_char<typename iterator_traits<_Iter>::value_type>::__char_type>> + : __can_convert_char<typename iterator_traits<_Iter>::value_type> +{ + using _ECharT = typename iterator_traits<_Iter>::value_type; + using _Base = __can_convert_char<_ECharT>; + + static _Iter __range_begin(_Iter __b) { return __b; } + static _NullSentinal __range_end(_Iter) { return _NullSentinal{}; } + + static _ECharT __first_or_null(_Iter __b) { return *__b; } +}; + +template <class _Tp, bool _IsStringT = __is_pathable_string<_Tp>::value, + bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value + > +struct __is_pathable : false_type { + static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); +}; + +template <class _Tp> +struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; + + +template <class _Tp> +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {}; + + +template <class _Tp> +struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; + + +template <class _ECharT> +struct _PathCVT { + static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible"); + + typedef __narrow_to_utf8<sizeof(_ECharT)*__CHAR_BIT__> _Narrower; + + static void __append_range(string& __dest, _ECharT const* __b, _ECharT const* __e) { + _Narrower()(back_inserter(__dest), __b, __e); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _Iter __e) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + if (__b == __e) return; + basic_string<_ECharT> __tmp(__b, __e); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); + const _ECharT __sentinal = _ECharT{}; + if (*__b == __sentinal) return; + basic_string<_ECharT> __tmp; + for (; *__b != __sentinal; ++__b) + __tmp.push_back(*__b); + _Narrower()(back_inserter(__dest), __tmp.data(), + __tmp.data() + __tmp.length()); + } + + template <class _Source> + 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)); + } +}; + +template <> +struct _PathCVT<char> { + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _Iter __e) { + for (; __b != __e; ++__b) + __dest.push_back(*__b); + } + + template <class _Iter> + static void __append_range(string& __dest, _Iter __b, _NullSentinal) { + const char __sentinal = char{}; + for (; *__b != __sentinal; ++__b) + __dest.push_back(*__b); + } + + template <class _Source> + 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)); + } +}; + + +class _LIBCPP_TYPE_VIS path +{ + template <class _SourceOrIter, class _Tp = path&> + using _EnableIfPathable = typename + enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + + template <class _Tp> + using _SourceChar = typename __is_pathable<_Tp>::__char_type; + + template <class _Tp> + using _SourceCVT = _PathCVT<_SourceChar<_Tp>>; + +public: + typedef char value_type; + typedef basic_string<value_type> string_type; + static _LIBCPP_CONSTEXPR value_type preferred_separator = '/'; + + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY path() _NOEXCEPT {} + _LIBCPP_INLINE_VISIBILITY path(const path& __p) : __pn_(__p.__pn_) {} + _LIBCPP_INLINE_VISIBILITY path(path&& __p) _NOEXCEPT : __pn_(_VSTD::move(__p.__pn_)) {} + + _LIBCPP_INLINE_VISIBILITY + path(string_type&& __s) _NOEXCEPT : __pn_(_VSTD::move(__s)) {} + + template < + class _Source, + class = _EnableIfPathable<_Source, void> + > + path(const _Source& __src) { + _SourceCVT<_Source>::__append_source(__pn_, __src); + } + + template <class _InputIt> + path(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + } + + // TODO Implement locale conversions. + template <class _Source, + class = _EnableIfPathable<_Source, void> + > + path(const _Source& __src, const locale& __loc); + template <class _InputIt> + path(_InputIt __first, _InputIt _last, const locale& __loc); + + _LIBCPP_INLINE_VISIBILITY + ~path() = default; + + // assignments + _LIBCPP_INLINE_VISIBILITY + path& operator=(const path& __p) { + __pn_ = __p.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(path&& __p) _NOEXCEPT { + __pn_ = _VSTD::move(__p.__pn_); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator=(string_type&& __s) _NOEXCEPT { + __pn_ = _VSTD::move(__s); + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& assign(string_type&& __s) _NOEXCEPT { + __pn_ = _VSTD::move(__s); + return *this; + } + + template <class _Source> + _LIBCPP_INLINE_VISIBILITY + _EnableIfPathable<_Source> + operator=(const _Source& __src) + { return this->assign(__src); } + + + template <class _Source> + _EnableIfPathable<_Source> + assign(const _Source& __src) { + __pn_.clear(); + _SourceCVT<_Source>::__append_source(__pn_, __src); + return *this; + } + + template <class _InputIt> + path& assign(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + __pn_.clear(); + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + +private: + template <class _ECharT> + void __append_sep_if_needed(_ECharT __first_or_null) { + const _ECharT __null_val = {}; + bool __append_sep = !empty() && + !__is_separator(__pn_.back()) && + __first_or_null != __null_val && // non-empty + !__is_separator(__first_or_null); + if (__append_sep) + __pn_ += preferred_separator; + } + +public: + // appends + path& operator/=(const path& __p) { + __append_sep_if_needed(__p.empty() ? char{} : __p.__pn_[0]); + __pn_ += __p.native(); + return *this; + } + + template <class _Source> + _LIBCPP_INLINE_VISIBILITY + _EnableIfPathable<_Source> + operator/=(const _Source& __src) { + return this->append(__src); + } + + template <class _Source> + _EnableIfPathable<_Source> + append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source>>; + __append_sep_if_needed(_Traits::__first_or_null(__src)); + _CVT::__append_source(__pn_, __src); + return *this; + } + + template <class _InputIt> + path& append(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); + using _CVT = _PathCVT<_ItVal>; + if (__first != __last) { + __append_sep_if_needed(*__first); + _CVT::__append_range(__pn_, __first, __last); + } + return *this; + } + + // concatenation + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const path& __x) { + __pn_ += __x.__pn_; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const string_type& __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(const value_type* __x) { + __pn_ += __x; + return *this; + } + + _LIBCPP_INLINE_VISIBILITY + path& operator+=(value_type __x) { + __pn_ += __x; + return *this; + } + + + template <class _ECharT> + typename enable_if<__can_convert_char<_ECharT>::value, path&>::type + operator+=(_ECharT __x) + { + basic_string<_ECharT> __tmp; + __tmp += __x; + _PathCVT<_ECharT>::__append_source(__pn_, __tmp); + return *this; + } + + template <class _Source> + _EnableIfPathable<_Source> + operator+=(const _Source& __x) { + return this->concat(__x); + } + + template <class _Source> + _EnableIfPathable<_Source> + concat(const _Source& __x) { + _SourceCVT<_Source>::__append_source(__pn_, __x); + return *this; + } + + template <class _InputIt> + path& concat(_InputIt __first, _InputIt __last) { + typedef typename iterator_traits<_InputIt>::value_type _ItVal; + _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); + return *this; + } + + // modifiers + _LIBCPP_INLINE_VISIBILITY + void clear() _NOEXCEPT { + __pn_.clear(); + } + + path& make_preferred() { return *this; } + path& remove_filename() { return *this = parent_path(); } + + path& replace_filename(const path& __replacement) { + remove_filename(); + return (*this /= __replacement); + } + + path& replace_extension(const path& __replacement = path()); + + _LIBCPP_INLINE_VISIBILITY + void swap(path& __rhs) _NOEXCEPT { + __pn_.swap(__rhs.__pn_); + } + + // native format observers + _LIBCPP_INLINE_VISIBILITY + const string_type& native() const _NOEXCEPT { + return __pn_; + } + + _LIBCPP_INLINE_VISIBILITY + const value_type* c_str() const _NOEXCEPT { return __pn_.c_str(); } + + _LIBCPP_INLINE_VISIBILITY operator string_type() const { return __pn_; } + + template <class _ECharT, class _Traits = char_traits<_ECharT>, + class _Allocator = allocator<_ECharT> > + basic_string<_ECharT, _Traits, _Allocator> + string(const _Allocator& __a = _Allocator()) const { + using _CVT = __widen_from_utf8<sizeof(_ECharT)*__CHAR_BIT__>; + using _Str = basic_string<_ECharT, _Traits, _Allocator>; + _Str __s(__a); + __s.reserve(__pn_.size()); + _CVT()(back_inserter(__s), __pn_.data(), __pn_.data() + __pn_.size()); + return __s; + } + + _LIBCPP_INLINE_VISIBILITY std::string string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::wstring wstring() const { return string<wchar_t>(); } + _LIBCPP_INLINE_VISIBILITY std::string u8string() const { return __pn_; } + _LIBCPP_INLINE_VISIBILITY std::u16string u16string() const { return string<char16_t>(); } + _LIBCPP_INLINE_VISIBILITY std::u32string u32string() const { return string<char32_t>(); } + + // generic format observers + template <class _ECharT, class _Traits = char_traits<_ECharT>, + class _Allocator = allocator<_ECharT> + > + basic_string<_ECharT, _Traits, _Allocator> + generic_string(const _Allocator& __a = _Allocator()) const { + return string<_ECharT, _Traits, _Allocator>(__a); + } + + std::string generic_string() const { return __pn_; } + std::wstring generic_wstring() const { return string<wchar_t>(); } + std::string generic_u8string() const { return __pn_; } + std::u16string generic_u16string() const { return string<char16_t>(); } + 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; + +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 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(); } + + // 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_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(); } + _LIBCPP_INLINE_VISIBILITY bool has_stem() const { return !__stem().empty(); } + _LIBCPP_INLINE_VISIBILITY bool has_extension() const { return !__extension().empty(); } + + _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { return has_root_directory(); } + _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } + + // iterators + class _LIBCPP_TYPE_VIS iterator; + typedef iterator const_iterator; + + _LIBCPP_FUNC_VIS iterator begin() const; + _LIBCPP_FUNC_VIS iterator end() const; + +private: + inline _LIBCPP_INLINE_VISIBILITY + path& __assign_view(string_view const& __s) noexcept { __pn_ = __s.to_string(); return *this; } + string_type __pn_; +}; + +inline _LIBCPP_ALWAYS_INLINE +void swap(path& __lhs, path& __rhs) _NOEXCEPT { + __lhs.swap(__rhs); +} + +_LIBCPP_FUNC_VIS +size_t hash_value(const path& __p) _NOEXCEPT; + +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) == 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) != 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator<(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) < 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator<=(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) <= 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator>(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) > 0; } + +inline _LIBCPP_INLINE_VISIBILITY +bool operator>=(const path& __lhs, const path& __rhs) _NOEXCEPT +{ return __lhs.compare(__rhs) >= 0; } + +inline _LIBCPP_INLINE_VISIBILITY +path operator/(const path& __lhs, const path& __rhs) { + return path(__lhs) /= __rhs; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<is_same<_CharT, char>::value && + is_same<_Traits, char_traits<char>>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.native()); + return __os; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<!is_same<_CharT, char>::value || + !is_same<_Traits, char_traits<char>>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.string<_CharT, _Traits>()); + return __os; +} + +template <class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) +{ + basic_string<_CharT, _Traits> __tmp; + __is >> __quoted(__tmp); + __p = __tmp; + return __is; +} + +template <class _Source> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<__is_pathable<_Source>::value, path>::type +u8path(const _Source& __s){ + static_assert(is_same<typename __is_pathable<_Source>::__char_type, char>::value, + "u8path(Source const&) requires Source have a character type of type 'char'"); + return path(__s); +} + +template <class _InputIt> +_LIBCPP_INLINE_VISIBILITY +typename enable_if<__is_pathable<_InputIt>::value, path>::type +u8path(_InputIt __f, _InputIt __l) { + static_assert(is_same<typename __is_pathable<_InputIt>::__char_type, char>::value, + "u8path(Iter, Iter) requires Iter have a value_type of type 'char'"); + return path(__f, __l); +} + +class _LIBCPP_TYPE_VIS path::iterator +{ +public: + typedef bidirectional_iterator_tag iterator_category; + typedef path value_type; + typedef std::ptrdiff_t difference_type; + typedef const path* pointer; + typedef const path& reference; +public: + _LIBCPP_INLINE_VISIBILITY + iterator() : __elem_(), __path_ptr_(nullptr), __pos_(0) {} + + iterator(const iterator&) = default; + ~iterator() = default; + + iterator& operator=(const iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + reference operator*() const { + return __elem_; + } + + _LIBCPP_INLINE_VISIBILITY + pointer operator->() const { + return &__elem_; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator++() { + return __increment(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator++(int) { + iterator __it(*this); + this->operator++(); + return __it; + } + + _LIBCPP_INLINE_VISIBILITY + iterator& operator--() { + return __decrement(); + } + + _LIBCPP_INLINE_VISIBILITY + iterator operator--(int) { + iterator __it(*this); + this->operator--(); + return __it; + } + +private: + friend class path; + friend bool operator==(const iterator&, const iterator&); + + _LIBCPP_FUNC_VIS iterator& __increment(); + _LIBCPP_FUNC_VIS iterator& __decrement(); + + path __elem_; + const path* __path_ptr_; + size_t __pos_; +}; + +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_; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) { + return !(__lhs == __rhs); +} + +class _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error +{ +public: + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), + __paths_(make_shared<_Storage>(path(), path())) + {} + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), + __paths_(make_shared<_Storage>(__p1, path())) + {} + + _LIBCPP_INLINE_VISIBILITY + filesystem_error(const string& __what, const path& __p1, const path& __p2, + error_code __ec) + : system_error(__ec, __what), + __paths_(make_shared<_Storage>(__p1, __p2)) + {} + + _LIBCPP_INLINE_VISIBILITY + const path& path1() const _NOEXCEPT { + return __paths_->first; + } + + _LIBCPP_INLINE_VISIBILITY + const path& path2() const _NOEXCEPT { + return __paths_->second; + } + + _LIBCPP_FUNC_VIS + ~filesystem_error() override; // key function + + // TODO(ericwf): Create a custom error message. + //const char* what() const _NOEXCEPT; + +private: + typedef pair<path, path> _Storage; + shared_ptr<_Storage> __paths_; +}; + +// operational functions + +_LIBCPP_FUNC_VIS +path __canonical(const path&, const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __copy(const path& __from, const path& __to, copy_options __opt, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __copy_file(const path& __from, const path& __to, copy_options __opt, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __create_directories(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +bool __create_directory(const path& p, const path & attributes, + error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __create_directory_symlink(const path& __to, const path& __new_symlink, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __create_hard_link(const path& __to, const path& __new_hard_link, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __create_symlink(const path& __to, const path& __new_symlink, + error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +path __current_path(error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +void __current_path(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __equivalent(const path&, const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __file_size(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __hard_link_count(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +bool __fs_is_empty(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +file_time_type __last_write_time(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __last_write_time(const path& p, file_time_type new_time, + error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __permissions(const path& p, perms prms, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +path __read_symlink(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +bool __remove(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +uintmax_t __remove_all(const path& p, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __rename(const path& from, const path& to, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +void __resize_file(const path& p, uintmax_t size, error_code *ec=nullptr); +_LIBCPP_FUNC_VIS +space_info __space(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +file_status __status(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +file_status __symlink_status(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +path __system_complete(const path&, error_code *__ec=nullptr); +_LIBCPP_FUNC_VIS +path __temp_directory_path(error_code *__ec=nullptr); + +inline _LIBCPP_INLINE_VISIBILITY +path current_path() { + return __current_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY +path current_path(error_code& __ec) { + return __current_path(&__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void current_path(const path& __p) { + __current_path(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +void current_path(const path& __p, error_code& __ec) _NOEXCEPT { + __current_path(__p, &__ec); +} + +_LIBCPP_FUNC_VIS +path absolute(const path&, const path& __p2 = current_path()); + +inline _LIBCPP_INLINE_VISIBILITY +path canonical(const path& __p, const path& __base = current_path()) { + return __canonical(__p, __base); +} + +inline _LIBCPP_INLINE_VISIBILITY +path canonical(const path& __p, error_code& __ec) { + path __base = __current_path(&__ec); + if (__ec) return {}; + return __canonical(__p, __base, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path canonical(const path& __p, const path& __base, error_code& __ec) { + return __canonical(__p, __base, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to) { + __copy(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { + __copy(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to, copy_options __opt) { + __copy(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy(const path& __from, const path& __to, + copy_options __opt, error_code& __ec) _NOEXCEPT { + __copy(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to) { + return __copy_file(__from, __to, copy_options::none); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { + return __copy_file(__from, __to, copy_options::none, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to, copy_options __opt) { + return __copy_file(__from, __to, __opt); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool copy_file(const path& __from, const path& __to, + copy_options __opt, error_code& __ec) _NOEXCEPT { + return __copy_file(__from, __to, __opt, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy_symlink(const path& __existing, const path& __new) { + __copy_symlink(__existing, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void copy_symlink(const path& __ext, const path& __new, error_code& __ec) _NOEXCEPT { + __copy_symlink(__ext, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directories(const path& __p) { + return __create_directories(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT { + return __create_directories(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p) { + return __create_directory(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p, error_code& __ec) _NOEXCEPT { + return __create_directory(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p, const path& __attrs) { + return __create_directory(__p, __attrs); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool create_directory(const path& __p, const path& __attrs, error_code& __ec) _NOEXCEPT { + return __create_directory(__p, __attrs, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_directory_symlink(const path& __to, const path& __new) { + __create_directory_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_directory_symlink(const path& __to, const path& __new, + error_code& __ec) _NOEXCEPT { + __create_directory_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_hard_link(const path& __to, const path& __new) { + __create_hard_link(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_hard_link(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { + __create_hard_link(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_symlink(const path& __to, const path& __new) { + __create_symlink(__to, __new); +} + +inline _LIBCPP_INLINE_VISIBILITY +void create_symlink(const path& __to, const path& __new, error_code& __ec) _NOEXCEPT { + return __create_symlink(__to, __new, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool status_known(file_status __s) _NOEXCEPT { + return __s.type() != file_type::none; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool exists(file_status __s) _NOEXCEPT { + return status_known(__s) && __s.type() != file_type::not_found; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool exists(const path& __p) { + return exists(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool exists(const path& __p, error_code& __ec) _NOEXCEPT { + auto __s = __status(__p, &__ec); + if (status_known(__s)) __ec.clear(); + return exists(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool equivalent(const path& __p1, const path& __p2) { + return __equivalent(__p1, __p2); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool equivalent(const path& __p1, const path& __p2, error_code& __ec) _NOEXCEPT { + return __equivalent(__p1, __p2, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t file_size(const path& __p) { + return __file_size(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t file_size(const path& __p, error_code& __ec) _NOEXCEPT { + return __file_size(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t hard_link_count(const path& __p) { + return __hard_link_count(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t hard_link_count(const path& __p, error_code& __ec) _NOEXCEPT { + return __hard_link_count(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_block_file(file_status __s) _NOEXCEPT { + return __s.type() == file_type::block; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_block_file(const path& __p) { + return is_block_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_block_file(const path& __p, error_code& __ec) _NOEXCEPT { + return is_block_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_character_file(file_status __s) _NOEXCEPT { + return __s.type() == file_type::character; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_character_file(const path& __p) { + return is_character_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_character_file(const path& __p, error_code& __ec) _NOEXCEPT { + return is_character_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_directory(file_status __s) _NOEXCEPT { + return __s.type() == file_type::directory; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_directory(const path& __p) { + return is_directory(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_directory(const path& __p, error_code& __ec) _NOEXCEPT { + return is_directory(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_empty(const path& __p) { + return __fs_is_empty(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_empty(const path& __p, error_code& __ec) _NOEXCEPT { + return __fs_is_empty(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_fifo(file_status __s) _NOEXCEPT { + return __s.type() == file_type::fifo; +} +inline _LIBCPP_INLINE_VISIBILITY +bool is_fifo(const path& __p) { + return is_fifo(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_fifo(const path& __p, error_code& __ec) _NOEXCEPT { + return is_fifo(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_regular_file(file_status __s) _NOEXCEPT { + return __s.type() == file_type::regular; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_regular_file(const path& __p) { + return is_regular_file(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_regular_file(const path& __p, error_code& __ec) _NOEXCEPT { + return is_regular_file(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_socket(file_status __s) _NOEXCEPT { + return __s.type() == file_type::socket; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_socket(const path& __p) { + return is_socket(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_socket(const path& __p, error_code& __ec) _NOEXCEPT { + return is_socket(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_symlink(file_status __s) _NOEXCEPT { + return __s.type() == file_type::symlink; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_symlink(const path& __p) { + return is_symlink(__symlink_status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_symlink(const path& __p, error_code& __ec) _NOEXCEPT { + return is_symlink(__symlink_status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_other(file_status __s) _NOEXCEPT { + return exists(__s) + && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_other(const path& __p) { + return is_other(__status(__p)); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool is_other(const path& __p, error_code& __ec) _NOEXCEPT { + return is_other(__status(__p, &__ec)); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_time_type last_write_time(const path& __p) { + return __last_write_time(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_time_type last_write_time(const path& __p, error_code& __ec) _NOEXCEPT { + return __last_write_time(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void last_write_time(const path& __p, file_time_type __t) { + __last_write_time(__p, __t); +} + +inline _LIBCPP_INLINE_VISIBILITY +void last_write_time(const path& __p, file_time_type __t, error_code& __ec) _NOEXCEPT { + __last_write_time(__p, __t, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void permissions(const path& __p, perms __prms) { + __permissions(__p, __prms); +} + +inline _LIBCPP_INLINE_VISIBILITY +void permissions(const path& __p, perms __prms, error_code& __ec) { + __permissions(__p, __prms, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path read_symlink(const path& __p) { + return __read_symlink(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +path read_symlink(const path& __p, error_code& __ec) { + return __read_symlink(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool remove(const path& __p) { + return __remove(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool remove(const path& __p, error_code& __ec) _NOEXCEPT { + return __remove(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t remove_all(const path& __p) { + return __remove_all(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT { + return __remove_all(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void rename(const path& __from, const path& __to) { + return __rename(__from, __to); +} + +inline _LIBCPP_INLINE_VISIBILITY +void rename(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { + return __rename(__from, __to, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +void resize_file(const path& __p, uintmax_t __ns) { + return __resize_file(__p, __ns); +} + +inline _LIBCPP_INLINE_VISIBILITY +void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) _NOEXCEPT { + return __resize_file(__p, __ns, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +space_info space(const path& __p) { + return __space(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +space_info space(const path& __p, error_code& __ec) _NOEXCEPT { + return __space(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status status(const path& __p) { + return __status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status status(const path& __p, error_code& __ec) _NOEXCEPT { + return __status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status symlink_status(const path& __p) { + return __symlink_status(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +file_status symlink_status(const path& __p, error_code& __ec) _NOEXCEPT { + return __symlink_status(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path system_complete(const path& __p) { + return __system_complete(__p); +} + +inline _LIBCPP_INLINE_VISIBILITY +path system_complete(const path& __p, error_code& __ec) { + return __system_complete(__p, &__ec); +} + +inline _LIBCPP_INLINE_VISIBILITY +path temp_directory_path() { + return __temp_directory_path(); +} + +inline _LIBCPP_INLINE_VISIBILITY +path temp_directory_path(error_code& __ec) { + return __temp_directory_path(&__ec); +} + + +class directory_entry +{ + typedef _VSTD_FS::path _Path; + +public: + // constructors and destructors + directory_entry() _NOEXCEPT = default; + directory_entry(directory_entry const&) = default; + directory_entry(directory_entry&&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + explicit directory_entry(_Path const& __p) : __p_(__p) {} + + ~directory_entry() {} + + directory_entry& operator=(directory_entry const&) = default; + directory_entry& operator=(directory_entry&&) _NOEXCEPT = default; + + _LIBCPP_INLINE_VISIBILITY + void assign(_Path const& __p) { + __p_ = __p; + } + + _LIBCPP_INLINE_VISIBILITY + void replace_filename(_Path const& __p) { + __p_ = __p_.parent_path() / __p; + } + + _LIBCPP_INLINE_VISIBILITY + _Path const& path() const _NOEXCEPT { + return __p_; + } + + _LIBCPP_INLINE_VISIBILITY + operator const _Path&() const _NOEXCEPT { + return __p_; + } + + _LIBCPP_INLINE_VISIBILITY + file_status status() const { + return _VSTD_FS::status(__p_); + } + + _LIBCPP_INLINE_VISIBILITY + file_status status(error_code& __ec) const _NOEXCEPT { + return _VSTD_FS::status(__p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status() const { + return _VSTD_FS::symlink_status(__p_); + } + + _LIBCPP_INLINE_VISIBILITY + file_status symlink_status(error_code& __ec) const _NOEXCEPT { + return _VSTD_FS::symlink_status(__p_, __ec); + } + + _LIBCPP_INLINE_VISIBILITY + bool operator< (directory_entry const& __rhs) const _NOEXCEPT { + return __p_ < __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator==(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ == __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator!=(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ != __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator<=(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ <= __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator> (directory_entry const& __rhs) const _NOEXCEPT { + return __p_ > __rhs.__p_; + } + + _LIBCPP_INLINE_VISIBILITY + bool operator>=(directory_entry const& __rhs) const _NOEXCEPT { + return __p_ >= __rhs.__p_; + } +private: + _Path __p_; +}; + + +class directory_iterator; +class recursive_directory_iterator; +class __dir_stream; + +class __dir_element_proxy { +public: + + inline _LIBCPP_INLINE_VISIBILITY + directory_entry operator*() { return _VSTD::move(__elem_); } + +private: + friend class directory_iterator; + friend class recursive_directory_iterator; + explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} + __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(_VSTD::move(__o.__elem_)) {} + directory_entry __elem_; +}; + +class directory_iterator +{ +public: + typedef directory_entry value_type; + typedef ptrdiff_t difference_type; + typedef value_type const* pointer; + typedef value_type const& reference; + typedef input_iterator_tag iterator_category; + +public: + //ctor & dtor + directory_iterator() _NOEXCEPT + { } + + explicit directory_iterator(const path& __p) + : directory_iterator(__p, nullptr) + { } + + directory_iterator(const path& __p, directory_options __opts) + : directory_iterator(__p, nullptr, __opts) + { } + + directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT + : directory_iterator(__p, &__ec) + { } + + directory_iterator(const path& __p, directory_options __opts, + error_code& __ec) _NOEXCEPT + : directory_iterator(__p, &__ec, __opts) + { } + + directory_iterator(const directory_iterator&) = default; + directory_iterator(directory_iterator&&) = default; + directory_iterator& operator=(const directory_iterator&) = default; + + directory_iterator& operator=(directory_iterator&& __o) _NOEXCEPT { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + } + return *this; + } + + ~directory_iterator() = default; + + const directory_entry& operator*() const { + _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + return __deref(); + } + + const directory_entry* operator->() const + { return &**this; } + + directory_iterator& operator++() + { return __increment(); } + + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + directory_iterator& increment(error_code& __ec) _NOEXCEPT + { return __increment(&__ec); } + +private: + friend bool operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) _NOEXCEPT; + + // construct the dir_stream + _LIBCPP_FUNC_VIS + directory_iterator(const path&, error_code *, directory_options = directory_options::none); + _LIBCPP_FUNC_VIS + directory_iterator& __increment(error_code * __ec = nullptr); + _LIBCPP_FUNC_VIS + const directory_entry& __deref() const; + +private: + shared_ptr<__dir_stream> __imp_; +}; + + +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(const directory_iterator& __lhs, + const directory_iterator& __rhs) _NOEXCEPT { + return __lhs.__imp_ == __rhs.__imp_; +} + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(const directory_iterator& __lhs, + const directory_iterator& __rhs) _NOEXCEPT { + return !(__lhs == __rhs); +} + +// enable directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY +directory_iterator begin(directory_iterator __iter) _NOEXCEPT { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY +directory_iterator end(const directory_iterator&) _NOEXCEPT { + return directory_iterator(); +} + +class recursive_directory_iterator { +public: + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = directory_entry const *; + using reference = directory_entry const &; + using iterator_category = std::input_iterator_tag; + +public: + // constructors and destructor + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator() _NOEXCEPT + : __rec_(false) + {} + + _LIBCPP_INLINE_VISIBILITY + explicit recursive_directory_iterator(const path& __p, + directory_options __xoptions = directory_options::none) + : recursive_directory_iterator(__p, __xoptions, nullptr) + { } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, + directory_options __xoptions, error_code& __ec) _NOEXCEPT + : recursive_directory_iterator(__p, __xoptions, &__ec) + { } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT + : recursive_directory_iterator(__p, directory_options::none, &__ec) + { } + + recursive_directory_iterator(const recursive_directory_iterator&) = default; + recursive_directory_iterator(recursive_directory_iterator&&) = default; + + recursive_directory_iterator & + operator=(const recursive_directory_iterator&) = default; + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator & + operator=(recursive_directory_iterator&& __o) noexcept { + // non-default implementation provided to support self-move assign. + if (this != &__o) { + __imp_ = _VSTD::move(__o.__imp_); + __rec_ = __o.__rec_; + } + return *this; + } + + ~recursive_directory_iterator() = default; + + _LIBCPP_INLINE_VISIBILITY + const directory_entry& operator*() const + { return __deref(); } + + _LIBCPP_INLINE_VISIBILITY + const directory_entry* operator->() const + { return &__deref(); } + + recursive_directory_iterator& operator++() + { return __increment(); } + + _LIBCPP_INLINE_VISIBILITY + __dir_element_proxy operator++(int) { + __dir_element_proxy __p(**this); + __increment(); + return __p; + } + + _LIBCPP_INLINE_VISIBILITY + recursive_directory_iterator& increment(error_code& __ec) _NOEXCEPT + { return __increment(&__ec); } + + _LIBCPP_FUNC_VIS directory_options options() const; + _LIBCPP_FUNC_VIS int depth() const; + + _LIBCPP_INLINE_VISIBILITY + void pop() { __pop(); } + + _LIBCPP_INLINE_VISIBILITY + void pop(error_code& __ec) + { __pop(&__ec); } + + _LIBCPP_INLINE_VISIBILITY + bool recursion_pending() const + { return __rec_; } + + _LIBCPP_INLINE_VISIBILITY + void disable_recursion_pending() + { __rec_ = false; } + +private: + recursive_directory_iterator(const path& __p, directory_options __opt, + error_code *__ec); + + _LIBCPP_FUNC_VIS + const directory_entry& __deref() const; + + _LIBCPP_FUNC_VIS + bool __try_recursion(error_code* __ec); + + _LIBCPP_FUNC_VIS + void __advance(error_code* __ec=nullptr); + + _LIBCPP_FUNC_VIS + recursive_directory_iterator& __increment(error_code *__ec=nullptr); + + _LIBCPP_FUNC_VIS + void __pop(error_code* __ec=nullptr); + + friend bool operator==(const recursive_directory_iterator&, + const recursive_directory_iterator&) _NOEXCEPT; + + struct __shared_imp; + shared_ptr<__shared_imp> __imp_; + bool __rec_; +}; // class recursive_directory_iterator + + +_LIBCPP_INLINE_VISIBILITY +inline bool operator==(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) _NOEXCEPT +{ + return __lhs.__imp_ == __rhs.__imp_; +} + +_LIBCPP_INLINE_VISIBILITY +inline bool operator!=(const recursive_directory_iterator& __lhs, + const recursive_directory_iterator& __rhs) _NOEXCEPT +{ + return !(__lhs == __rhs); +} +// enable recursive_directory_iterator range-based for statements +inline _LIBCPP_INLINE_VISIBILITY +recursive_directory_iterator begin(recursive_directory_iterator __iter) _NOEXCEPT { + return __iter; +} + +inline _LIBCPP_INLINE_VISIBILITY +recursive_directory_iterator end(const recursive_directory_iterator&) _NOEXCEPT { + return recursive_directory_iterator(); +} + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +#endif // _LIBCPP_EXPERIMENTAL_FILESYSTEM diff --git a/contrib/libc++/include/experimental/forward_list b/contrib/libc++/include/experimental/forward_list new file mode 100644 index 0000000..55e195f --- /dev/null +++ b/contrib/libc++/include/experimental/forward_list @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- forward_list -----------------------------===// +// +// 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_FORWARD_LIST +#define _LIBCPP_EXPERIMENTAL_FORWARD_LIST +/* + experimental/forward_list synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using forward_list = std::forward_list<T,polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <forward_list> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using forward_list = _VSTD::forward_list<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_FORWARD_LIST */ diff --git a/contrib/libc++/include/experimental/functional b/contrib/libc++/include/experimental/functional index c7a7869..75fc8e9 100644 --- a/contrib/libc++/include/experimental/functional +++ b/contrib/libc++/include/experimental/functional @@ -119,9 +119,12 @@ public: template <typename _ForwardIterator2> _LIBCPP_INLINE_VISIBILITY - _ForwardIterator2 operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const + pair<_ForwardIterator2, _ForwardIterator2> + operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const { - return _VSTD::search(__f, __l, __first_, __last_, __pred_); + return _VSTD::__search(__f, __l, __first_, __last_, __pred_, + typename _VSTD::iterator_traits<_ForwardIterator>::iterator_category(), + typename _VSTD::iterator_traits<_ForwardIterator2>::iterator_category()); } private: @@ -233,7 +236,7 @@ public: } template <typename _RandomAccessIterator2> - _RandomAccessIterator2 + pair<_RandomAccessIterator2, _RandomAccessIterator2> operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { static_assert ( std::is_same< @@ -242,12 +245,12 @@ public: >::value, "Corpus and Pattern iterators must point to the same type" ); - if (__f == __l ) return __l; // empty corpus - if (__first_ == __last_) return __f; // empty pattern + if (__f == __l ) return make_pair(__l, __l); // empty corpus + if (__first_ == __last_) return make_pair(__f, __f); // empty pattern // If the pattern is larger than the corpus, we can't find it! if ( __pattern_length_ > _VSTD::distance (__f, __l)) - return __l; + return make_pair(__l, __l); // Do the search return this->__search(__f, __l); @@ -262,7 +265,8 @@ public: // TODO private: shared_ptr<vector<difference_type>> __suffix_; template <typename _RandomAccessIterator2> - _RandomAccessIterator2 __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { _RandomAccessIterator2 __cur = __f; const _RandomAccessIterator2 __last = __l - __pattern_length_; @@ -278,7 +282,7 @@ public: // TODO private: __j--; // We matched - we're done! if ( __j == 0 ) - return __cur; + return make_pair(__cur, __cur + __pattern_length_); } // Since we didn't match, figure out how far to skip forward @@ -290,7 +294,7 @@ public: // TODO private: __cur += __suffix[ __j ]; } - return __l; // We didn't find anything + return make_pair(__l, __l); // We didn't find anything } @@ -384,8 +388,8 @@ public: } } - template <typename _RandomAccessIterator2> - _RandomAccessIterator2 + template <typename _RandomAccessIterator2> + pair<_RandomAccessIterator2, _RandomAccessIterator2> operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { static_assert ( std::is_same< @@ -394,12 +398,12 @@ public: >::value, "Corpus and Pattern iterators must point to the same type" ); - if (__f == __l ) return __l; // empty corpus - if (__first_ == __last_) return __f; // empty pattern + if (__f == __l ) return make_pair(__l, __l); // empty corpus + if (__first_ == __last_) return make_pair(__f, __f); // empty pattern // If the pattern is larger than the corpus, we can't find it! if ( __pattern_length_ > _VSTD::distance (__f, __l)) - return __l; + return make_pair(__l, __l); // Do the search return this->__search(__f, __l); @@ -413,7 +417,8 @@ private: shared_ptr<skip_table_type> __skip_; template <typename _RandomAccessIterator2> - _RandomAccessIterator2 __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { + pair<_RandomAccessIterator2, _RandomAccessIterator2> + __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { _RandomAccessIterator2 __cur = __f; const _RandomAccessIterator2 __last = __l - __pattern_length_; const skip_table_type & __skip = *__skip_.get(); @@ -427,12 +432,12 @@ private: __j--; // We matched - we're done! if ( __j == 0 ) - return __cur; + return make_pair(__cur, __cur + __pattern_length_); } __cur += __skip[__cur[__pattern_length_-1]]; } - return __l; + return make_pair(__l, __l); } }; diff --git a/contrib/libc++/include/experimental/iterator b/contrib/libc++/include/experimental/iterator new file mode 100644 index 0000000..da593fe --- /dev/null +++ b/contrib/libc++/include/experimental/iterator @@ -0,0 +1,114 @@ +// -*- C++ -*- +//===----------------------------- iterator -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_ITERATOR +#define _LIBCPP_EXPERIMENTAL_ITERATOR + +/* +namespace std { + namespace experimental { + inline namespace fundamentals_v2 { + + template <class DelimT, class charT = char, class traits = char_traits<charT>> + class ostream_joiner { + public: + typedef charT char_type; + typedef traits traits_type; + typedef basic_ostream<charT, traits> ostream_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_joiner(ostream_type& s, const DelimT& delimiter); + ostream_joiner(ostream_type& s, DelimT&& delimiter); + + template<typename T> + ostream_joiner& operator=(const T& value); + + ostream_joiner& operator*() noexcept; + ostream_joiner& operator++() noexcept; + ostream_joiner& operator++(int) noexcept; + private: + ostream_type* out_stream; // exposition only + DelimT delim; // exposition only + bool first_element; // exposition only + }; + + template <class charT, class traits, class DelimT> + ostream_joiner<decay_t<DelimT>, charT, traits> + make_ostream_joiner(basic_ostream<charT, traits>& os, DelimT&& delimiter); + + } // inline namespace fundamentals_v2 + } // namespace experimental +} // namespace std + +*/ + +#include <experimental/__config> + +#if _LIBCPP_STD_VER > 11 + +#include <iterator> + +_LIBCPP_BEGIN_NAMESPACE_LFTS + +template <class _Delim, class _CharT = char, class _Traits = char_traits<_CharT>> +class ostream_joiner { +public: + + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<char_type,traits_type> ostream_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + ostream_joiner(ostream_type& __os, _Delim&& __d) + : __out(_VSTD::addressof(__os)), __delim(_VSTD::move(__d)), __first(true) {} + + ostream_joiner(ostream_type& __os, const _Delim& __d) + : __out(_VSTD::addressof(__os)), __delim(__d), __first(true) {} + + + template<typename _Tp> + ostream_joiner& operator=(const _Tp& __v) + { + if (!__first) + *__out << __delim; + __first = false; + *__out << __v; + return *this; + } + + ostream_joiner& operator*() _NOEXCEPT { return *this; } + ostream_joiner& operator++() _NOEXCEPT { return *this; } + ostream_joiner& operator++(int) _NOEXCEPT { return *this; } + +private: + ostream_type* __out; + _Delim __delim; + bool __first; +}; + + +template <class _CharT, class _Traits, class _Delim> +ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> +make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) +{ return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } + +_LIBCPP_END_NAMESPACE_LFTS + +#endif /* _LIBCPP_STD_VER > 11 */ + +#endif // _LIBCPP_EXPERIMENTAL_ITERATOR diff --git a/contrib/libc++/include/experimental/list b/contrib/libc++/include/experimental/list new file mode 100644 index 0000000..1678ee3 --- /dev/null +++ b/contrib/libc++/include/experimental/list @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- list ------------------------------------===// +// +// 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_LIST +#define _LIBCPP_EXPERIMENTAL_LIST +/* + experimental/list synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using list = std::list<T,polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <list> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using list = _VSTD::list<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_LIST */ diff --git a/contrib/libc++/include/experimental/map b/contrib/libc++/include/experimental/map new file mode 100644 index 0000000..cff2c5e --- /dev/null +++ b/contrib/libc++/include/experimental/map @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===----------------------------- map ------------------------------------===// +// +// 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_MAP +#define _LIBCPP_EXPERIMENTAL_MAP +/* + experimental/map synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class Key, class T, class Compare = less<Key>> + using map = std::map<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + + template <class Key, class T, class Compare = less<Key>> + using multimap = std::multimap<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <map> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Key, class _Value, class _Compare = less<_Key>> +using map = _VSTD::map<_Key, _Value, _Compare, + polymorphic_allocator<pair<const _Key, _Value>>>; + +template <class _Key, class _Value, class _Compare = less<_Key>> +using multimap = _VSTD::multimap<_Key, _Value, _Compare, + polymorphic_allocator<pair<const _Key, _Value>>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_MAP */ diff --git a/contrib/libc++/include/experimental/memory_resource b/contrib/libc++/include/experimental/memory_resource new file mode 100644 index 0000000..9b34521 --- /dev/null +++ b/contrib/libc++/include/experimental/memory_resource @@ -0,0 +1,422 @@ +// -*- C++ -*- +//===------------------------ memory_resource -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE +#define _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE + +/** + experimental/memory_resource synopsis + +// C++1y + +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + class memory_resource; + + bool operator==(const memory_resource& a, + const memory_resource& b) noexcept; + bool operator!=(const memory_resource& a, + const memory_resource& b) noexcept; + + template <class Tp> class polymorphic_allocator; + + template <class T1, class T2> + bool operator==(const polymorphic_allocator<T1>& a, + const polymorphic_allocator<T2>& b) noexcept; + template <class T1, class T2> + bool operator!=(const polymorphic_allocator<T1>& a, + const polymorphic_allocator<T2>& b) noexcept; + + // The name resource_adaptor_imp is for exposition only. + template <class Allocator> class resource_adaptor_imp; + + template <class Allocator> + using resource_adaptor = resource_adaptor_imp< + allocator_traits<Allocator>::rebind_alloc<char>>; + + // Global memory resources + memory_resource* new_delete_resource() noexcept; + memory_resource* null_memory_resource() noexcept; + + // The default memory resource + memory_resource* set_default_resource(memory_resource* r) noexcept; + memory_resource* get_default_resource() noexcept; + + // Standard memory resources + struct pool_options; + class synchronized_pool_resource; + class unsynchronized_pool_resource; + class monotonic_buffer_resource; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <experimental/__memory> +#include <limits> +#include <memory> +#include <new> +#include <stdexcept> +#include <tuple> +#include <type_traits> +#include <utility> +#include <cstddef> +#include <cstdlib> +#include <__debug> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +// Round __s up to next multiple of __a. +inline _LIBCPP_INLINE_VISIBILITY +size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT +{ + _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows"); + return (__s + __a - 1) & ~(__a - 1); +} + +// 8.5, memory.resource +class _LIBCPP_TYPE_VIS_ONLY memory_resource +{ + static const size_t __max_align = alignof(max_align_t); + +// 8.5.2, memory.resource.public +public: + virtual ~memory_resource() = default; + + _LIBCPP_INLINE_VISIBILITY + void* allocate(size_t __bytes, size_t __align = __max_align) + { return do_allocate(__bytes, __align); } + + _LIBCPP_INLINE_VISIBILITY + void deallocate(void * __p, size_t __bytes, size_t __align = __max_align) + { do_deallocate(__p, __bytes, __align); } + + _LIBCPP_INLINE_VISIBILITY + bool is_equal(memory_resource const & __other) const _NOEXCEPT + { return do_is_equal(__other); } + +// 8.5.3, memory.resource.priv +protected: + virtual void* do_allocate(size_t, size_t) = 0; + virtual void do_deallocate(void*, size_t, size_t) = 0; + virtual bool do_is_equal(memory_resource const &) const _NOEXCEPT = 0; +}; + +// 8.5.4, memory.resource.eq +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(memory_resource const & __lhs, + memory_resource const & __rhs) _NOEXCEPT +{ + return &__lhs == &__rhs || __lhs.is_equal(__rhs); +} + +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(memory_resource const & __lhs, + memory_resource const & __rhs) _NOEXCEPT +{ + return !(__lhs == __rhs); +} + +_LIBCPP_FUNC_VIS +memory_resource * new_delete_resource() _NOEXCEPT; + +_LIBCPP_FUNC_VIS +memory_resource * null_memory_resource() _NOEXCEPT; + +_LIBCPP_FUNC_VIS +memory_resource * get_default_resource() _NOEXCEPT; + +_LIBCPP_FUNC_VIS +memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT; + +// 8.6, memory.polymorphic.allocator.class + +// 8.6.1, memory.polymorphic.allocator.overview +template <class _ValueType> +class _LIBCPP_TYPE_VIS_ONLY polymorphic_allocator +{ +public: + typedef _ValueType value_type; + + // 8.6.2, memory.polymorphic.allocator.ctor + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator() _NOEXCEPT + : __res_(_VSTD_LFTS_PMR::get_default_resource()) + {} + + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator(memory_resource * __r) _NOEXCEPT + : __res_(__r) + {} + + polymorphic_allocator(polymorphic_allocator const &) = default; + + template <class _Tp> + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator(polymorphic_allocator<_Tp> const & __other) _NOEXCEPT + : __res_(__other.resource()) + {} + + polymorphic_allocator & + operator=(polymorphic_allocator const &) = delete; + + // 8.6.3, memory.polymorphic.allocator.mem + _LIBCPP_INLINE_VISIBILITY + _ValueType* allocate(size_t __n) { + if (__n > max_size()) { + __libcpp_throw(length_error( + "std::experimental::pmr::polymorphic_allocator<T>::allocate(size_t n)" + " 'n' exceeds maximum supported size")); + } + return static_cast<_ValueType*>( + __res_->allocate(__n * sizeof(_ValueType), alignof(_ValueType)) + ); + } + + _LIBCPP_INLINE_VISIBILITY + void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { + _LIBCPP_ASSERT(__n <= max_size(), + "deallocate called for size which exceeds max_size()"); + __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType)); + } + + template <class _Tp, class ..._Ts> + _LIBCPP_INLINE_VISIBILITY + void construct(_Tp* __p, _Ts &&... __args) + { + _VSTD_LFTS::__lfts_user_alloc_construct( + __p, resource(), _VSTD::forward<_Ts>(__args)... + ); + } + + template <class _T1, class _T2, class ..._Args1, class ..._Args2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2>* __p, piecewise_construct_t, + tuple<_Args1...> __x, tuple<_Args2...> __y) + { + ::new ((void*)__p) pair<_T1, _T2>(piecewise_construct + , __transform_tuple( + typename __lfts_uses_alloc_ctor< + _T1, memory_resource*, _Args1... + >::type() + , _VSTD::move(__x) + , typename __make_tuple_indices<sizeof...(_Args1)>::type{} + ) + , __transform_tuple( + typename __lfts_uses_alloc_ctor< + _T2, memory_resource*, _Args2... + >::type() + , _VSTD::move(__y) + , typename __make_tuple_indices<sizeof...(_Args2)>::type{} + ) + ); + } + + template <class _T1, class _T2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2>* __p) { + construct(__p, piecewise_construct, tuple<>(), tuple<>()); + } + + template <class _T1, class _T2, class _Up, class _Vp> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2> * __p, _Up && __u, _Vp && __v) { + construct(__p, piecewise_construct + , _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__u)) + , _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__v))); + } + + template <class _T1, class _T2, class _U1, class _U2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> const & __pr) { + construct(__p, piecewise_construct + , _VSTD::forward_as_tuple(__pr.first) + , _VSTD::forward_as_tuple(__pr.second)); + } + + template <class _T1, class _T2, class _U1, class _U2> + _LIBCPP_INLINE_VISIBILITY + void construct(pair<_T1, _T2> * __p, pair<_U1, _U2> && __pr){ + construct(__p, piecewise_construct + , _VSTD::forward_as_tuple(_VSTD::forward<_U1>(__pr.first)) + , _VSTD::forward_as_tuple(_VSTD::forward<_U2>(__pr.second))); + } + + template <class _Tp> + _LIBCPP_INLINE_VISIBILITY + void destroy(_Tp * __p) _NOEXCEPT + { __p->~_Tp(); } + + _LIBCPP_INLINE_VISIBILITY + size_t max_size() const _NOEXCEPT + { return numeric_limits<size_t>::max() / sizeof(value_type); } + + _LIBCPP_INLINE_VISIBILITY + polymorphic_allocator + select_on_container_copy_construction() const _NOEXCEPT + { return polymorphic_allocator(); } + + _LIBCPP_INLINE_VISIBILITY + memory_resource * resource() const _NOEXCEPT + { return __res_; } + +private: + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&...> + __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, + __tuple_indices<_Idx...>) const + { + return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<allocator_arg_t const&, memory_resource*, _Args&&...> + __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) const + { + using _Tup = tuple<allocator_arg_t const&, memory_resource*, _Args&&...>; + return _Tup(allocator_arg, resource(), + _VSTD::get<_Idx>(_VSTD::move(__t))...); + } + + template <class ..._Args, size_t ..._Idx> + _LIBCPP_INLINE_VISIBILITY + tuple<_Args&&..., memory_resource*> + __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, + __tuple_indices<_Idx...>) const + { + using _Tup = tuple<_Args&&..., memory_resource*>; + return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., resource()); + } + + memory_resource * __res_; +}; + +// 8.6.4, memory.polymorphic.allocator.eq + +template <class _Tp, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +bool operator==(polymorphic_allocator<_Tp> const & __lhs, + polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT +{ + return *__lhs.resource() == *__rhs.resource(); +} + +template <class _Tp, class _Up> +inline _LIBCPP_INLINE_VISIBILITY +bool operator!=(polymorphic_allocator<_Tp> const & __lhs, + polymorphic_allocator<_Up> const & __rhs) _NOEXCEPT +{ + return !(__lhs == __rhs); +} + +// 8.7, memory.resource.adaptor + +// 8.7.1, memory.resource.adaptor.overview +template <class _CharAlloc> +class _LIBCPP_TYPE_VIS_ONLY __resource_adaptor_imp + : public memory_resource +{ + using _CTraits = allocator_traits<_CharAlloc>; + static_assert(is_same<typename _CTraits::value_type, char>::value + && is_same<typename _CTraits::pointer, char*>::value + && is_same<typename _CTraits::void_pointer, void*>::value, ""); + + static const size_t _MaxAlign = alignof(max_align_t); + + using _Alloc = typename _CTraits::template rebind_alloc< + typename aligned_storage<_MaxAlign, _MaxAlign>::type + >; + + using _ValueType = typename _Alloc::value_type; + + _Alloc __alloc_; + +public: + typedef _CharAlloc allocator_type; + + __resource_adaptor_imp() = default; + __resource_adaptor_imp(__resource_adaptor_imp const &) = default; + __resource_adaptor_imp(__resource_adaptor_imp &&) = default; + + // 8.7.2, memory.resource.adaptor.ctor + + _LIBCPP_INLINE_VISIBILITY + explicit __resource_adaptor_imp(allocator_type const & __a) + : __alloc_(__a) + {} + + _LIBCPP_INLINE_VISIBILITY + explicit __resource_adaptor_imp(allocator_type && __a) + : __alloc_(_VSTD::move(__a)) + {} + + __resource_adaptor_imp & + operator=(__resource_adaptor_imp const &) = default; + + _LIBCPP_INLINE_VISIBILITY + allocator_type get_allocator() const + { return __alloc_; } + +// 8.7.3, memory.resource.adaptor.mem +protected: + virtual void * do_allocate(size_t __bytes, size_t) + { + if (__bytes > __max_size()) { + __libcpp_throw(length_error( + "std::experimental::pmr::resource_adaptor<T>::do_allocate(size_t bytes, size_t align)" + " 'bytes' exceeds maximum supported size")); + } + size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; + return __alloc_.allocate(__s); + } + + virtual void do_deallocate(void * __p, size_t __bytes, size_t) + { + _LIBCPP_ASSERT(__bytes <= __max_size(), + "do_deallocate called for size which exceeds the maximum allocation size"); + size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; + __alloc_.deallocate((_ValueType*)__p, __s); + } + + virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT { + __resource_adaptor_imp const * __p + = dynamic_cast<__resource_adaptor_imp const *>(&__other); + return __p ? __alloc_ == __p->__alloc_ : false; + } + +private: + _LIBCPP_INLINE_VISIBILITY + size_t __max_size() const _NOEXCEPT { + return numeric_limits<size_t>::max() - _MaxAlign; + } +}; + +template <class _Alloc> +using resource_adaptor = __resource_adaptor_imp< + typename allocator_traits<_Alloc>::template rebind_alloc<char> + >; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_MEMORY_RESOURCE */ diff --git a/contrib/libc++/include/experimental/optional b/contrib/libc++/include/experimental/optional index a384882..3912438 100644 --- a/contrib/libc++/include/experimental/optional +++ b/contrib/libc++/include/experimental/optional @@ -517,7 +517,11 @@ public: constexpr value_type const& value() const { if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif return this->__val_; } @@ -525,7 +529,11 @@ public: value_type& value() { if (!this->__engaged_) +#ifndef _LIBCPP_NO_EXCEPTIONS throw bad_optional_access(); +#else + assert(!"bad optional access"); +#endif return this->__val_; } diff --git a/contrib/libc++/include/experimental/propagate_const b/contrib/libc++/include/experimental/propagate_const new file mode 100644 index 0000000..f267ba2 --- /dev/null +++ b/contrib/libc++/include/experimental/propagate_const @@ -0,0 +1,576 @@ +// -*- C++ -*- +//===------------------------ propagate_const -----------------------------===// +// +// 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_PROPAGATE_CONST +#define _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST +/* + propagate_const synopsis + + namespace std { namespace experimental { inline namespace fundamentals_v2 { + + // [propagate_const] + template <class T> class propagate_const; + + // [propagate_const.underlying], underlying pointer access + constexpr const _Tp& _VSTD_LFTS_V2::get_underlying(const propagate_const<T>& pt) noexcept; + constexpr T& _VSTD_LFTS_V2::get_underlying(propagate_const<T>& pt) noexcept; + + // [propagate_const.relational], relational operators + template <class T> constexpr bool operator==(const propagate_const<T>& pt, nullptr_t); + template <class T> constexpr bool operator==(nullptr_t, const propagate_const<T>& pu); + template <class T> constexpr bool operator!=(const propagate_const<T>& pt, nullptr_t); + template <class T> constexpr bool operator!=(nullptr_t, const propagate_const<T>& pu); + template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator==(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator!=(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator<(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator>(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator<=(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator>=(const propagate_const<T>& pt, const _Up& u); + template <class T, class U> constexpr bool operator==(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator!=(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator<=(const _Tp& t, const propagate_const<_Up>& pu); + template <class T, class U> constexpr bool operator>=(const _Tp& t, const propagate_const<_Up>& pu); + + // [propagate_const.algorithms], specialized algorithms + template <class T> constexpr void swap(propagate_const<T>& pt, propagate_const<T>& pu) noexcept(see below); + + template <class T> + class propagate_const + { + + public: + typedef remove_reference_t<decltype(*declval<T&>())> element_type; + + // [propagate_const.ctor], constructors + constexpr propagate_const() = default; + propagate_const(const propagate_const& p) = delete; + constexpr propagate_const(propagate_const&& p) = default; + template <class U> EXPLICIT constexpr propagate_const(propagate_const<_Up>&& pu); // see below + template <class U> EXPLICIT constexpr propagate_const(U&& u); // see below + + // [propagate_const.assignment], assignment + propagate_const& operator=(const propagate_const& p) = delete; + constexpr propagate_const& operator=(propagate_const&& p) = default; + template <class U> constexpr propagate_const& operator=(propagate_const<_Up>&& pu); + template <class U> constexpr propagate_const& operator=(U&& u); // see below + + // [propagate_const.const_observers], const observers + explicit constexpr operator bool() const; + constexpr const element_type* operator->() const; + constexpr operator const element_type*() const; // Not always defined + constexpr const element_type& operator*() const; + constexpr const element_type* get() const; + + // [propagate_const.non_const_observers], non-const observers + constexpr element_type* operator->(); + constexpr operator element_type*(); // Not always defined + constexpr element_type& operator*(); + constexpr element_type* get(); + + // [propagate_const.modifiers], modifiers + constexpr void swap(propagate_const& pt) noexcept(see below) + + private: + T t_; // exposition only + }; + + } // namespace fundamentals_v2 + } // namespace experimental + + // [propagate_const.hash], hash support + template <class T> struct hash<experimental::fundamentals_v2::propagate_const<T>>; + + // [propagate_const.comparison_function_objects], comparison function objects + template <class T> struct equal_to<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct not_equal_to<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct less<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct greater<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct less_equal<experimental::fundamentals_v2::propagate_const<T>>; + template <class T> struct greater_equal<experimental::fundamentals_v2::propagate_const<T>>; + +} // namespace std + +*/ + +#include <experimental/__config> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER > 11 + +#include <type_traits> +#include <utility> +#include <functional> + +_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 _Tp> +class propagate_const +{ +public: + typedef remove_reference_t<decltype(*_VSTD::declval<_Tp&>())> element_type; + + static_assert(!is_array<_Tp>::value, + "Instantiation of propagate_const with an array type is ill-formed."); + static_assert(!is_reference<_Tp>::value, + "Instantiation of propagate_const with a reference type is ill-formed."); + static_assert(!(is_pointer<_Tp>::value && is_function<typename remove_pointer<_Tp>::type>::value), + "Instantiation of propagate_const with a function-pointer type is ill-formed."); + static_assert(!(is_pointer<_Tp>::value && is_same<typename remove_cv<typename remove_pointer<_Tp>::type>::type, void>::value), + "Instantiation of propagate_const with a pointer to (possibly cv-qualified) void is ill-formed."); + +private: + template <class _Up> + static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) + { + return __u; + } + + template <class _Up> + static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) + { + return __get_pointer(__u.get()); + } + + template <class _Up> + static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) + { + return __u; + } + + template <class _Up> + static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) + { + return __get_pointer(__u.get()); + } + + template <class _Up> + struct __is_propagate_const : false_type + { + }; + + template <class _Up> + struct __is_propagate_const<propagate_const<_Up>> : true_type + { + }; + + _Tp __t_; + +public: + + template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; + template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; + + _LIBCPP_CONSTEXPR propagate_const() = default; + + propagate_const(const propagate_const&) = delete; + + _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; + + template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && + is_constructible<_Tp, _Up&&>::value,bool> = true> + explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) + : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) + { + } + + template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && + is_constructible<_Tp, _Up&&>::value,bool> = false> + _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) + : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) + { + } + + template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && + is_constructible<_Tp, _Up&&>::value && + !__is_propagate_const<decay_t<_Up>>::value,bool> = true> + explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) + : __t_(std::forward<_Up>(__u)) + { + } + + template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && + is_constructible<_Tp, _Up&&>::value && + !__is_propagate_const<decay_t<_Up>>::value,bool> = false> + _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) + : __t_(std::forward<_Up>(__u)) + { + } + + propagate_const& operator=(const propagate_const&) = delete; + + _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; + + template <class _Up> + _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) + { + __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); + return *this; + } + + template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> + _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) + { + __t_ = std::forward<_Up>(__u); + return *this; + } + + _LIBCPP_CONSTEXPR const element_type* get() const + { + return __get_pointer(__t_); + } + + _LIBCPP_CONSTEXPR element_type* get() + { + return __get_pointer(__t_); + } + + explicit _LIBCPP_CONSTEXPR operator bool() const + { + return get() != nullptr; + } + + _LIBCPP_CONSTEXPR const element_type* operator->() const + { + return get(); + } + + template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible< + const _Tp_, const element_type *>::value>> + _LIBCPP_CONSTEXPR operator const element_type *() const { + return get(); + } + + _LIBCPP_CONSTEXPR const element_type& operator*() const + { + return *get(); + } + + _LIBCPP_CONSTEXPR element_type* operator->() + { + return get(); + } + + template <class _Tp_ = _Tp, class _Up = enable_if_t< + is_convertible<_Tp_, element_type *>::value>> + _LIBCPP_CONSTEXPR operator element_type *() { + return get(); + } + + _LIBCPP_CONSTEXPR element_type& operator*() + { + return *get(); + } + + _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) + { + using _VSTD::swap; + swap(__t_, __pt.__t_); + } +}; + + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, nullptr_t) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) == nullptr; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(nullptr_t, const propagate_const<_Tp>& __pt) +{ + return nullptr == _VSTD_LFTS_V2::get_underlying(__pt); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, nullptr_t) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) != nullptr; +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(nullptr_t, const propagate_const<_Tp>& __pt) +{ + return nullptr != _VSTD_LFTS_V2::get_underlying(__pt); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) == _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) != _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) < _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) > _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) <= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, + const propagate_const<_Up>& __pu) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) >= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) == __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) != __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) < __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) > __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<=(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) <= __u; +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>=(const propagate_const<_Tp>& __pt, const _Up& __u) +{ + return _VSTD_LFTS_V2::get_underlying(__pt) >= __u; +} + + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator==(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t == _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator!=(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t != _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t < _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t > _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator<=(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t <= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp, class _Up> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR bool operator>=(const _Tp& __t, const propagate_const<_Up>& __pu) +{ + return __t >= _VSTD_LFTS_V2::get_underlying(__pu); +} + +template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR void swap(propagate_const<_Tp>& __pc1, propagate_const<_Tp>& __pc2) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) +{ + using _VSTD::swap; + swap(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); +} + +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_; +} + +_LIBCPP_END_NAMESPACE_LFTS_V2 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template <class _Tp> +struct hash<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef size_t result_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; + + size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const + { + return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); + } +}; + +template <class _Tp> +struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct less<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct greater<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +template <class _Tp> +struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> +{ + typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; + typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; + + bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, + const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const + { + return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 11 +#endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST + diff --git a/contrib/libc++/include/experimental/regex b/contrib/libc++/include/experimental/regex new file mode 100644 index 0000000..d38891c --- /dev/null +++ b/contrib/libc++/include/experimental/regex @@ -0,0 +1,62 @@ +// -*- C++ -*- +//===----------------------------- regex ----------------------------------===// +// +// 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_REGEX +#define _LIBCPP_EXPERIMENTAL_REGEX +/* + experimental/regex synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class BidirectionalIterator> + using match_results = + std::match_results<BidirectionalIterator, + polymorphic_allocator<sub_match<BidirectionalIterator>>>; + + typedef match_results<const char*> cmatch; + typedef match_results<const wchar_t*> wcmatch; + typedef match_results<string::const_iterator> smatch; + typedef match_results<wstring::const_iterator> wsmatch; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <regex> +#include <experimental/string> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _BiDirIter> +using match_results = + _VSTD::match_results<_BiDirIter, + polymorphic_allocator<_VSTD::sub_match<_BiDirIter>>>; + +typedef match_results<const char*> cmatch; +typedef match_results<const wchar_t*> wcmatch; +typedef match_results<_VSTD_LFTS_PMR::string::const_iterator> smatch; +typedef match_results<_VSTD_LFTS_PMR::wstring::const_iterator> wsmatch; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_REGEX */ diff --git a/contrib/libc++/include/experimental/set b/contrib/libc++/include/experimental/set new file mode 100644 index 0000000..20cf6d4 --- /dev/null +++ b/contrib/libc++/include/experimental/set @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===--------------------------- list ------------------------------------===// +// +// 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_SET +#define _LIBCPP_EXPERIMENTAL_SET +/* + experimental/set synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class Key, class T, class Compare = less<Key>> + using set = std::set<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + + template <class Key, class T, class Compare = less<Key>> + using multiset = std::multiset<Key, T, Compare, + polymorphic_allocator<pair<const Key,T>>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <set> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Value, class _Compare = less<_Value>> +using set = _VSTD::set<_Value, _Compare, + polymorphic_allocator<_Value>>; + +template <class _Value, class _Compare = less<_Value>> +using multiset = _VSTD::multiset<_Value, _Compare, + polymorphic_allocator<_Value>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_SET */ diff --git a/contrib/libc++/include/experimental/string b/contrib/libc++/include/experimental/string new file mode 100644 index 0000000..8b85451 --- /dev/null +++ b/contrib/libc++/include/experimental/string @@ -0,0 +1,62 @@ +// -*- C++ -*- +//===--------------------------- string ----------------------------------===// +// +// 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_STRING +#define _LIBCPP_EXPERIMENTAL_STRING +/* + experimental/string synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + // basic_string using polymorphic allocator in namespace pmr + template <class charT, class traits = char_traits<charT>> + using basic_string = + std::basic_string<charT, traits, polymorphic_allocator<charT>>; + + // basic_string typedef names using polymorphic allocator in namespace + // std::experimental::pmr + typedef basic_string<char> string; + typedef basic_string<char16_t> u16string; + typedef basic_string<char32_t> u32string; + typedef basic_string<wchar_t> wstring; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <string> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _CharT, class _Traits = char_traits<_CharT>> +using basic_string = + _VSTD::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; + +typedef basic_string<char> string; +typedef basic_string<char16_t> u16string; +typedef basic_string<char32_t> u32string; +typedef basic_string<wchar_t> wstring; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_STRING */ diff --git a/contrib/libc++/include/experimental/string_view b/contrib/libc++/include/experimental/string_view index 2a20d7c..0a7239b 100644 --- a/contrib/libc++/include/experimental/string_view +++ b/contrib/libc++/include/experimental/string_view @@ -180,6 +180,7 @@ namespace std { #include <algorithm> #include <iterator> #include <ostream> +#include <stdexcept> #include <iomanip> #include <__debug> @@ -227,7 +228,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS basic_string_view(const _CharT* __s, size_type __len) : __data(__s), __size(__len) { -// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): recieved nullptr"); +// _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); } _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY @@ -280,7 +281,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS const_reference at(size_type __pos) const { return __pos >= size() - ? (throw out_of_range("string_view::at"), __data[0]) + ? (__libcpp_throw(out_of_range("string_view::at")), __data[0]) : __data[__pos]; } @@ -351,7 +352,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const { if ( __pos > size()) - throw out_of_range("string_view::copy"); + __libcpp_throw(out_of_range("string_view::copy")); size_type __rlen = _VSTD::min( __n, size() - __pos ); _VSTD::copy_n(begin() + __pos, __rlen, __s ); return __rlen; @@ -365,7 +366,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS // size_type __rlen = _VSTD::min( __n, size() - __pos ); // return basic_string_view(data() + __pos, __rlen); return __pos > size() - ? throw out_of_range("string_view::substr") + ? (__libcpp_throw((out_of_range("string_view::substr"))), basic_string_view()) : basic_string_view(data() + __pos, _VSTD::min(__n, size() - __pos)); } @@ -413,7 +414,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_find<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -428,7 +429,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -436,7 +437,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_find<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -445,7 +446,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -460,7 +461,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -468,7 +469,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); return _VSTD::__str_rfind<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -477,7 +478,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -489,7 +490,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -497,7 +498,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); return _VSTD::__str_find_first_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -506,7 +507,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -518,7 +519,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -526,7 +527,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); return _VSTD::__str_find_last_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -535,7 +536,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -550,7 +551,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -558,7 +559,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); return _VSTD::__str_find_first_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } @@ -567,7 +568,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s.data(), __pos, __s.size()); } @@ -582,7 +583,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, __n); } @@ -590,7 +591,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS _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(): recieved nullptr"); + _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); return _VSTD::__str_find_last_not_of<value_type, size_type, traits_type, npos> (data(), size(), __s, __pos, traits_type::length(__s)); } diff --git a/contrib/libc++/include/experimental/tuple b/contrib/libc++/include/experimental/tuple index 50d1e05..e00d2ec 100644 --- a/contrib/libc++/include/experimental/tuple +++ b/contrib/libc++/include/experimental/tuple @@ -57,9 +57,10 @@ _LIBCPP_CONSTEXPR size_t tuple_size_v = tuple_size<_Tp>::value; template <class _Fn, class _Tuple, size_t ..._Id> inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR_AFTER_CXX11 decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, integer_sequence<size_t, _Id...>) { - return _VSTD::__invoke( + return _VSTD::__invoke_constexpr( _VSTD::forward<_Fn>(__f), _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))... ); diff --git a/contrib/libc++/include/experimental/unordered_map b/contrib/libc++/include/experimental/unordered_map new file mode 100644 index 0000000..1f998c2 --- /dev/null +++ b/contrib/libc++/include/experimental/unordered_map @@ -0,0 +1,65 @@ +// -*- C++ -*- +//===------------------------- unordered_map ------------------------------===// +// +// 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_UNORDERED_MAP +#define _LIBCPP_EXPERIMENTAL_UNORDERED_MAP +/* + experimental/unordered_map synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class Key, class T, + class Hash = hash<Key>, + class Pred = equal_to<Key>> + using unordered_map = + std::unordered_map<Key, T, Hash, Pred, + polymorphic_allocator<pair<const Key,T>>>; + + template <class Key, class T, + class Hash = hash<Key>, + class Pred = equal_to<Key>> + using unordered_multimap = + std::unordered_multimap<Key, T, Hash, Pred, + polymorphic_allocator<pair<const Key,T>>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <unordered_map> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Key, class _Value, + class _Hash = hash<_Key>, class _Pred = equal_to<_Key>> +using unordered_map = _VSTD::unordered_map<_Key, _Value, _Hash, _Pred, + polymorphic_allocator<pair<const _Key, _Value>>>; + +template <class _Key, class _Value, + class _Hash = hash<_Key>, class _Pred = equal_to<_Key>> +using unordered_multimap = _VSTD::unordered_multimap<_Key, _Value, _Hash, _Pred, + polymorphic_allocator<pair<const _Key, _Value>>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_UNORDERED_MAP */ diff --git a/contrib/libc++/include/experimental/unordered_set b/contrib/libc++/include/experimental/unordered_set new file mode 100644 index 0000000..d00a837 --- /dev/null +++ b/contrib/libc++/include/experimental/unordered_set @@ -0,0 +1,59 @@ +// -*- C++ -*- +//===------------------------- unordered_set ------------------------------===// +// +// 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_UNORDERED_SET +#define _LIBCPP_EXPERIMENTAL_UNORDERED_SET +/* + experimental/unordered_set synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T, class Hash = hash<T>, class Pred = equal_to<T>> + using unordered_set = std::unordered_set<T, Hash, Pred, + polymorphic_allocator<T>>; + + template <class T, class Hash = hash<T>, class Pred = equal_to<T>> + using unordered_multiset = std::unordered_multiset<T, Hash, Pred, + polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <unordered_set> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _Value, + class _Hash = hash<_Value>, class _Pred = equal_to<_Value>> +using unordered_set = _VSTD::unordered_set<_Value, _Hash, _Pred, + polymorphic_allocator<_Value>>; + +template <class _Value, + class _Hash = hash<_Value>, class _Pred = equal_to<_Value>> +using unordered_multiset = _VSTD::unordered_multiset<_Value, _Hash, _Pred, + polymorphic_allocator<_Value>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_UNORDERED_SET */ diff --git a/contrib/libc++/include/experimental/vector b/contrib/libc++/include/experimental/vector new file mode 100644 index 0000000..bd10492 --- /dev/null +++ b/contrib/libc++/include/experimental/vector @@ -0,0 +1,47 @@ +// -*- C++ -*- +//===--------------------------- vector ------------------------------------===// +// +// 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_VECTOR +#define _LIBCPP_EXPERIMENTAL_VECTOR +/* + experimental/vector synopsis + +// C++1z +namespace std { +namespace experimental { +inline namespace fundamentals_v1 { +namespace pmr { + + template <class T> + using vector = std::vector<T, polymorphic_allocator<T>>; + +} // namespace pmr +} // namespace fundamentals_v1 +} // namespace experimental +} // namespace std + + */ + +#include <experimental/__config> +#include <vector> +#include <experimental/memory_resource> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_LFTS_PMR + +template <class _ValueT> +using vector = _VSTD::vector<_ValueT, polymorphic_allocator<_ValueT>>; + +_LIBCPP_END_NAMESPACE_LFTS_PMR + +#endif /* _LIBCPP_EXPERIMENTAL_VECTOR */ diff --git a/contrib/libc++/include/ext/hash_map b/contrib/libc++/include/ext/hash_map index 3ac27b2..5e1e9f5 100644 --- a/contrib/libc++/include/ext/hash_map +++ b/contrib/libc++/include/ext/hash_map @@ -309,7 +309,7 @@ class __hash_map_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + typedef typename __alloc_traits::value_type::__node_value_type value_type; public: typedef typename __alloc_traits::pointer pointer; private: @@ -549,6 +549,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -674,7 +675,7 @@ hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -820,6 +821,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x);} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -927,7 +929,7 @@ hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::hash_multimap( template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/contrib/libc++/include/ext/hash_set b/contrib/libc++/include/ext/hash_set index c4bb898..91850b5 100644 --- a/contrib/libc++/include/ext/hash_set +++ b/contrib/libc++/include/ext/hash_set @@ -282,6 +282,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x).first;} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -385,7 +386,7 @@ hash_set<_Value, _Hash, _Pred, _Alloc>::hash_set( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -502,6 +503,7 @@ public: _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator, const value_type& __x) {return insert(__x);} template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY @@ -606,7 +608,7 @@ hash_multiset<_Value, _Hash, _Pred, _Alloc>::hash_multiset( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void hash_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/contrib/libc++/include/forward_list b/contrib/libc++/include/forward_list index 4f9ecf4..18b300d 100644 --- a/contrib/libc++/include/forward_list +++ b/contrib/libc++/include/forward_list @@ -183,15 +183,69 @@ template <class T, class Allocator> _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp, class _VoidPtr> struct __forward_list_node; +template <class _NodePtr> struct __forward_begin_node; + + +template <class> +struct __forward_list_node_value_type; + +template <class _Tp, class _VoidPtr> +struct __forward_list_node_value_type<__forward_list_node<_Tp, _VoidPtr> > { + typedef _Tp type; +}; + +template <class _NodePtr> +struct __forward_node_traits { + + typedef typename remove_cv< + typename pointer_traits<_NodePtr>::element_type>::type __node; + typedef typename __forward_list_node_value_type<__node>::type __node_value_type; + typedef _NodePtr __node_pointer; + typedef __forward_begin_node<_NodePtr> __begin_node; + typedef typename __rebind_pointer<_NodePtr, __begin_node>::type + __begin_node_pointer; + typedef typename __rebind_pointer<_NodePtr, void>::type __void_pointer; + +#if defined(_LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB) + typedef __begin_node_pointer __iter_node_pointer; +#else + typedef typename conditional< + is_pointer<__void_pointer>::value, + __begin_node_pointer, + __node_pointer + >::type __iter_node_pointer; +#endif + + typedef typename conditional< + is_same<__iter_node_pointer, __node_pointer>::value, + __begin_node_pointer, + __node_pointer + >::type __non_iter_node_pointer; + + _LIBCPP_INLINE_VISIBILITY + static __iter_node_pointer __as_iter_node(__iter_node_pointer __p) { + return __p; + } + _LIBCPP_INLINE_VISIBILITY + static __iter_node_pointer __as_iter_node(__non_iter_node_pointer __p) { + return static_cast<__iter_node_pointer>(static_cast<__void_pointer>(__p)); + } +}; template <class _NodePtr> struct __forward_begin_node { typedef _NodePtr pointer; + typedef typename __rebind_pointer<_NodePtr, __forward_begin_node>::type __begin_node_pointer; pointer __next_; - _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __next_as_begin() const { + return static_cast<__begin_node_pointer>(__next_); + } }; template <class _Tp, class _VoidPtr> @@ -211,26 +265,49 @@ struct __forward_list_node value_type __value_; }; + template <class _Tp, class _Alloc = allocator<_Tp> > class _LIBCPP_TYPE_VIS_ONLY forward_list; template<class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator; template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_iterator { - typedef _NodePtr __node_pointer; + typedef __forward_node_traits<_NodePtr> __traits; + typedef typename __traits::__node_pointer __node_pointer; + typedef typename __traits::__begin_node_pointer __begin_node_pointer; + typedef typename __traits::__iter_node_pointer __iter_node_pointer; + typedef typename __traits::__void_pointer __void_pointer; - __node_pointer __ptr_; + __iter_node_pointer __ptr_; + + _LIBCPP_INLINE_VISIBILITY + __begin_node_pointer __get_begin() const { + return static_cast<__begin_node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + _LIBCPP_INLINE_VISIBILITY + __node_pointer __get_unsafe_node_pointer() const { + return static_cast<__node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {} + explicit __forward_list_iterator(nullptr_t) _NOEXCEPT : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__begin_node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} template<class, class> friend class _LIBCPP_TYPE_VIS_ONLY forward_list; template<class> friend class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator; public: typedef forward_iterator_tag iterator_category; - typedef typename pointer_traits<__node_pointer>::element_type::value_type - value_type; + typedef typename __traits::__node_value_type value_type; typedef value_type& reference; typedef typename pointer_traits<__node_pointer>::difference_type difference_type; @@ -240,14 +317,16 @@ public: __forward_list_iterator() _NOEXCEPT : __ptr_(nullptr) {} _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __ptr_->__value_;} + reference operator*() const {return __get_unsafe_node_pointer()->__value_;} _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + pointer operator->() const { + return pointer_traits<pointer>::pointer_to(__get_unsafe_node_pointer()->__value_); + } _LIBCPP_INLINE_VISIBILITY __forward_list_iterator& operator++() { - __ptr_ = __ptr_->__next_; + __ptr_ = __traits::__as_iter_node(__ptr_->__next_); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -271,29 +350,50 @@ public: template <class _NodeConstPtr> class _LIBCPP_TYPE_VIS_ONLY __forward_list_const_iterator { - typedef _NodeConstPtr __node_const_pointer; + static_assert((!is_const<typename pointer_traits<_NodeConstPtr>::element_type>::value), ""); + typedef _NodeConstPtr _NodePtr; + + typedef __forward_node_traits<_NodePtr> __traits; + typedef typename __traits::__node __node; + typedef typename __traits::__node_pointer __node_pointer; + typedef typename __traits::__begin_node_pointer __begin_node_pointer; + typedef typename __traits::__iter_node_pointer __iter_node_pointer; + typedef typename __traits::__void_pointer __void_pointer; - __node_const_pointer __ptr_; + __iter_node_pointer __ptr_; + + __begin_node_pointer __get_begin() const { + return static_cast<__begin_node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } + __node_pointer __get_unsafe_node_pointer() const { + return static_cast<__node_pointer>( + static_cast<__void_pointer>(__ptr_)); + } _LIBCPP_INLINE_VISIBILITY - explicit __forward_list_const_iterator(__node_const_pointer __p) _NOEXCEPT - : __ptr_(__p) {} + explicit __forward_list_const_iterator(nullptr_t) _NOEXCEPT + : __ptr_(nullptr) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__begin_node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_const_iterator(__node_pointer __p) _NOEXCEPT + : __ptr_(__traits::__as_iter_node(__p)) {} - typedef typename remove_const - < - typename pointer_traits<__node_const_pointer>::element_type - >::type __node; - typedef typename __rebind_pointer<__node_const_pointer, __node>::type __node_pointer; template<class, class> friend class forward_list; public: typedef forward_iterator_tag iterator_category; - typedef typename __node::value_type value_type; + typedef typename __traits::__node_value_type value_type; typedef const value_type& reference; - typedef typename pointer_traits<__node_const_pointer>::difference_type + typedef typename pointer_traits<__node_pointer>::difference_type difference_type; - typedef typename __rebind_pointer<__node_const_pointer, const value_type>::type pointer; + typedef typename __rebind_pointer<__node_pointer, const value_type>::type + pointer; _LIBCPP_INLINE_VISIBILITY __forward_list_const_iterator() _NOEXCEPT : __ptr_(nullptr) {} @@ -302,14 +402,15 @@ public: : __ptr_(__p.__ptr_) {} _LIBCPP_INLINE_VISIBILITY - reference operator*() const {return __ptr_->__value_;} + reference operator*() const {return __get_unsafe_node_pointer()->__value_;} _LIBCPP_INLINE_VISIBILITY - pointer operator->() const {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);} + pointer operator->() const {return pointer_traits<pointer>::pointer_to( + __get_unsafe_node_pointer()->__value_);} _LIBCPP_INLINE_VISIBILITY __forward_list_const_iterator& operator++() { - __ptr_ = __ptr_->__next_; + __ptr_ = __traits::__as_iter_node(__ptr_->__next_); return *this; } _LIBCPP_INLINE_VISIBILITY @@ -343,21 +444,21 @@ protected: typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __node>::type __node_allocator; typedef allocator_traits<__node_allocator> __node_traits; typedef typename __node_traits::pointer __node_pointer; - typedef typename __node_traits::pointer __node_const_pointer; - typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, __begin_node>::type __begin_node_allocator; - typedef typename allocator_traits<__begin_node_allocator>::pointer __begin_node_pointer; + typedef typename __rebind_alloc_helper< + allocator_traits<allocator_type>, __begin_node + >::type __begin_node_allocator; + typedef typename allocator_traits<__begin_node_allocator>::pointer + __begin_node_pointer; __compressed_pair<__begin_node, __node_allocator> __before_begin_; _LIBCPP_INLINE_VISIBILITY - __node_pointer __before_begin() _NOEXCEPT - {return static_cast<__node_pointer>(pointer_traits<__begin_node_pointer>:: - pointer_to(__before_begin_.first()));} + __begin_node_pointer __before_begin() _NOEXCEPT + {return pointer_traits<__begin_node_pointer>::pointer_to(__before_begin_.first());} _LIBCPP_INLINE_VISIBILITY - __node_const_pointer __before_begin() const _NOEXCEPT - {return static_cast<__node_const_pointer>(pointer_traits<__begin_node_pointer>:: - pointer_to(const_cast<__begin_node&>(__before_begin_.first())));} + __begin_node_pointer __before_begin() const _NOEXCEPT + {return pointer_traits<__begin_node_pointer>::pointer_to(const_cast<__begin_node&>(__before_begin_.first()));} _LIBCPP_INLINE_VISIBILITY __node_allocator& __alloc() _NOEXCEPT @@ -379,8 +480,10 @@ protected: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES public: + _LIBCPP_INLINE_VISIBILITY __forward_list_base(__forward_list_base&& __x) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY __forward_list_base(__forward_list_base&& __x, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -405,6 +508,7 @@ protected: __node_traits::propagate_on_container_move_assignment::value>());} public: + _LIBCPP_INLINE_VISIBILITY void swap(__forward_list_base& __x) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT; @@ -438,7 +542,7 @@ private: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) : __before_begin_(_VSTD::move(__x.__before_begin_)) @@ -447,7 +551,7 @@ __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __forward_list_base<_Tp, _Alloc>::__forward_list_base(__forward_list_base&& __x, const allocator_type& __a) : __before_begin_(__begin_node(), __node_allocator(__a)) @@ -468,7 +572,7 @@ __forward_list_base<_Tp, _Alloc>::~__forward_list_base() } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) #if _LIBCPP_STD_VER >= 14 @@ -505,9 +609,10 @@ class _LIBCPP_TYPE_VIS_ONLY forward_list { typedef __forward_list_base<_Tp, _Alloc> base; typedef typename base::__node_allocator __node_allocator; - typedef typename base::__node __node; - typedef typename base::__node_traits __node_traits; - typedef typename base::__node_pointer __node_pointer; + typedef typename base::__node __node; + typedef typename base::__node_traits __node_traits; + typedef typename base::__node_pointer __node_pointer; + typedef typename base::__begin_node_pointer __begin_node_pointer; public: typedef _Tp value_type; @@ -530,6 +635,7 @@ public: forward_list() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} // = default; + _LIBCPP_INLINE_VISIBILITY explicit forward_list(const allocator_type& __a); explicit forward_list(size_type __n); #if _LIBCPP_STD_VER > 11 @@ -566,12 +672,14 @@ public: forward_list& operator=(const forward_list& __x); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY forward_list& operator=(forward_list&& __x) _NOEXCEPT_( __node_traits::propagate_on_container_move_assignment::value && is_nothrow_move_assignable<allocator_type>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY forward_list& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -584,6 +692,7 @@ public: assign(_InputIterator __f, _InputIterator __l); void assign(size_type __n, const value_type& __v); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY void assign(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -714,7 +823,7 @@ public: template <class _Compare> void merge(forward_list& __x, _Compare __comp); _LIBCPP_INLINE_VISIBILITY void sort() {sort(__less<value_type>());} - template <class _Compare> void sort(_Compare __comp); + template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp); void reverse() _NOEXCEPT; private: @@ -737,7 +846,7 @@ private: }; template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) : base(__a) { @@ -751,8 +860,8 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n) __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, - __p = __p->__next_) + for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); @@ -772,8 +881,8 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __a __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __p = base::__before_begin(); __n > 0; --__n, - __p = __p->__next_) + for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, + __p = __p->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); @@ -911,7 +1020,7 @@ forward_list<_Tp, _Alloc>::__move_assign(forward_list& __x, false_type) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) _NOEXCEPT_( @@ -928,7 +1037,7 @@ forward_list<_Tp, _Alloc>::operator=(forward_list&& __x) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) { @@ -976,7 +1085,7 @@ forward_list<_Tp, _Alloc>::assign(size_type __n, const value_type& __v) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) { @@ -1049,7 +1158,7 @@ template <class... _Args> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::emplace_after(const_iterator __p, _Args&&... __args) { - __node_pointer const __r = __p.__ptr_; + __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); @@ -1066,7 +1175,7 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, value_type&& __v) { - __node_pointer const __r = __p.__ptr_; + __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); @@ -1082,7 +1191,7 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, const value_type& __v) { - __node_pointer const __r = __p.__ptr_; + __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); @@ -1097,7 +1206,7 @@ typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, const value_type& __v) { - __node_pointer __r = __p.__ptr_; + __begin_node_pointer __r = __p.__get_begin(); if (__n > 0) { __node_allocator& __a = base::__alloc(); @@ -1132,7 +1241,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, #endif // _LIBCPP_NO_EXCEPTIONS __last->__next_ = __r->__next_; __r->__next_ = __first; - __r = __last; + __r = static_cast<__begin_node_pointer>(__last); } return iterator(__r); } @@ -1147,7 +1256,7 @@ typename enable_if forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l) { - __node_pointer __r = __p.__ptr_; + __begin_node_pointer __r = __p.__get_begin(); if (__f != __l) { __node_allocator& __a = base::__alloc(); @@ -1182,7 +1291,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, #endif // _LIBCPP_NO_EXCEPTIONS __last->__next_ = __r->__next_; __r->__next_ = __first; - __r = __last; + __r = static_cast<__begin_node_pointer>(__last); } return iterator(__r); } @@ -1191,7 +1300,7 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::erase_after(const_iterator __f) { - __node_pointer __p = __f.__ptr_; + __begin_node_pointer __p = __f.__get_begin(); __node_pointer __n = __p->__next_; __p->__next_ = __n->__next_; __node_allocator& __a = base::__alloc(); @@ -1204,21 +1313,22 @@ template <class _Tp, class _Alloc> typename forward_list<_Tp, _Alloc>::iterator forward_list<_Tp, _Alloc>::erase_after(const_iterator __f, const_iterator __l) { - __node_pointer __e = __l.__ptr_; + __node_pointer __e = __l.__get_unsafe_node_pointer(); if (__f != __l) { - __node_pointer __p = __f.__ptr_; - __node_pointer __n = __p->__next_; + __begin_node_pointer __bp = __f.__get_begin(); + + __node_pointer __n = __bp->__next_; if (__n != __e) { - __p->__next_ = __e; + __bp->__next_ = __e; __node_allocator& __a = base::__alloc(); do { - __p = __n->__next_; + __node_pointer __tmp = __n->__next_; __node_traits::destroy(__a, _VSTD::addressof(__n->__value_)); __node_traits::deallocate(__a, __n, 1); - __n = __p; + __n = __tmp; } while (__n != __e); } } @@ -1245,8 +1355,8 @@ forward_list<_Tp, _Alloc>::resize(size_type __n) __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, - __ptr = __ptr->__next_) + for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, + __ptr = __ptr->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); @@ -1277,8 +1387,8 @@ forward_list<_Tp, _Alloc>::resize(size_type __n, const value_type& __v) __node_allocator& __a = base::__alloc(); typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); - for (__node_pointer __ptr = __p.__ptr_; __n > 0; --__n, - __ptr = __ptr->__next_) + for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, + __ptr = __ptr->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); @@ -1296,14 +1406,14 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, { if (!__x.empty()) { - if (__p.__ptr_->__next_ != nullptr) + if (__p.__get_begin()->__next_ != nullptr) { const_iterator __lm1 = __x.before_begin(); - while (__lm1.__ptr_->__next_ != nullptr) + while (__lm1.__get_begin()->__next_ != nullptr) ++__lm1; - __lm1.__ptr_->__next_ = __p.__ptr_->__next_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; } - __p.__ptr_->__next_ = __x.__before_begin()->__next_; + __p.__get_begin()->__next_ = __x.__before_begin()->__next_; __x.__before_begin()->__next_ = nullptr; } } @@ -1317,9 +1427,9 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, const_iterator __lm1 = _VSTD::next(__i); if (__p != __i && __p != __lm1) { - __i.__ptr_->__next_ = __lm1.__ptr_->__next_; - __lm1.__ptr_->__next_ = __p.__ptr_->__next_; - __p.__ptr_->__next_ = __lm1.__ptr_; + __i.__get_begin()->__next_ = __lm1.__get_begin()->__next_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + __p.__get_begin()->__next_ = __lm1.__get_unsafe_node_pointer(); } } @@ -1332,13 +1442,13 @@ forward_list<_Tp, _Alloc>::splice_after(const_iterator __p, if (__f != __l && __p != __f) { const_iterator __lm1 = __f; - while (__lm1.__ptr_->__next_ != __l.__ptr_) + while (__lm1.__get_begin()->__next_ != __l.__get_begin()) ++__lm1; if (__f != __lm1) { - __lm1.__ptr_->__next_ = __p.__ptr_->__next_; - __p.__ptr_->__next_ = __f.__ptr_->__next_; - __f.__ptr_->__next_ = __l.__ptr_; + __lm1.__get_begin()->__next_ = __p.__get_begin()->__next_; + __p.__get_begin()->__next_ = __f.__get_begin()->__next_; + __f.__get_begin()->__next_ = __l.__get_unsafe_node_pointer(); } } } @@ -1382,9 +1492,9 @@ forward_list<_Tp, _Alloc>::remove(const value_type& __v) { forward_list<_Tp, _Alloc> __deleted_nodes; // collect the nodes we're removing iterator __e = end(); - for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) + for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) { - if (__i.__ptr_->__next_->__value_ == __v) + if (__i.__get_begin()->__next_->__value_ == __v) { iterator __j = _VSTD::next(__i, 2); for (; __j != __e && *__j == __v; ++__j) @@ -1405,9 +1515,9 @@ void forward_list<_Tp, _Alloc>::remove_if(_Predicate __pred) { iterator __e = end(); - for (iterator __i = before_begin(); __i.__ptr_->__next_ != nullptr;) + for (iterator __i = before_begin(); __i.__get_begin()->__next_ != nullptr;) { - if (__pred(__i.__ptr_->__next_->__value_)) + if (__pred(__i.__get_begin()->__next_->__value_)) { iterator __j = _VSTD::next(__i, 2); for (; __j != __e && __pred(*__j); ++__j) @@ -1432,7 +1542,7 @@ forward_list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) iterator __j = _VSTD::next(__i); for (; __j != __e && __binary_pred(*__i, *__j); ++__j) ; - if (__i.__ptr_->__next_ != __j.__ptr_) + if (__i.__get_begin()->__next_ != __j.__get_unsafe_node_pointer()) erase_after(__i, __j); __i = __j; } @@ -1499,7 +1609,7 @@ forward_list<_Tp, _Alloc>::__merge(__node_pointer __f1, __node_pointer __f2, template <class _Tp, class _Alloc> template <class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void forward_list<_Tp, _Alloc>::sort(_Compare __comp) { @@ -1530,7 +1640,7 @@ forward_list<_Tp, _Alloc>::__sort(__node_pointer __f1, difference_type __sz, } difference_type __sz1 = __sz / 2; difference_type __sz2 = __sz - __sz1; - __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__ptr_; + __node_pointer __t = _VSTD::next(iterator(__f1), __sz1 - 1).__get_unsafe_node_pointer(); __node_pointer __f2 = __t->__next_; __t->__next_ = nullptr; return __merge(__sort(__f1, __sz1, __comp), diff --git a/contrib/libc++/include/fstream b/contrib/libc++/include/fstream index 1f289ed..3cb3b13 100644 --- a/contrib/libc++/include/fstream +++ b/contrib/libc++/include/fstream @@ -200,14 +200,17 @@ public: // 27.9.1.3 Assign/swap: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_filebuf& operator=(basic_filebuf&& __rhs); #endif void swap(basic_filebuf& __rhs); // 27.9.1.4 Members: + _LIBCPP_INLINE_VISIBILITY bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE basic_filebuf* open(const char* __s, ios_base::openmode __mode); + _LIBCPP_INLINE_VISIBILITY basic_filebuf* open(const string& __s, ios_base::openmode __mode); #endif basic_filebuf* close(); @@ -340,7 +343,7 @@ basic_filebuf<_CharT, _Traits>::basic_filebuf(basic_filebuf&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>& basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) { @@ -458,7 +461,7 @@ swap(basic_filebuf<_CharT, _Traits>& __x, basic_filebuf<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_filebuf<_CharT, _Traits>::is_open() const { @@ -547,7 +550,7 @@ basic_filebuf<_CharT, _Traits>::open(const char* __s, ios_base::openmode __mode) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_filebuf<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mode) { @@ -603,7 +606,9 @@ basic_filebuf<_CharT, _Traits>::underflow() } else { - memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + _LIBCPP_ASSERT ( !(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); + if (__extbufend_ != __extbufnext_) + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); size_t __nmemb = _VSTD::min(static_cast<size_t>(__ibs_ - __unget_sz), @@ -1008,26 +1013,35 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + _LIBCPP_INLINE_VISIBILITY basic_ifstream(); #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + _LIBCPP_INLINE_VISIBILITY explicit basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in); + _LIBCPP_INLINE_VISIBILITY explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ifstream(basic_ifstream&& __rhs); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ifstream& operator=(basic_ifstream&& __rhs); #endif + _LIBCPP_INLINE_VISIBILITY void swap(basic_ifstream& __rhs); + _LIBCPP_INLINE_VISIBILITY basic_filebuf<char_type, traits_type>* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE void open(const char* __s, ios_base::openmode __mode = ios_base::in); void open(const string& __s, ios_base::openmode __mode = ios_base::in); #endif + _LIBCPP_INLINE_VISIBILITY void close(); private: @@ -1035,7 +1049,7 @@ private: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream() : basic_istream<char_type, traits_type>(&__sb_) { @@ -1043,7 +1057,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream() #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openmode __mode) : basic_istream<char_type, traits_type>(&__sb_) { @@ -1052,7 +1066,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(const char* __s, ios_base::openm } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::openmode __mode) : basic_istream<char_type, traits_type>(&__sb_) { @@ -1064,7 +1078,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(const string& __s, ios_base::ope #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) : basic_istream<char_type, traits_type>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -1073,7 +1087,7 @@ basic_ifstream<_CharT, _Traits>::basic_ifstream(basic_ifstream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ifstream<_CharT, _Traits>& basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) { @@ -1085,7 +1099,7 @@ basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ifstream<_CharT, _Traits>::swap(basic_ifstream& __rhs) { @@ -1102,7 +1116,7 @@ swap(basic_ifstream<_CharT, _Traits>& __x, basic_ifstream<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_ifstream<_CharT, _Traits>::rdbuf() const { @@ -1110,7 +1124,7 @@ basic_ifstream<_CharT, _Traits>::rdbuf() const } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_ifstream<_CharT, _Traits>::is_open() const { @@ -1140,7 +1154,7 @@ basic_ifstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo #endif template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ifstream<_CharT, _Traits>::close() { @@ -1161,24 +1175,33 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + _LIBCPP_INLINE_VISIBILITY basic_ofstream(); + _LIBCPP_INLINE_VISIBILITY explicit basic_ofstream(const char* __s, ios_base::openmode __mode = ios_base::out); + _LIBCPP_INLINE_VISIBILITY explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ofstream(basic_ofstream&& __rhs); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_ofstream& operator=(basic_ofstream&& __rhs); #endif + _LIBCPP_INLINE_VISIBILITY void swap(basic_ofstream& __rhs); + _LIBCPP_INLINE_VISIBILITY basic_filebuf<char_type, traits_type>* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE void open(const char* __s, ios_base::openmode __mode = ios_base::out); void open(const string& __s, ios_base::openmode __mode = ios_base::out); #endif + _LIBCPP_INLINE_VISIBILITY void close(); private: @@ -1186,7 +1209,7 @@ private: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream() : basic_ostream<char_type, traits_type>(&__sb_) { @@ -1194,7 +1217,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream() #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openmode __mode) : basic_ostream<char_type, traits_type>(&__sb_) { @@ -1203,7 +1226,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(const char* __s, ios_base::openm } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::openmode __mode) : basic_ostream<char_type, traits_type>(&__sb_) { @@ -1215,7 +1238,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(const string& __s, ios_base::ope #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) : basic_ostream<char_type, traits_type>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -1224,7 +1247,7 @@ basic_ofstream<_CharT, _Traits>::basic_ofstream(basic_ofstream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_ofstream<_CharT, _Traits>& basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) { @@ -1236,7 +1259,7 @@ basic_ofstream<_CharT, _Traits>::operator=(basic_ofstream&& __rhs) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ofstream<_CharT, _Traits>::swap(basic_ofstream& __rhs) { @@ -1253,7 +1276,7 @@ swap(basic_ofstream<_CharT, _Traits>& __x, basic_ofstream<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_ofstream<_CharT, _Traits>::rdbuf() const { @@ -1261,7 +1284,7 @@ basic_ofstream<_CharT, _Traits>::rdbuf() const } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_ofstream<_CharT, _Traits>::is_open() const { @@ -1291,7 +1314,7 @@ basic_ofstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mo #endif template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_ofstream<_CharT, _Traits>::close() { @@ -1312,26 +1335,35 @@ public: typedef typename traits_type::pos_type pos_type; typedef typename traits_type::off_type off_type; + _LIBCPP_INLINE_VISIBILITY basic_fstream(); #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE + _LIBCPP_INLINE_VISIBILITY explicit basic_fstream(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); + _LIBCPP_INLINE_VISIBILITY explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_fstream(basic_fstream&& __rhs); #endif #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY basic_fstream& operator=(basic_fstream&& __rhs); #endif + _LIBCPP_INLINE_VISIBILITY void swap(basic_fstream& __rhs); + _LIBCPP_INLINE_VISIBILITY basic_filebuf<char_type, traits_type>* rdbuf() const; + _LIBCPP_INLINE_VISIBILITY bool is_open() const; #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); #endif + _LIBCPP_INLINE_VISIBILITY void close(); private: @@ -1339,7 +1371,7 @@ private: }; template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream() : basic_iostream<char_type, traits_type>(&__sb_) { @@ -1347,7 +1379,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream() #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmode __mode) : basic_iostream<char_type, traits_type>(&__sb_) { @@ -1356,7 +1388,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream(const char* __s, ios_base::openmod } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openmode __mode) : basic_iostream<char_type, traits_type>(&__sb_) { @@ -1368,7 +1400,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream(const string& __s, ios_base::openm #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) : basic_iostream<char_type, traits_type>(_VSTD::move(__rhs)), __sb_(_VSTD::move(__rhs.__sb_)) @@ -1377,7 +1409,7 @@ basic_fstream<_CharT, _Traits>::basic_fstream(basic_fstream&& __rhs) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_fstream<_CharT, _Traits>& basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) { @@ -1389,7 +1421,7 @@ basic_fstream<_CharT, _Traits>::operator=(basic_fstream&& __rhs) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_fstream<_CharT, _Traits>::swap(basic_fstream& __rhs) { @@ -1406,7 +1438,7 @@ swap(basic_fstream<_CharT, _Traits>& __x, basic_fstream<_CharT, _Traits>& __y) } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline basic_filebuf<_CharT, _Traits>* basic_fstream<_CharT, _Traits>::rdbuf() const { @@ -1414,7 +1446,7 @@ basic_fstream<_CharT, _Traits>::rdbuf() const } template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline bool basic_fstream<_CharT, _Traits>::is_open() const { @@ -1444,7 +1476,7 @@ basic_fstream<_CharT, _Traits>::open(const string& __s, ios_base::openmode __mod #endif template <class _CharT, class _Traits> -inline _LIBCPP_INLINE_VISIBILITY +inline void basic_fstream<_CharT, _Traits>::close() { diff --git a/contrib/libc++/include/functional b/contrib/libc++/include/functional index dbe9b01..581f965 100644 --- a/contrib/libc++/include/functional +++ b/contrib/libc++/include/functional @@ -207,6 +207,8 @@ public: template <class Predicate> binary_negate<Predicate> not2(const Predicate& pred); +template <class F> unspecified not_fn(F&& f); // C++17 + template<class T> struct is_bind_expression; template<class T> struct is_placeholder; @@ -407,7 +409,7 @@ public: // function modifiers: void swap(function&) noexcept; template<class F, class Alloc> - void assign(F&&, const Alloc&); + void assign(F&&, const Alloc&); // Removed in C++17 // function capacity: explicit operator bool() const noexcept; @@ -1564,6 +1566,10 @@ class _LIBCPP_TYPE_VIS_ONLY function<_Rp(_ArgTypes...)> typename aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; + _LIBCPP_NO_CFI static __base *__as_base(void *p) { + return reinterpret_cast<__base*>(p); + } + template <class _Fp, bool = !is_same<_Fp, function>::value && __invokable<_Fp&, _ArgTypes...>::value> struct __callable; @@ -1626,10 +1632,13 @@ public: // function modifiers: void swap(function&) _NOEXCEPT; + +#if _LIBCPP_STD_VER <= 14 template<class _Fp, class _Alloc> _LIBCPP_INLINE_VISIBILITY void assign(_Fp&& __f, const _Alloc& __a) {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} +#endif // function capacity: _LIBCPP_INLINE_VISIBILITY @@ -1657,9 +1666,9 @@ function<_Rp(_ArgTypes...)>::function(const function& __f) { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1673,9 +1682,9 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (const __base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1687,9 +1696,9 @@ function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1706,9 +1715,9 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, { if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1733,8 +1742,7 @@ function<_Rp(_ArgTypes...)>::function(_Fp __f, typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(_VSTD::move(__f)); + __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f)); } else { @@ -1763,8 +1771,7 @@ function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a0, _Fp _ if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && is_nothrow_copy_constructible<_Ap>::value) { - __f_ = (__base*)&__buf_; - ::new (__f_) _FF(_VSTD::move(__f), _Alloc(__a)); + __f_ = ::new((void*)&__buf_) _FF(_VSTD::move(__f), _Alloc(__a)); } else { @@ -1788,16 +1795,16 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); __f_ = 0; if (__f.__f_ == 0) __f_ = 0; - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); __f.__f_->__clone(__f_); } else @@ -1812,7 +1819,7 @@ template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); @@ -1837,7 +1844,7 @@ function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) template<class _Rp, class ..._ArgTypes> function<_Rp(_ArgTypes...)>::~function() { - if (__f_ == (__base*)&__buf_) + if ((void *)__f_ == &__buf_) __f_->destroy(); else if (__f_) __f_->destroy_deallocate(); @@ -1847,34 +1854,34 @@ template<class _Rp, class ..._ArgTypes> void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { - if (__f_ == (__base*)&__buf_ && __f.__f_ == (__base*)&__f.__buf_) + if ((void *)__f_ == &__buf_ && (void *)__f.__f_ == &__f.__buf_) { typename aligned_storage<sizeof(__buf_)>::type __tempbuf; - __base* __t = (__base*)&__tempbuf; + __base* __t = __as_base(&__tempbuf); __f_->__clone(__t); __f_->destroy(); __f_ = 0; - __f.__f_->__clone((__base*)&__buf_); + __f.__f_->__clone(__as_base(&__buf_)); __f.__f_->destroy(); __f.__f_ = 0; - __f_ = (__base*)&__buf_; - __t->__clone((__base*)&__f.__buf_); + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); __t->destroy(); - __f.__f_ = (__base*)&__f.__buf_; + __f.__f_ = __as_base(&__f.__buf_); } - else if (__f_ == (__base*)&__buf_) + else if ((void *)__f_ == &__buf_) { - __f_->__clone((__base*)&__f.__buf_); + __f_->__clone(__as_base(&__f.__buf_)); __f_->destroy(); __f_ = __f.__f_; - __f.__f_ = (__base*)&__f.__buf_; + __f.__f_ = __as_base(&__f.__buf_); } - else if (__f.__f_ == (__base*)&__f.__buf_) + else if ((void *)__f.__f_ == &__f.__buf_) { - __f.__f_->__clone((__base*)&__buf_); + __f.__f_->__clone(__as_base(&__buf_)); __f.__f_->destroy(); __f.__f_ = __f_; - __f_ = (__base*)&__buf_; + __f_ = __as_base(&__buf_); } else _VSTD::swap(__f_, __f.__f_); @@ -1973,16 +1980,29 @@ namespace placeholders template <int _Np> struct __ph {}; -_LIBCPP_FUNC_VIS extern __ph<1> _1; -_LIBCPP_FUNC_VIS extern __ph<2> _2; -_LIBCPP_FUNC_VIS extern __ph<3> _3; -_LIBCPP_FUNC_VIS extern __ph<4> _4; -_LIBCPP_FUNC_VIS extern __ph<5> _5; -_LIBCPP_FUNC_VIS extern __ph<6> _6; -_LIBCPP_FUNC_VIS extern __ph<7> _7; -_LIBCPP_FUNC_VIS extern __ph<8> _8; -_LIBCPP_FUNC_VIS extern __ph<9> _9; -_LIBCPP_FUNC_VIS extern __ph<10> _10; +#if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND) +_LIBCPP_FUNC_VIS extern const __ph<1> _1; +_LIBCPP_FUNC_VIS extern const __ph<2> _2; +_LIBCPP_FUNC_VIS extern const __ph<3> _3; +_LIBCPP_FUNC_VIS extern const __ph<4> _4; +_LIBCPP_FUNC_VIS extern const __ph<5> _5; +_LIBCPP_FUNC_VIS extern const __ph<6> _6; +_LIBCPP_FUNC_VIS extern const __ph<7> _7; +_LIBCPP_FUNC_VIS extern const __ph<8> _8; +_LIBCPP_FUNC_VIS extern const __ph<9> _9; +_LIBCPP_FUNC_VIS extern const __ph<10> _10; +#else +constexpr __ph<1> _1{}; +constexpr __ph<2> _2{}; +constexpr __ph<3> _3{}; +constexpr __ph<4> _4{}; +constexpr __ph<5> _5{}; +constexpr __ph<6> _6{}; +constexpr __ph<7> _7{}; +constexpr __ph<8> _8{}; +constexpr __ph<9> _9{}; +constexpr __ph<10> _10{}; +#endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_BIND) } // placeholders @@ -2468,6 +2488,22 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<unsigned long long> { }; +#ifndef _LIBCPP_HAS_NO_INT128 + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash<__int128_t> + : public __scalar_hash<__int128_t> +{ +}; + +template <> +struct _LIBCPP_TYPE_VIS_ONLY hash<__uint128_t> + : public __scalar_hash<__uint128_t> +{ +}; + +#endif + template <> struct _LIBCPP_TYPE_VIS_ONLY hash<float> : public __scalar_hash<float> @@ -2564,11 +2600,69 @@ struct _LIBCPP_TYPE_VIS_ONLY hash #if _LIBCPP_STD_VER > 14 + template <class _Fn, class ..._Args> result_of_t<_Fn&&(_Args&&...)> -invoke(_Fn&& __f, _Args&&... __args) { - return __invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +invoke(_Fn&& __f, _Args&&... __args) + noexcept(noexcept(_VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...))) +{ + return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +} + +template <class _DecayFunc> +class _LIBCPP_TYPE_VIS_ONLY __not_fn_imp { + _DecayFunc __fd; + +public: + __not_fn_imp() = delete; + + template <class ..._Args> + _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)...); } + + 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)...); } + + 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)...); } + + + 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)...); } + +private: + template <class _RawFunc, + class = enable_if_t<!is_same<decay_t<_RawFunc>, __not_fn_imp>::value>> + _LIBCPP_INLINE_VISIBILITY + explicit __not_fn_imp(_RawFunc&& __rf) + : __fd(_VSTD::forward<_RawFunc>(__rf)) {} + + template <class _RawFunc> + friend inline _LIBCPP_INLINE_VISIBILITY + __not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&&); +}; + +template <class _RawFunc> +inline _LIBCPP_INLINE_VISIBILITY +__not_fn_imp<decay_t<_RawFunc>> not_fn(_RawFunc&& __fn) { + return __not_fn_imp<decay_t<_RawFunc>>(_VSTD::forward<_RawFunc>(__fn)); } + #endif // struct hash<T*> in <memory> diff --git a/contrib/libc++/include/future b/contrib/libc++/include/future index ce15eaf..936060e 100644 --- a/contrib/libc++/include/future +++ b/contrib/libc++/include/future @@ -322,7 +322,7 @@ template <class R, class... ArgTypes> class packaged_task<R(ArgTypes...)> { public: - typedef R result_type; + typedef R result_type; // extension // construction and destruction packaged_task() noexcept; @@ -1482,6 +1482,7 @@ template <class _Rp> void promise<_Rp>::set_exception(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception(__p); @@ -1513,6 +1514,7 @@ template <class _Rp> void promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception_at_thread_exit(__p); @@ -1629,6 +1631,7 @@ template <class _Rp> void promise<_Rp&>::set_exception(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception(__p); @@ -1647,6 +1650,7 @@ template <class _Rp> void promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) { + _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); if (__state_ == nullptr) __throw_future_error(future_errc::no_state); __state_->set_exception_at_thread_exit(__p); @@ -1994,7 +1998,7 @@ template<class _Rp, class ..._ArgTypes> class _LIBCPP_TYPE_VIS_ONLY packaged_task<_Rp(_ArgTypes...)> { public: - typedef _Rp result_type; + typedef _Rp result_type; // extension private: __packaged_task_function<result_type(_ArgTypes...)> __f_; @@ -2123,7 +2127,7 @@ template<class ..._ArgTypes> class _LIBCPP_TYPE_VIS_ONLY packaged_task<void(_ArgTypes...)> { public: - typedef void result_type; + typedef void result_type; // extension private: __packaged_task_function<result_type(_ArgTypes...)> __f_; diff --git a/contrib/libc++/include/iomanip b/contrib/libc++/include/iomanip index a5042c7..9efcbe0 100644 --- a/contrib/libc++/include/iomanip +++ b/contrib/libc++/include/iomanip @@ -512,8 +512,6 @@ put_time(const tm* __tm, const _CharT* __fmt) return __iom_t10<_CharT>(__tm, __fmt); } -#if _LIBCPP_STD_VER > 11 - template <class _CharT, class _Traits, class _ForwardIterator> std::basic_ostream<_CharT, _Traits> & __quoted_output ( basic_ostream<_CharT, _Traits> &__os, @@ -569,7 +567,7 @@ __quoted_input ( basic_istream<_CharT, _Traits> &__is, _String & __string, _Char } -template <class _CharT, class _Iter, class _Traits=char_traits<_CharT>> +template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> > struct __quoted_output_proxy { _Iter __first; @@ -631,22 +629,43 @@ quoted ( const _CharT *__s, _CharT __delim = _CharT('"'), _CharT __escape =_Char return __quoted_output_proxy<_CharT, const _CharT *> ( __s, __end, __delim, __escape ); } + template <class _CharT, class _Traits, class _Allocator> _LIBCPP_INLINE_VISIBILITY __quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> -quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +__quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) { - return __quoted_output_proxy<_CharT, - typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> + return __quoted_output_proxy<_CharT, + typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> ( __s.cbegin(), __s.cend (), __delim, __escape ); } template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_INLINE_VISIBILITY __quoted_proxy<_CharT, _Traits, _Allocator> -quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +__quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) { return __quoted_proxy<_CharT, _Traits, _Allocator>( __s, __delim, __escape ); } + + +#if _LIBCPP_STD_VER > 11 + +template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_INLINE_VISIBILITY +__quoted_output_proxy<_CharT, typename basic_string <_CharT, _Traits, _Allocator>::const_iterator> +quoted ( const basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted(__s, __delim, __escape); +} + +template <class _CharT, class _Traits, class _Allocator> +_LIBCPP_INLINE_VISIBILITY +__quoted_proxy<_CharT, _Traits, _Allocator> +quoted ( basic_string <_CharT, _Traits, _Allocator> &__s, _CharT __delim = _CharT('"'), _CharT __escape=_CharT('\\')) +{ + return __quoted(__s, __delim, __escape); +} #endif _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libc++/include/ios b/contrib/libc++/include/ios index 1deb5f6..cbea478 100644 --- a/contrib/libc++/include/ios +++ b/contrib/libc++/include/ios @@ -231,7 +231,7 @@ typedef ptrdiff_t streamsize; class _LIBCPP_TYPE_VIS ios_base { public: - class _LIBCPP_TYPE_VIS failure; + class _LIBCPP_EXCEPTION_ABI failure; typedef unsigned int fmtflags; static const fmtflags boolalpha = 0x0001; diff --git a/contrib/libc++/include/iosfwd b/contrib/libc++/include/iosfwd index eccfd34..e4149ef 100644 --- a/contrib/libc++/include/iosfwd +++ b/contrib/libc++/include/iosfwd @@ -194,6 +194,11 @@ template <class _CharT, // for <stdexcept> typedef basic_string<char, char_traits<char>, allocator<char> > string; typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring; + +// Include other forward declarations here +template <class _Tp, class _Alloc = allocator<_Tp> > +class _LIBCPP_TYPE_VIS_ONLY vector; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_IOSFWD diff --git a/contrib/libc++/include/istream b/contrib/libc++/include/istream index 0bcc7ee..ee69400 100644 --- a/contrib/libc++/include/istream +++ b/contrib/libc++/include/istream @@ -1251,18 +1251,35 @@ streamsize basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) { __gc_ = 0; - streamsize __c = this->rdbuf()->in_avail(); - switch (__c) - { - case -1: - this->setstate(ios_base::eofbit); - break; - case 0: - break; - default: - read(__s, _VSTD::min(__c, __n)); - break; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + sentry __sen(*this, true); + if (__sen) + { + streamsize __c = this->rdbuf()->in_avail(); + switch (__c) + { + case -1: + this->setstate(ios_base::eofbit); + break; + case 0: + break; + default: + read(__s, _VSTD::min(__c, __n)); + break; + } + } + else + this->setstate(ios_base::failbit); +#ifndef _LIBCPP_NO_EXCEPTIONS } + catch (...) + { + this->__set_badbit_and_consider_rethrow(); + } +#endif // _LIBCPP_NO_EXCEPTIONS return __gc_; } diff --git a/contrib/libc++/include/iterator b/contrib/libc++/include/iterator index 8d9b311..0caabbb 100644 --- a/contrib/libc++/include/iterator +++ b/contrib/libc++/include/iterator @@ -131,8 +131,9 @@ bool operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); template <class Iterator1, class Iterator2> -typename reverse_iterator<Iterator1>::difference_type -operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); +auto +operator-(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y) +-> decltype(__y.base() - __x.base()); template <class Iterator> reverse_iterator<Iterator> @@ -149,7 +150,7 @@ public: typedef Container container_type; typedef void value_type; typedef void difference_type; - typedef back_insert_iterator<Cont>& reference; + typedef void reference; typedef void pointer; explicit back_insert_iterator(Container& x); @@ -170,7 +171,7 @@ public: typedef Container container_type; typedef void value_type; typedef void difference_type; - typedef front_insert_iterator<Cont>& reference; + typedef void reference; typedef void pointer; explicit front_insert_iterator(Container& x); @@ -192,7 +193,7 @@ public: typedef Container container_type; typedef void value_type; typedef void difference_type; - typedef insert_iterator<Cont>& reference; + typedef void reference; typedef void pointer; insert_iterator(Container& x, typename Container::iterator i); @@ -205,6 +206,73 @@ public: template <class Container, class Iterator> insert_iterator<Container> inserter(Container& x, Iterator i); +template <class Iterator> +class move_iterator { +public: + typedef Iterator iterator_type; + typedef typename iterator_traits<Iterator>::difference_type difference_type; + typedef Iterator pointer; + typedef typename iterator_traits<Iterator>::value_type value_type; + 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; +private: + Iterator current; // exposition only +}; + +template <class Iterator1, class Iterator2> +bool +operator==(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator!=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator<(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator<=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator>(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +bool +operator>=(const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y); + +template <class Iterator1, class Iterator2> +auto +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); + +template <class Iterator> +move_iterator<Iterator> make_move_iterator(const Iterator& i); + + template <class T, class charT = char, class traits = char_traits<charT>, class Distance = ptrdiff_t> class istream_iterator : public iterator<input_iterator_tag, T, Distance, const T*, const T&> @@ -340,10 +408,10 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; */ #include <__config> +#include <iosfwd> // for forward declarations of vector and string. #include <__functional_base> #include <type_traits> #include <cstddef> -#include <iosfwd> #include <initializer_list> #ifdef __APPLE__ #include <Availability.h> @@ -632,6 +700,16 @@ operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& return __x.base() >= __y.base(); } +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +-> decltype(__y.base() - __x.base()) +{ + return __y.base() - __x.base(); +} +#else template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename reverse_iterator<_Iter1>::difference_type @@ -639,6 +717,7 @@ operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& _ { return __y.base() - __x.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY @@ -663,7 +742,7 @@ class _LIBCPP_TYPE_VIS_ONLY back_insert_iterator void, void, void, - back_insert_iterator<_Container>&> + void> { protected: _Container* container; @@ -696,7 +775,7 @@ class _LIBCPP_TYPE_VIS_ONLY front_insert_iterator void, void, void, - front_insert_iterator<_Container>&> + void> { protected: _Container* container; @@ -729,7 +808,7 @@ class _LIBCPP_TYPE_VIS_ONLY insert_iterator void, void, void, - insert_iterator<_Container>&> + void> { protected: _Container* container; @@ -772,14 +851,14 @@ private: _Tp __value_; public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(0), __value_() {} - _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(&__s) + _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) { if (!(*__in_stream_ >> __value_)) __in_stream_ = 0; } _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;} - _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return &(operator*());} + _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));} _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++() { if (!(*__in_stream_ >> __value_)) @@ -811,9 +890,9 @@ private: const char_type* __delim_; public: _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) - : __out_stream_(&__s), __delim_(0) {} + : __out_stream_(_VSTD::addressof(__s)), __delim_(0) {} _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) - : __out_stream_(&__s), __delim_(__delimiter) {} + : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value_) { *__out_stream_ << __value_; @@ -949,9 +1028,14 @@ public: typedef typename iterator_traits<iterator_type>::iterator_category iterator_category; typedef typename iterator_traits<iterator_type>::value_type value_type; typedef typename iterator_traits<iterator_type>::difference_type difference_type; - typedef typename iterator_traits<iterator_type>::pointer pointer; + typedef iterator_type pointer; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - typedef value_type&& reference; + typedef typename iterator_traits<iterator_type>::reference __reference; + typedef typename conditional< + is_reference<__reference>::value, + typename remove_reference<__reference>::type&&, + __reference + >::type reference; #else typedef typename iterator_traits<iterator_type>::reference reference; #endif @@ -964,10 +1048,7 @@ public: _LIBCPP_INLINE_VISIBILITY reference operator*() const { return static_cast<reference>(*__i); } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const { - typename iterator_traits<iterator_type>::reference __ref = *__i; - return &__ref; - } + _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;} @@ -1036,6 +1117,16 @@ operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) return __x.base() <= __y.base(); } +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) +-> decltype(__x.base() - __y.base()) +{ + return __x.base() - __y.base(); +} +#else template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename move_iterator<_Iter1>::difference_type @@ -1043,6 +1134,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() - __y.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY @@ -1094,10 +1186,18 @@ _LIBCPP_INLINE_VISIBILITY bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#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 +-> 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; +#endif template <class _Iter> _LIBCPP_INLINE_VISIBILITY @@ -1185,7 +1285,7 @@ public: _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), "Attempted to dereference a non-dereferenceable iterator"); #endif - return (pointer)&reinterpret_cast<const volatile char&>(*__i); + return (pointer)_VSTD::addressof(*__i); } _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT { @@ -1279,10 +1379,18 @@ private: bool operator<=(const __wrap_iter<_Iter1>&, const __wrap_iter<_Iter2>&) _NOEXCEPT; +#ifndef _LIBCPP_CXX03_LANG + template <class _Iter1, class _Iter2> + friend + auto + operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT + -> 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; +#endif template <class _Iter1> friend @@ -1388,6 +1496,20 @@ operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEX return !(__y < __x); } +#ifndef _LIBCPP_CXX03_LANG +template <class _Iter1, class _Iter2> +inline _LIBCPP_INLINE_VISIBILITY +auto +operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT +-> decltype(__x.base() - __y.base()) +{ +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), + "Attempted to subtract incompatible iterators"); +#endif + return __x.base() - __y.base(); +} +#else template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type @@ -1399,6 +1521,7 @@ operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXC #endif return __x.base() - __y.base(); } +#endif template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY @@ -1509,16 +1632,16 @@ reverse_iterator<const _Ep*> rend(initializer_list<_Ep> __il) template <class _Cp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -auto cbegin(const _Cp& __c) -> decltype(begin(__c)) +auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c)) { - return begin(__c); + return _VSTD::begin(__c); } template <class _Cp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 -auto cend(const _Cp& __c) -> decltype(end(__c)) +auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c)) { - return end(__c); + return _VSTD::end(__c); } template <class _Cp> @@ -1551,16 +1674,16 @@ auto rend(const _Cp& __c) -> decltype(__c.rend()) template <class _Cp> inline _LIBCPP_INLINE_VISIBILITY -auto crbegin(const _Cp& __c) -> decltype(rbegin(__c)) +auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c)) { - return rbegin(__c); + return _VSTD::rbegin(__c); } template <class _Cp> inline _LIBCPP_INLINE_VISIBILITY -auto crend(const _Cp& __c) -> decltype(rend(__c)) +auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) { - return rend(__c); + return _VSTD::rend(__c); } #endif diff --git a/contrib/libc++/include/list b/contrib/libc++/include/list index 44b20e2..cff0a85 100644 --- a/contrib/libc++/include/list +++ b/contrib/libc++/include/list @@ -570,10 +570,13 @@ protected: const __node_allocator& __node_alloc() const _NOEXCEPT {return __size_alloc_.second();} + _LIBCPP_INLINE_VISIBILITY static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT; + _LIBCPP_INLINE_VISIBILITY __list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY __list_imp(const allocator_type& __a); ~__list_imp(); void clear() _NOEXCEPT; @@ -666,7 +669,7 @@ private: // Unlink nodes [__f, __l] template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void __list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT @@ -676,7 +679,7 @@ __list_imp<_Tp, _Alloc>::__unlink_nodes(__link_pointer __f, __link_pointer __l) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __list_imp<_Tp, _Alloc>::__list_imp() _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) : __size_alloc_(0) @@ -684,7 +687,7 @@ __list_imp<_Tp, _Alloc>::__list_imp() } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline __list_imp<_Tp, _Alloc>::__list_imp(const allocator_type& __a) : __size_alloc_(0, __node_allocator(__a)) { @@ -858,15 +861,19 @@ public: list(const list& __c); list(const list& __c, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY list& operator=(const list& __c); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS list(initializer_list<value_type> __il); list(initializer_list<value_type> __il, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value); + _LIBCPP_INLINE_VISIBILITY list(list&& __c, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY list& operator=(list&& __c) _NOEXCEPT_( __node_alloc_traits::propagate_on_container_move_assignment::value && @@ -888,6 +895,7 @@ public: {assign(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY @@ -1024,9 +1032,11 @@ public: void remove(const value_type& __x); template <class _Pred> void remove_if(_Pred __pred); + _LIBCPP_INLINE_VISIBILITY void unique(); template <class _BinaryPred> void unique(_BinaryPred __binary_pred); + _LIBCPP_INLINE_VISIBILITY void merge(list& __c); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -1039,8 +1049,10 @@ public: _LIBCPP_INLINE_VISIBILITY void merge(list&& __c, _Comp __comp) {merge(__c, __comp);} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY void sort(); template <class _Comp> + _LIBCPP_INLINE_VISIBILITY void sort(_Comp __comp); void reverse() _NOEXCEPT; @@ -1057,8 +1069,11 @@ public: #endif // _LIBCPP_DEBUG_LEVEL >= 2 private: + _LIBCPP_INLINE_VISIBILITY static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l); + _LIBCPP_INLINE_VISIBILITY void __link_nodes_at_front(__link_pointer __f, __link_pointer __l); + _LIBCPP_INLINE_VISIBILITY void __link_nodes_at_back (__link_pointer __f, __link_pointer __l); iterator __iterator(size_type __n); template <class _Comp> @@ -1071,7 +1086,7 @@ private: // Link in nodes [__f, __l] just prior to __p template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_pointer __l) { @@ -1083,7 +1098,7 @@ list<_Tp, _Alloc>::__link_nodes(__link_pointer __p, __link_pointer __f, __link_p // Link in nodes [__f, __l] at the front of the list template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) { @@ -1095,7 +1110,7 @@ list<_Tp, _Alloc>::__link_nodes_at_front(__link_pointer __f, __link_pointer __l) // Link in nodes [__f, __l] at the front of the list template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) { @@ -1107,7 +1122,7 @@ list<_Tp, _Alloc>::__link_nodes_at_back(__link_pointer __f, __link_pointer __l) template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline typename list<_Tp, _Alloc>::iterator list<_Tp, _Alloc>::__iterator(size_type __n) { @@ -1243,7 +1258,7 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il) #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list& __c) { @@ -1258,7 +1273,7 @@ list<_Tp, _Alloc>::operator=(const list& __c) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>::list(list&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) : base(allocator_type(_VSTD::move(__c.__node_alloc()))) @@ -1270,7 +1285,7 @@ list<_Tp, _Alloc>::list(list&& __c) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a) : base(__a) { @@ -1287,7 +1302,7 @@ list<_Tp, _Alloc>::list(list&& __c, const allocator_type& __a) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(list&& __c) _NOEXCEPT_( @@ -1355,7 +1370,7 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline _Alloc list<_Tp, _Alloc>::get_allocator() const _NOEXCEPT { @@ -2108,7 +2123,7 @@ list<_Tp, _Alloc>::remove_if(_Pred __pred) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::unique() { @@ -2131,7 +2146,7 @@ list<_Tp, _Alloc>::unique(_BinaryPred __binary_pred) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::merge(list& __c) { @@ -2193,7 +2208,7 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) } template <class _Tp, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::sort() { @@ -2202,7 +2217,7 @@ list<_Tp, _Alloc>::sort() template <class _Tp, class _Alloc> template <class _Comp> -inline _LIBCPP_INLINE_VISIBILITY +inline void list<_Tp, _Alloc>::sort(_Comp __comp) { diff --git a/contrib/libc++/include/locale b/contrib/libc++/include/locale index 84cb5a5..3d804e8 100644 --- a/contrib/libc++/include/locale +++ b/contrib/libc++/include/locale @@ -180,6 +180,7 @@ template <class charT> class messages_byname; #include <__config> #include <__locale> +#include <__debug> #include <algorithm> #include <memory> #include <ios> @@ -213,6 +214,12 @@ template <class charT> class messages_byname; #pragma GCC system_header #endif +#ifdef _LIBCPP_LOCALE__L_EXTENSIONS +#include <__bsd_locale_defaults.h> +#else +#include <__bsd_locale_fallbacks.h> +#endif + _LIBCPP_BEGIN_NAMESPACE_STD #if defined(__APPLE__) || defined(__FreeBSD__) @@ -228,189 +235,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD typedef _VSTD::remove_pointer<locale_t>::type __locale_struct; typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; -#ifndef _LIBCPP_LOCALE__L_EXTENSIONS -typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; -#endif - -// OSX has nice foo_l() functions that let you turn off use of the global -// locale. Linux, not so much. The following functions avoid the locale when -// that's possible and otherwise do the wrong thing. FIXME. -#if defined(__linux__) || defined(__EMSCRIPTEN__) || defined(_AIX) || \ - defined(_NEWLIB_VERSION) || defined(__GLIBC__) - -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS -decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>())) -inline _LIBCPP_INLINE_VISIBILITY -__mb_cur_max_l(locale_t __l) -{ - return MB_CUR_MAX_L(__l); -} -#else // _LIBCPP_LOCALE__L_EXTENSIONS -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; -} -#endif // _LIBCPP_LOCALE__L_EXTENSIONS - -inline _LIBCPP_ALWAYS_INLINE -wint_t __btowc_l(int __c, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return btowc_l(__c, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return btowc(__c); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -int __wctob_l(wint_t __c, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wctob_l(__c, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wctob(__c); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, - size_t __len, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wcsnrtombs(__dest, __src, __nwc, __len, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return wcrtomb_l(__s, __wc, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return wcrtomb(__s, __wc, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, - size_t __len, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbsnrtowcs(__dest, __src, __nms, __len, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, - mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbrtowc_l(__pwc, __s, __n, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbrtowc(__pwc, __s, __n, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbtowc_l(__pwc, __pmb, __max, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbtowc(__pwc, __pmb, __max); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbrlen_l(__s, __n, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbrlen(__s, __n, __ps); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -lconv *__localeconv_l(locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return localeconv_l(__l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return localeconv(); -#endif -} - -inline _LIBCPP_ALWAYS_INLINE -size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, - mbstate_t *__ps, locale_t __l) -{ -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - return mbsrtowcs_l(__dest, __src, __len, __ps, __l); -#else - __locale_raii __current(uselocale(__l), uselocale); - return mbsrtowcs(__dest, __src, __len, __ps); -#endif -} - -inline -int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vsnprintf_l(__s, __n, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vsnprintf(__s, __n, __format, __va); -#endif - va_end(__va); - return __res; -} - -inline -int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vasprintf_l(__s, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vasprintf(__s, __format, __va); -#endif - va_end(__va); - return __res; -} - -inline -int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { - va_list __va; - va_start(__va, __format); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __res = vsscanf_l(__s, __l, __format, __va); -#else - __locale_raii __current(uselocale(__l), uselocale); - int __res = vsscanf(__s, __format, __va); -#endif - va_end(__va); - return __res; -} - -#endif // __linux__ // __scan_keyword // Scans [__b, __e) until a match is found in the basic_strings range @@ -933,6 +757,28 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end, } template <class _Tp> +_LIBCPP_INLINE_VISIBILITY +_Tp __do_strtod(const char* __a, char** __p2); + +template <> +inline _LIBCPP_INLINE_VISIBILITY +float __do_strtod<float>(const char* __a, char** __p2) { + return strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE); +} + +template <> +inline _LIBCPP_INLINE_VISIBILITY +double __do_strtod<double>(const char* __a, char** __p2) { + return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE); +} + +template <> +inline _LIBCPP_INLINE_VISIBILITY +long double __do_strtod<long double>(const char* __a, char** __p2) { + return strtold_l(__a, __p2, _LIBCPP_GET_C_LOCALE); +} + +template <class _Tp> _Tp __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) { @@ -941,7 +787,7 @@ __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) typename remove_reference<decltype(errno)>::type __save_errno = errno; errno = 0; char *__p2; - long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); + _Tp __ld = __do_strtod<_Tp>(__a, &__p2); typename remove_reference<decltype(errno)>::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; @@ -952,7 +798,7 @@ __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) } else if (__current_errno == ERANGE) __err = ios_base::failbit; - return static_cast<_Tp>(__ld); + return __ld; } __err = ios_base::failbit; return 0; @@ -1188,11 +1034,7 @@ num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, } // Stage 3 __buf.resize(__a_end - __a); -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - if (sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) -#else - if (__sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) -#endif + if (__libcpp_sscanf_l(__buf.c_str(), _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) __err = ios_base::failbit; // EOF checked if (__b == __e) @@ -1556,13 +1398,9 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, this->__format_int(__fmt+1, __len, true, __iob.flags()); const unsigned __nbuf = (numeric_limits<long>::digits / 3) + ((numeric_limits<long>::digits % 3) != 0) - + 1; + + 2; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1588,11 +1426,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<long long>::digits % 3) != 0) + 2; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1618,11 +1452,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<unsigned long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1648,11 +1478,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, + ((numeric_limits<unsigned long long>::digits % 3) != 0) + 1; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar while adding thousands separators @@ -1679,34 +1505,17 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, - (int)__iob.precision(), __v); -#endif else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); unique_ptr<char, void(*)(void*)> __nbh(0, free); if (__nc > static_cast<int>(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1747,34 +1556,17 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char* __nb = __nar; int __nc; if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, - (int)__iob.precision(), __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = __libcpp_snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); unique_ptr<char, void(*)(void*)> __nbh(0, free); if (__nc > static_cast<int>(__nbuf-1)) { if (__specify_precision) -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); else -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - __nc = __asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + __nc = __libcpp_asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); if (__nb == 0) __throw_bad_alloc(); __nbh.reset(__nb); @@ -1810,11 +1602,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, char __fmt[6] = "%p"; const unsigned __nbuf = 20; char __nar[__nbuf]; -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - int __nc = snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#else - int __nc = __snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); -#endif + int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v); char* __ne = __nar + __nc; char* __np = this->__identify_padding(__nar, __ne, __iob); // Stage 2 - Widen __nar @@ -3526,11 +3314,7 @@ money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, // secure memory for digit storage if (__n > __bs-1) { -#ifdef _LIBCPP_LOCALE__L_EXTENSIONS - __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); -#else - __n = __asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units); -#endif + __n = static_cast<size_t>(__libcpp_asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); if (__bb == 0) __throw_bad_alloc(); __hn.reset(__bb); @@ -3850,7 +3634,7 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), __cvtptr_(__wc.__cvtptr_), - __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_) + __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtcount_) { __wc.__cvtptr_ = nullptr; } @@ -4140,7 +3924,9 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() } else { - memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); + _LIBCPP_ASSERT(!(__extbufnext_ == NULL && (__extbufend_ != __extbufnext_)), "underflow moving from NULL" ); + if (__extbufend_ != __extbufnext_) + memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), diff --git a/contrib/libc++/include/map b/contrib/libc++/include/map index 87add43..bdde949 100644 --- a/contrib/libc++/include/map +++ b/contrib/libc++/include/map @@ -162,7 +162,7 @@ public: void swap(map& m) noexcept(allocator_traits<allocator_type>::is_always_equal::value && - __is_nothrow_swappable<key_compare>::value); // C++17 + is_nothrow_swappable<key_compare>::value); // C++17 // observers: allocator_type get_allocator() const noexcept; @@ -357,7 +357,7 @@ public: void swap(multimap& m) noexcept(allocator_traits<allocator_type>::is_always_equal::value && - __is_nothrow_swappable<key_compare>::value); // C++17 + is_nothrow_swappable<key_compare>::value); // C++17 // observers: allocator_type get_allocator() const noexcept; @@ -564,13 +564,11 @@ class __map_node_destructor { typedef _Allocator allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + public: typedef typename __alloc_traits::pointer pointer; -private: - typedef typename value_type::value_type::first_type first_type; - typedef typename value_type::value_type::second_type second_type; +private: allocator_type& __na_; __map_node_destructor& operator=(const __map_node_destructor&); @@ -615,7 +613,7 @@ template <class _Key, class _Tp, class _Compare, class _Allocator> class multimap; template <class _TreeIterator> class __map_const_iterator; -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp> union __value_type @@ -628,33 +626,29 @@ union __value_type value_type __cc; __nc_value_type __nc; - template <class ..._Args> - _LIBCPP_INLINE_VISIBILITY - __value_type(_Args&& ...__args) - : __cc(std::forward<_Args>(__args)...) {} - - _LIBCPP_INLINE_VISIBILITY - __value_type(const __value_type& __v) - : __cc(__v.__cc) {} - - _LIBCPP_INLINE_VISIBILITY - __value_type(__value_type& __v) - : __cc(__v.__cc) {} - - _LIBCPP_INLINE_VISIBILITY - __value_type(__value_type&& __v) - : __nc(std::move(__v.__nc)) {} - _LIBCPP_INLINE_VISIBILITY __value_type& operator=(const __value_type& __v) {__nc = __v.__cc; return *this;} _LIBCPP_INLINE_VISIBILITY __value_type& operator=(__value_type&& __v) - {__nc = std::move(__v.__nc); return *this;} + {__nc = _VSTD::move(__v.__nc); return *this;} + template <class _ValueTp, + class = typename enable_if< + __is_same_uncvref<_ValueTp, value_type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY - ~__value_type() {__cc.~value_type();} + __value_type& operator=(_ValueTp&& __v) { + __nc = _VSTD::forward<_ValueTp>(__v); return *this; + } + +private: + __value_type() _LIBCPP_EQUAL_DELETE; + ~__value_type() _LIBCPP_EQUAL_DELETE; + __value_type(const __value_type& __v) _LIBCPP_EQUAL_DELETE; + __value_type(__value_type&& __v) _LIBCPP_EQUAL_DELETE; }; #else @@ -668,18 +662,11 @@ struct __value_type value_type __cc; - _LIBCPP_INLINE_VISIBILITY - __value_type() {} - - template <class _A0> - _LIBCPP_INLINE_VISIBILITY - __value_type(const _A0& __a0) - : __cc(__a0) {} - - template <class _A0, class _A1> - _LIBCPP_INLINE_VISIBILITY - __value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} +private: + __value_type(); + __value_type(__value_type const&); + __value_type& operator=(__value_type const&); + ~__value_type(); }; #endif @@ -697,19 +684,17 @@ struct __extract_key_value_types<__value_type<_Key, _Tp> > template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator { + typedef typename _TreeIterator::_NodeTypes _NodeTypes; + typedef typename _TreeIterator::__pointer_traits __pointer_traits; + _TreeIterator __i_; - typedef typename _TreeIterator::__pointer_traits __pointer_traits; - typedef typename _TreeIterator::value_type __value_type; - typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; - typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; public: typedef bidirectional_iterator_tag iterator_category; - typedef pair<__key_type, __mapped_type> value_type; + typedef typename _NodeTypes::__map_value_type value_type; typedef typename _TreeIterator::difference_type difference_type; typedef value_type& reference; - typedef typename __rebind_pointer<typename __pointer_traits::pointer, value_type>::type - pointer; + typedef typename _NodeTypes::__map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __map_iterator() _NOEXCEPT {} @@ -758,19 +743,17 @@ public: template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator { + typedef typename _TreeIterator::_NodeTypes _NodeTypes; + typedef typename _TreeIterator::__pointer_traits __pointer_traits; + _TreeIterator __i_; - typedef typename _TreeIterator::__pointer_traits __pointer_traits; - typedef typename _TreeIterator::value_type __value_type; - typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; - typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; public: typedef bidirectional_iterator_tag iterator_category; - typedef pair<__key_type, __mapped_type> value_type; + typedef typename _NodeTypes::__map_value_type value_type; typedef typename _TreeIterator::difference_type difference_type; typedef const value_type& reference; - typedef typename __rebind_pointer<typename __pointer_traits::pointer, const value_type>::type - pointer; + typedef typename _NodeTypes::__const_map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __map_const_iterator() _NOEXCEPT {} @@ -890,7 +873,7 @@ public: _LIBCPP_INLINE_VISIBILITY explicit map(const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) {} + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {} template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY @@ -905,7 +888,7 @@ public: _LIBCPP_INLINE_VISIBILITY map(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__f, __l); } @@ -927,7 +910,7 @@ public: _LIBCPP_INLINE_VISIBILITY map& operator=(const map& __m) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else if (this != &__m) { @@ -972,7 +955,7 @@ public: _LIBCPP_INLINE_VISIBILITY map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__il.begin(), __il.end()); } @@ -994,13 +977,13 @@ public: _LIBCPP_INLINE_VISIBILITY explicit map(const allocator_type& __a) - : __tree_(__a) + : __tree_(typename __base::allocator_type(__a)) { } _LIBCPP_INLINE_VISIBILITY map(const map& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), __a) + : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) { insert(__m.begin(), __m.end()); } @@ -1043,7 +1026,7 @@ public: size_type max_size() const _NOEXCEPT {return __tree_.max_size();} mapped_type& operator[](const key_type& __k); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG mapped_type& operator[](key_type&& __k); #endif @@ -1051,24 +1034,24 @@ public: const mapped_type& at(const key_type& __k) const; _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} _LIBCPP_INLINE_VISIBILITY key_compare key_comp() const {return __tree_.value_comp().key_comp();} _LIBCPP_INLINE_VISIBILITY value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS - +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - pair<iterator, bool> - emplace(_Args&& ...__args); + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> emplace(_Args&& ...__args) { + return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...); + } template <class ..._Args> - iterator - emplace_hint(const_iterator __p, _Args&& ...__args); - -#endif // _LIBCPP_HAS_NO_VARIADICS + _LIBCPP_INLINE_VISIBILITY + iterator emplace_hint(const_iterator __p, _Args&& ...__args) { + return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...); + } template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> @@ -1082,7 +1065,7 @@ public: iterator insert(const_iterator __pos, _Pp&& __p) {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> @@ -1093,15 +1076,14 @@ public: insert(const_iterator __p, const value_type& __v) {return __tree_.__insert_unique(__p.__i_, __v);} -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +#ifndef _LIBCPP_CXX03_LANG _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> - insert( value_type&& __v) {return __tree_.__insert_unique(_VSTD::forward<value_type>(__v));} + insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));} _LIBCPP_INLINE_VISIBILITY - iterator - insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_unique(__p.__i_, _VSTD::forward<value_type>(__v));} + iterator insert(const_iterator __p, value_type&& __v) + {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));} #endif template <class _InputIterator> @@ -1121,62 +1103,45 @@ public: #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS #if _LIBCPP_STD_VER > 14 -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS + template <class... _Args> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) { - iterator __p = lower_bound(__k); - if ( __p != end() && !key_comp()(__k, __p->first)) - return _VSTD::make_pair(__p, false); - else - return _VSTD::make_pair( - emplace_hint(__p, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)), - true); + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class... _Args> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) { - iterator __p = lower_bound(__k); - if ( __p != end() && !key_comp()(__k, __p->first)) - return _VSTD::make_pair(__p, false); - else - return _VSTD::make_pair( - emplace_hint(__p, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)), - true); + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class... _Args> _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { - iterator __p = lower_bound(__k); - if ( __p != end() && !key_comp()(__k, __p->first)) - return __p; - else - return emplace_hint(__p, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); + return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class... _Args> _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { - iterator __p = lower_bound(__k); - if ( __p != end() && !key_comp()(__k, __p->first)) - return __p; - else - return emplace_hint(__p, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); + return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class _Vp> @@ -1191,7 +1156,7 @@ public: } return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true); } - + template <class _Vp> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) @@ -1230,8 +1195,7 @@ public: } return emplace_hint(__h, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); } -#endif -#endif + #endif _LIBCPP_INLINE_VISIBILITY @@ -1332,85 +1296,38 @@ private: typedef typename __base::__node __node; typedef typename __base::__node_allocator __node_allocator; typedef typename __base::__node_pointer __node_pointer; - typedef typename __base::__node_const_pointer __node_const_pointer; typedef typename __base::__node_base_pointer __node_base_pointer; - typedef typename __base::__node_base_const_pointer __node_base_const_pointer; + typedef __map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder __construct_node(_A0&& __a0); - __node_holder __construct_node_with_key(key_type&& __k); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif +#ifdef _LIBCPP_CXX03_LANG __node_holder __construct_node_with_key(const key_type& __k); +#endif + + __node_base_pointer const& + __find_equal_key(__node_base_pointer& __parent, const key_type& __k) const; + _LIBCPP_INLINE_VISIBILITY __node_base_pointer& - __find_equal_key(__node_base_pointer& __parent, const key_type& __k); - __node_base_const_pointer - __find_equal_key(__node_base_const_pointer& __parent, const key_type& __k) const; + __find_equal_key(__node_base_pointer& __parent, const key_type& __k) { + map const* __const_this = this; + return const_cast<__node_base_pointer&>( + __const_this->__find_equal_key(__parent, __k)); + } }; -// Find place to insert if __k doesn't exist -// Set __parent to parent of null leaf -// Return reference to null leaf -// If __k exists, set parent to node of __k and return reference to node of __k -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer& -map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent, - const key_type& __k) -{ - __node_pointer __nd = __tree_.__root(); - if (__nd != nullptr) - { - while (true) - { - if (__tree_.value_comp().key_comp()(__k, __nd->__value_.__cc.first)) - { - if (__nd->__left_ != nullptr) - __nd = static_cast<__node_pointer>(__nd->__left_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__left_; - } - } - else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) - { - if (__nd->__right_ != nullptr) - __nd = static_cast<__node_pointer>(__nd->__right_); - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent->__right_; - } - } - else - { - __parent = static_cast<__node_base_pointer>(__nd); - return __parent; - } - } - } - __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); - return __parent->__left_; -} // Find __k // Set __parent to parent of null leaf and // return reference to null leaf iv __k does not exist. // If __k exists, set parent to node of __k and return reference to node of __k template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_const_pointer -map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer& __parent, +typename map<_Key, _Tp, _Compare, _Allocator>::__node_base_pointer const& +map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_pointer& __parent, const key_type& __k) const { - __node_const_pointer __nd = __tree_.__root(); + __node_pointer __nd = __tree_.__root(); if (__nd != nullptr) { while (true) @@ -1422,7 +1339,7 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer else { __parent = static_cast<__node_base_pointer>(__nd); - return const_cast<const __node_base_const_pointer&>(__parent->__left_); + return __parent->__left_; } } else if (__tree_.value_comp().key_comp()(__nd->__value_.__cc.first, __k)) @@ -1432,7 +1349,7 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer else { __parent = static_cast<__node_base_pointer>(__nd); - return const_cast<const __node_base_const_pointer&>(__parent->__right_); + return __parent->__right_; } } else @@ -1443,83 +1360,28 @@ map<_Key, _Tp, _Compare, _Allocator>::__find_equal_key(__node_base_const_pointer } } __parent = static_cast<__node_base_pointer>(__tree_.__end_node()); - return const_cast<const __node_base_const_pointer&>(__parent->__left_); + return __parent->__left_; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) - : __tree_(_VSTD::move(__m.__tree_), __a) + : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a)) { if (__a != __m.get_allocator()) { const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_unique(__e.__i_, - _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); } } -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node() -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(key_type&& __k) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS +#endif // !_LIBCPP_CXX03_LANG -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0, class _A1, class ..._Args> -typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder -map<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} -#endif // _LIBCPP_HAS_NO_VARIADICS - -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifdef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder @@ -1550,25 +1412,29 @@ map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) return __r->__value_.__cc.second; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#else + +template <class _Key, class _Tp, class _Compare, class _Allocator> +_Tp& +map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) +{ + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple()).first->__cc.second; +} template <class _Key, class _Tp, class _Compare, class _Allocator> _Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) { - __node_base_pointer __parent; - __node_base_pointer& __child = __find_equal_key(__parent, __k); - __node_pointer __r = static_cast<__node_pointer>(__child); - if (__child == nullptr) - { - __node_holder __h = __construct_node_with_key(_VSTD::move(__k)); - __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); - __r = __h.release(); - } - return __r->__value_.__cc.second; + return __tree_.__emplace_unique_key_args(__k, + _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple()).first->__cc.second; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // !_LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> _Tp& @@ -1587,43 +1453,15 @@ template <class _Key, class _Tp, class _Compare, class _Allocator> const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const { - __node_base_const_pointer __parent; - __node_base_const_pointer __child = __find_equal_key(__parent, __k); + __node_base_pointer __parent; + __node_base_pointer __child = __find_equal_key(__parent, __k); #ifndef _LIBCPP_NO_EXCEPTIONS if (__child == nullptr) throw out_of_range("map::at: key not found"); #endif // _LIBCPP_NO_EXCEPTIONS - return static_cast<__node_const_pointer>(__child)->__value_.__cc.second; -} - -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -pair<typename map<_Key, _Tp, _Compare, _Allocator>::iterator, bool> -map<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - pair<iterator, bool> __r = __tree_.__node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -typename map<_Key, _Tp, _Compare, _Allocator>::iterator -map<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p, - _Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __tree_.__node_insert_unique(__p.__i_, __h.get()); - if (__r.__i_.__ptr_ == __h.get()) - __h.release(); - return __r; + return static_cast<__node_pointer>(__child)->__value_.__cc.second; } -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) template <class _Key, class _Tp, class _Compare, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY @@ -1761,7 +1599,7 @@ public: _LIBCPP_INLINE_VISIBILITY explicit multimap(const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) {} + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {} template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY @@ -1776,7 +1614,7 @@ public: _LIBCPP_INLINE_VISIBILITY multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__f, __l); } @@ -1799,7 +1637,7 @@ public: _LIBCPP_INLINE_VISIBILITY multimap& operator=(const multimap& __m) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else if (this != &__m) { @@ -1844,7 +1682,7 @@ public: _LIBCPP_INLINE_VISIBILITY multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a) - : __tree_(__vc(__comp), __a) + : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { insert(__il.begin(), __il.end()); } @@ -1866,13 +1704,13 @@ public: _LIBCPP_INLINE_VISIBILITY explicit multimap(const allocator_type& __a) - : __tree_(__a) + : __tree_(typename __base::allocator_type(__a)) { } _LIBCPP_INLINE_VISIBILITY multimap(const multimap& __m, const allocator_type& __a) - : __tree_(__m.__tree_.value_comp(), __a) + : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) { insert(__m.begin(), __m.end()); } @@ -1914,25 +1752,26 @@ public: size_type max_size() const _NOEXCEPT {return __tree_.max_size();} _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const _NOEXCEPT {return __tree_.__alloc();} + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} _LIBCPP_INLINE_VISIBILITY key_compare key_comp() const {return __tree_.value_comp().key_comp();} _LIBCPP_INLINE_VISIBILITY value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG template <class ..._Args> - iterator - emplace(_Args&& ...__args); + _LIBCPP_INLINE_VISIBILITY + iterator emplace(_Args&& ...__args) { + return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...); + } template <class ..._Args> - iterator - emplace_hint(const_iterator __p, _Args&& ...__args); - -#endif // _LIBCPP_HAS_NO_VARIADICS + _LIBCPP_INLINE_VISIBILITY + iterator emplace_hint(const_iterator __p, _Args&& ...__args) { + return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); + } template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> @@ -1946,23 +1785,22 @@ public: iterator insert(const_iterator __pos, _Pp&& __p) {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} + iterator insert(value_type&& __v) + {return __tree_.__insert_multi(_VSTD::move(__v));} _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, const value_type& __v) - {return __tree_.__insert_multi(__p.__i_, __v);} + iterator insert(const_iterator __p, value_type&& __v) + {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));} + +#endif // _LIBCPP_CXX03_LANG -#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) _LIBCPP_INLINE_VISIBILITY - iterator insert( value_type&& __v) {return __tree_.__insert_multi(_VSTD::forward<value_type>(__v));} + iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, value_type&& __v) - {return __tree_.__insert_multi(__p.__i_, _VSTD::forward<value_type>(__v));} -#endif + iterator insert(const_iterator __p, const value_type& __v) + {return __tree_.__insert_multi(__p.__i_, __v);} template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY @@ -2077,109 +1915,25 @@ private: typedef typename __base::__node __node; typedef typename __base::__node_allocator __node_allocator; typedef typename __base::__node_pointer __node_pointer; - typedef typename __base::__node_const_pointer __node_const_pointer; + typedef __map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; - -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder - __construct_node(_A0&& __a0); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES }; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Compare, class _Allocator> multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) - : __tree_(_VSTD::move(__m.__tree_), __a) + : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a)) { if (__a != __m.get_allocator()) { const_iterator __e = cend(); while (!__m.empty()) __tree_.__insert_multi(__e.__i_, - _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_)); + _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__nc)); } } - -template <class _Key, class _Tp, class _Compare, class _Allocator> -typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder -multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node() -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0> -typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder -multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class _A0, class _A1, class ..._Args> -typename multimap<_Key, _Tp, _Compare, _Allocator>::__node_holder -multimap<_Key, _Tp, _Compare, _Allocator>::__construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args) -{ - __node_allocator& __na = __tree_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator -multimap<_Key, _Tp, _Compare, _Allocator>::emplace(_Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __tree_.__node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template <class _Key, class _Tp, class _Compare, class _Allocator> -template <class ..._Args> -typename multimap<_Key, _Tp, _Compare, _Allocator>::iterator -multimap<_Key, _Tp, _Compare, _Allocator>::emplace_hint(const_iterator __p, - _Args&& ...__args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __tree_.__node_insert_multi(__p.__i_, __h.get()); - __h.release(); - return __r; -} - -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) +#endif template <class _Key, class _Tp, class _Compare, class _Allocator> inline _LIBCPP_INLINE_VISIBILITY diff --git a/contrib/libc++/include/memory b/contrib/libc++/include/memory index 3ef687c..7a3281e 100644 --- a/contrib/libc++/include/memory +++ b/contrib/libc++/include/memory @@ -361,6 +361,7 @@ class shared_ptr { public: typedef T element_type; + typedef weak_ptr<T> weak_type; // C++17 // constructors: constexpr shared_ptr() noexcept; @@ -607,6 +608,7 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space); #include <__functional_base> #include <iosfwd> #include <tuple> +#include <stdexcept> #include <cstring> #if defined(_LIBCPP_NO_EXCEPTIONS) #include <cassert> @@ -1726,7 +1728,12 @@ public: _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) - {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));} + { + if (__n > max_size()) + __libcpp_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 {_VSTD::__deallocate((void*)__p);} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT @@ -1817,7 +1824,12 @@ public: _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT {return _VSTD::addressof(__x);} _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0) - {return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));} + { + if (__n > max_size()) + __libcpp_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 {_VSTD::__deallocate((void*)__p);} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT @@ -2548,7 +2560,7 @@ public: typename enable_if<__same_or_less_cv_qualified<_Up*, _Tp*>::value>::type* = 0) const _NOEXCEPT { static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type"); - static_assert(!is_void<_Tp>::value, "default_delete can not delete incomplete type"); + static_assert(!is_void<_Tp>::value, "default_delete can not delete void type"); delete [] __ptr; } }; @@ -2918,7 +2930,6 @@ public: return __t; } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Pp> _LIBCPP_INLINE_VISIBILITY typename enable_if<__same_or_less_cv_qualified<_Pp, pointer>::value, void>::type @@ -2929,29 +2940,13 @@ public: if (__tmp) __ptr_.second()(__tmp); } - _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t) _NOEXCEPT - { - pointer __tmp = __ptr_.first(); - __ptr_.first() = nullptr; - if (__tmp) - __ptr_.second()(__tmp); - } - _LIBCPP_INLINE_VISIBILITY void reset() _NOEXCEPT + _LIBCPP_INLINE_VISIBILITY void reset(nullptr_t = nullptr) _NOEXCEPT { pointer __tmp = __ptr_.first(); __ptr_.first() = nullptr; if (__tmp) __ptr_.second()(__tmp); } -#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY void reset(pointer __p = pointer()) - { - pointer __tmp = __ptr_.first(); - __ptr_.first() = __p; - if (__tmp) - __ptr_.second()(__tmp); - } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY void swap(unique_ptr& __u) {__ptr_.swap(__u.__ptr_);} private: @@ -2975,7 +2970,10 @@ private: template <class _Tp, class _Dp> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Dp>::value, + void +>::type swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);} template <class _T1, class _D1, class _T2, class _D2> @@ -3167,8 +3165,6 @@ template<class _Tp, class... _Args> #endif // _LIBCPP_STD_VER > 11 -template <class _Tp> struct hash; - template <class _Size> inline _LIBCPP_INLINE_VISIBILITY _Size @@ -3868,6 +3864,9 @@ class _LIBCPP_TYPE_VIS_ONLY shared_ptr { public: typedef _Tp element_type; +#if _LIBCPP_STD_VER > 14 + typedef weak_ptr<_Tp> weak_type; +#endif private: element_type* __ptr_; __shared_weak_count* __cntrl_; @@ -3979,23 +3978,23 @@ public: _LIBCPP_INLINE_VISIBILITY operator=(shared_ptr<_Yp>&& __r); template<class _Yp> + _LIBCPP_INLINE_VISIBILITY typename enable_if < !is_array<_Yp>::value && is_convertible<_Yp*, element_type*>::value, shared_ptr >::type& - _LIBCPP_INLINE_VISIBILITY operator=(auto_ptr<_Yp>&& __r); #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES template<class _Yp> + _LIBCPP_INLINE_VISIBILITY typename enable_if < !is_array<_Yp>::value && is_convertible<_Yp*, element_type*>::value, shared_ptr& >::type - _LIBCPP_INLINE_VISIBILITY operator=(auto_ptr<_Yp> __r); #endif template <class _Yp, class _Dp> @@ -4120,21 +4119,22 @@ public: private: - template <class _Yp> + template <class _Yp, class _OrigPtr> _LIBCPP_INLINE_VISIBILITY void - __enable_weak_this(const enable_shared_from_this<_Yp>* __e) _NOEXCEPT + __enable_weak_this(const enable_shared_from_this<_Yp>* __e, + _OrigPtr* __ptr) _NOEXCEPT { - if (__e) + typedef typename remove_cv<_Yp>::type _RawYp; + if (__e && __e->__weak_this_.expired()) { - __e->__weak_this_.__ptr_ = const_cast<_Yp*>(static_cast<const _Yp*>(__e)); - __e->__weak_this_.__cntrl_ = __cntrl_; - __cntrl_->__add_weak(); + __e->__weak_this_ = shared_ptr<_RawYp>(*this, + const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr))); } } _LIBCPP_INLINE_VISIBILITY - void __enable_weak_this(const volatile void*) _NOEXCEPT {} + void __enable_weak_this(const volatile void*, const volatile void*) _NOEXCEPT {} template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY shared_ptr; template <class _Up> friend class _LIBCPP_TYPE_VIS_ONLY weak_ptr; @@ -4168,7 +4168,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), allocator<_Yp>()); __hold.release(); - __enable_weak_this(__p); + __enable_weak_this(__p, __p); } template<class _Tp> @@ -4183,7 +4183,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, #endif // _LIBCPP_NO_EXCEPTIONS typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__p, __d, allocator<_Yp>()); - __enable_weak_this(__p); + __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -4233,7 +4233,7 @@ shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a, ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get()))) _CntrlBlk(__p, __d, __a); __cntrl_ = _VSTD::addressof(*__hold2.release()); - __enable_weak_this(__p); + __enable_weak_this(__p, __p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) @@ -4344,7 +4344,7 @@ shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r, { typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); - __enable_weak_this(__r.get()); + __enable_weak_this(__r.get(), __r.get()); __r.release(); } @@ -4372,7 +4372,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, { typedef __shared_ptr_pointer<_Yp*, _Dp, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), allocator<_Yp>()); - __enable_weak_this(__r.get()); + __enable_weak_this(__r.get(), __r.get()); } __r.release(); } @@ -4403,7 +4403,7 @@ shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r, reference_wrapper<typename remove_reference<_Dp>::type>, allocator<_Yp> > _CntrlBlk; __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), allocator<_Yp>()); - __enable_weak_this(__r.get()); + __enable_weak_this(__r.get(), __r.get()); } __r.release(); } @@ -4424,7 +4424,7 @@ shared_ptr<_Tp>::make_shared(_Args&& ...__args) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4443,7 +4443,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4462,7 +4462,7 @@ shared_ptr<_Tp>::make_shared() shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4480,7 +4480,7 @@ shared_ptr<_Tp>::make_shared(_A0& __a0) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4498,7 +4498,7 @@ shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4516,7 +4516,7 @@ shared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1, _A2& __a2) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = __hold2.release(); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4535,7 +4535,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4554,7 +4554,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4573,7 +4573,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1) shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -4592,7 +4592,7 @@ shared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& _ shared_ptr<_Tp> __r; __r.__ptr_ = __hold2.get()->get(); __r.__cntrl_ = _VSTD::addressof(*__hold2.release()); - __r.__enable_weak_this(__r.__ptr_); + __r.__enable_weak_this(__r.__ptr_, __r.__ptr_); return __r; } @@ -5437,6 +5437,16 @@ public: shared_ptr<_Tp const> shared_from_this() const {return shared_ptr<const _Tp>(__weak_this_);} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + weak_ptr<_Tp> weak_from_this() _NOEXCEPT + { return __weak_this_; } + + _LIBCPP_INLINE_VISIBILITY + weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT + { return __weak_this_; } +#endif // _LIBCPP_STD_VER > 14 + template <class _Up> friend class shared_ptr; }; @@ -5457,9 +5467,8 @@ inline _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); -// TODO(EricWF): Enable this for both Clang and GCC. Currently it is only -// enabled with clang. -#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) + +#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) class _LIBCPP_TYPE_VIS __sp_mut { @@ -5546,14 +5555,17 @@ template <class _Tp> bool atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w) { + shared_ptr<_Tp> __temp; __sp_mut& __m = __get_sp_mut(__p); __m.lock(); if (__p->__owner_equivalent(*__v)) { + _VSTD::swap(__temp, *__p); *__p = __w; __m.unlock(); return true; } + _VSTD::swap(__temp, *__v); *__v = *__p; __m.unlock(); return false; @@ -5585,7 +5597,7 @@ atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v return atomic_compare_exchange_weak(__p, __v, __w); } -#endif // defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) +#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) //enum class struct _LIBCPP_TYPE_VIS pointer_safety @@ -5623,7 +5635,7 @@ _LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& // --- Helper for container swap -- template <typename _Alloc> -_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc & __a1, _Alloc & __a2) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT @@ -5649,7 +5661,7 @@ void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) } template <typename _Alloc> -_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> > @@ -5662,6 +5674,26 @@ struct __noexcept_move_assign_container : public integral_constant<bool, #endif > {}; + +#ifndef _LIBCPP_HAS_NO_VARIADICS +template <class _Tp, class _Alloc> +struct __temp_value { + typedef allocator_traits<_Alloc> _Traits; + + typename aligned_storage<sizeof(_Tp), alignof(_Tp)>::type __v; + _Alloc &__a; + + _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); } + _Tp & get() { return *__addr(); } + + template<class... _Args> + __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) + { _Traits::construct(__a, __addr(), _VSTD::forward<_Args>(__args)...); } + + ~__temp_value() { _Traits::destroy(__a, __addr()); } + }; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MEMORY diff --git a/contrib/libc++/include/mutex b/contrib/libc++/include/mutex index a0875a5..c047cf9 100644 --- a/contrib/libc++/include/mutex +++ b/contrib/libc++/include/mutex @@ -109,6 +109,19 @@ public: lock_guard& operator=(lock_guard const&) = delete; }; +template <class... MutexTypes> // Variadic lock_guard only provided in ABI V2. +class lock_guard +{ +public: + explicit lock_guard(MutexTypes&... m); + lock_guard(MutexTypes&... m, adopt_lock_t); + ~lock_guard(); + lock_guard(lock_guard const&) = delete; + lock_guard& operator=(lock_guard const&) = delete; +private: + tuple<MutexTypes&...> pm; // exposition only +}; + template <class Mutex> class unique_lock { @@ -179,9 +192,7 @@ template<class Callable, class ...Args> #ifndef _LIBCPP_HAS_NO_VARIADICS #include <tuple> #endif -#ifndef _LIBCPP_HAS_NO_THREADS -#include <sched.h> -#endif +#include <__threading_support> #include <__undef_min_max> @@ -195,7 +206,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_TYPE_VIS recursive_mutex { - pthread_mutex_t __m_; + __libcpp_mutex_t __m_; public: recursive_mutex(); @@ -210,7 +221,7 @@ public: bool try_lock() _NOEXCEPT; void unlock() _NOEXCEPT; - typedef pthread_mutex_t* native_handle_type; + typedef __libcpp_mutex_t* native_handle_type; _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} }; @@ -262,7 +273,7 @@ class _LIBCPP_TYPE_VIS recursive_timed_mutex mutex __m_; condition_variable __cv_; size_t __count_; - pthread_t __id_; + __libcpp_thread_id __id_; public: recursive_timed_mutex(); ~recursive_timed_mutex(); @@ -288,9 +299,9 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - pthread_t __id = pthread_self(); + __libcpp_thread_id __id = __libcpp_thread_get_current_id(); unique_lock<mutex> lk(__m_); - if (pthread_equal(__id, __id_)) + if (__libcpp_thread_id_equal(__id, __id_)) { if (__count_ == numeric_limits<size_t>::max()) return false; @@ -362,7 +373,7 @@ lock(_L0& __l0, _L1& __l1) break; } } - sched_yield(); + __libcpp_thread_yield(); { unique_lock<_L1> __u1(__l1); if (__l0.try_lock()) @@ -371,7 +382,7 @@ lock(_L0& __l0, _L1& __l1) break; } } - sched_yield(); + __libcpp_thread_yield(); } } @@ -396,7 +407,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) } } ++__i; - sched_yield(); + __libcpp_thread_yield(); break; case 1: { @@ -412,7 +423,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) __i = 0; else __i += 2; - sched_yield(); + __libcpp_thread_yield(); break; default: __lock_first(__i - 2, __l2, __l3..., __l0, __l1); @@ -429,6 +440,27 @@ lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) __lock_first(0, __l0, __l1, __l2, __l3...); } +template <class _L0> +inline _LIBCPP_INLINE_VISIBILITY +void __unlock(_L0& __l0) { + __l0.unlock(); +} + +template <class _L0, class _L1> +inline _LIBCPP_INLINE_VISIBILITY +void __unlock(_L0& __l0, _L1& __l1) { + __l0.unlock(); + __l1.unlock(); +} + +template <class _L0, class _L1, class _L2, class ..._L3> +inline _LIBCPP_INLINE_VISIBILITY +void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) { + __l0.unlock(); + __l1.unlock(); + _VSTD::__unlock(__l2, __l3...); +} + #endif // _LIBCPP_HAS_NO_VARIADICS #endif // !_LIBCPP_HAS_NO_THREADS @@ -579,6 +611,63 @@ call_once(once_flag& __flag, const _Callable& __func) #endif // _LIBCPP_HAS_NO_VARIADICS + +#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \ + && !defined(_LIBCPP_CXX03_LANG) +template <> +class _LIBCPP_TYPE_VIS_ONLY lock_guard<> { +public: + explicit lock_guard() {} + ~lock_guard() = default; + + _LIBCPP_INLINE_VISIBILITY + explicit lock_guard(adopt_lock_t) {} + + lock_guard(lock_guard const&) = delete; + lock_guard& operator=(lock_guard const&) = delete; +}; + +template <class ..._MArgs> +class _LIBCPP_TYPE_VIS_ONLY lock_guard +{ + static_assert(sizeof...(_MArgs) >= 2, "At least 2 lock types required"); + typedef tuple<_MArgs&...> _MutexTuple; + +public: + _LIBCPP_INLINE_VISIBILITY + explicit lock_guard(_MArgs&... __margs) + : __t_(__margs...) + { + _VSTD::lock(__margs...); + } + + _LIBCPP_INLINE_VISIBILITY + lock_guard(_MArgs&... __margs, adopt_lock_t) + : __t_(__margs...) + { + } + + _LIBCPP_INLINE_VISIBILITY + ~lock_guard() { + typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices; + __unlock_unpack(_Indices{}, __t_); + } + + lock_guard(lock_guard const&) = delete; + lock_guard& operator=(lock_guard const&) = delete; + +private: + template <size_t ..._Indx> + _LIBCPP_INLINE_VISIBILITY + static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) { + _VSTD::__unlock(_VSTD::get<_Indx>(__mt)...); + } + + _MutexTuple __t_; +}; + +#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_MUTEX diff --git a/contrib/libc++/include/queue b/contrib/libc++/include/queue index 6f49c87..c657b52 100644 --- a/contrib/libc++/include/queue +++ b/contrib/libc++/include/queue @@ -66,7 +66,7 @@ public: template <class... Args> void emplace(Args&&... args); void pop(); - void swap(queue& q) noexcept(noexcept(swap(c, q.c))); + void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>) }; template <class T, class Container> @@ -153,7 +153,8 @@ public: void pop(); void swap(priority_queue& q) - noexcept(noexcept(swap(c, q.c)) && noexcept(swap(comp.q.comp))); + noexcept(is_nothrow_swappable_v<Container> && + is_nothrow_swappable_v<Comp>) }; template <class T, class Container, class Compare> @@ -198,6 +199,7 @@ public: typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; typedef typename container_type::size_type size_type; + static_assert((is_same<_Tp, value_type>::value), "" ); protected: container_type c; @@ -368,7 +370,10 @@ operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Container>::value, + void +>::type swap(queue<_Tp, _Container>& __x, queue<_Tp, _Container>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { @@ -392,6 +397,7 @@ public: typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; typedef typename container_type::size_type size_type; + static_assert((is_same<_Tp, value_type>::value), "" ); protected: container_type c; @@ -430,45 +436,56 @@ public: _LIBCPP_INLINE_VISIBILITY explicit priority_queue(const value_compare& __comp) : c(), comp(__comp) {} + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, const container_type& __c); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY explicit priority_queue(const value_compare& __comp, container_type&& __c); #endif template <class _InputIter> + _LIBCPP_INLINE_VISIBILITY priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp = value_compare()); template <class _InputIter> + _LIBCPP_INLINE_VISIBILITY priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, const container_type& __c); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIter> + _LIBCPP_INLINE_VISIBILITY priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, container_type&& __c); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY explicit priority_queue(const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, const container_type& __c, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const priority_queue& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(const value_compare& __comp, container_type&& __c, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); template <class _Alloc> + _LIBCPP_INLINE_VISIBILITY priority_queue(priority_queue&& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type* = 0); @@ -481,22 +498,26 @@ public: _LIBCPP_INLINE_VISIBILITY const_reference top() const {return c.front();} + _LIBCPP_INLINE_VISIBILITY void push(const value_type& __v); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY void push(value_type&& __v); #ifndef _LIBCPP_HAS_NO_VARIADICS - template <class... _Args> void emplace(_Args&&... __args); + template <class... _Args> _LIBCPP_INLINE_VISIBILITY void emplace(_Args&&... __args); #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY void pop(); + _LIBCPP_INLINE_VISIBILITY void swap(priority_queue& __q) _NOEXCEPT_(__is_nothrow_swappable<container_type>::value && __is_nothrow_swappable<value_compare>::value); }; template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp, const container_type& __c) : c(__c), @@ -508,7 +529,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, container_type&& __c) : c(_VSTD::move(__c)), @@ -521,7 +542,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _InputIter> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp) : c(__f, __l), @@ -532,7 +553,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input template <class _Tp, class _Container, class _Compare> template <class _InputIter> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, const container_type& __c) @@ -547,7 +568,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input template <class _Tp, class _Container, class _Compare> template <class _InputIter> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _InputIter __l, const value_compare& __comp, container_type&& __c) @@ -562,7 +583,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(_InputIter __f, _Input template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a, typename enable_if<uses_allocator<container_type, _Alloc>::value>::type*) @@ -572,7 +593,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Alloc& __a, template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, const _Alloc& __a, typename enable_if<uses_allocator<container_type, @@ -584,7 +605,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, const container_type& __c, const _Alloc& __a, @@ -598,7 +619,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, @@ -613,7 +634,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const priority_queue& template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& __comp, container_type&& __c, const _Alloc& __a, @@ -627,7 +648,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(const value_compare& _ template <class _Tp, class _Container, class _Compare> template <class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q, const _Alloc& __a, typename enable_if<uses_allocator<container_type, @@ -641,7 +662,7 @@ priority_queue<_Tp, _Container, _Compare>::priority_queue(priority_queue&& __q, #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v) { @@ -652,7 +673,7 @@ priority_queue<_Tp, _Container, _Compare>::push(const value_type& __v) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v) { @@ -664,7 +685,7 @@ priority_queue<_Tp, _Container, _Compare>::push(value_type&& __v) template <class _Tp, class _Container, class _Compare> template <class... _Args> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args) { @@ -676,7 +697,7 @@ priority_queue<_Tp, _Container, _Compare>::emplace(_Args&&... __args) #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::pop() { @@ -685,7 +706,7 @@ priority_queue<_Tp, _Container, _Compare>::pop() } template <class _Tp, class _Container, class _Compare> -inline _LIBCPP_INLINE_VISIBILITY +inline void priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q) _NOEXCEPT_(__is_nothrow_swappable<container_type>::value && @@ -698,7 +719,11 @@ priority_queue<_Tp, _Container, _Compare>::swap(priority_queue& __q) template <class _Tp, class _Container, class _Compare> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Container>::value + && __is_swappable<_Compare>::value, + void +>::type swap(priority_queue<_Tp, _Container, _Compare>& __x, priority_queue<_Tp, _Container, _Compare>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) diff --git a/contrib/libc++/include/shared_mutex b/contrib/libc++/include/shared_mutex index dcb9394..923fe07 100644 --- a/contrib/libc++/include/shared_mutex +++ b/contrib/libc++/include/shared_mutex @@ -319,25 +319,25 @@ public: _LIBCPP_INLINE_VISIBILITY explicit shared_lock(mutex_type& __m) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock_shared();} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(false) {} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, try_to_lock_t) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared()) {} _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, adopt_lock_t) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(true) {} @@ -345,7 +345,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_until(__abs_time)) {} @@ -353,7 +353,7 @@ public: _LIBCPP_INLINE_VISIBILITY shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) - : __m_(&__m), + : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_for(__rel_time)) {} diff --git a/contrib/libc++/include/stack b/contrib/libc++/include/stack index 2992b09..48b3b0d 100644 --- a/contrib/libc++/include/stack +++ b/contrib/libc++/include/stack @@ -58,7 +58,7 @@ public: template <class... Args> void emplace(Args&&... args); void pop(); - void swap(stack& c) noexcept(noexcept(swap(c, q.c))); + void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>) }; template <class T, class Container> @@ -112,7 +112,8 @@ public: typedef typename container_type::reference reference; typedef typename container_type::const_reference const_reference; typedef typename container_type::size_type size_type; - + static_assert((is_same<_Tp, value_type>::value), "" ); + protected: container_type c; @@ -274,7 +275,10 @@ operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) template <class _Tp, class _Container> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Container>::value, + void +>::type swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { diff --git a/contrib/libc++/include/stdbool.h b/contrib/libc++/include/stdbool.h new file mode 100644 index 0000000..86a127f --- /dev/null +++ b/contrib/libc++/include/stdbool.h @@ -0,0 +1,39 @@ +// -*- C++ -*- +//===--------------------------- stdbool.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_STDBOOL_H +#define _LIBCPP_STDBOOL_H + + +/* + stdbool.h synopsis + +Macros: + + __bool_true_false_are_defined + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next <stdbool.h> + +#ifdef __cplusplus +#undef bool +#undef true +#undef false +#undef __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 +#endif + +#endif // _LIBCPP_STDBOOL_H diff --git a/contrib/libc++/include/stdexcept b/contrib/libc++/include/stdexcept index f251806..4218b13 100644 --- a/contrib/libc++/include/stdexcept +++ b/contrib/libc++/include/stdexcept @@ -53,7 +53,11 @@ public: #ifndef _LIBCPP___REFSTRING _LIBCPP_BEGIN_NAMESPACE_STD class _LIBCPP_HIDDEN __libcpp_refstring { - const char *__imp_ _LIBCPP_UNUSED; +#ifdef __clang__ + const char *__imp_ __attribute__((__unused__)); // only clang emits a warning +#else + const char *__imp_; +#endif }; _LIBCPP_END_NAMESPACE_STD #endif diff --git a/contrib/libc++/include/streambuf b/contrib/libc++/include/streambuf index 603c680..7544aaf 100644 --- a/contrib/libc++/include/streambuf +++ b/contrib/libc++/include/streambuf @@ -495,12 +495,22 @@ basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n) const int_type __eof = traits_type::eof(); int_type __c; streamsize __i = 0; - for (;__i < __n; ++__i, ++__s) + while(__i < __n) { if (__ninp_ < __einp_) - *__s = *__ninp_++; + { + const streamsize __len = _VSTD::min(__einp_ - __ninp_, __n - __i); + traits_type::copy(__s, __ninp_, __len); + __s += __len; + __i += __len; + this->gbump(__len); + } else if ((__c = uflow()) != __eof) + { *__s = traits_type::to_char_type(__c); + ++__s; + ++__i; + } else break; } diff --git a/contrib/libc++/include/string b/contrib/libc++/include/string index 9150244..786735f 100644 --- a/contrib/libc++/include/string +++ b/contrib/libc++/include/string @@ -98,8 +98,10 @@ public: basic_string(const basic_string& str); basic_string(basic_string&& str) noexcept(is_nothrow_move_constructible<allocator_type>::value); - basic_string(const basic_string& str, size_type pos, size_type n = npos, + 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()); 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()); @@ -225,6 +227,7 @@ public: const value_type* c_str() const noexcept; const value_type* data() const noexcept; + value_type* data() noexcept; // C++17 allocator_type get_allocator() const noexcept; @@ -958,7 +961,7 @@ char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) // __str_find template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -971,7 +974,7 @@ __str_find(const _CharT *__p, _SizeT __sz, } template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -982,7 +985,7 @@ __str_find(const _CharT *__p, _SizeT __sz, const _CharT* __r = _VSTD::__search(__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq, - random_access_iterator_tag(), random_access_iterator_tag()); + random_access_iterator_tag(), random_access_iterator_tag()).first; if (__r == __p + __sz) return __npos; return static_cast<_SizeT>(__r - __p); @@ -992,7 +995,7 @@ __str_find(const _CharT *__p, _SizeT __sz, // __str_rfind template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_rfind(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -1011,7 +1014,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, } template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_rfind(const _CharT *__p, _SizeT __sz, const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT { @@ -1030,7 +1033,7 @@ __str_rfind(const _CharT *__p, _SizeT __sz, // __str_find_first_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +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 { @@ -1046,7 +1049,7 @@ __str_find_first_of(const _CharT *__p, _SizeT __sz, // __str_find_last_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +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 { @@ -1069,7 +1072,7 @@ __str_find_last_of(const _CharT *__p, _SizeT __sz, // __str_find_first_not_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +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 { @@ -1085,7 +1088,7 @@ __str_find_first_not_of(const _CharT *__p, _SizeT __sz, template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_first_not_of(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -1102,7 +1105,7 @@ __str_find_first_not_of(const _CharT *__p, _SizeT __sz, // __str_find_last_not_of template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +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 { @@ -1118,7 +1121,7 @@ __str_find_last_not_of(const _CharT *__p, _SizeT __sz, template<class _CharT, class _SizeT, class _Traits, _SizeT __npos> -_SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY +inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY __str_find_last_not_of(const _CharT *__p, _SizeT __sz, _CharT __c, _SizeT __pos) _NOEXCEPT { @@ -1396,7 +1399,10 @@ public: basic_string(size_type __n, value_type __c); _LIBCPP_INLINE_VISIBILITY basic_string(size_type __n, value_type __c, const allocator_type& __a); - basic_string(const basic_string& __str, size_type __pos, size_type __n = npos, + basic_string(const basic_string& __str, size_type __pos, size_type __n, + const allocator_type& __a = allocator_type()); + _LIBCPP_INLINE_VISIBILITY + basic_string(const basic_string& __str, size_type __pos, const allocator_type& __a = allocator_type()); template<class _InputIterator> _LIBCPP_INLINE_VISIBILITY @@ -1546,7 +1552,7 @@ public: _LIBCPP_INLINE_VISIBILITY const_reference back() const; _LIBCPP_INLINE_VISIBILITY - basic_string& assign(const basic_string& __str); + basic_string& assign(const basic_string& __str) { return *this = __str; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY basic_string& assign(basic_string&& str) @@ -1659,6 +1665,10 @@ public: const value_type* c_str() const _NOEXCEPT {return data();} _LIBCPP_INLINE_VISIBILITY const value_type* data() const _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} +#if _LIBCPP_STD_VER > 14 + _LIBCPP_INLINE_VISIBILITY + value_type* data() _NOEXCEPT {return _VSTD::__to_raw_pointer(__get_pointer());} +#endif _LIBCPP_INLINE_VISIBILITY allocator_type get_allocator() const _NOEXCEPT {return __alloc();} @@ -2218,6 +2228,21 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st } template <class _CharT, class _Traits, class _Allocator> +inline _LIBCPP_INLINE_VISIBILITY +basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, + const allocator_type& __a) + : __r_(__a) +{ + size_type __str_sz = __str.size(); + if (__pos > __str_sz) + this->__throw_out_of_range(); + __init(__str.data() + __pos, __str_sz - __pos); +#if _LIBCPP_DEBUG_LEVEL >= 2 + __get_db()->__insert_c(this); +#endif +} + +template <class _CharT, class _Traits, class _Allocator> template <class _InputIterator> typename enable_if < @@ -2466,7 +2491,7 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) if (this != &__str) { __copy_assign_alloc(__str); - assign(__str); + assign(__str.data(), __str.size()); } return *this; } @@ -2558,14 +2583,6 @@ basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _For } template <class _CharT, class _Traits, class _Allocator> -inline _LIBCPP_INLINE_VISIBILITY -basic_string<_CharT, _Traits, _Allocator>& -basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str) -{ - return assign(__str.data(), __str.size()); -} - -template <class _CharT, class _Traits, class _Allocator> basic_string<_CharT, _Traits, _Allocator>& basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, size_type __pos, size_type __n) { diff --git a/contrib/libc++/include/string.h b/contrib/libc++/include/string.h new file mode 100644 index 0000000..a1ce56c --- /dev/null +++ b/contrib/libc++/include/string.h @@ -0,0 +1,110 @@ +// -*- C++ -*- +//===--------------------------- string.h ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_STRING_H +#define _LIBCPP_STRING_H + +/* + string.h synopsis + +Macros: + + NULL + +Types: + + size_t + +void* memcpy(void* restrict s1, const void* restrict s2, size_t n); +void* memmove(void* s1, const void* s2, size_t n); +char* strcpy (char* restrict s1, const char* restrict s2); +char* strncpy(char* restrict s1, const char* restrict s2, size_t n); +char* strcat (char* restrict s1, const char* restrict s2); +char* strncat(char* restrict s1, const char* restrict s2, size_t n); +int memcmp(const void* s1, const void* s2, size_t n); +int strcmp (const char* s1, const char* s2); +int strncmp(const char* s1, const char* s2, size_t n); +int strcoll(const char* s1, const char* s2); +size_t strxfrm(char* restrict s1, const char* restrict s2, size_t n); +const void* memchr(const void* s, int c, size_t n); + void* memchr( void* s, int c, size_t n); +const char* strchr(const char* s, int c); + char* strchr( char* s, int c); +size_t strcspn(const char* s1, const char* s2); +const char* strpbrk(const char* s1, const char* s2); + char* strpbrk( char* s1, const char* s2); +const char* strrchr(const char* s, int c); + char* strrchr( char* s, int c); +size_t strspn(const char* s1, const char* s2); +const char* strstr(const char* s1, const char* s2); + char* strstr( char* s1, const char* s2); +char* strtok(char* restrict s1, const char* restrict s2); +void* memset(void* s, int c, size_t n); +char* strerror(int errnum); +size_t strlen(const char* s); + +*/ + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#include_next <string.h> + +// MSVCRT, GNU libc and its derivates may already have the correct prototype in +// <string.h>. This macro can be defined by users if their C library provides +// the right signature. +#if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || \ + defined(__sun__) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) +#define _LIBCPP_STRING_H_HAS_CONST_OVERLOADS +#endif + +#if defined(__cplusplus) && !defined(_LIBCPP_STRING_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) +extern "C++" { +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strchr(const char* __s, int __c) {return (char*)strchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strchr(const char* __s, int __c) {return __libcpp_strchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strchr( char* __s, int __c) {return __libcpp_strchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strpbrk(const char* __s1, const char* __s2) {return (char*)strpbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strpbrk(const char* __s1, const char* __s2) {return __libcpp_strpbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strpbrk( char* __s1, const char* __s2) {return __libcpp_strpbrk(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strrchr(const char* __s, int __c) {return (char*)strrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strrchr(const char* __s, int __c) {return __libcpp_strrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strrchr( char* __s, int __c) {return __libcpp_strrchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +void* __libcpp_memchr(const void* __s, int __c, size_t __n) {return (void*)memchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const void* memchr(const void* __s, int __c, size_t __n) {return __libcpp_memchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + void* memchr( void* __s, int __c, size_t __n) {return __libcpp_memchr(__s, __c, __n);} + +inline _LIBCPP_INLINE_VISIBILITY +char* __libcpp_strstr(const char* __s1, const char* __s2) {return (char*)strstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const char* strstr(const char* __s1, const char* __s2) {return __libcpp_strstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + char* strstr( char* __s1, const char* __s2) {return __libcpp_strstr(__s1, __s2);} +} +#endif + +#endif // _LIBCPP_STRING_H diff --git a/contrib/libc++/include/thread b/contrib/libc++/include/thread index 6857e9e..022021c 100644 --- a/contrib/libc++/include/thread +++ b/contrib/libc++/include/thread @@ -98,8 +98,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); #ifndef _LIBCPP_HAS_NO_VARIADICS #include <tuple> #endif -#include <pthread.h> -#include <sched.h> +#include <__threading_support> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -137,7 +136,7 @@ public: template <class _Tp> class __thread_specific_ptr { - pthread_key_t __key_; + __libcpp_tl_key __key_; // Only __thread_local_data() may construct a __thread_specific_ptr // and only with _Tp == __thread_struct. @@ -155,7 +154,7 @@ public: ~__thread_specific_ptr(); _LIBCPP_INLINE_VISIBILITY - pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));} + pointer get() const {return static_cast<_Tp*>(__libcpp_tl_get(__key_));} _LIBCPP_INLINE_VISIBILITY pointer operator*() const {return *get();} _LIBCPP_INLINE_VISIBILITY @@ -174,12 +173,12 @@ __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) template <class _Tp> __thread_specific_ptr<_Tp>::__thread_specific_ptr() { - int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit); -#ifndef _LIBCPP_NO_EXCEPTIONS + int __ec = __libcpp_tl_create( + &__key_, + &__thread_specific_ptr::__at_thread_exit); if (__ec) - throw system_error(error_code(__ec, system_category()), + __throw_system_error(__ec, "__thread_specific_ptr construction failed"); -#endif } template <class _Tp> @@ -196,7 +195,7 @@ typename __thread_specific_ptr<_Tp>::pointer __thread_specific_ptr<_Tp>::release() { pointer __p = get(); - pthread_setspecific(__key_, 0); + __libcpp_tl_set(__key_, nullptr); return __p; } @@ -205,7 +204,7 @@ void __thread_specific_ptr<_Tp>::reset(pointer __p) { pointer __p_old = get(); - pthread_setspecific(__key_, __p); + __libcpp_tl_set(__key_, __p); delete __p_old; } @@ -219,14 +218,14 @@ _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; } // this_thread -template<> struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>; +template<> struct hash<__thread_id>; class _LIBCPP_TYPE_VIS_ONLY __thread_id { // FIXME: pthread_t is a pointer on Darwin but a long on Linux. // NULL is the no-thread value on Darwin. Someone needs to check // on other platforms. We assume 0 works everywhere for now. - pthread_t __id_; + __libcpp_thread_id __id_; public: _LIBCPP_INLINE_VISIBILITY @@ -234,13 +233,13 @@ public: friend _LIBCPP_INLINE_VISIBILITY bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT - {return __x.__id_ == __y.__id_;} + {return __libcpp_thread_id_equal(__x.__id_, __y.__id_);} friend _LIBCPP_INLINE_VISIBILITY bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {return !(__x == __y);} friend _LIBCPP_INLINE_VISIBILITY bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT - {return __x.__id_ < __y.__id_;} + {return __libcpp_thread_id_less(__x.__id_, __y.__id_);} friend _LIBCPP_INLINE_VISIBILITY bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT {return !(__y < __x);} @@ -260,7 +259,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY - __thread_id(pthread_t __id) : __id_(__id) {} + __thread_id(__libcpp_thread_id __id) : __id_(__id) {} friend __thread_id this_thread::get_id() _NOEXCEPT; friend class _LIBCPP_TYPE_VIS thread; @@ -274,7 +273,7 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id> _LIBCPP_INLINE_VISIBILITY size_t operator()(__thread_id __v) const { - return hash<pthread_t>()(__v.__id_); + return hash<__libcpp_thread_id>()(__v.__id_); } }; @@ -285,20 +284,20 @@ inline _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT { - return pthread_self(); + return __libcpp_thread_get_current_id(); } } // this_thread class _LIBCPP_TYPE_VIS thread { - pthread_t __t_; + __libcpp_thread_t __t_; thread(const thread&); thread& operator=(const thread&); public: typedef __thread_id id; - typedef pthread_t native_handle_type; + typedef __libcpp_thread_t native_handle_type; _LIBCPP_INLINE_VISIBILITY thread() _NOEXCEPT : __t_(0) {} @@ -330,7 +329,7 @@ public: void join(); void detach(); _LIBCPP_INLINE_VISIBILITY - id get_id() const _NOEXCEPT {return __t_;} + id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() _NOEXCEPT {return __t_;} @@ -339,21 +338,21 @@ public: #ifndef _LIBCPP_HAS_NO_VARIADICS -template <class _Fp, class ..._Args, size_t ..._Indices> +template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> inline _LIBCPP_INLINE_VISIBILITY void -__thread_execute(tuple<_Fp, _Args...>& __t, __tuple_indices<_Indices...>) +__thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) { - __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); + __invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); } template <class _Fp> -void* -__thread_proxy(void* __vp) +void* __thread_proxy(void* __vp) { - __thread_local_data().reset(new __thread_struct); + // _Fp = std::tuple< unique_ptr<__thread_struct>, Functor, Args...> std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); - typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; + __thread_local_data().reset(_VSTD::get<0>(*__p).release()); + typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; __thread_execute(*__p, _Index()); return nullptr; } @@ -363,10 +362,14 @@ template <class _Fp, class ..._Args, > thread::thread(_Fp&& __f, _Args&&... __args) { - typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; - _VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)), - __decay_copy(_VSTD::forward<_Args>(__args))...)); - int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get()); + typedef unique_ptr<__thread_struct> _TSPtr; + _TSPtr __tsp(new __thread_struct); + typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; + _VSTD::unique_ptr<_Gp> __p( + new _Gp(std::move(__tsp), + __decay_copy(_VSTD::forward<_Fp>(__f)), + __decay_copy(_VSTD::forward<_Args>(__args))...)); + int __ec = __libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); if (__ec == 0) __p.release(); else @@ -376,22 +379,34 @@ thread::thread(_Fp&& __f, _Args&&... __args) #else // _LIBCPP_HAS_NO_VARIADICS template <class _Fp> -void* -__thread_proxy(void* __vp) +struct __thread_invoke_pair { + // This type is used to pass memory for thread local storage and a functor + // to a newly created thread because std::pair doesn't work with + // std::unique_ptr in C++03. + __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} + unique_ptr<__thread_struct> __tsp_; + _Fp __fn_; +}; + +template <class _Fp> +void* __thread_proxy_cxx03(void* __vp) { - __thread_local_data().reset(new __thread_struct); std::unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); - (*__p)(); + __thread_local_data().reset(__p->__tsp_.release()); + (__p->__fn_)(); return nullptr; } template <class _Fp> thread::thread(_Fp __f) { - std::unique_ptr<_Fp> __p(new _Fp(__f)); - int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get()); + + typedef __thread_invoke_pair<_Fp> _InvokePair; + typedef std::unique_ptr<_InvokePair> _PairPtr; + _PairPtr __pp(new _InvokePair(__f)); + int __ec = __libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); if (__ec == 0) - __p.release(); + __pp.release(); else __throw_system_error(__ec, "thread constructor failed"); } @@ -464,7 +479,7 @@ sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) } inline _LIBCPP_INLINE_VISIBILITY -void yield() _NOEXCEPT {sched_yield();} +void yield() _NOEXCEPT {__libcpp_thread_yield();} } // this_thread diff --git a/contrib/libc++/include/tuple b/contrib/libc++/include/tuple index cb1e27d..744a3ff 100644 --- a/contrib/libc++/include/tuple +++ b/contrib/libc++/include/tuple @@ -76,10 +76,18 @@ template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14 template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14 template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14 template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14 - + +// [tuple.apply], calling a function with a tuple of arguments: +template <class F, class Tuple> + constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17 +template <class T, class Tuple> + constexpr T make_from_tuple(Tuple&& t); // C++17 + // 20.4.1.4, tuple helper classes: template <class T> class tuple_size; // undefined template <class... T> class tuple_size<tuple<T...>>; +template <class T> + constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17 template <size_t I, class T> class tuple_element; // undefined template <size_t I, class... T> class tuple_element<I, tuple<T...>>; template <size_t I, class T> @@ -379,10 +387,8 @@ template <class ..._Tp> _LIBCPP_INLINE_VISIBILITY void __swallow(_Tp&&...) _NOEXCEPT {} -template <bool ..._Pred> -struct __all - : is_same<__all<_Pred...>, __all<(_Pred, true)...>> -{ }; +template <class ..._Tp> +struct __lazy_all : __all<_Tp::value...> {}; template <class _Tp> struct __all_default_constructible; @@ -446,7 +452,7 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> template <class _Alloc, class _Tuple, class = typename enable_if < - __tuple_convertible<_Tuple, tuple<_Tp...> >::value + __tuple_constructible<_Tuple, tuple<_Tp...> >::value >::type > _LIBCPP_INLINE_VISIBILITY @@ -499,6 +505,28 @@ 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 { @@ -506,6 +534,118 @@ class _LIBCPP_TYPE_VIS_ONLY tuple base base_; + template <class ..._Args> + struct _PackExpandsToThisTuple : false_type {}; + + template <class _Arg> + struct _PackExpandsToThisTuple<_Arg> + : is_same<typename __uncvref<_Arg>::type, tuple> {}; + + template <bool _MaybeEnable, class _Dummy = void> + struct _CheckArgsConstructor : __check_tuple_constructor_fail {}; + + template <class _Dummy> + struct _CheckArgsConstructor<true, _Dummy> + { + template <class ..._Args> + static constexpr bool __enable_explicit() { + return + __tuple_constructible< + tuple<_Args...>, + typename __make_tuple_types<tuple, + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value && + !__tuple_convertible< + tuple<_Args...>, + typename __make_tuple_types<tuple, + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value && + __all_default_constructible< + typename __make_tuple_types<tuple, sizeof...(_Tp), + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value; + } + + template <class ..._Args> + static constexpr bool __enable_implicit() { + return + __tuple_convertible< + tuple<_Args...>, + typename __make_tuple_types<tuple, + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value && + __all_default_constructible< + typename __make_tuple_types<tuple, sizeof...(_Tp), + sizeof...(_Args) < sizeof...(_Tp) ? + sizeof...(_Args) : + sizeof...(_Tp)>::type + >::value; + } + }; + + template <bool _MaybeEnable, + bool = sizeof...(_Tp) == 1, + class _Dummy = void> + struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {}; + + template <class _Dummy> + struct _CheckTupleLikeConstructor<true, false, _Dummy> + { + template <class _Tuple> + static constexpr bool __enable_implicit() { + return __tuple_convertible<_Tuple, tuple>::value; + } + + template <class _Tuple> + static constexpr bool __enable_explicit() { + return __tuple_constructible<_Tuple, tuple>::value + && !__tuple_convertible<_Tuple, tuple>::value; + } + }; + + template <class _Dummy> + struct _CheckTupleLikeConstructor<true, true, _Dummy> + { + // This trait is used to disable the tuple-like constructor when + // the UTypes... constructor should be selected instead. + // See LWG issue #2549. + template <class _Tuple> + using _PreferTupleLikeConstructor = __lazy_or< + // Don't attempt the two checks below if the tuple we are given + // has the same type as this tuple. + is_same<typename __uncvref<_Tuple>::type, tuple>, + __lazy_and< + __lazy_not<is_constructible<_Tp..., _Tuple>>, + __lazy_not<is_convertible<_Tuple, _Tp...>> + > + >; + + template <class _Tuple> + static constexpr bool __enable_implicit() { + return __lazy_and< + __tuple_convertible<_Tuple, tuple>, + _PreferTupleLikeConstructor<_Tuple> + >::value; + } + + template <class _Tuple> + static constexpr bool __enable_explicit() { + return __lazy_and< + __tuple_constructible<_Tuple, tuple>, + _PreferTupleLikeConstructor<_Tuple>, + __lazy_not<__tuple_convertible<_Tuple, tuple>> + >::value; + } + }; + template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -523,8 +663,30 @@ public: _LIBCPP_CONSTEXPR tuple() _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} + template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if< + __lazy_and< + is_same<allocator_arg_t, _AllocArgT>, + __lazy_all<__dependent_type<is_default_constructible<_Tp>, _Dummy>...> + >::value + >::type> + _LIBCPP_INLINE_VISIBILITY + tuple(_AllocArgT, _Alloc const& __a) + : base_(allocator_arg_t(), __a, + __tuple_indices<>(), __tuple_types<>(), + typename __make_tuple_indices<sizeof...(_Tp), 0>::type(), + __tuple_types<_Tp...>()) {} + + template <bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_implicit<_Tp const&...>(), + bool + >::type = false + > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) + tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), typename __make_tuple_indices<0>::type(), @@ -532,8 +694,54 @@ public: __t... ) {} - template <class _Alloc> + template <bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_explicit<_Tp const&...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) + : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), + typename __make_tuple_indices<0>::type(), + typename __make_tuple_types<tuple, 0>::type(), + __t... + ) {} + + template <class _Alloc, bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_implicit<_Tp const&...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) + : base_(allocator_arg_t(), __a, + typename __make_tuple_indices<sizeof...(_Tp)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), + typename __make_tuple_indices<0>::type(), + typename __make_tuple_types<tuple, 0>::type(), + __t... + ) {} + + template <class _Alloc, bool _Dummy = true, + typename enable_if + < + _CheckArgsConstructor< + _Dummy + >::template __enable_explicit<_Tp const&...>(), + bool + >::type = false + > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) : base_(allocator_arg_t(), __a, typename __make_tuple_indices<sizeof...(_Tp)>::type(), @@ -546,21 +754,10 @@ public: template <class ..._Up, typename enable_if < - sizeof...(_Up) <= sizeof...(_Tp) && - __tuple_convertible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - __all_default_constructible< - typename __make_tuple_types<tuple, sizeof...(_Tp), - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value, + _CheckArgsConstructor< + sizeof...(_Up) <= sizeof...(_Tp) + && !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_implicit<_Up...>(), bool >::type = false > @@ -584,31 +781,12 @@ public: template <class ..._Up, typename enable_if < - sizeof...(_Up) <= sizeof...(_Tp) && - __tuple_constructible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - !__tuple_convertible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - __all_default_constructible< - typename __make_tuple_types<tuple, sizeof...(_Tp), - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value, + _CheckArgsConstructor< + sizeof...(_Up) <= sizeof...(_Tp) + && !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_explicit<_Up...>(), bool - >::type =false + >::type = false > _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit @@ -629,26 +807,36 @@ public: _VSTD::forward<_Up>(__u)...) {} template <class _Alloc, class ..._Up, - class = typename enable_if + typename enable_if < - sizeof...(_Up) <= sizeof...(_Tp) && - __tuple_convertible - < - tuple<_Up...>, - typename __make_tuple_types<tuple, - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value && - __all_default_constructible< - typename __make_tuple_types<tuple, sizeof...(_Tp), - sizeof...(_Up) < sizeof...(_Tp) ? - sizeof...(_Up) : - sizeof...(_Tp)>::type - >::value - >::type + _CheckArgsConstructor< + sizeof...(_Up) == sizeof...(_Tp) && + !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_implicit<_Up...>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) + : base_(allocator_arg_t(), __a, + typename __make_tuple_indices<sizeof...(_Up)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), + typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), + typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), + _VSTD::forward<_Up>(__u)...) {} + + template <class _Alloc, class ..._Up, + typename enable_if + < + _CheckArgsConstructor< + sizeof...(_Up) == sizeof...(_Tp) && + !_PackExpandsToThisTuple<_Up...>::value + >::template __enable_explicit<_Up...>(), + bool + >::type = false > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) : base_(allocator_arg_t(), __a, typename __make_tuple_indices<sizeof...(_Up)>::type(), @@ -660,7 +848,10 @@ public: template <class _Tuple, typename enable_if < - __tuple_convertible<_Tuple, tuple>::value, + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + && !_PackExpandsToThisTuple<_Tuple>::value + >::template __enable_implicit<_Tuple>(), bool >::type = false > @@ -671,8 +862,10 @@ public: template <class _Tuple, typename enable_if < - __tuple_constructible<_Tuple, tuple>::value && - !__tuple_convertible<_Tuple, tuple>::value, + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + && !_PackExpandsToThisTuple<_Tuple>::value + >::template __enable_explicit<_Tuple>(), bool >::type = false > @@ -682,12 +875,29 @@ public: : base_(_VSTD::forward<_Tuple>(__t)) {} template <class _Alloc, class _Tuple, - class = typename enable_if + typename enable_if < - __tuple_convertible<_Tuple, tuple>::value - >::type + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + >::template __enable_implicit<_Tuple>(), + bool + >::type = false + > + _LIBCPP_INLINE_VISIBILITY + tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) + : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} + + template <class _Alloc, class _Tuple, + typename enable_if + < + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + >::template __enable_explicit<_Tuple>(), + bool + >::type = false > _LIBCPP_INLINE_VISIBILITY + explicit tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} @@ -784,39 +994,44 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT } #if _LIBCPP_STD_VER > 11 -// get by type -template <typename _T1, size_t _Idx, typename... _Args> -struct __find_exactly_one_t_helper; - -// -- find exactly one -template <typename _T1, size_t _Idx, typename... _Args> -struct __find_exactly_one_t_checker { - static constexpr size_t value = _Idx; -// Check the rest of the list to make sure there's only one - static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" ); - }; +namespace __find_detail { -template <typename _T1, size_t _Idx> -struct __find_exactly_one_t_helper <_T1, _Idx> { - static constexpr size_t value = -1; - }; +static constexpr size_t __not_found = -1; +static constexpr size_t __ambiguous = __not_found - 1; -template <typename _T1, size_t _Idx, typename _Head, typename... _Args> -struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> { - static constexpr size_t value = - std::conditional< - std::is_same<_T1, _Head>::value, - __find_exactly_one_t_checker<_T1, _Idx, _Args...>, - __find_exactly_one_t_helper <_T1, _Idx+1, _Args...> - >::type::value; - }; +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { + return !__matches ? __res : + (__res == __not_found ? __curr_i : __ambiguous); +} + +template <size_t _Nx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { + return __i == _Nx ? __not_found : + __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]); +} + +template <class _T1, class ..._Args> +struct __find_exactly_one_checked { + static constexpr bool __matches[] = {is_same<_T1, _Args>::value...}; + static constexpr size_t value = __find_detail::__find_idx(0, __matches); + static_assert (value != __not_found, "type not found in type list" ); + static_assert(value != __ambiguous,"type occurs more than once in type list"); +}; + +template <class _T1> +struct __find_exactly_one_checked<_T1> { + static_assert(!is_same<_T1, _T1>::value, "type not in empty type list"); +}; + +} // namespace __find_detail; template <typename _T1, typename... _Args> -struct __find_exactly_one_t { - static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value; - static_assert ( value != -1, "type not found in type list" ); - }; +struct __find_exactly_one_t + : public __find_detail::__find_exactly_one_checked<_T1, _Args...> { +}; template <class _T1, class... _Args> inline _LIBCPP_INLINE_VISIBILITY @@ -1154,6 +1369,50 @@ pair<_T1, _T2>::pair(piecewise_construct_t, #endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +constexpr size_t tuple_size_v = tuple_size<_Tp>::value; + +#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; } + +template <class _Fn, class _Tuple, size_t ..._Id> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, + __tuple_indices<_Id...>) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__invoke_constexpr( + _VSTD::forward<_Fn>(__f), + _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...) +) + +template <class _Fn, class _Tuple> +inline _LIBCPP_INLINE_VISIBILITY +constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__apply_tuple_impl( + _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), + typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) +) + +template <class _Tp, class _Tuple, size_t... _Idx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>) +_LIBCPP_NOEXCEPT_RETURN( + _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...) +) + +template <class _Tp, class _Tuple> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp make_from_tuple(_Tuple&& __t) +_LIBCPP_NOEXCEPT_RETURN( + _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t), + typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{}) +) + +#undef _LIBCPP_NOEXCEPT_RETURN + +#endif // _LIBCPP_STD_VER > 14 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TUPLE diff --git a/contrib/libc++/include/type_traits b/contrib/libc++/include/type_traits index b7adfeb..821a73c 100644 --- a/contrib/libc++/include/type_traits +++ b/contrib/libc++/include/type_traits @@ -105,6 +105,8 @@ namespace std template <class T, class U> struct is_assignable; template <class T> struct is_copy_assignable; template <class T> struct is_move_assignable; + template <class T, class U> struct is_swappable_with; // C++17 + template <class T> struct is_swappable; // C++17 template <class T> struct is_destructible; template <class T, class... Args> struct is_trivially_constructible; @@ -123,6 +125,8 @@ namespace std template <class T, class U> struct is_nothrow_assignable; template <class T> struct is_nothrow_copy_assignable; template <class T> struct is_nothrow_move_assignable; + template <class T, class U> struct is_nothrow_swappable_with; // C++17 + template <class T> struct is_nothrow_swappable; // C++17 template <class T> struct is_nothrow_destructible; template <class T> struct has_virtual_destructor; @@ -132,6 +136,14 @@ namespace std template <class Base, class Derived> struct is_base_of; template <class From, class To> struct is_convertible; + template <class, class R = void> struct is_callable; // not defined + template <class Fn, class... ArgTypes, class R> + struct is_callable<Fn(ArgTypes...), R>; + + template <class, class R = void> struct is_nothrow_callable; // not defined + template <class Fn, class... ArgTypes, class R> + struct is_nothrow_callable<Fn(ArgTypes...), R>; + // Alignment properties and transformations: template <class T> struct alignment_of; template <size_t Len, size_t Align = most_stringent_alignment_requirement> @@ -292,6 +304,10 @@ namespace std = is_copy_assignable<T>::value; // C++17 template <class T> constexpr bool is_move_assignable_v = is_move_assignable<T>::value; // C++17 + template <class T, class U> constexpr bool is_swappable_with_v + = is_swappable_with<T, U>::value; // C++17 + template <class T> constexpr bool is_swappable_v + = is_swappable<T>::value; // C++17 template <class T> constexpr bool is_destructible_v = is_destructible<T>::value; // C++17 template <class T, class... Args> constexpr bool is_trivially_constructible_v @@ -324,6 +340,10 @@ namespace std = is_nothrow_copy_assignable<T>::value; // C++17 template <class T> constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<T>::value; // C++17 + template <class T, class U> constexpr bool is_nothrow_swappable_with_v + = is_nothrow_swappable_with<T, U>::value; // C++17 + template <class T> constexpr bool is_nothrow_swappable_v + = is_nothrow_swappable<T>::value; // C++17 template <class T> constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<T>::value; // C++17 template <class T> constexpr bool has_virtual_destructor_v @@ -344,6 +364,10 @@ namespace std = is_base_of<Base, Derived>::value; // C++17 template <class From, class To> constexpr bool is_convertible_v = is_convertible<From, To>::value; // C++17 + template <class T, class R = void> constexpr bool is_callable_v + = is_callable<T, R>::value; // C++17 + template <class T, class R = void> constexpr bool is_nothrow_callable_v + = is_nothrow_callable<T, R>::value; // C++17 // [meta.logical], logical operator traits: template<class... B> struct conjunction; // C++17 @@ -368,6 +392,10 @@ namespace std _LIBCPP_BEGIN_NAMESPACE_STD +template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; +template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper; +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY hash; + template <class> struct __void_t { typedef void type; }; @@ -397,15 +425,29 @@ template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp #endif // addressof +#if __has_builtin(__builtin_addressof) template <class _Tp> -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_CONSTEXPR_AFTER_CXX14 +_LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY +_Tp* +addressof(_Tp& __x) _NOEXCEPT +{ + return __builtin_addressof(__x); +} + +#else + +template <class _Tp> +inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY _Tp* addressof(_Tp& __x) _NOEXCEPT { return (_Tp*)&reinterpret_cast<const volatile char&>(__x); } +#endif // __has_builtin(__builtin_addressof) + #if defined(_LIBCPP_HAS_OBJC_ARC) && !defined(_LIBCPP_PREDEFINED_OBJC_ARC_ADDRESSOF) // Objective-C++ Automatic Reference Counting uses qualified pointers // that require special addressof() signatures. When @@ -957,6 +999,19 @@ template <class _Tp> _LIBCPP_CONSTEXPR bool is_compound_v = is_compound<_Tp>::value; #endif + +// __is_referenceable [defns.referenceable] + +struct __is_referenceable_impl { + template <class _Tp> static _Tp& __test(int); + template <class _Tp> static __two __test(...); +}; + +template <class _Tp> +struct __is_referenceable : integral_constant<bool, + !is_same<decltype(__is_referenceable_impl::__test<_Tp>(0)), __two>::value> {}; + + // add_const template <class _Tp, bool = is_reference<_Tp>::value || @@ -1014,12 +1069,11 @@ template <class _Tp> using remove_reference_t = typename remove_reference<_Tp>:: // add_lvalue_reference -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference {typedef _Tp& type;}; -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<_Tp&> {typedef _Tp& type;}; // for older compiler -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<void> {typedef void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const void> {typedef const void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<volatile void> {typedef volatile void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference<const volatile void> {typedef const volatile void type;}; +template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_lvalue_reference_impl { typedef _Tp type; }; +template <class _Tp > struct __add_lvalue_reference_impl<_Tp, true> { typedef _Tp& type; }; + +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_lvalue_reference +{typedef typename __add_lvalue_reference_impl<_Tp>::type type;}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; @@ -1027,11 +1081,11 @@ template <class _Tp> using add_lvalue_reference_t = typename add_lvalue_referenc #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference {typedef _Tp&& type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<void> {typedef void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const void> {typedef const void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<volatile void> {typedef volatile void type;}; -template <> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference<const volatile void> {typedef const volatile void type;}; +template <class _Tp, bool = __is_referenceable<_Tp>::value> struct __add_rvalue_reference_impl { typedef _Tp type; }; +template <class _Tp > struct __add_rvalue_reference_impl<_Tp, true> { typedef _Tp&& type; }; + +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_rvalue_reference +{typedef typename __add_rvalue_reference_impl<_Tp>::type type;}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; @@ -1041,8 +1095,11 @@ template <class _Tp> using add_rvalue_reference_t = typename add_rvalue_referenc #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +template <class _Tp> _Tp&& __declval(int); +template <class _Tp> _Tp __declval(long); + template <class _Tp> -typename add_rvalue_reference<_Tp>::type +decltype(_VSTD::__declval<_Tp>(0)) declval() _NOEXCEPT; #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1053,6 +1110,24 @@ declval(); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +// __uncvref + +template <class _Tp> +struct __uncvref { + typedef typename remove_cv<typename remove_reference<_Tp>::type>::type type; +}; + +template <class _Tp> +struct __unconstref { + typedef typename remove_const<typename remove_reference<_Tp>::type>::type type; +}; + +// __is_same_uncvref + +template <class _Tp, class _Up> +struct __is_same_uncvref : is_same<typename __uncvref<_Tp>::type, + typename __uncvref<_Up>::type> {}; + struct __any { __any(...); @@ -1072,8 +1147,16 @@ template <class _Tp> using remove_pointer_t = typename remove_pointer<_Tp>::type // add_pointer -template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer +template <class _Tp, + bool = __is_referenceable<_Tp>::value || + is_same<typename remove_cv<_Tp>::type, void>::value> +struct __add_pointer_impl {typedef typename remove_reference<_Tp>::type* type;}; +template <class _Tp> struct __add_pointer_impl<_Tp, false> + {typedef _Tp type;}; + +template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY add_pointer + {typedef typename __add_pointer_impl<_Tp>::type type;}; #if _LIBCPP_STD_VER > 11 template <class _Tp> using add_pointer_t = typename add_pointer<_Tp>::type; @@ -1301,16 +1384,9 @@ struct __is_convertible_test : public false_type {}; template <class _From, class _To> struct __is_convertible_test<_From, _To, - decltype(__test_convert<_To>(_VSTD::declval<_From>()))> : public true_type + decltype(_VSTD::__is_convertible_imp::__test_convert<_To>(_VSTD::declval<_From>()))> : public true_type {}; -template <class _Tp> __two __test(...); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _Tp> _Tp&& __source(); -#else -template <class _Tp> typename remove_reference<_Tp>::type& __source(); -#endif - template <class _Tp, bool _IsArray = is_array<_Tp>::value, bool _IsFunction = is_function<_Tp>::value, bool _IsVoid = is_void<_Tp>::value> @@ -1350,41 +1426,6 @@ struct __is_convertible > {}; -template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 0> : false_type {}; - -template <class _T1> struct __is_convertible<_T1, const _T1&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<const _T1, const _T1&, 1, 0> : true_type {}; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _T1> struct __is_convertible<_T1, _T1&&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<_T1, const _T1&&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<_T1, volatile _T1&&, 1, 0> : true_type {}; -template <class _T1> struct __is_convertible<_T1, const volatile _T1&&, 1, 0> : true_type {}; -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2*, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2* volatile, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*volatile>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2* const volatile, 1, 0> - : public integral_constant<bool, __is_convertible<typename remove_all_extents<_T1>::type*, _T2*const volatile>::value> {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 0> : public false_type {}; -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _T1> struct __is_convertible<_T1, _T1&&, 2, 0> : public true_type {}; -#endif -template <class _T1> struct __is_convertible<_T1, _T1&, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*const, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*volatile, 2, 0> : public true_type {}; -template <class _T1> struct __is_convertible<_T1, _T1*const volatile, 2, 0> : public true_type {}; - -template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 0> : public false_type {}; - template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {}; template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {}; template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {}; @@ -2136,7 +2177,7 @@ move(_Tp&& __t) _NOEXCEPT template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& -forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT +forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT { return static_cast<_Tp&&>(__t); } @@ -2144,9 +2185,9 @@ forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& -forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT +forward(typename remove_reference<_Tp>::type&& __t) _NOEXCEPT { - static_assert(!std::is_lvalue_reference<_Tp>::value, + static_assert(!is_lvalue_reference<_Tp>::value, "Can not forward an rvalue as an lvalue."); return static_cast<_Tp&&>(__t); } @@ -2172,7 +2213,7 @@ move(const _Tp& __t) template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY _Tp& -forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT +forward(typename remove_reference<_Tp>::type& __t) _NOEXCEPT { return __t; } @@ -2691,6 +2732,15 @@ struct __member_pointer_traits // typedef ... _FnType; }; + +template <class _DecayedFp> +struct __member_pointer_class_type {}; + +template <class _Ret, class _ClassType> +struct __member_pointer_class_type<_Ret _ClassType::*> { + typedef _ClassType type; +}; + // result_of template <class _Callable> class result_of; @@ -3918,7 +3968,12 @@ template <class _Tp> _LIBCPP_CONSTEXPR bool is_trivial_v = is_trivial<_Tp>::value; #endif -#ifndef _LIBCPP_HAS_NO_VARIADICS +template <class _Tp> struct __is_reference_wrapper_impl : public false_type {}; +template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {}; +template <class _Tp> struct __is_reference_wrapper + : public __is_reference_wrapper_impl<typename remove_cv<_Tp>::type> {}; + +#ifndef _LIBCPP_CXX03_LANG // Check for complete types @@ -4006,8 +4061,6 @@ struct __check_complete<_Rp (_Class::*)(_Param...) const volatile> { }; -#if __has_feature(cxx_reference_qualified_functions) - template <class _Rp, class _Class, class ..._Param> struct __check_complete<_Rp (_Class::*)(_Param...) &> : private __check_complete<_Class> @@ -4056,125 +4109,257 @@ struct __check_complete<_Rp (_Class::*)(_Param...) const volatile&&> { }; -#endif - template <class _Rp, class _Class> struct __check_complete<_Rp _Class::*> : private __check_complete<_Class> { }; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet1 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet2 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet3 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet4 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type> +using __enable_if_bullet5 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + +template <class _Fp, class _A0, + class _DecayFp = typename decay<_Fp>::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> +using __enable_if_bullet6 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + // __invoke forward declarations // fall back - none of the bullets +#define _LIBCPP_INVOKE_RETURN(...) \ + noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) \ + { return __VA_ARGS__; } + +template <class ..._Args> +auto __invoke(__any, _Args&& ...__args) -> __nat; + template <class ..._Args> +auto __invoke_constexpr(__any, _Args&& ...__args) -> __nat; + +// bullets 1, 2 and 3 + +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet1<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto -__invoke(__any, _Args&& ...__args) - -> __nat; +__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) -// bullets 1 and 2 +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet1<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) template <class _Fp, class _A0, class ..._Args, - class = typename enable_if - < - is_member_function_pointer<typename remove_reference<_Fp>::type>::value && - is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet2<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)); +_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...)) template <class _Fp, class _A0, class ..._Args, - class = typename enable_if - < - is_member_function_pointer<typename remove_reference<_Fp>::type>::value && - !is_base_of<typename remove_reference<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType>::type, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet2<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(_VSTD::forward<_Args>(__args)...)) + +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet3<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)); +_LIBCPP_INVOKE_RETURN(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) + +template <class _Fp, class _A0, class ..._Args, + class = __enable_if_bullet3<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) -// bullets 3 and 4 +// bullets 4, 5 and 6 template <class _Fp, class _A0, - class = typename enable_if - < - is_member_object_pointer<typename remove_reference<_Fp>::type>::value && - is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet4<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) - -> decltype(_VSTD::forward<_A0>(__a0).*__f); +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f) + +template <class _Fp, class _A0, + class = __enable_if_bullet4<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_A0>(__a0).*__f) template <class _Fp, class _A0, - class = typename enable_if - < - is_member_object_pointer<typename remove_reference<_Fp>::type>::value && - !is_base_of<typename __member_pointer_traits<typename remove_reference<_Fp>::type>::_ClassType, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY + class = __enable_if_bullet5<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _A0&& __a0) - -> decltype((*_VSTD::forward<_A0>(__a0)).*__f); +_LIBCPP_INVOKE_RETURN(__a0.get().*__f) -// bullet 5 +template <class _Fp, class _A0, + class = __enable_if_bullet5<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN(__a0.get().*__f) + +template <class _Fp, class _A0, + class = __enable_if_bullet6<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +auto +__invoke(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN((*_VSTD::forward<_A0>(__a0)).*__f) + +template <class _Fp, class _A0, + class = __enable_if_bullet6<_Fp, _A0>> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _A0&& __a0) +_LIBCPP_INVOKE_RETURN((*_VSTD::forward<_A0>(__a0)).*__f) + +// bullet 7 template <class _Fp, class ..._Args> -_LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY auto __invoke(_Fp&& __f, _Args&& ...__args) - -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)); +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) + +template <class _Fp, class ..._Args> +inline _LIBCPP_INLINE_VISIBILITY +_LIBCPP_CONSTEXPR auto +__invoke_constexpr(_Fp&& __f, _Args&& ...__args) +_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) + +#undef _LIBCPP_INVOKE_RETURN // __invokable -template <class _Fp, class ..._Args> -struct __invokable_imp +template <class _Ret, class _Fp, class ..._Args> +struct __invokable_r : private __check_complete<_Fp> { - typedef decltype( - __invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...) - ) type; - static const bool value = !is_same<type, __nat>::value; + using _Result = decltype( + _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); + + static const bool value = + conditional< + !is_same<_Result, __nat>::value, + typename conditional< + is_void<_Ret>::value, + true_type, + is_convertible<_Result, _Ret> + >::type, + false_type + >::type::value; }; template <class _Fp, class ..._Args> -struct __invokable - : public integral_constant<bool, - __invokable_imp<_Fp, _Args...>::value> -{ -}; +using __invokable = __invokable_r<void, _Fp, _Args...>; -// __invoke_of +template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args> +struct __nothrow_invokable_r_imp { + static const bool value = false; +}; -template <bool _Invokable, class _Fp, class ..._Args> -struct __invoke_of_imp // false +template <class _Ret, class _Fp, class ..._Args> +struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> { + typedef __nothrow_invokable_r_imp _ThisT; + + template <class _Tp> + static void __test_noexcept(_Tp) noexcept; + + static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( + _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...))); }; -template <class _Fp, class ..._Args> -struct __invoke_of_imp<true, _Fp, _Args...> +template <class _Ret, class _Fp, class ..._Args> +struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> { - typedef typename __invokable_imp<_Fp, _Args...>::type type; + static const bool value = noexcept( + _VSTD::__invoke(_VSTD::declval<_Fp>(), _VSTD::declval<_Args>()...)); }; +template <class _Ret, class _Fp, class ..._Args> +using __nothrow_invokable_r = + __nothrow_invokable_r_imp< + __invokable_r<_Ret, _Fp, _Args...>::value, + is_void<_Ret>::value, + _Ret, _Fp, _Args... + >; + template <class _Fp, class ..._Args> struct __invoke_of - : public __invoke_of_imp<__invokable<_Fp, _Args...>::value, _Fp, _Args...> + : public enable_if< + __invokable<_Fp, _Args...>::value, + typename __invokable_r<void, _Fp, _Args...>::_Result> { }; +// result_of + template <class _Fp, class ..._Args> class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)> : public __invoke_of<_Fp, _Args...> @@ -4185,7 +4370,39 @@ class _LIBCPP_TYPE_VIS_ONLY result_of<_Fp(_Args...)> template <class _Tp> using result_of_t = typename result_of<_Tp>::type; #endif -#endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 14 + +// is_callable + +template <class _Fn, class _Ret = void> +struct _LIBCPP_TYPE_VIS_ONLY is_callable; + +template <class _Fn, class ..._Args, class _Ret> +struct _LIBCPP_TYPE_VIS_ONLY is_callable<_Fn(_Args...), _Ret> + : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {}; + +template <class _Fn, class _Ret = void> +constexpr bool is_callable_v = is_callable<_Fn, _Ret>::value; + +// is_nothrow_callable + +template <class _Fn, class _Ret = void> +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_callable; + +template <class _Fn, class ..._Args, class _Ret> +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_callable<_Fn(_Args...), _Ret> + : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> +{}; + +template <class _Fn, class _Ret = void> +constexpr bool is_nothrow_callable_v = is_nothrow_callable<_Fn, _Ret>::value; + +#endif // _LIBCPP_STD_VER > 14 + +#endif // !defined(_LIBCPP_CXX03_LANG) + +template <class _Tp> struct __is_swappable; +template <class _Tp> struct __is_nothrow_swappable; template <class _Tp> inline _LIBCPP_INLINE_VISIBILITY @@ -4206,6 +4423,13 @@ swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && __y = _VSTD::move(__t); } +template<class _Tp, size_t _Np> +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if< + __is_swappable<_Tp>::value +>::type +swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); + template <class _ForwardIterator1, class _ForwardIterator2> inline _LIBCPP_INLINE_VISIBILITY void @@ -4221,55 +4445,108 @@ iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) namespace __detail { +// ALL generic swap overloads MUST already have a declaration available at this point. -using _VSTD::swap; -__nat swap(__any, __any); - -template <class _Tp> -struct __swappable +template <class _Tp, class _Up = _Tp, + bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value> +struct __swappable_with { - typedef decltype(swap(_VSTD::declval<_Tp&>(), _VSTD::declval<_Tp&>())) type; - static const bool value = !is_same<type, __nat>::value; + template <class _LHS, class _RHS> + static decltype(swap(_VSTD::declval<_LHS>(), _VSTD::declval<_RHS>())) + __test_swap(int); + template <class, class> + static __nat __test_swap(long); + + // Extra parens are needed for the C++03 definition of decltype. + typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; + typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; + + static const bool value = !is_same<__swap1, __nat>::value + && !is_same<__swap2, __nat>::value; }; +template <class _Tp, class _Up> +struct __swappable_with<_Tp, _Up, false> : false_type {}; + +template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value> +struct __nothrow_swappable_with { + static const bool value = +#ifndef _LIBCPP_HAS_NO_NOEXCEPT + noexcept(swap(_VSTD::declval<_Tp>(), _VSTD::declval<_Up>())) + && noexcept(swap(_VSTD::declval<_Up>(), _VSTD::declval<_Tp>())); +#else + false; +#endif +}; + +template <class _Tp, class _Up> +struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; + } // __detail template <class _Tp> struct __is_swappable - : public integral_constant<bool, __detail::__swappable<_Tp>::value> + : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> { }; -#if __has_feature(cxx_noexcept) || (_GNUC_VER >= 407 && __cplusplus >= 201103L) - -template <bool, class _Tp> -struct __is_nothrow_swappable_imp - : public integral_constant<bool, noexcept(swap(_VSTD::declval<_Tp&>(), - _VSTD::declval<_Tp&>()))> +template <class _Tp> +struct __is_nothrow_swappable + : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> { }; -template <class _Tp> -struct __is_nothrow_swappable_imp<false, _Tp> - : public false_type +#if _LIBCPP_STD_VER > 14 + +template <class _Tp, class _Up> +struct _LIBCPP_TYPE_VIS_ONLY is_swappable_with + : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> { }; template <class _Tp> -struct __is_nothrow_swappable - : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp> +struct _LIBCPP_TYPE_VIS_ONLY is_swappable + : public conditional< + __is_referenceable<_Tp>::value, + is_swappable_with< + typename add_lvalue_reference<_Tp>::type, + typename add_lvalue_reference<_Tp>::type>, + false_type + >::type { }; -#else // __has_feature(cxx_noexcept) +template <class _Tp, class _Up> +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_swappable_with + : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> +{ +}; template <class _Tp> -struct __is_nothrow_swappable - : public false_type +struct _LIBCPP_TYPE_VIS_ONLY is_nothrow_swappable + : public conditional< + __is_referenceable<_Tp>::value, + is_nothrow_swappable_with< + typename add_lvalue_reference<_Tp>::type, + typename add_lvalue_reference<_Tp>::type>, + false_type + >::type { }; -#endif // __has_feature(cxx_noexcept) +template <class _Tp, class _Up> +constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; + +template <class _Tp> +constexpr bool is_swappable_v = is_swappable<_Tp>::value; + +template <class _Tp, class _Up> +constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Tp, _Up>::value; + +template <class _Tp> +constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; + +#endif // _LIBCPP_STD_VER > 14 #ifdef _LIBCPP_UNDERLYING_TYPE @@ -4296,7 +4573,7 @@ struct underlying_type #endif // _LIBCPP_UNDERLYING_TYPE -template <class _Tp, bool = std::is_enum<_Tp>::value> +template <class _Tp, bool = is_enum<_Tp>::value> struct __sfinae_underlying_type { typedef typename underlying_type<_Tp>::type type; @@ -4389,6 +4666,39 @@ template<class _Tp> constexpr bool negation_v = negation<_Tp>::value; # endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_STD_VER > 14 +// These traits are used in __tree and __hash_table +#ifndef _LIBCPP_CXX03_LANG +struct __extract_key_fail_tag {}; +struct __extract_key_self_tag {}; +struct __extract_key_first_tag {}; + +template <class _ValTy, class _Key, + class _RawValTy = typename __unconstref<_ValTy>::type> +struct __can_extract_key + : conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag, + __extract_key_fail_tag>::type {}; + +template <class _Pair, class _Key, class _First, class _Second> +struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> + : conditional<is_same<typename remove_const<_First>::type, _Key>::value, + __extract_key_first_tag, __extract_key_fail_tag>::type {}; + +// __can_extract_map_key uses true_type/false_type instead of the tags. +// It returns true if _Key != _ContainerValueTy (the container is a map not a set) +// and _ValTy == _Key. +template <class _ValTy, class _Key, class _ContainerValueTy, + class _RawValTy = typename __unconstref<_ValTy>::type> +struct __can_extract_map_key + : integral_constant<bool, is_same<_RawValTy, _Key>::value> {}; + +// This specialization returns __extract_key_fail_tag for non-map containers +// because _Key == _ContainerValueTy +template <class _ValTy, class _Key, class _RawValTy> +struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> + : false_type {}; + +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TYPE_TRAITS diff --git a/contrib/libc++/include/unordered_map b/contrib/libc++/include/unordered_map index 85a54a7..8d7edaf 100644 --- a/contrib/libc++/include/unordered_map +++ b/contrib/libc++/include/unordered_map @@ -369,6 +369,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> #include <__hash_table> #include <functional> #include <stdexcept> +#include <tuple> #include <__debug> @@ -413,7 +414,6 @@ template <class _Key, class _Cp, class _Hash> class __unordered_map_hasher<_Key, _Cp, _Hash, false> { _Hash __hash_; - public: _LIBCPP_INLINE_VISIBILITY __unordered_map_hasher() @@ -487,7 +487,6 @@ template <class _Key, class _Cp, class _Pred> class __unordered_map_equal<_Key, _Cp, _Pred, false> { _Pred __pred_; - public: _LIBCPP_INLINE_VISIBILITY __unordered_map_equal() @@ -531,12 +530,11 @@ class __hash_map_node_destructor { typedef _Alloc allocator_type; typedef allocator_traits<allocator_type> __alloc_traits; - typedef typename __alloc_traits::value_type::value_type value_type; + public: - typedef typename __alloc_traits::pointer pointer; + + typedef typename __alloc_traits::pointer pointer; private: - typedef typename value_type::value_type::first_type first_type; - typedef typename value_type::value_type::second_type second_type; allocator_type& __na_; @@ -586,8 +584,7 @@ public: } }; -#if __cplusplus >= 201103L - +#ifndef _LIBCPP_CXX03_LANG template <class _Key, class _Tp> union __hash_value_type { @@ -599,19 +596,6 @@ union __hash_value_type value_type __cc; __nc_value_type __nc; - template <class ..._Args> - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(_Args&& ...__args) - : __cc(std::forward<_Args>(__args)...) {} - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(const __hash_value_type& __v) - : __cc(__v.__cc) {} - - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(__hash_value_type&& __v) - : __nc(_VSTD::move(__v.__nc)) {} - _LIBCPP_INLINE_VISIBILITY __hash_value_type& operator=(const __hash_value_type& __v) {__nc = __v.__cc; return *this;} @@ -620,8 +604,23 @@ union __hash_value_type __hash_value_type& operator=(__hash_value_type&& __v) {__nc = _VSTD::move(__v.__nc); return *this;} + template <class _ValueTp, + class = typename enable_if< + __is_same_uncvref<_ValueTp, value_type>::value + >::type + > _LIBCPP_INLINE_VISIBILITY - ~__hash_value_type() {__cc.~value_type();} + __hash_value_type& operator=(_ValueTp&& __v) { + __nc = _VSTD::forward<_ValueTp>(__v); return *this; + } + +private: + __hash_value_type(const __hash_value_type& __v) = delete; + __hash_value_type(__hash_value_type&& __v) = delete; + template <class ..._Args> + explicit __hash_value_type(_Args&& ...__args) = delete; + + ~__hash_value_type() = delete; }; #else @@ -635,18 +634,8 @@ struct __hash_value_type value_type __cc; - _LIBCPP_INLINE_VISIBILITY - __hash_value_type() {} - - template <class _A0> - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(const _A0& __a0) - : __cc(__a0) {} - - template <class _A0, class _A1> - _LIBCPP_INLINE_VISIBILITY - __hash_value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} +private: + ~__hash_value_type(); }; #endif @@ -656,15 +645,14 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator { _HashIterator __i_; - typedef const typename _HashIterator::value_type::value_type::first_type key_type; - typedef typename _HashIterator::value_type::value_type::second_type mapped_type; + typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; + public: typedef forward_iterator_tag iterator_category; - typedef pair<key_type, mapped_type> value_type; - typedef typename _HashIterator::difference_type difference_type; + typedef typename _NodeTypes::__map_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; typedef value_type& reference; - typedef typename __rebind_pointer<typename _HashIterator::pointer, value_type>::type - pointer; + typedef typename _NodeTypes::__map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_map_iterator() _NOEXCEPT {} @@ -706,15 +694,14 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator { _HashIterator __i_; - typedef const typename _HashIterator::value_type::value_type::first_type key_type; - typedef typename _HashIterator::value_type::value_type::second_type mapped_type; + typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; + public: typedef forward_iterator_tag iterator_category; - typedef pair<key_type, mapped_type> value_type; - typedef typename _HashIterator::difference_type difference_type; + typedef typename _NodeTypes::__map_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; typedef const value_type& reference; - typedef typename __rebind_pointer<typename _HashIterator::pointer, const value_type>::type - pointer; + typedef typename _NodeTypes::__const_map_value_type_pointer pointer; _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator() _NOEXCEPT {} @@ -785,6 +772,7 @@ private: __table __table_; + typedef typename __table::_NodeTypes _NodeTypes; typedef typename __table::__node_pointer __node_pointer; typedef typename __table::__node_const_pointer __node_const_pointer; typedef typename __table::__node_traits __node_traits; @@ -793,11 +781,14 @@ private: typedef __hash_map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; typedef allocator_traits<allocator_type> __alloc_traits; + + static_assert((is_same<typename __table::__container_value_type, value_type>::value), ""); + static_assert((is_same<typename __table::__node_value_type, __value_type>::value), ""); public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; + typedef typename __table::size_type size_type; + typedef typename __table::difference_type difference_type; typedef __hash_map_iterator<typename __table::iterator> iterator; typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; @@ -828,10 +819,12 @@ public: size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY explicit unordered_map(const allocator_type& __a); unordered_map(const unordered_map& __u); unordered_map(const unordered_map& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_map(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_map(unordered_map&& __u, const allocator_type& __a); @@ -872,7 +865,7 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(const unordered_map& __u) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else if (this != &__u) { @@ -887,10 +880,12 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY unordered_map& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -918,189 +913,162 @@ public: _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return __table_.end();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> insert(const value_type& __x) + {return __table_.__insert_unique(__x);} - template <class... _Args> - pair<iterator, bool> emplace(_Args&&... __args); + iterator insert(const_iterator __p, const value_type& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _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"); +#endif + return insert(__x).first; + } - template <class... _Args> + template <class _InputIterator> _LIBCPP_INLINE_VISIBILITY + void insert(_InputIterator __first, _InputIterator __last); + +#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY + void insert(initializer_list<value_type> __il) + {insert(__il.begin(), __il.end());} +#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> insert(value_type&& __x) + {return __table_.__insert_unique(_VSTD::move(__x));} + + iterator insert(const_iterator __p, value_type&& __x) { #if _LIBCPP_DEBUG_LEVEL >= 2 - iterator emplace_hint(const_iterator __p, _Args&&... __args) - { - _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"); - return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; - } -#else - iterator emplace_hint(const_iterator, _Args&&... __args) - {return emplace(_VSTD::forward<_Args>(__args)...).first;} + _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"); #endif -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY - pair<iterator, bool> insert(const value_type& __x) - {return __table_.__insert_unique(__x);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + return __table_.__insert_unique(_VSTD::move(__x)).first; + } + template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> insert(_Pp&& __x) {return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 - iterator insert(const_iterator __p, const value_type& __x) - { - _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"); - return insert(__x).first; - } -#else - iterator insert(const_iterator, const value_type& __x) - {return insert(__x).first;} -#endif -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _Pp, class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> _LIBCPP_INLINE_VISIBILITY -#if _LIBCPP_DEBUG_LEVEL >= 2 iterator insert(const_iterator __p, _Pp&& __x) { +#if _LIBCPP_DEBUG_LEVEL >= 2 _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"); +#endif return insert(_VSTD::forward<_Pp>(__x)).first; } -#else - iterator insert(const_iterator, _Pp&& __x) - {return insert(_VSTD::forward<_Pp>(__x)).first;} -#endif -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _InputIterator> - void insert(_InputIterator __first, _InputIterator __last); -#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + + template <class... _Args> _LIBCPP_INLINE_VISIBILITY - void insert(initializer_list<value_type> __il) - {insert(__il.begin(), __il.end());} -#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + pair<iterator, bool> emplace(_Args&&... __args) { + return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator emplace_hint(const_iterator __p, _Args&&... __args) { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _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"); +#endif + return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; + } + +#endif // _LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER > 14 -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS template <class... _Args> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) { - iterator __p = __table_.find(__k); - if ( __p != end()) - return _VSTD::make_pair(__p, false); - else - return _VSTD::make_pair( - emplace_hint(__p, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)), - true); + return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(__k), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class... _Args> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) { - iterator __p = __table_.find(__k); - if ( __p != end()) - return _VSTD::make_pair(__p, false); - else - return _VSTD::make_pair( - emplace_hint(__p, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)), - true); + return __table_.__emplace_unique_key_args(__k, _VSTD::piecewise_construct, + _VSTD::forward_as_tuple(_VSTD::move(__k)), + _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } template <class... _Args> _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) { - iterator __p = __table_.find(__k); - if ( __p != end()) - return __p; - else - return emplace_hint(__h, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(__k), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); +#endif + return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; } template <class... _Args> _LIBCPP_INLINE_VISIBILITY iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) { - iterator __p = __table_.find(__k); - if ( __p != end()) - return __p; - else - return emplace_hint(__h, - _VSTD::piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__k)), - _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this, + "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" + " referring to this unordered_map"); +#endif + return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; } template <class _Vp> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) { - iterator __p = __table_.find(__k); - if ( __p != end()) - { - __p->second = _VSTD::move(__v); - return _VSTD::make_pair(__p, false); + pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, + __k, _VSTD::forward<_Vp>(__v)); + if (!__res.second) { + __res.first->second = _VSTD::forward<_Vp>(__v); } - return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true); + return __res; } - + template <class _Vp> _LIBCPP_INLINE_VISIBILITY pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) { - iterator __p = __table_.find(__k); - if ( __p != end()) - { - __p->second = _VSTD::move(__v); - return _VSTD::make_pair(__p, false); + pair<iterator, bool> __res = __table_.__emplace_unique_key_args(__k, + _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); + if (!__res.second) { + __res.first->second = _VSTD::forward<_Vp>(__v); } - return _VSTD::make_pair(emplace_hint(__p, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v)), true); + return __res; } template <class _Vp> _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) { - iterator __p = __table_.find(__k); - if ( __p != end()) - { - __p->second = _VSTD::move(__v); - return __p; - } - return emplace_hint(__h, __k, _VSTD::forward<_Vp>(__v)); + 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 __p = __table_.find(__k); - if ( __p != end()) - { - __p->second = _VSTD::move(__v); - return __p; - } - return emplace_hint(__h, _VSTD::forward<key_type>(__k), _VSTD::forward<_Vp>(__v)); + return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; } #endif -#endif -#endif _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} @@ -1140,7 +1108,7 @@ public: {return __table_.__equal_range_unique(__k);} mapped_type& operator[](const key_type& __k); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#ifndef _LIBCPP_CXX03_LANG mapped_type& operator[](key_type&& __k); #endif @@ -1196,18 +1164,10 @@ public: #endif // _LIBCPP_DEBUG_LEVEL >= 2 private: -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder - __construct_node(_A0&& __a0); - __node_holder __construct_node_with_key(key_type&& __k); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifdef _LIBCPP_CXX03_LANG __node_holder __construct_node_with_key(const key_type& __k); +#endif }; template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1225,7 +1185,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1234,10 +1194,10 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const allocator_type& __a) - : __table_(__a) + : __table_(typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1274,7 +1234,7 @@ template <class _InputIterator> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1298,7 +1258,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( const unordered_map& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) + : __table_(__u.__table_, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1310,7 +1270,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -1325,7 +1285,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) + : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1333,10 +1293,10 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( if (__a != __u.get_allocator()) { iterator __i = __u.begin(); - while (__u.size() != 0) - __table_.__insert_unique( - _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_) - ); + while (__u.size() != 0) { + __table_.__emplace_unique(_VSTD::move( + __u.__table_.remove((__i++).__i_)->__value_.__nc)); + } } #if _LIBCPP_DEBUG_LEVEL >= 2 else @@ -1375,7 +1335,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( initializer_list<value_type> __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1389,7 +1349,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) @@ -1403,7 +1363,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( initializer_list<value_type> __il) @@ -1414,81 +1374,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node() -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(key_type&& __k) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.first), _VSTD::move(__k)); - __h.get_deleter().__first_constructed = true; - __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__cc.second)); - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0, class _A1, class ..._Args> -typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0, - _A1&& __a1, - _Args&&... __args) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class... _Args> -pair<typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator, bool> -unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; -} - -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - +#ifdef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> typename unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const key_type& __k) @@ -1501,10 +1387,11 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node_with_key(const __h.get_deleter().__second_constructed = true; return _LIBCPP_EXPLICIT_MOVE(__h); // explicitly moved for C++03 } +#endif template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -1513,6 +1400,7 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, __table_.__insert_unique(*__first); } +#ifdef _LIBCPP_CXX03_LANG template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) @@ -1525,23 +1413,27 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) __h.release(); return __r.first->second; } +#else -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> +_Tp& +unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](const key_type& __k) +{ + return __table_.__emplace_unique_key_args(__k, + std::piecewise_construct, std::forward_as_tuple(__k), + std::forward_as_tuple()).first->__cc.second; +} template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> _Tp& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&& __k) { - iterator __i = find(__k); - if (__i != end()) - return __i->second; - __node_holder __h = __construct_node_with_key(_VSTD::move(__k)); - pair<iterator, bool> __r = __table_.__node_insert_unique(__h.get()); - __h.release(); - return __r.first->second; + return __table_.__emplace_unique_key_args(__k, + std::piecewise_construct, std::forward_as_tuple(std::move(__k)), + std::forward_as_tuple()).first->__cc.second; } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // !_LIBCPP_CXX03_MODE template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> _Tp& @@ -1635,17 +1527,21 @@ private: __table __table_; + typedef typename __table::_NodeTypes _NodeTypes; typedef typename __table::__node_traits __node_traits; typedef typename __table::__node_allocator __node_allocator; typedef typename __table::__node __node; typedef __hash_map_node_destructor<__node_allocator> _Dp; typedef unique_ptr<__node, _Dp> __node_holder; typedef allocator_traits<allocator_type> __alloc_traits; + static_assert((is_same<typename __node_traits::size_type, + typename __alloc_traits::size_type>::value), + "Allocator uses different size_type for different types"); public: typedef typename __alloc_traits::pointer pointer; typedef typename __alloc_traits::const_pointer const_pointer; - typedef typename __alloc_traits::size_type size_type; - typedef typename __alloc_traits::difference_type difference_type; + typedef typename __table::size_type size_type; + typedef typename __table::difference_type difference_type; typedef __hash_map_iterator<typename __table::iterator> iterator; typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; @@ -1676,10 +1572,12 @@ public: size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); + _LIBCPP_INLINE_VISIBILITY explicit unordered_multimap(const allocator_type& __a); unordered_multimap(const unordered_multimap& __u); unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multimap(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); @@ -1721,7 +1619,7 @@ public: _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(const unordered_multimap& __u) { -#if __cplusplus >= 201103L +#ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else if (this != &__u) { @@ -1736,10 +1634,12 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY unordered_multimap& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -1767,43 +1667,55 @@ public: _LIBCPP_INLINE_VISIBILITY const_iterator cend() const _NOEXCEPT {return __table_.end();} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -#ifndef _LIBCPP_HAS_NO_VARIADICS - - template <class... _Args> - iterator emplace(_Args&&... __args); - - template <class... _Args> - iterator emplace_hint(const_iterator __p, _Args&&... __args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(_Pp&& __x) - {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY iterator insert(const_iterator __p, const value_type& __x) {return __table_.__insert_multi(__p.__i_, __x);} -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - template <class _Pp, - class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> - _LIBCPP_INLINE_VISIBILITY - iterator insert(const_iterator __p, _Pp&& __x) - {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + template <class _InputIterator> - void insert(_InputIterator __first, _InputIterator __last); + _LIBCPP_INLINE_VISIBILITY + void insert(_InputIterator __first, _InputIterator __last); + #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY void insert(initializer_list<value_type> __il) {insert(__il.begin(), __il.end());} #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));} + + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, value_type&& __x) + {return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));} + + template <class _Pp, + class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(_Pp&& __x) + {return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));} + + template <class _Pp, + class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> + _LIBCPP_INLINE_VISIBILITY + iterator insert(const_iterator __p, _Pp&& __x) + {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} + + template <class... _Args> + iterator emplace(_Args&&... __args) { + return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...); + } + + template <class... _Args> + iterator emplace_hint(const_iterator __p, _Args&&... __args) { + return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); + } +#endif // _LIBCPP_CXX03_LANG + + _LIBCPP_INLINE_VISIBILITY iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} _LIBCPP_INLINE_VISIBILITY @@ -1890,17 +1802,7 @@ public: #endif // _LIBCPP_DEBUG_LEVEL >= 2 -private: -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __node_holder __construct_node(); - template <class _A0> - __node_holder - __construct_node(_A0&& __a0); -#ifndef _LIBCPP_HAS_NO_VARIADICS - template <class _A0, class _A1, class ..._Args> - __node_holder __construct_node(_A0&& __a0, _A1&& __a1, _Args&& ...__args); -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + }; template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> @@ -1918,7 +1820,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1956,7 +1858,7 @@ template <class _InputIterator> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1966,10 +1868,10 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( } template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const allocator_type& __a) - : __table_(__a) + : __table_(typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -1991,7 +1893,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( const unordered_multimap& __u, const allocator_type& __a) - : __table_(__u.__table_, __a) + : __table_(__u.__table_, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -2003,7 +1905,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -2018,7 +1920,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u, const allocator_type& __a) - : __table_(_VSTD::move(__u.__table_), __a) + : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -2029,7 +1931,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( while (__u.size() != 0) { __table_.__insert_multi( - _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_) + _VSTD::move(__u.__table_.remove((__i++).__i_)->__value_.__nc) ); } } @@ -2070,7 +1972,7 @@ template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( initializer_list<value_type> __il, size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a) - : __table_(__hf, __eql, __a) + : __table_(__hf, __eql, typename __table::allocator_type(__a)) { #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__insert_c(this); @@ -2084,7 +1986,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) @@ -2098,7 +2000,7 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multima #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( initializer_list<value_type> __il) @@ -2109,81 +2011,11 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=( #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node() -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(_A0&& __a0) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0)); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -#ifndef _LIBCPP_HAS_NO_VARIADICS - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class _A0, class _A1, class ..._Args> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node( - _A0&& __a0, _A1&& __a1, _Args&&... __args) -{ - __node_allocator& __na = __table_.__node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _VSTD::addressof(__h->__value_), - _VSTD::forward<_A0>(__a0), _VSTD::forward<_A1>(__a1), - _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__first_constructed = true; - __h.get_deleter().__second_constructed = true; - return __h; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class... _Args> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace(_Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __table_.__node_insert_multi(__h.get()); - __h.release(); - return __r; -} - -template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> -template <class... _Args> -typename unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::iterator -unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::emplace_hint( - const_iterator __p, _Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __table_.__node_insert_multi(__p.__i_, __h.get()); - __h.release(); - return __r; -} -#endif // _LIBCPP_HAS_NO_VARIADICS -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/contrib/libc++/include/unordered_set b/contrib/libc++/include/unordered_set index f6ccdc3..fb38b64 100644 --- a/contrib/libc++/include/unordered_set +++ b/contrib/libc++/include/unordered_set @@ -404,10 +404,12 @@ public: size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} #endif + _LIBCPP_INLINE_VISIBILITY explicit unordered_set(const allocator_type& __a); unordered_set(const unordered_set& __u); unordered_set(const unordered_set& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_set(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_set(unordered_set&& __u, const allocator_type& __a); @@ -439,10 +441,12 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_set& operator=(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS + _LIBCPP_INLINE_VISIBILITY unordered_set& operator=(initializer_list<value_type> __il); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -527,6 +531,7 @@ public: #endif #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY @@ -678,7 +683,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( } template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( const allocator_type& __a) : __table_(__a) @@ -715,7 +720,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -792,7 +797,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>& unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) @@ -806,7 +811,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=(unordered_set&& __u) #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_set<_Value, _Hash, _Pred, _Alloc>& unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=( initializer_list<value_type> __il) @@ -819,7 +824,7 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::operator=( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_set<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) @@ -940,10 +945,12 @@ public: size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} #endif + _LIBCPP_INLINE_VISIBILITY explicit unordered_multiset(const allocator_type& __a); unordered_multiset(const unordered_multiset& __u); unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multiset(unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); @@ -973,6 +980,7 @@ public: return *this; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_INLINE_VISIBILITY unordered_multiset& operator=(unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif @@ -1029,6 +1037,7 @@ public: {return __table_.__insert_multi(__p, _VSTD::move(__x));} #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _InputIterator> + _LIBCPP_INLINE_VISIBILITY void insert(_InputIterator __first, _InputIterator __last); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS _LIBCPP_INLINE_VISIBILITY @@ -1181,7 +1190,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( } template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( const allocator_type& __a) : __table_(__a) @@ -1218,7 +1227,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( unordered_multiset&& __u) _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) @@ -1295,7 +1304,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template <class _Value, class _Hash, class _Pred, class _Alloc> -inline _LIBCPP_INLINE_VISIBILITY +inline unordered_multiset<_Value, _Hash, _Pred, _Alloc>& unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=( unordered_multiset&& __u) @@ -1323,7 +1332,7 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::operator=( template <class _Value, class _Hash, class _Pred, class _Alloc> template <class _InputIterator> -inline _LIBCPP_INLINE_VISIBILITY +inline void unordered_multiset<_Value, _Hash, _Pred, _Alloc>::insert(_InputIterator __first, _InputIterator __last) diff --git a/contrib/libc++/include/utility b/contrib/libc++/include/utility index c9f5785..7b978ad 100644 --- a/contrib/libc++/include/utility +++ b/contrib/libc++/include/utility @@ -82,8 +82,8 @@ struct pair is_nothrow_move_assignable<T2>::value); template <class U, class V> pair& operator=(pair<U, V>&& p); - void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && - noexcept(swap(second, p.second))); + void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> && + is_nothrow_swappable_v<T2>); }; template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14 @@ -169,7 +169,7 @@ template<size_t N> template<class... T> using index_sequence_for = make_index_sequence<sizeof...(T)>; -template<class T, class U=T> +template<class T, class U=T> T exchange(T& obj, U&& new_value); } // std @@ -178,6 +178,7 @@ template<class T, class U=T> #include <__config> #include <__tuple> #include <type_traits> +#include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -224,10 +225,6 @@ operator>=(const _Tp& __x, const _Tp& __y) // swap_ranges -// forward -template<class _Tp, size_t _Np> -inline _LIBCPP_INLINE_VISIBILITY -void swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); template <class _ForwardIterator1, class _ForwardIterator2> inline _LIBCPP_INLINE_VISIBILITY @@ -239,9 +236,12 @@ swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardItera return __first2; } +// forward declared in <type_traits> template<class _Tp, size_t _Np> inline _LIBCPP_INLINE_VISIBILITY -void +typename enable_if< + __is_swappable<_Tp>::value +>::type swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { _VSTD::swap_ranges(__a, __a + _Np, __b); @@ -285,9 +285,6 @@ struct _LIBCPP_TYPE_VIS_ONLY pair _T1 first; _T2 second; - // pair(const pair&) = default; - // pair(pair&&) = default; - #ifndef _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS template <bool _Dummy = true, class = typename enable_if< __dependent_type<is_default_constructible<_T1>, _Dummy>::value && @@ -310,10 +307,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pair ) : first(__p.first), second(__p.second) {} -#if !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && _LIBCPP_TRIVIAL_PAIR_COPY_CTOR - _LIBCPP_INLINE_VISIBILITY - pair(const pair& __p) = default; -#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR +#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 && @@ -322,6 +316,21 @@ struct _LIBCPP_TYPE_VIS_ONLY pair second(__p.second) { } + +# ifndef _LIBCPP_CXX03_LANG + _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)) + { + } +# endif +#elif !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 @@ -353,19 +362,6 @@ struct _LIBCPP_TYPE_VIS_ONLY pair : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} -#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS - _LIBCPP_INLINE_VISIBILITY - pair(pair&& __p) = default; -#else - _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)) - { - } -#endif - _LIBCPP_INLINE_VISIBILITY pair& operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && @@ -501,7 +497,6 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES -template <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper; template <class _Tp> struct __make_pair_return_impl @@ -742,63 +737,15 @@ template<size_t... _Ip> #if __has_builtin(__make_integer_seq) && !defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) template <class _Tp, _Tp _Ep> -struct __make_integer_sequence -{ - typedef __make_integer_seq<integer_sequence, _Tp, _Ep> type; -}; +using __make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Ep>; #else -namespace __detail { - -template<typename _Tp, size_t ..._Extra> struct __repeat; -template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<integer_sequence<_Tp, _Np...>, _Extra...> { - typedef integer_sequence<_Tp, - _Np..., - sizeof...(_Np) + _Np..., - 2 * sizeof...(_Np) + _Np..., - 3 * sizeof...(_Np) + _Np..., - 4 * sizeof...(_Np) + _Np..., - 5 * sizeof...(_Np) + _Np..., - 6 * sizeof...(_Np) + _Np..., - 7 * sizeof...(_Np) + _Np..., - _Extra...> type; -}; - -template<size_t _Np> struct __parity; -template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; - -template<> struct __make<0> { typedef integer_sequence<size_t> type; }; -template<> struct __make<1> { typedef integer_sequence<size_t, 0> type; }; -template<> struct __make<2> { typedef integer_sequence<size_t, 0, 1> type; }; -template<> struct __make<3> { typedef integer_sequence<size_t, 0, 1, 2> type; }; -template<> struct __make<4> { typedef integer_sequence<size_t, 0, 1, 2, 3> type; }; -template<> struct __make<5> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; -template<> struct __make<6> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; -template<> struct __make<7> { typedef integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; - -template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; -template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; -template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; -template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; - -template<typename _Tp, typename _Up> struct __convert { - template<typename> struct __result; - template<_Tp ..._Np> struct __result<integer_sequence<_Tp, _Np...> > { typedef integer_sequence<_Up, _Np...> type; }; -}; -template<typename _Tp> struct __convert<_Tp, _Tp> { template<typename _Up> struct __result { typedef _Up type; }; }; - -} - template<typename _Tp, _Tp _Np> using __make_integer_sequence_unchecked = - typename __detail::__convert<size_t, _Tp>::template __result<typename __detail::__make<_Np>::type>::type; + typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>; template <class _Tp, _Tp _Ep> -struct __make_integer_sequence +struct __make_integer_sequence_checked { static_assert(is_integral<_Tp>::value, "std::make_integer_sequence can only be instantiated with an integral type" ); @@ -808,17 +755,20 @@ struct __make_integer_sequence typedef __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0> type; }; +template <class _Tp, _Tp _Ep> +using __make_integer_sequence = typename __make_integer_sequence_checked<_Tp, _Ep>::type; + #endif template<class _Tp, _Tp _Np> - using make_integer_sequence = typename __make_integer_sequence<_Tp, _Np>::type; + using make_integer_sequence = __make_integer_sequence<_Tp, _Np>; template<size_t _Np> using make_index_sequence = make_integer_sequence<size_t, _Np>; template<class... _Tp> using index_sequence_for = make_index_sequence<sizeof...(_Tp)>; - + #endif // _LIBCPP_STD_VER > 11 #if _LIBCPP_STD_VER > 11 @@ -829,7 +779,7 @@ _T1 exchange(_T1& __obj, _T2 && __new_value) _T1 __old_value = _VSTD::move(__obj); __obj = _VSTD::forward<_T2>(__new_value); return __old_value; -} +} #endif // _LIBCPP_STD_VER > 11 _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libc++/include/vector b/contrib/libc++/include/vector index dbc0dd3..021bbfb 100644 --- a/contrib/libc++/include/vector +++ b/contrib/libc++/include/vector @@ -262,6 +262,7 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) */ #include <__config> +#include <iosfwd> // for forward declaration of vector #include <__bit_reference> #include <type_traits> #include <climits> @@ -453,7 +454,7 @@ __vector_base<_Tp, _Allocator>::~__vector_base() } } -template <class _Tp, class _Allocator = allocator<_Tp> > +template <class _Tp, class _Allocator /* = allocator<_Tp> */> class _LIBCPP_TYPE_VIS_ONLY vector : private __vector_base<_Tp, _Allocator> { @@ -1811,9 +1812,9 @@ vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) } else { - value_type __tmp(_VSTD::forward<_Args>(__args)...); + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), _VSTD::forward<_Args>(__args)...); __move_range(__p, this->__end_, __p + 1); - *__p = _VSTD::move(__tmp); + *__p = _VSTD::move(__tmp.get()); } __annotator.__done(); } @@ -2362,6 +2363,7 @@ public: _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); } void resize(size_type __sz, value_type __x = false); void flip() _NOEXCEPT; diff --git a/contrib/libc++/include/wchar.h b/contrib/libc++/include/wchar.h index da34f73..c0c6ef7 100644 --- a/contrib/libc++/include/wchar.h +++ b/contrib/libc++/include/wchar.h @@ -118,7 +118,7 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, #include_next <wchar.h> -// Let <cwchar> know if we have const-correct overloads for wcschr and friends. +// Determine whether we have const-correct overloads for wcschr and friends. #if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_) # define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1 #elif defined(__GLIBC_PREREQ) @@ -127,6 +127,45 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, # endif #endif +#if defined(__cplusplus) && !defined(_LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS) && defined(_LIBCPP_PREFERRED_OVERLOAD) +extern "C++" { +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcschr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcschr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return __libcpp_wcschr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcschr( wchar_t* __s, wchar_t __c) {return __libcpp_wcschr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return (wchar_t*)wcspbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcspbrk(const wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcspbrk(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcspbrk( wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcspbrk(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcsrchr(const wchar_t* __s, wchar_t __c) {return (wchar_t*)wcsrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcsrchr(const wchar_t* __s, wchar_t __c) {return __libcpp_wcsrchr(__s, __c);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcsrchr( wchar_t* __s, wchar_t __c) {return __libcpp_wcsrchr(__s, __c);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return (wchar_t*)wcsstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wcsstr(const wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcsstr(__s1, __s2);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wcsstr( wchar_t* __s1, const wchar_t* __s2) {return __libcpp_wcsstr(__s1, __s2);} + +inline _LIBCPP_INLINE_VISIBILITY +wchar_t* __libcpp_wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return (wchar_t*)wmemchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD +const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return __libcpp_wmemchr(__s, __c, __n);} +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_PREFERRED_OVERLOAD + wchar_t* wmemchr( wchar_t* __s, wchar_t __c, size_t __n) {return __libcpp_wmemchr(__s, __c, __n);} +} +#endif + #if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)) extern "C++" { #include <support/win32/support.h> // pull in *swprintf defines |