Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/libcxx/include/__algorithm/sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,9 @@ __sort<__less<long double>&, long double*>(long double*, long double*, __less<lo
template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
if (__first == __last) // log(0) is undefined, so don't try computing the depth
return;

typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
difference_type __depth_limit = 2 * std::__bit_log2(std::__to_unsigned_like(__last - __first));

Expand Down
2 changes: 2 additions & 0 deletions lib/libcxx/include/__bit/bit_log2.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#ifndef _LIBCPP___BIT_BIT_LOG2_H
#define _LIBCPP___BIT_BIT_LOG2_H

#include <__assert>
#include <__bit/countl.h>
#include <__config>
#include <__type_traits/integer_traits.h>
Expand All @@ -23,6 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __bit_log2(_Tp __t) _NOEXCEPT {
static_assert(__is_unsigned_integer_v<_Tp>, "__bit_log2 requires an unsigned integer type");
_LIBCPP_ASSERT_INTERNAL(__t != 0, "logarithm of 0 is undefined");
return numeric_limits<_Tp>::digits - 1 - std::__countl_zero(__t);
}

Expand Down
14 changes: 10 additions & 4 deletions lib/libcxx/include/__functional/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <__type_traits/is_enum.h>
#include <__type_traits/is_floating_point.h>
#include <__type_traits/is_integral.h>
#include <__type_traits/is_unqualified.h>
#include <__type_traits/underlying_type.h>
#include <__utility/pair.h>
#include <__utility/swap.h>
Expand Down Expand Up @@ -355,25 +356,30 @@ struct __hash_impl {
};

template <class _Tp>
struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value> > : __unary_function<_Tp, size_t> {
struct __hash_impl<_Tp, __enable_if_t<is_enum<_Tp>::value && __is_unqualified_v<_Tp> > >
: __unary_function<_Tp, size_t> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
using type = __underlying_type_t<_Tp>;
return hash<type>()(static_cast<type>(__v));
}
};

template <class _Tp>
struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) <= sizeof(size_t))> >
struct __hash_impl<
_Tp,
__enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) <= sizeof(size_t))> >
: __unary_function<_Tp, size_t> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { return static_cast<size_t>(__v); }
};

template <class _Tp>
struct __hash_impl<_Tp, __enable_if_t<is_integral<_Tp>::value && (sizeof(_Tp) > sizeof(size_t))> >
struct __hash_impl<_Tp,
__enable_if_t<is_integral<_Tp>::value && __is_unqualified_v<_Tp> && (sizeof(_Tp) > sizeof(size_t))> >
: __scalar_hash<_Tp> {};

template <class _Tp>
struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value> > : __scalar_hash<_Tp> {
struct __hash_impl<_Tp, __enable_if_t<is_floating_point<_Tp>::value && __is_unqualified_v<_Tp> > >
: __scalar_hash<_Tp> {
_LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT {
// -0.0 and 0.0 should return same hash
if (__v == 0.0f)
Expand Down
25 changes: 25 additions & 0 deletions lib/libcxx/include/__type_traits/is_unqualified.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H
#define _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H

#include <__config>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Tp>
inline const bool __is_unqualified_v = __is_same(_Tp, __remove_cvref(_Tp));

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___TYPE_TRAITS_IS_UNQUALIFIED_H
35 changes: 24 additions & 11 deletions lib/libcxx/include/fstream
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,14 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>

template <class _CharT, class _Traits>
typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>::overflow(int_type __c) {
auto __failed = [this]() {
if (this->pptr() == this->epptr() + 1) {
this->pbump(-1); // lose the character we overflowed above -- we don't really have a
// choice since we couldn't commit the contents of the put area
}
return traits_type::eof();
};

if (__file_ == nullptr)
return traits_type::eof();
__write_mode();
Expand All @@ -841,8 +849,9 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>

if (__always_noconv_) {
size_t __n = static_cast<size_t>(this->pptr() - this->pbase());
if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n)
return traits_type::eof();
if (std::fwrite(this->pbase(), sizeof(char_type), __n, __file_) != __n) {
return __failed();
}
} else {
if (!__cv_)
std::__throw_bad_cast();
Expand All @@ -854,34 +863,38 @@ typename basic_filebuf<_CharT, _Traits>::int_type basic_filebuf<_CharT, _Traits>
char* __extbuf_end = __extbuf_;
do {
codecvt_base::result __r = __cv_->out(__st_, __b, __p, __end, __extbuf_, __extbuf_ + __ebs_, __extbuf_end);
if (__end == __b)
return traits_type::eof();
if (__end == __b) {
return __failed();
}

// No conversion needed: output characters directly to the file, done.
if (__r == codecvt_base::noconv) {
size_t __n = static_cast<size_t>(__p - __b);
if (std::fwrite(__b, 1, __n, __file_) != __n)
return traits_type::eof();
if (std::fwrite(__b, 1, __n, __file_) != __n) {
return __failed();
}
break;

// Conversion successful: output the converted characters to the file, done.
} else if (__r == codecvt_base::ok) {
size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n)
return traits_type::eof();
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
return __failed();
}
break;

// Conversion partially successful: output converted characters to the file and repeat with the
// remaining characters.
} else if (__r == codecvt_base::partial) {
size_t __n = static_cast<size_t>(__extbuf_end - __extbuf_);
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n)
return traits_type::eof();
if (std::fwrite(__extbuf_, 1, __n, __file_) != __n) {
return __failed();
}
__b = const_cast<char_type*>(__end);
continue;

} else {
return traits_type::eof();
return __failed();
}
} while (true);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/libcxx/src/algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class Comp, class RandomAccessIterator>
void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) {
if (first == last) // log(0) is undefined, so don't try computing the depth
return;

auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first));

// Only use bitset partitioning for arithmetic types. We should also check
Expand Down