Skip to content
79 changes: 28 additions & 51 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -190,21 +190,21 @@ inline void _Adjust_manually_vector_aligned(void*& _Ptr, size_t& _Bytes) {
}
#endif // defined(_M_IX86) || defined(_M_X64)

#ifdef __cpp_aligned_new
template <size_t _Align, class _Traits = _Default_allocate_traits,
enable_if_t<(_Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0>
template <size_t _Align, class _Traits = _Default_allocate_traits>
__declspec(allocator) _CONSTEXPR20 void* _Allocate(const size_t _Bytes) {
// allocate _Bytes when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__
// allocate _Bytes
if (_Bytes == 0) {
return nullptr;
}

#if _HAS_CXX20 // TRANSITION, GH-1532
if (_STD is_constant_evaluated()) {
return _Traits::_Allocate(_Bytes);
} else
}
#endif // _HAS_CXX20
{

#ifdef __cpp_aligned_new
if constexpr (_Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
size_t _Passed_align = _Align;
#if defined(_M_IX86) || defined(_M_X64)
if (_Bytes >= _Big_allocation_threshold) {
Expand All @@ -213,75 +213,52 @@ __declspec(allocator) _CONSTEXPR20 void* _Allocate(const size_t _Bytes) {
}
#endif // defined(_M_IX86) || defined(_M_X64)
return _Traits::_Allocate_aligned(_Bytes, _Passed_align);
}
}

template <size_t _Align, enable_if_t<(_Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0>
_CONSTEXPR20 void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept {
// deallocate storage allocated by _Allocate when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__
#if _HAS_CXX20 // TRANSITION, GH-1532
if (_STD is_constant_evaluated()) {
::operator delete(_Ptr);
} else
#endif // _HAS_CXX20
#endif // defined(__cpp_aligned_new)
{
size_t _Passed_align = _Align;
#if defined(_M_IX86) || defined(_M_X64)
if (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization
_Passed_align = (_STD max)(_Align, _Big_allocation_alignment);
}
#endif // defined(_M_IX86) || defined(_M_X64)
::operator delete(_Ptr, _Bytes, align_val_t{_Passed_align});
}
}

#define _HAS_ALIGNED_NEW 1
#else // ^^^ defined(__cpp_aligned_new) / !defined(__cpp_aligned_new) vvv
#define _HAS_ALIGNED_NEW 0
#endif // ^^^ !defined(__cpp_aligned_new) ^^^

template <size_t _Align, class _Traits = _Default_allocate_traits,
enable_if_t<(!_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0>
__declspec(allocator) _CONSTEXPR20 void* _Allocate(const size_t _Bytes) {
// allocate _Bytes when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__
#if defined(_M_IX86) || defined(_M_X64)
#if _HAS_CXX20 // TRANSITION, GH-1532
if (!_STD is_constant_evaluated())
#endif // _HAS_CXX20
{
if (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization
if (_Bytes >= _Big_allocation_threshold) {
// boost the alignment of big allocations to help autovectorization
return _Allocate_manually_vector_aligned<_Traits>(_Bytes);
}
}
#endif // defined(_M_IX86) || defined(_M_X64)

if (_Bytes != 0) {
return _Traits::_Allocate(_Bytes);
}

return nullptr;
}

template <size_t _Align, enable_if_t<(!_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0>
template <size_t _Align>
_CONSTEXPR20 void _Deallocate(void* _Ptr, size_t _Bytes) noexcept {
// deallocate storage allocated by _Allocate when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__
// deallocate storage allocated by _Allocate
#if _HAS_CXX20 // TRANSITION, GH-1532
if (_STD is_constant_evaluated()) {
::operator delete(_Ptr);
} else
return;
}
#endif // _HAS_CXX20

#ifdef __cpp_aligned_new
if constexpr (_Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
size_t _Passed_align = _Align;
#if defined(_M_IX86) || defined(_M_X64)
if (_Bytes >= _Big_allocation_threshold) {
// boost the alignment of big allocations to help autovectorization
_Passed_align = (_STD max)(_Align, _Big_allocation_alignment);
}
#endif // defined(_M_IX86) || defined(_M_X64)
::operator delete(_Ptr, _Bytes, align_val_t{_Passed_align});
} else
#endif // defined(__cpp_aligned_new)
{
#if defined(_M_IX86) || defined(_M_X64)
if (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization
if (_Bytes >= _Big_allocation_threshold) {
// boost the alignment of big allocations to help autovectorization
_Adjust_manually_vector_aligned(_Ptr, _Bytes);
}
#endif // defined(_M_IX86) || defined(_M_X64)
::operator delete(_Ptr, _Bytes);
}
}

#undef _HAS_ALIGNED_NEW

template <class _Ptr, class _Ty>
using _Rebind_pointer_t = typename pointer_traits<_Ptr>::template rebind<_Ty>;

Expand Down