Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<xmemory>: Unify overloads of _Allocate and _Deallocate with if constexpr #4432

Merged
merged 7 commits into from
Mar 8, 2024
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