| author | |
| committer | |
| log | 27a396db4fd2e9734dab63d203fb354084e2c237 |
| tree | 998fe71c701da161fc7726694644532fa4d577dc |
| parent | 4edebf40d53c7e69afd088c9967f13ab8aafe1fd |
| parent | bc58b5dc53cce066d224925ce8fb4bb79665a1d1 |
| signature |
`libcxx`: backport llvm/llvm-project#155476, llvm/llvm-project#147389, llvm/llvm-project#1557866 files changed, 67 insertions(+), 15 deletions(-)
lib/libcxx/include/__algorithm/sort.h+3| ... | ... | @@ -860,6 +860,9 @@ __sort<__less<long double>&, long double*>(long double*, long double*, __less<lo |
| 860 | 860 | template <class _AlgPolicy, class _RandomAccessIterator, class _Comp> |
| 861 | 861 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void |
| 862 | 862 | __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { |
| 863 | if (__first == __last) // log(0) is undefined, so don't try computing the depth | |
| 864 | return; | |
| 865 | ||
| 863 | 866 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; |
| 864 | 867 | difference_type __depth_limit = 2 * std::__bit_log2(std::__to_unsigned_like(__last - __first)); |
| 865 | 868 |
lib/libcxx/include/__bit/bit_log2.h+2| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef _LIBCPP___BIT_BIT_LOG2_H |
| 10 | 10 | #define _LIBCPP___BIT_BIT_LOG2_H |
| 11 | 11 | |
| 12 | #include <__assert> | |
| 12 | 13 | #include <__bit/countl.h> |
| 13 | 14 | #include <__config> |
| 14 | 15 | #include <__type_traits/integer_traits.h> |
| ... | ... | @@ -23,6 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 24 | template <class _Tp> |
| 24 | 25 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT { |
| 25 | 26 | static_assert(__is_unsigned_integer_v<_Tp>, "__bit_log2 requires an unsigned integer type"); |
| 27 | _LIBCPP_ASSERT_INTERNAL(__t != 0, "logarithm of 0 is undefined"); | |
| 26 | 28 | return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t); |
| 27 | 29 | } |
| 28 | 30 |
lib/libcxx/include/__functional/hash.h+10-4| ... | ... | @@ -21,6 +21,7 @@ |
| 21 | 21 | #include <__type_traits/is_enum.h> |
| 22 | 22 | #include <__type_traits/is_floating_point.h> |
| 23 | 23 | #include <__type_traits/is_integral.h> |
| 24 | #include <__type_traits/is_unqualified.h> | |
| 24 | 25 | #include <__type_traits/underlying_type.h> |
| 25 | 26 | #include <__utility/pair.h> |
| 26 | 27 | #include <__utility/swap.h> |
| ... | ... | @@ -355,7 +356,8 @@ struct __hash_impl { |
| 355 | 356 | }; |
| 356 | 357 | |
| 357 | 358 | template <class _Tp> |
| 358 | struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<_Tp, size_t> { | |
| 359 | struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value && __is_unqualified_v<_Tp> > > | |
| 360 | : __unary_function<_Tp, size_t> { | |
| 359 | 361 | _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { |
| 360 | 362 | using type = __underlying_type_t<_Tp>; |
| 361 | 363 | return hash<type>()(static_cast<type>(__v)); |
| ... | ... | @@ -363,17 +365,21 @@ struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function< |
| 363 | 365 | }; |
| 364 | 366 | |
| 365 | 367 | template <class _Tp> |
| 366 | struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) <= sizeof(size_t))> > | |
| 368 | struct __hash_impl< | |
| 369 | _Tp, | |
| 370 | __enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) <= sizeof(size_t))> > | |
| 367 | 371 | : __unary_function<_Tp, size_t> { |
| 368 | 372 | _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { return static_cast<size_t>(__v); } |
| 369 | 373 | }; |
| 370 | 374 | |
| 371 | 375 | template <class _Tp> |
| 372 | struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) > sizeof(size_t))> > | |
| 376 | struct __hash_impl<_Tp, | |
| 377 | __enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) > sizeof(size_t))> > | |
| 373 | 378 | : __scalar_hash<_Tp> {}; |
| 374 | 379 | |
| 375 | 380 | template <class _Tp> |
| 376 | struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value> > : __scalar_hash<_Tp> { | |
| 381 | struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value && __is_unqualified_v<_Tp> > > | |
| 382 | : __scalar_hash<_Tp> { | |
| 377 | 383 | _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { |
| 378 | 384 | // -0.0 and 0.0 should return same hash |
| 379 | 385 | if (__v == 0.0f) |
lib/libcxx/include/__type_traits/is_unqualified.h created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 19 | ||
| 20 | template <class _Tp> | |
| 21 | inline const bool __is_unqualified_v = __is_same(_Tp, __remove_cvref(_Tp)); | |
| 22 | ||
| 23 | _LIBCPP_END_NAMESPACE_STD | |
| 24 | ||
| 25 | #endif // _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H |
lib/libcxx/include/fstream+24-11| ... | ... | @@ -821,6 +821,14 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits> |
| 821 | 821 | |
| 822 | 822 | template <class _CharT, class _Traits> |
| 823 | 823 | typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) { |
| 824 | auto __failed = [this]() { | |
| 825 | if (this->pptr() == this->epptr() + 1) { | |
| 826 | this->pbump(-1); // lose the character we overflowed above -- we don't really have a | |
| 827 | // choice since we couldn't commit the contents of the put area | |
| 828 | } | |
| 829 | return traits_type::eof(); | |
| 830 | }; | |
| 831 | ||
| 824 | 832 | if (__file_ == nullptr) |
| 825 | 833 | return traits_type::eof(); |
| 826 | 834 | __write_mode(); |
| ... | ... | @@ -841,8 +849,9 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits> |
| 841 | 849 | |
| 842 | 850 | if (__always_noconv_) { |
| 843 | 851 | size_t __n = static_cast<size_t>(this->pptr() - this->pbase()); |
| 844 | if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) | |
| 845 | return traits_type::eof(); | |
| 852 | if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) { | |
| 853 | return __failed(); | |
| 854 | } | |
| 846 | 855 | } else { |
| 847 | 856 | if (!__cv_) |
| 848 | 857 | std::__throw_bad_cast(); |
| ... | ... | @@ -854,34 +863,38 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits> |
| 854 | 863 | char* __extbuf_end = __extbuf_; |
| 855 | 864 | do { |
| 856 | 865 | codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end); |
| 857 | if (__end == __b) | |
| 858 | return traits_type::eof(); | |
| 866 | if (__end == __b) { | |
| 867 | return __failed(); | |
| 868 | } | |
| 859 | 869 | |
| 860 | 870 | // No conversion needed: output characters directly to the file, done. |
| 861 | 871 | if (__r == codecvt_base::noconv) { |
| 862 | 872 | size_t __n = static_cast<size_t>(__p - __b); |
| 863 | if (std::fwrite(__b, 1, __n, __file_) != __n) | |
| 864 | return traits_type::eof(); | |
| 873 | if (std::fwrite(__b, 1, __n, __file_) != __n) { | |
| 874 | return __failed(); | |
| 875 | } | |
| 865 | 876 | break; |
| 866 | 877 | |
| 867 | 878 | // Conversion successful: output the converted characters to the file, done. |
| 868 | 879 | } else if (__r == codecvt_base::ok) { |
| 869 | 880 | size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_); |
| 870 | if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) | |
| 871 | return traits_type::eof(); | |
| 881 | if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) { | |
| 882 | return __failed(); | |
| 883 | } | |
| 872 | 884 | break; |
| 873 | 885 | |
| 874 | 886 | // Conversion partially successful: output converted characters to the file and repeat with the |
| 875 | 887 | // remaining characters. |
| 876 | 888 | } else if (__r == codecvt_base::partial) { |
| 877 | 889 | size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_); |
| 878 | if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) | |
| 879 | return traits_type::eof(); | |
| 890 | if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) { | |
| 891 | return __failed(); | |
| 892 | } | |
| 880 | 893 | __b = const_cast<char_type*>(__end); |
| 881 | 894 | continue; |
| 882 | 895 | |
| 883 | 896 | } else { |
| 884 | return traits_type::eof(); | |
| 897 | return __failed(); | |
| 885 | 898 | } |
| 886 | 899 | } while (true); |
| 887 | 900 | } |
lib/libcxx/src/algorithm.cpp+3| ... | ... | @@ -13,6 +13,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 13 | 13 | |
| 14 | 14 | template <class Comp, class RandomAccessIterator> |
| 15 | 15 | void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) { |
| 16 | if (first == last) // log(0) is undefined, so don't try computing the depth | |
| 17 | return; | |
| 18 | ||
| 16 | 19 | auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first)); |
| 17 | 20 | |
| 18 | 21 | // Only use bitset partitioning for arithmetic types. We should also check |