Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
2 changes: 2 additions & 0 deletions stl/inc/concepts
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,14 @@ namespace ranges {
noexcept(noexcept(operator()(__t[0], __u[0])))
requires requires(_Cpo __fn) { __fn(__t[0], __u[0]); }
{
#ifndef __clang__
if constexpr (is_same_v<_Ty1, _Ty2> && _Is_trivially_swappable_v<_Ty1>) {
if (!_STD is_constant_evaluated()) {
_STD _Swap_trivial_arrays(__t, __u);
return;
}
}
#endif // !defined(__clang__)

for (size_t __i = 0; __i < _Size; ++__i) {
operator()(__t[__i], __u[__i]);
Expand Down
29 changes: 20 additions & 9 deletions stl/inc/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#if _STL_COMPILER_PREPROCESSOR
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <xtr1common>

#pragma pack(push, _CRT_PACKING)
Expand Down Expand Up @@ -2494,6 +2493,7 @@ _NODISCARD constexpr bool _Is_finite(const _Ty _Xx) noexcept { // constexpr isfi
template <bool _IsConst, class _Ty>
using _Maybe_const = conditional_t<_IsConst, const _Ty, _Ty>;

#ifndef __clang__
template <class _Ty, size_t _Size>
void _Swap_trivial_arrays(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size]) noexcept {
// Swap arrays using temporary buffers of 64 bytes, followed by the tail.
Expand All @@ -2513,23 +2513,34 @@ void _Swap_trivial_arrays(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size]) noexcept {
if constexpr (_Size_parts != 0) {
const auto _Stop = _Left_ptr + _Size_parts;
do {
unsigned char _Buf[_Part_size_bytes];
_CSTD memcpy(_Buf, _Left_ptr, _Part_size_bytes);
_CSTD memcpy(_Left_ptr, _Right_ptr, _Part_size_bytes);
_CSTD memcpy(_Right_ptr, _Buf, _Part_size_bytes);
struct _Buffer_type {
unsigned char _Data[_Part_size_bytes];
};

_STL_INTERNAL_STATIC_ASSERT(sizeof(_Buffer_type) == _Part_size_bytes); // assume no padding

const _Buffer_type _Buffer = *reinterpret_cast<const _Buffer_type*>(_Left_ptr);
*reinterpret_cast<_Buffer_type*>(_Left_ptr) = *reinterpret_cast<const _Buffer_type*>(_Right_ptr);
*reinterpret_cast<_Buffer_type*>(_Right_ptr) = _Buffer;
_Left_ptr += _Part_size_bytes;
_Right_ptr += _Part_size_bytes;

} while (_Left_ptr != _Stop);
}

if constexpr (_Size_tail != 0) {
unsigned char _Buf[_Size_tail];
_CSTD memcpy(_Buf, _Left_ptr, _Size_tail);
_CSTD memcpy(_Left_ptr, _Right_ptr, _Size_tail);
_CSTD memcpy(_Right_ptr, _Buf, _Size_tail);
struct _Last_buffer_type {
unsigned char _Data[_Size_tail];
};

_STL_INTERNAL_STATIC_ASSERT(sizeof(_Last_buffer_type) == _Size_tail); // assume no padding

const _Last_buffer_type _Last_buffer = *reinterpret_cast<const _Last_buffer_type*>(_Left_ptr);
*reinterpret_cast<_Last_buffer_type*>(_Left_ptr) = *reinterpret_cast<const _Last_buffer_type*>(_Right_ptr);
*reinterpret_cast<_Last_buffer_type*>(_Right_ptr) = _Last_buffer;
}
}
#endif // !defined(__clang__)

#if _HAS_TR1_NAMESPACE
_STL_DISABLE_DEPRECATED_WARNING
Expand Down
2 changes: 2 additions & 0 deletions stl/inc/utility
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,14 @@ _CONSTEXPR20 void swap(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size]) noexcept(_Is_n
return; // Handle self-swap as a no-op; see LWG-4165
}

#ifndef __clang__
if constexpr (_Is_trivially_swappable_v<_Ty>) {
if (!_STD _Is_constant_evaluated()) {
_STD _Swap_trivial_arrays(_Left, _Right);
return;
}
}
#endif // !defined(__clang__)

_Ty* _First1 = _Left;
_Ty* _Last1 = _First1 + _Size;
Expand Down