From 0b94bc2ed8fb56a9865c28ea9c0cabcac38f4435 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 14 Oct 2020 00:40:57 +0100 Subject: [PATCH 01/54] Add support for more constexpr containers This is Following P0784R7. --- stl/inc/xmemory | 32 +++++++++++++++++++------------- stl/inc/xutility | 4 ++-- stl/inc/yvals_core.h | 9 +++++---- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 188e616ff15..39151fde61d 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -519,12 +519,13 @@ struct _Normal_allocator_traits { // defines traits for allocators template using rebind_traits = allocator_traits>; - _NODISCARD static __declspec(allocator) pointer allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count) { + _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer + allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count) { return _Al.allocate(_Count); } #if _HAS_IF_CONSTEXPR - _NODISCARD static __declspec(allocator) pointer + _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count, const const_void_pointer _Hint) { if constexpr (_Has_allocate_hint<_Alloc, size_type, const_void_pointer>::value) { return _Al.allocate(_Count, _Hint); @@ -549,15 +550,16 @@ struct _Normal_allocator_traits { // defines traits for allocators } #endif // _HAS_IF_CONSTEXPR - static void deallocate(_Alloc& _Al, pointer _Ptr, size_type _Count) { + static _CONSTEXPR20_DYNALLOC void deallocate(_Alloc& _Al, pointer _Ptr, size_type _Count) { _Al.deallocate(_Ptr, _Count); } #if _HAS_IF_CONSTEXPR template - static void construct(_Alloc& _Al, _Ty* _Ptr, _Types&&... _Args) { + static _CONSTEXPR20_DYNALLOC void construct(_Alloc& _Al, _Ty* _Ptr, _Types&&... _Args) { if constexpr (_Uses_default_construct<_Alloc, _Ty*, _Types...>::value) { (void) _Al; // TRANSITION, DevCom-1004719 + //construct_at(_Ptr, _STD forward<_Types>(_Args)...); ::new (static_cast(_Ptr)) _Ty(_STD forward<_Types>(_Args)...); } else { _Al.construct(_Ptr, _STD forward<_Types>(_Args)...); @@ -583,8 +585,10 @@ struct _Normal_allocator_traits { // defines traits for allocators #if _HAS_IF_CONSTEXPR template - static void destroy(_Alloc& _Al, _Ty* _Ptr) { + static _CONSTEXPR20_DYNALLOC void destroy(_Alloc& _Al, _Ty* _Ptr) { if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { + (void) _Al; + //destroy_at(_Ptr) _Ptr->~_Ty(); } else { _Al.destroy(_Ptr); @@ -608,7 +612,7 @@ struct _Normal_allocator_traits { // defines traits for allocators #endif // _HAS_IF_CONSTEXPR #if _HAS_IF_CONSTEXPR - _NODISCARD static size_type max_size(const _Alloc& _Al) noexcept { + _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc& _Al) noexcept { if constexpr (_Has_max_size<_Alloc>::value) { return _Al.max_size(); } else { @@ -630,7 +634,7 @@ struct _Normal_allocator_traits { // defines traits for allocators #endif // _HAS_IF_CONSTEXPR #if _HAS_IF_CONSTEXPR - _NODISCARD static _Alloc select_on_container_copy_construction(const _Alloc& _Al) { + _NODISCARD static _CONSTEXPR20_DYNALLOC _Alloc select_on_container_copy_construction(const _Alloc& _Al) { if constexpr (_Has_select_on_container_copy_construction<_Alloc>::value) { return _Al.select_on_container_copy_construction(); } else { @@ -762,8 +766,8 @@ struct _Simple_types { // wraps types from allocators with simple addressing for template class allocator { public: - static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " - "because allocator is ill-formed."); + /*static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " + "because allocator is ill-formed.");*/ using _From_primary = allocator; @@ -799,13 +803,15 @@ public: constexpr allocator(const allocator&) noexcept = default; template constexpr allocator(const allocator<_Other>&) noexcept {} + _CONSTEXPR20_DYNALLOC ~allocator() = default; + _CONSTEXPR20_DYNALLOC allocator& operator=(const allocator&) = default; - void deallocate(_Ty* const _Ptr, const size_t _Count) { + _CONSTEXPR20_DYNALLOC void deallocate(_Ty* const _Ptr, const size_t _Count) { // no overflow check on the following multiply; we assume _Allocate did that check _Deallocate<_New_alignof<_Ty>>(_Ptr, sizeof(_Ty) * _Count); } - _NODISCARD __declspec(allocator) _Ty* allocate(_CRT_GUARDOVERFLOW const size_t _Count) { + _NODISCARD _CONSTEXPR20_DYNALLOC __declspec(allocator) _Ty* allocate(_CRT_GUARDOVERFLOW const size_t _Count) { return static_cast<_Ty*>(_Allocate<_New_alignof<_Ty>>(_Get_size_of_n(_Count))); } @@ -850,12 +856,12 @@ public: }; template -_NODISCARD bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { +_NODISCARD _CONSTEXPR20_DYNALLOC bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { return true; } template -_NODISCARD bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) noexcept { +_NODISCARD _CONSTEXPR20_DYNALLOC bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) noexcept { return false; } diff --git a/stl/inc/xutility b/stl/inc/xutility index 9853514c011..071036f7270 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -121,7 +121,7 @@ struct _Get_rebind_alias<_Ty, _Other, void_t -_NODISCARD void* _Voidify_iter(_Iter _It) noexcept { +_NODISCARD _CONSTEXPR20_DYNALLOC void* _Voidify_iter(_Iter _It) noexcept { #if _HAS_IF_CONSTEXPR if constexpr (is_pointer_v<_Iter>) { return const_cast(static_cast(_It)); @@ -3886,7 +3886,7 @@ namespace ranges { subrange(_It, _Se, _Make_unsigned_like_t>) -> subrange<_It, _Se, subrange_kind::sized>; template - subrange(_Rng &&) -> subrange, sentinel_t<_Rng>, + subrange(_Rng&&) -> subrange, sentinel_t<_Rng>, (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized : subrange_kind::unsized>; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 5c80252c9e0..4a1078ddb61 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1234,10 +1234,11 @@ #define __cpp_lib_three_way_comparison 201711L #endif // __cpp_lib_concepts -#define __cpp_lib_to_address 201711L -#define __cpp_lib_to_array 201907L -#define __cpp_lib_type_identity 201806L -#define __cpp_lib_unwrap_ref 201811L +#define __cpp_lib_to_address 201711L +#define __cpp_lib_to_array 201907L +#define __cpp_lib_type_identity 201806L +#define __cpp_lib_unwrap_ref 201811L +#define __cpp_lib_constexpr_dynamic_alloc 201907L #endif // _HAS_CXX20 #ifndef _M_CEE From ac7ef50545b6f30f097bf811a437237dd330fa1f Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 14 Oct 2020 02:10:12 +0100 Subject: [PATCH 02/54] Conform to clang-format. --- stl/inc/xmemory | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 39151fde61d..210393a5b52 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -559,7 +559,7 @@ struct _Normal_allocator_traits { // defines traits for allocators static _CONSTEXPR20_DYNALLOC void construct(_Alloc& _Al, _Ty* _Ptr, _Types&&... _Args) { if constexpr (_Uses_default_construct<_Alloc, _Ty*, _Types...>::value) { (void) _Al; // TRANSITION, DevCom-1004719 - //construct_at(_Ptr, _STD forward<_Types>(_Args)...); + // construct_at(_Ptr, _STD forward<_Types>(_Args)...); ::new (static_cast(_Ptr)) _Ty(_STD forward<_Types>(_Args)...); } else { _Al.construct(_Ptr, _STD forward<_Types>(_Args)...); @@ -588,7 +588,7 @@ struct _Normal_allocator_traits { // defines traits for allocators static _CONSTEXPR20_DYNALLOC void destroy(_Alloc& _Al, _Ty* _Ptr) { if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { (void) _Al; - //destroy_at(_Ptr) + // destroy_at(_Ptr) _Ptr->~_Ty(); } else { _Al.destroy(_Ptr); @@ -766,8 +766,8 @@ struct _Simple_types { // wraps types from allocators with simple addressing for template class allocator { public: - /*static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " - "because allocator is ill-formed.");*/ + static_assert(!is_const_v<_Ty>, "The C++ Standard forbids containers of const elements " + "because allocator is ill-formed."); using _From_primary = allocator; From 4255a9e74c15e11de0fe3e0ed56511574df11e9e Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" Date: Wed, 14 Oct 2020 12:36:15 +0100 Subject: [PATCH 03/54] Apply suggestions from code review Co-authored-by: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> --- stl/inc/xmemory | 6 +++--- stl/inc/xutility | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 210393a5b52..7dc099148fd 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -634,7 +634,7 @@ struct _Normal_allocator_traits { // defines traits for allocators #endif // _HAS_IF_CONSTEXPR #if _HAS_IF_CONSTEXPR - _NODISCARD static _CONSTEXPR20_DYNALLOC _Alloc select_on_container_copy_construction(const _Alloc& _Al) { + _NODISCARD static _CONSTEXPR20 _Alloc select_on_container_copy_construction(const _Alloc& _Al) { if constexpr (_Has_select_on_container_copy_construction<_Alloc>::value) { return _Al.select_on_container_copy_construction(); } else { @@ -856,12 +856,12 @@ public: }; template -_NODISCARD _CONSTEXPR20_DYNALLOC bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { +_NODISCARD _CONSTEXPR20 bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { return true; } template -_NODISCARD _CONSTEXPR20_DYNALLOC bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) noexcept { +_NODISCARD _CONSTEXPR20 bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) noexcept { return false; } diff --git a/stl/inc/xutility b/stl/inc/xutility index 071036f7270..1ea28bbcb19 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -121,7 +121,7 @@ struct _Get_rebind_alias<_Ty, _Other, void_t -_NODISCARD _CONSTEXPR20_DYNALLOC void* _Voidify_iter(_Iter _It) noexcept { +_NODISCARD constexpr void* _Voidify_iter(_Iter _It) noexcept { #if _HAS_IF_CONSTEXPR if constexpr (is_pointer_v<_Iter>) { return const_cast(static_cast(_It)); From 7276cecf46c74b05f030afcddf61be5d58568eaf Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:34:42 +0100 Subject: [PATCH 04/54] _Default_allocator_traits members, _Allocate and _Deallocate made constexpr Changes as per the code review --- stl/inc/xmemory | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 7dc099148fd..24ff2a24576 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -73,12 +73,14 @@ _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty), // STRUCT _Default_allocate_traits struct _Default_allocate_traits { - __declspec(allocator) static void* _Allocate(const size_t _Bytes) { + __declspec(allocator) static _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) { return ::operator new(_Bytes); } #ifdef __cpp_aligned_new - __declspec(allocator) static void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { + __declspec(allocator) static _CONSTEXPR20_DYNALLOC + void* _Allocate_aligned( + const size_t _Bytes, const size_t _Align) { return ::operator new (_Bytes, align_val_t{_Align}); } #endif // __cpp_aligned_new @@ -157,7 +159,7 @@ inline void _Adjust_manually_vector_aligned(void*& _Ptr, size_t& _Bytes) { #ifdef __cpp_aligned_new template __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0> -__declspec(allocator) void* _Allocate(const size_t _Bytes) { +__declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) { // allocate _Bytes when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__ if (_Bytes == 0) { return nullptr; @@ -175,7 +177,7 @@ __declspec(allocator) void* _Allocate(const size_t _Bytes) { } template __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0> -void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept { +_CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__ size_t _Passed_align = _Align; #if defined(_M_IX86) || defined(_M_X64) @@ -194,7 +196,7 @@ void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept { template = 0> -__declspec(allocator) void* _Allocate(const size_t _Bytes) { +__declspec(allocator) _CONSTEXPR20_DYNALLOC 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 (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization @@ -210,7 +212,7 @@ __declspec(allocator) void* _Allocate(const size_t _Bytes) { } template = 0> -void _Deallocate(void* _Ptr, size_t _Bytes) noexcept { +_CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__ #if defined(_M_IX86) || defined(_M_X64) if (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization @@ -681,35 +683,36 @@ struct _Default_allocator_traits { // traits for std::allocator template using rebind_traits = allocator_traits>; - _NODISCARD static __declspec(allocator) pointer allocate(_Alloc&, _CRT_GUARDOVERFLOW const size_type _Count) { + _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer + allocate(_Alloc&, _CRT_GUARDOVERFLOW const size_type _Count) { return static_cast(_Allocate<_New_alignof>(_Get_size_of_n(_Count))); } - _NODISCARD static __declspec(allocator) pointer + _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer allocate(_Alloc&, _CRT_GUARDOVERFLOW const size_type _Count, const_void_pointer) { return static_cast(_Allocate<_New_alignof>(_Get_size_of_n(_Count))); } - static void deallocate(_Alloc&, const pointer _Ptr, const size_type _Count) { + static _CONSTEXPR20_DYNALLOC void deallocate(_Alloc&, const pointer _Ptr, const size_type _Count) { // no overflow check on the following multiply; we assume _Allocate did that check _Deallocate<_New_alignof>(_Ptr, sizeof(value_type) * _Count); } template - static void construct(_Alloc&, _Objty* const _Ptr, _Types&&... _Args) { + static _CONSTEXPR20_DYNALLOC void construct(_Alloc&, _Objty* const _Ptr, _Types&&... _Args) { ::new (const_cast(static_cast(_Ptr))) _Objty(_STD forward<_Types>(_Args)...); } template - static void destroy(_Alloc&, _Uty* const _Ptr) { + static _CONSTEXPR20_DYNALLOC void destroy(_Alloc&, _Uty* const _Ptr) { _Ptr->~_Uty(); } - _NODISCARD static size_type max_size(const _Alloc&) noexcept { + _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc&) noexcept { return static_cast(-1) / sizeof(value_type); } - _NODISCARD static _Alloc select_on_container_copy_construction(const _Alloc& _Al) { + _NODISCARD static _CONSTEXPR20_DYNALLOC _Alloc select_on_container_copy_construction(const _Alloc& _Al) { return _Al; } }; From 31425fdb1c1b89bdbe3c94e0ddf6d9e6ec4d3e47 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 14 Oct 2020 13:40:02 +0100 Subject: [PATCH 05/54] Conform to clang-format --- stl/inc/xmemory | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 24ff2a24576..381943f8c5b 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -79,8 +79,7 @@ struct _Default_allocate_traits { #ifdef __cpp_aligned_new __declspec(allocator) static _CONSTEXPR20_DYNALLOC - void* _Allocate_aligned( - const size_t _Bytes, const size_t _Align) { + void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { return ::operator new (_Bytes, align_val_t{_Align}); } #endif // __cpp_aligned_new From 822be04408c39504581d8e6ee87fe49919828602 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 14 Oct 2020 15:28:07 +0100 Subject: [PATCH 06/54] correctly place __cpp_lib_constexpr_dynamic_alloc and add feature test --- stl/inc/yvals_core.h | 18 +++++++++++------- .../test.compile.pass.cpp | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 4a1078ddb61..b4e42b2c5c3 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1194,8 +1194,13 @@ #define __cpp_lib_concepts 201907L #endif // !defined(__EDG__) || defined(__INTELLISENSE__) -#define __cpp_lib_constexpr_algorithms 201806L -#define __cpp_lib_constexpr_complex 201711L +#define __cpp_lib_constexpr_algorithms 201806L +#define __cpp_lib_constexpr_complex 201711L + +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#define __cpp_lib_constexpr_dynamic_alloc 201907L +#endif + #define __cpp_lib_constexpr_functional 201907L #define __cpp_lib_constexpr_iterator 201811L #define __cpp_lib_constexpr_memory 201811L @@ -1234,11 +1239,10 @@ #define __cpp_lib_three_way_comparison 201711L #endif // __cpp_lib_concepts -#define __cpp_lib_to_address 201711L -#define __cpp_lib_to_array 201907L -#define __cpp_lib_type_identity 201806L -#define __cpp_lib_unwrap_ref 201811L -#define __cpp_lib_constexpr_dynamic_alloc 201907L +#define __cpp_lib_to_address 201711L +#define __cpp_lib_to_array 201907L +#define __cpp_lib_type_identity 201806L +#define __cpp_lib_unwrap_ref 201811L #endif // _HAS_CXX20 #ifndef _M_CEE diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index a513a4f5332..3b1874a720c 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -411,6 +411,20 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L); #endif #endif +#if _HAS_CXX20 +#ifndef __cpp_lib_constexpr_dynamic_alloc +#error __cpp_lib_constexpr_dynamic_alloc is not defined +#elif __cpp_lib_constexpr_dynamic_alloc != 201907L +#error __cpp_lib_constexpr_dynamic_alloc is not 201907L +#else +STATIC_ASSERT(__cpp_lib_constexpr_dynamic_alloc == 201907L); +#endif +#else +#ifdef __cpp_lib_constexpr_dynamic_alloc +#error __cpp_lib_constexpr_dynamic_alloc is defined +#endif +#endif + #if _HAS_CXX20 #ifndef __cpp_lib_constexpr_functional #error __cpp_lib_constexpr_functional is not defined From 45d123460942fc188f38657526ceb65145c74df2 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 14 Oct 2020 15:31:58 +0100 Subject: [PATCH 07/54] Enforce clang-format --- .../tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 3b1874a720c..5abd194fa84 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -416,7 +416,7 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L); #error __cpp_lib_constexpr_dynamic_alloc is not defined #elif __cpp_lib_constexpr_dynamic_alloc != 201907L #error __cpp_lib_constexpr_dynamic_alloc is not 201907L -#else +#else STATIC_ASSERT(__cpp_lib_constexpr_dynamic_alloc == 201907L); #endif #else From 8b158005e830a737682860a2a87d497a6ef88eb4 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" Date: Thu, 15 Oct 2020 16:52:24 +0100 Subject: [PATCH 08/54] Update tests/std/tests/VSO_0157762_feature_test_macros/test.cpp Apply review suggestion Co-authored-by: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> --- .../tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 5abd194fa84..1aa7807505b 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -411,7 +411,7 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L); #endif #endif -#if _HAS_CXX20 +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) #ifndef __cpp_lib_constexpr_dynamic_alloc #error __cpp_lib_constexpr_dynamic_alloc is not defined #elif __cpp_lib_constexpr_dynamic_alloc != 201907L From a16d3cc114574cd0ee011ac5962a13a30b58054e Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Fri, 16 Oct 2020 12:19:45 +0100 Subject: [PATCH 09/54] Add allocator_traits and allocator tests Tests check if allocation tasks can be completed at compile time. --- .../test.cpp | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 7cf1685a980..62c5e6fe785 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -272,6 +272,107 @@ constexpr void test_compiletime() { } } static_assert((test_compiletime(), true)); + +template +struct A { + T value; + + constexpr A() noexcept = default; + constexpr ~A() = default; +}; + +template +struct nontrivial_A { + T value; + + constexpr nontrivial_A(T in = T{}) noexcept : value(in){}; + constexpr ~nontrivial_A() { + value.~T(); + }; +}; + +template +struct Alloc { + using value_type = T; + using size_type = std::size_t; + + constexpr Alloc(int id_) noexcept : id(id_) {} + constexpr ~Alloc() = default; + + constexpr value_type* allocate(size_t n) { + assert(n == 10); + return ::operator new(n * sizeof(value_type)); + } + + constexpr void deallocate(value_type* ptr, size_t n) { + assert(n == 10); + ::operator delete(ptr, n * sizeof(value_type)); + } + + constexpr Alloc select_on_container_copy_construction() const noexcept { + return Alloc{id + 1}; + } + + constexpr size_type max_size() noexcept { + return std::numeric_limits::max() / sizeof(value_type); + } + + int id; +}; + +constexpr void test_compiletime_allocator_traits() { + { + storage_for> a; + Alloc> alloc{10}; + assert(alloc.id == 10); + + auto result = std::allocator_traits>>::allocate(alloc, 10); + assert(result != nullptr); + std::allocator_traits>>::deallocate(alloc, result, 10); + + std::allocator_traits>>::construct(alloc, &a.object, 10); + assert(a.object.value == 10); + std::allocator_traits>>::destroy(alloc, &a.object); + + static_assert(std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); + + static_assert(std::allocator_traits>>::max_size() + == std::numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); + } + { + storage_for> a; + Alloc> alloc{10}; + assert(alloc.id == 10); + + auto result = std::allocator_traits>>::allocate(alloc, 10); + assert(result != nullptr); + std::allocator_traits>>::deallocate(alloc, result, 10); + + std::allocator_traits>>::construct(alloc, &a.object, 10); + assert(a.object.value == 10); + std::allocator_traits>>::destroy(alloc, &a.object); + + static_assert( + std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); + + static_assert(std::allocator_traits>>::max_size() + == std::numeric_limits>::size_type>::max() + / sizeof(Alloc>::value_type)); + } +} +static_assert((test_compiletime_allocator_traits(), true)); + +constexpr void test_compiletime_allocator() { + { + auto result = std::allocator>{}.allocate(10); + std::allocator>{}.deallocate(result, 10); + } + { + auto result = std::allocator>{}.allocate(10); + std::allocator>{}.deallocate(result, 10); + } +} +static_assert((test_compiletime_allocator(), true)); #endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) int main() { From 6cfaf584e15124b283d02d9b7162f8c6dee0a1d5 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Fri, 16 Oct 2020 12:21:15 +0100 Subject: [PATCH 10/54] Enforce clang-format Again --- .../test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 62c5e6fe785..45ebd8a446a 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -363,7 +363,7 @@ constexpr void test_compiletime_allocator_traits() { static_assert((test_compiletime_allocator_traits(), true)); constexpr void test_compiletime_allocator() { - { + { auto result = std::allocator>{}.allocate(10); std::allocator>{}.deallocate(result, 10); } From 3ca91cf733872ed41e0ccc5f5ac05b269e9d3b56 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Fri, 16 Oct 2020 20:15:02 +0100 Subject: [PATCH 11/54] Modify allocator_traits:: construct and destroy This commit assumes a3e3dc8 is merged first --- stl/inc/xmemory | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 381943f8c5b..aa36b2b2f14 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -560,8 +560,11 @@ struct _Normal_allocator_traits { // defines traits for allocators static _CONSTEXPR20_DYNALLOC void construct(_Alloc& _Al, _Ty* _Ptr, _Types&&... _Args) { if constexpr (_Uses_default_construct<_Alloc, _Ty*, _Types...>::value) { (void) _Al; // TRANSITION, DevCom-1004719 - // construct_at(_Ptr, _STD forward<_Types>(_Args)...); +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) + construct_at(_Ptr, _STD forward<_Types>(_Args)...); +#else ::new (static_cast(_Ptr)) _Ty(_STD forward<_Types>(_Args)...); +#endif } else { _Al.construct(_Ptr, _STD forward<_Types>(_Args)...); } @@ -589,8 +592,11 @@ struct _Normal_allocator_traits { // defines traits for allocators static _CONSTEXPR20_DYNALLOC void destroy(_Alloc& _Al, _Ty* _Ptr) { if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { (void) _Al; - // destroy_at(_Ptr) +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) + destroy_at(_Ptr) +#else _Ptr->~_Ty(); +#endif } else { _Al.destroy(_Ptr); } From d90e6f9cb42e7401d228f023fe66814a3c1063e7 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Fri, 16 Oct 2020 20:19:13 +0100 Subject: [PATCH 12/54] Modify tests to fix test allocator bugs --- .../test.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 45ebd8a446a..f2c2c083da7 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -297,11 +297,12 @@ struct Alloc { using size_type = std::size_t; constexpr Alloc(int id_) noexcept : id(id_) {} - constexpr ~Alloc() = default; + constexpr Alloc(const Alloc&) = default; + constexpr ~Alloc() = default; constexpr value_type* allocate(size_t n) { assert(n == 10); - return ::operator new(n * sizeof(value_type)); + return static_cast(::operator new(n * sizeof(value_type))); } constexpr void deallocate(value_type* ptr, size_t n) { From 3ed0bc69cd1ee8e4ef897f485b38a37013baa18a Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 5 Nov 2020 04:57:51 -0800 Subject: [PATCH 13/54] Add missing semicolon Co-authored-by: Michael Schellenberger Costa --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index aa36b2b2f14..68eb7e61226 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -593,7 +593,7 @@ struct _Normal_allocator_traits { // defines traits for allocators if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { (void) _Al; #if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) - destroy_at(_Ptr) + destroy_at(_Ptr); #else _Ptr->~_Ty(); #endif From ccee00418a0f848ef76ae6b0826ab1bbce545df8 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" Date: Thu, 12 Nov 2020 21:57:13 +0000 Subject: [PATCH 14/54] Apply suggestions from code review Co-authored-by: mnatsuhara <46756417+mnatsuhara@users.noreply.github.com> --- stl/inc/xmemory | 16 ++++++++-------- stl/inc/yvals_core.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 68eb7e61226..9ee8b834821 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -561,10 +561,10 @@ struct _Normal_allocator_traits { // defines traits for allocators if constexpr (_Uses_default_construct<_Alloc, _Ty*, _Types...>::value) { (void) _Al; // TRANSITION, DevCom-1004719 #if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) - construct_at(_Ptr, _STD forward<_Types>(_Args)...); -#else + _STD construct_at(_Ptr, _STD forward<_Types>(_Args)...); +#else // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) ::new (static_cast(_Ptr)) _Ty(_STD forward<_Types>(_Args)...); -#endif +#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) } else { _Al.construct(_Ptr, _STD forward<_Types>(_Args)...); } @@ -593,10 +593,10 @@ struct _Normal_allocator_traits { // defines traits for allocators if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { (void) _Al; #if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) - destroy_at(_Ptr); -#else + _STD destroy_at(_Ptr); +#else // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) _Ptr->~_Ty(); -#endif +#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) } else { _Al.destroy(_Ptr); } @@ -713,11 +713,11 @@ struct _Default_allocator_traits { // traits for std::allocator _Ptr->~_Uty(); } - _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc&) noexcept { + _NODISCARD static _CONSTEXPR20 size_type max_size(const _Alloc&) noexcept { return static_cast(-1) / sizeof(value_type); } - _NODISCARD static _CONSTEXPR20_DYNALLOC _Alloc select_on_container_copy_construction(const _Alloc& _Al) { + _NODISCARD static _CONSTEXPR20 _Alloc select_on_container_copy_construction(const _Alloc& _Al) { return _Al; } }; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index b4e42b2c5c3..f4b095c43d1 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1199,7 +1199,7 @@ #if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) #define __cpp_lib_constexpr_dynamic_alloc 201907L -#endif +#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) #define __cpp_lib_constexpr_functional 201907L #define __cpp_lib_constexpr_iterator 201811L From 8471dad094f083f56fe6adfe1a3f71dbe053a513 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Fri, 13 Nov 2020 12:32:39 +0000 Subject: [PATCH 15/54] Update tests as per the review. Test constexpr'ness of operator== and operator != --- .../test.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index f2c2c083da7..900ae57e56d 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -376,6 +376,19 @@ constexpr void test_compiletime_allocator() { static_assert((test_compiletime_allocator(), true)); #endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#if _HAS_CXX20 +constexpr void test_compiletime_operators() { + { + auto allocatorA = std::allocator{}; + auto allocatorB = std::allocator{}; + + static_assert(allocatorA == allocatorB); + static_assert(!(allocatorA != allocatorB)); + } +} +static_assert((test_compiletime_operators(), true)); +#endif // _HAS_CXX20 + int main() { test_runtime(1234); test_runtime(string("hello world")); From ad304c80d3b90cd2da8418f9f930fe88abb9f4ba Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Mon, 23 Nov 2020 22:54:55 +0100 Subject: [PATCH 16/54] Fix tests and adopt for MSVC changes --- stl/inc/memory | 35 +---- stl/inc/xmemory | 147 ++++++++++++++---- stl/inc/xutility | 19 ++- .../test.cpp | 29 ++-- 4 files changed, 148 insertions(+), 82 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index e9050c26eee..a35e1a076ab 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -567,22 +567,7 @@ namespace ranges { }; inline constexpr _Uninitialized_fill_n_fn uninitialized_fill_n{_Not_quite_object::_Construct_tag{}}; -} // namespace ranges -#endif // __cpp_lib_concepts - -// FUNCTION TEMPLATE construct_at -#if _HAS_CXX20 -template -_CONSTEXPR20_DYNALLOC auto construct_at(_Ty* const _Location, _Types&&... _Args) noexcept( - noexcept(::new (const_cast(static_cast(_Location))) - _Ty(_STD forward<_Types>(_Args)...))) // strengthened - -> decltype( - ::new (const_cast(static_cast(_Location))) _Ty(_STD forward<_Types>(_Args)...)) { - return ::new (const_cast(static_cast(_Location))) _Ty(_STD forward<_Types>(_Args)...); -} -#ifdef __cpp_lib_concepts -namespace ranges { // VARIABLE ranges::construct_at class _Construct_at_fn : private _Not_quite_object { public: @@ -603,26 +588,7 @@ namespace ranges { }; inline constexpr _Construct_at_fn construct_at{_Not_quite_object::_Construct_tag{}}; -} // namespace ranges -#endif // __cpp_lib_concepts -#endif // _HAS_CXX20 -#if _HAS_CXX17 -// FUNCTION TEMPLATE destroy_at -template -_CONSTEXPR20_DYNALLOC void destroy_at(_Ty* const _Location) noexcept /* strengthened */ { -#if _HAS_CXX20 - if constexpr (is_array_v<_Ty>) { - _Destroy_range(_STD begin(*_Location), _STD end(*_Location)); - } else -#endif // _HAS_CXX20 - { - _Location->~_Ty(); - } -} - -#ifdef __cpp_lib_concepts -namespace ranges { // VARIABLE ranges::destroy_at // clang-format off template <_No_throw_input_iterator _It, _No_throw_sentinel_for<_It> _Se> @@ -648,6 +614,7 @@ namespace ranges { } // namespace ranges #endif // __cpp_lib_concepts +#if _HAS_CXX17 // FUNCTION TEMPLATE destroy template void destroy(const _NoThrowFwdIt _First, const _NoThrowFwdIt _Last) { // destroy all elements in [_First, _Last) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 9ee8b834821..aafdd9f31a9 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -73,14 +73,28 @@ _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty), // STRUCT _Default_allocate_traits struct _Default_allocate_traits { - __declspec(allocator) static _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) { +#ifdef __clang__ + _CONSTEXPR20_DYNALLOC +#endif // __clang__ + __declspec(allocator) static void* _Allocate(const size_t _Bytes) { return ::operator new(_Bytes); } #ifdef __cpp_aligned_new - __declspec(allocator) static _CONSTEXPR20_DYNALLOC - void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { - return ::operator new (_Bytes, align_val_t{_Align}); +#ifdef __clang__ + _CONSTEXPR20_DYNALLOC +#endif // __clang__ + __declspec(allocator) static void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { +#ifdef __clang__ +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + return ::operator new(_Bytes); + } else +#endif // __cpp_lib_is_constant_evaluated +#endif // __clang__ + { + return ::operator new (_Bytes, align_val_t{_Align}); + } } #endif // __cpp_aligned_new }; @@ -164,30 +178,43 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) return nullptr; } - size_t _Passed_align = _Align; +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + return _Traits::_Allocate(_Bytes); + } else +#endif // __cpp_lib_is_constant_evaluated + { + 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); - } + 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) - - return _Traits::_Allocate_aligned(_Bytes, _Passed_align); + return _Traits::_Allocate_aligned(_Bytes, _Passed_align); + } } template __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0> _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__ - size_t _Passed_align = _Align; +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + ::operator delete(_Ptr); + } else +#endif // __cpp_lib_is_constant_evaluated + { + 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); - } + 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}); + ::operator delete (_Ptr, _Bytes, align_val_t{_Passed_align}); + } } + #define _HAS_ALIGNED_NEW 1 #else // ^^^ __cpp_aligned_new ^^^ / vvv !__cpp_aligned_new vvv #define _HAS_ALIGNED_NEW 0 @@ -198,8 +225,13 @@ template = _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization - return _Allocate_manually_vector_aligned<_Traits>(_Bytes); +#ifdef __cpp_lib_is_constant_evaluated + if (!_STD is_constant_evaluated()) +#endif // __cpp_lib_is_constant_evaluated + { + 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) @@ -213,13 +245,19 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) template = 0> _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__ +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + ::operator delete(_Ptr); + } else +#endif // __cpp_lib_is_constant_evaluated + { #if defined(_M_IX86) || defined(_M_X64) - if (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization - _Adjust_manually_vector_aligned(_Ptr, _Bytes); - } + 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); + ::operator delete(_Ptr, _Bytes); + } } #undef _HAS_ALIGNED_NEW @@ -272,6 +310,21 @@ _CONSTEXPR20_DYNALLOC void _Destroy_in_place(_Ty& _Obj) noexcept { } } +#if _HAS_CXX17 +// FUNCTION TEMPLATE destroy_at +template +_CONSTEXPR20_DYNALLOC void destroy_at(_Ty* const _Location) noexcept /* strengthened */ { +#if _HAS_CXX20 + if constexpr (is_array_v<_Ty>) { + _Destroy_range(_STD begin(*_Location), _STD end(*_Location)); + } else +#endif // _HAS_CXX20 + { + _Location->~_Ty(); + } +} +#endif _HAS_CXX17 + // FUNCTION TEMPLATE _Const_cast template auto _Const_cast(_Ptrty _Ptr) noexcept { // remove constness from a fancy pointer @@ -689,23 +742,55 @@ struct _Default_allocator_traits { // traits for std::allocator using rebind_traits = allocator_traits>; _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer - allocate(_Alloc&, _CRT_GUARDOVERFLOW const size_type _Count) { - return static_cast(_Allocate<_New_alignof>(_Get_size_of_n(_Count))); + allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count) { +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + return _Al.allocate(_Count); + } else +#endif // __cpp_lib_is_constant_evaluated + { + return static_cast( + _Allocate<_New_alignof>(_Get_size_of_n(_Count))); + } } _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer - allocate(_Alloc&, _CRT_GUARDOVERFLOW const size_type _Count, const_void_pointer) { - return static_cast(_Allocate<_New_alignof>(_Get_size_of_n(_Count))); + allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count, const_void_pointer) { +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + return _Al.allocate(_Count); + } else +#endif // __cpp_lib_is_constant_evaluated + { + (void) _Al; + return static_cast( + _Allocate<_New_alignof>(_Get_size_of_n(_Count))); + } } - static _CONSTEXPR20_DYNALLOC void deallocate(_Alloc&, const pointer _Ptr, const size_type _Count) { + static _CONSTEXPR20_DYNALLOC void deallocate(_Alloc& _Al, const pointer _Ptr, const size_type _Count) { // no overflow check on the following multiply; we assume _Allocate did that check - _Deallocate<_New_alignof>(_Ptr, sizeof(value_type) * _Count); +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + return _Al.deallocate(_Ptr, _Count); + } else +#endif // __cpp_lib_is_constant_evaluated + { + (void) _Al; + _Deallocate<_New_alignof>(_Ptr, sizeof(value_type) * _Count); + } } template static _CONSTEXPR20_DYNALLOC void construct(_Alloc&, _Objty* const _Ptr, _Types&&... _Args) { - ::new (const_cast(static_cast(_Ptr))) _Objty(_STD forward<_Types>(_Args)...); +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + _STD construct_at(_Ptr, _STD forward<_Types>(_Args)...); + } else +#endif // __cpp_lib_is_constant_evaluated + { + ::new (const_cast(static_cast(_Ptr))) _Objty(_STD forward<_Types>(_Args)...); + } } template diff --git a/stl/inc/xutility b/stl/inc/xutility index 1ea28bbcb19..1f76c24555a 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -132,10 +132,27 @@ _NODISCARD constexpr void* _Voidify_iter(_Iter _It) noexcept { } } +// FUNCTION TEMPLATE construct_at +#if _HAS_CXX20 +template +_CONSTEXPR20_DYNALLOC auto construct_at(_Ty* const _Location, _Types&&... _Args) noexcept( + noexcept(::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...))) // strengthened + -> decltype(::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...)) { + return ::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...); +} +#endif _HAS_CXX20 + // FUNCTION TEMPLATE _Construct_in_place template void _Construct_in_place(_Ty& _Obj, _Types&&... _Args) noexcept(is_nothrow_constructible_v<_Ty, _Types...>) { - ::new (_Voidify_iter(_STD addressof(_Obj))) _Ty(_STD forward<_Types>(_Args)...); +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + _STD construct_at(_STD addressof(_Obj), _STD forward<_Types>(_Args)...); + } else +#endif // __cpp_lib_is_constant_evaluated + { + ::new (_Voidify_iter(_STD addressof(_Obj))) _Ty(_STD forward<_Types>(_Args)...); + } } // FUNCTION TEMPLATE _Default_construct_in_place diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 900ae57e56d..24a1b4aea5b 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -297,21 +297,19 @@ struct Alloc { using size_type = std::size_t; constexpr Alloc(int id_) noexcept : id(id_) {} - constexpr Alloc(const Alloc&) = default; - constexpr ~Alloc() = default; constexpr value_type* allocate(size_t n) { assert(n == 10); - return static_cast(::operator new(n * sizeof(value_type))); + return allocator{}.allocate(n); } constexpr void deallocate(value_type* ptr, size_t n) { assert(n == 10); - ::operator delete(ptr, n * sizeof(value_type)); + allocator{}.deallocate(ptr, n); } - constexpr Alloc select_on_container_copy_construction() const noexcept { - return Alloc{id + 1}; + constexpr Alloc select_on_container_copy_construction() const noexcept { + return Alloc{id + 1}; } constexpr size_type max_size() noexcept { @@ -331,14 +329,14 @@ constexpr void test_compiletime_allocator_traits() { assert(result != nullptr); std::allocator_traits>>::deallocate(alloc, result, 10); - std::allocator_traits>>::construct(alloc, &a.object, 10); - assert(a.object.value == 10); + std::allocator_traits>>::construct(alloc, &a.object); + assert(a.object.value == 0); std::allocator_traits>>::destroy(alloc, &a.object); - static_assert(std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); + assert(std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); - static_assert(std::allocator_traits>>::max_size() - == std::numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); + assert(std::allocator_traits>>::max_size(alloc) + == std::numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); } { storage_for> a; @@ -353,12 +351,11 @@ constexpr void test_compiletime_allocator_traits() { assert(a.object.value == 10); std::allocator_traits>>::destroy(alloc, &a.object); - static_assert( - std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); + assert(std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); - static_assert(std::allocator_traits>>::max_size() - == std::numeric_limits>::size_type>::max() - / sizeof(Alloc>::value_type)); + assert(std::allocator_traits>>::max_size(alloc) + == std::numeric_limits>::size_type>::max() + / sizeof(Alloc>::value_type)); } } static_assert((test_compiletime_allocator_traits(), true)); From a4614aa700aa0276450abbaa858aa36a0aaa5a7b Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 25 Nov 2020 22:23:31 +0000 Subject: [PATCH 17/54] Changes as requested by the last reviews - Add few more tests - more is_constant_evaluated - Remove _Voidify_Iter from memory --- stl/inc/xmemory | 23 ++++++++----- .../test.cpp | 34 ++++++++++++++++++- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index aafdd9f31a9..c8e5198415d 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -613,11 +613,11 @@ struct _Normal_allocator_traits { // defines traits for allocators static _CONSTEXPR20_DYNALLOC void construct(_Alloc& _Al, _Ty* _Ptr, _Types&&... _Args) { if constexpr (_Uses_default_construct<_Alloc, _Ty*, _Types...>::value) { (void) _Al; // TRANSITION, DevCom-1004719 -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#ifdef __cpp_lib_constexpr_dynamic_alloc _STD construct_at(_Ptr, _STD forward<_Types>(_Args)...); -#else // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#else // __cpp_lib_constexpr_dynamic_alloc ::new (static_cast(_Ptr)) _Ty(_STD forward<_Types>(_Args)...); -#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#endif // __cpp_lib_constexpr_dynamic_alloc } else { _Al.construct(_Ptr, _STD forward<_Types>(_Args)...); } @@ -645,11 +645,11 @@ struct _Normal_allocator_traits { // defines traits for allocators static _CONSTEXPR20_DYNALLOC void destroy(_Alloc& _Al, _Ty* _Ptr) { if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { (void) _Al; -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#ifdef __cpp_lib_constexpr_dynamic_alloc _STD destroy_at(_Ptr); -#else // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#else // __cpp_lib_constexpr_dynamic_alloc _Ptr->~_Ty(); -#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#endif // __cpp_lib_constexpr_dynamic_alloc } else { _Al.destroy(_Ptr); } @@ -789,13 +789,20 @@ struct _Default_allocator_traits { // traits for std::allocator } else #endif // __cpp_lib_is_constant_evaluated { - ::new (const_cast(static_cast(_Ptr))) _Objty(_STD forward<_Types>(_Args)...); + ::new (_Voidify_iter(_Ptr)) _Objty(_STD forward<_Types>(_Args)...); } } template static _CONSTEXPR20_DYNALLOC void destroy(_Alloc&, _Uty* const _Ptr) { - _Ptr->~_Uty(); +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + _STD destroy_at(_Ptr); + } else +#endif // __cpp_lib_is_constant_evaluated + { + _Ptr->~_Uty(); + } } _NODISCARD static _CONSTEXPR20 size_type max_size(const _Alloc&) noexcept { diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 24a1b4aea5b..79bc9500eed 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -291,7 +291,7 @@ struct nontrivial_A { }; }; -template +template struct Alloc { using value_type = T; using size_type = std::size_t; @@ -308,6 +308,17 @@ struct Alloc { allocator{}.deallocate(ptr, n); } + template > + constexpr void construct(value_type* ptr, value_type n) { + assert(n == 10); + allocator{}.construct(ptr, n); + } + + template > + constexpr void destroy(value_type* ptr) { + allocator{}.destroy(ptr); + } + constexpr Alloc select_on_container_copy_construction() const noexcept { return Alloc{id + 1}; } @@ -357,6 +368,27 @@ constexpr void test_compiletime_allocator_traits() { == std::numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); } + { + storage_for> a; + + std::allocator_traits, true>>::construct(alloc, &a.object, 10); + assert(a.object.value == 10); + std::allocator_traits, true>>::destroy(alloc, &a.object); + } + { + storage_for> a; + + std::allocator_traits, false, true>>::construct(alloc, &a.object, 10); + assert(a.object.value == 10); + std::allocator_traits, false, true>>::destroy(alloc, &a.object); + } + { + storage_for> a; + + std::allocator_traits, true, true>>::construct(alloc, &a.object, 10); + assert(a.object.value == 10); + std::allocator_traits, true, true>>::destroy(alloc, &a.object); + } } static_assert((test_compiletime_allocator_traits(), true)); From 740fb6507ad59111d460aef62a740c5a8af54057 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" Date: Thu, 26 Nov 2020 19:23:29 +0000 Subject: [PATCH 18/54] Apply suggestions from code review - cast an unused variable to void Co-authored-by: Michael Schellenberger Costa --- stl/inc/xmemory | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index c8e5198415d..690d85d96c5 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -749,6 +749,7 @@ struct _Default_allocator_traits { // traits for std::allocator } else #endif // __cpp_lib_is_constant_evaluated { + (void) _Al; return static_cast( _Allocate<_New_alignof>(_Get_size_of_n(_Count))); } From 92c7f940f2f64e159cd35bf234cbe713d4ebb10b Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Thu, 10 Dec 2020 12:27:29 +0000 Subject: [PATCH 19/54] Clang-format --- stl/inc/xutility | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 1f76c24555a..0d12f9ad83c 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -3903,7 +3903,7 @@ namespace ranges { subrange(_It, _Se, _Make_unsigned_like_t>) -> subrange<_It, _Se, subrange_kind::sized>; template - subrange(_Rng&&) -> subrange, sentinel_t<_Rng>, + subrange(_Rng &&) -> subrange, sentinel_t<_Rng>, (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized : subrange_kind::unsized>; From 1d2c8dbb98df474803b79ce5a6a2e313cdda7e62 Mon Sep 17 00:00:00 2001 From: Miya Natsuhara Date: Thu, 10 Dec 2020 12:32:33 -0800 Subject: [PATCH 20/54] Fix compilation errors, get tests passing, clang 11 format --- stl/inc/xmemory | 12 +++++----- stl/inc/xutility | 4 ++-- stl/inc/yvals_core.h | 4 ++-- .../test.cpp | 22 +++++++++++-------- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 690d85d96c5..8037fa8c8ad 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -114,7 +114,7 @@ static_assert(_Is_pow_2(_Big_allocation_alignment), "Big allocation alignment mu #ifdef _DEBUG constexpr size_t _Non_user_size = 2 * sizeof(void*) + _Big_allocation_alignment - 1; #else // _DEBUG -constexpr size_t _Non_user_size = sizeof(void*) + _Big_allocation_alignment - 1; +constexpr size_t _Non_user_size = sizeof(void*) + _Big_allocation_alignment - 1; #endif // _DEBUG #ifdef _WIN64 @@ -323,7 +323,7 @@ _CONSTEXPR20_DYNALLOC void destroy_at(_Ty* const _Location) noexcept /* strength _Location->~_Ty(); } } -#endif _HAS_CXX17 +#endif // _HAS_CXX17 // FUNCTION TEMPLATE _Const_cast template @@ -916,22 +916,22 @@ public: return static_cast<_Ty*>(_Allocate<_New_alignof<_Ty>>(_Get_size_of_n(_Count))); } - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD __declspec(allocator) _Ty* allocate( + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD _CONSTEXPR20_DYNALLOC __declspec(allocator) _Ty* allocate( _CRT_GUARDOVERFLOW const size_t _Count, const void*) { return allocate(_Count); } template - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS void construct(_Objty* const _Ptr, _Types&&... _Args) { + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _CONSTEXPR20_DYNALLOC void construct(_Objty* const _Ptr, _Types&&... _Args) { ::new (const_cast(static_cast(_Ptr))) _Objty(_STD forward<_Types>(_Args)...); } template - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS void destroy(_Uty* const _Ptr) { + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _CONSTEXPR20_DYNALLOC void destroy(_Uty* const _Ptr) { _Ptr->~_Uty(); } - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD size_t max_size() const noexcept { + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD _CONSTEXPR20_DYNALLOC size_t max_size() const noexcept { return static_cast(-1) / sizeof(_Ty); } }; diff --git a/stl/inc/xutility b/stl/inc/xutility index 0d12f9ad83c..c82670640a2 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -140,7 +140,7 @@ _CONSTEXPR20_DYNALLOC auto construct_at(_Ty* const _Location, _Types&&... _Args) -> decltype(::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...)) { return ::new (_Voidify_iter(_Location)) _Ty(_STD forward<_Types>(_Args)...); } -#endif _HAS_CXX20 +#endif // _HAS_CXX20 // FUNCTION TEMPLATE _Construct_in_place template @@ -3903,7 +3903,7 @@ namespace ranges { subrange(_It, _Se, _Make_unsigned_like_t>) -> subrange<_It, _Se, subrange_kind::sized>; template - subrange(_Rng &&) -> subrange, sentinel_t<_Rng>, + subrange(_Rng&&) -> subrange, sentinel_t<_Rng>, (sized_range<_Rng> || sized_sentinel_for, iterator_t<_Rng>>) ? subrange_kind::sized : subrange_kind::unsized>; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index f4b095c43d1..7758b67a1a1 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -554,7 +554,7 @@ #endif // ^^^ inline (not constexpr) in C++17 and earlier ^^^ // Functions that became constexpr in C++20 via P0784R7 -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) #define _CONSTEXPR20_DYNALLOC constexpr #else #define _CONSTEXPR20_DYNALLOC inline @@ -1197,7 +1197,7 @@ #define __cpp_lib_constexpr_algorithms 201806L #define __cpp_lib_constexpr_complex 201711L -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) #define __cpp_lib_constexpr_dynamic_alloc 201907L #endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 79bc9500eed..514599d79f8 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -1,6 +1,10 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#ifdef __cpp_constexpr_dynamic_alloc +#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING +#endif // __cpp_constexpr_dynamic_alloc + #include #include #include @@ -285,12 +289,11 @@ template struct nontrivial_A { T value; - constexpr nontrivial_A(T in = T{}) noexcept : value(in){}; - constexpr ~nontrivial_A() { - value.~T(); - }; + constexpr nontrivial_A(T in = T{}) noexcept : value(in) {} + constexpr ~nontrivial_A() {} }; +#if defined(__clang__) || defined(__EDG__) template struct Alloc { using value_type = T; @@ -308,14 +311,11 @@ struct Alloc { allocator{}.deallocate(ptr, n); } - template > - constexpr void construct(value_type* ptr, value_type n) { - assert(n == 10); + constexpr void construct(value_type* ptr, value_type n) requires(Construct) { allocator{}.construct(ptr, n); } - template > - constexpr void destroy(value_type* ptr) { + constexpr void destroy(value_type* ptr) requires(Destroy) { allocator{}.destroy(ptr); } @@ -370,6 +370,7 @@ constexpr void test_compiletime_allocator_traits() { } { storage_for> a; + Alloc, true> alloc{10}; std::allocator_traits, true>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); @@ -377,6 +378,7 @@ constexpr void test_compiletime_allocator_traits() { } { storage_for> a; + Alloc, false, true> alloc{10}; std::allocator_traits, false, true>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); @@ -384,6 +386,7 @@ constexpr void test_compiletime_allocator_traits() { } { storage_for> a; + Alloc, true, true> alloc{10}; std::allocator_traits, true, true>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); @@ -403,6 +406,7 @@ constexpr void test_compiletime_allocator() { } } static_assert((test_compiletime_allocator(), true)); +#endif // defined(__clang__ ) || defined(__EDG__) #endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) #if _HAS_CXX20 From 1b11372932d4297bf51044e788b18bffb705f2c7 Mon Sep 17 00:00:00 2001 From: Miya Natsuhara Date: Thu, 10 Dec 2020 13:48:40 -0800 Subject: [PATCH 21/54] Update feature test macro test to check when clang or EDG --- .../tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index 1aa7807505b..b5002f953fc 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -411,7 +411,7 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L); #endif #endif -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) #ifndef __cpp_lib_constexpr_dynamic_alloc #error __cpp_lib_constexpr_dynamic_alloc is not defined #elif __cpp_lib_constexpr_dynamic_alloc != 201907L From 5d16c019563f3d967894edc6990af45bbe9f3f2c Mon Sep 17 00:00:00 2001 From: Curtis Jacques Bezault Date: Thu, 10 Dec 2020 16:34:21 -0800 Subject: [PATCH 22/54] Remove XPASSing tests from XFAIL list --- tests/libcxx/expected_results.txt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 3996fe4e0ed..65b72baf910 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -15,7 +15,7 @@ std/input.output/iostreams.base/ios.base/ios.base.storage/pword.pass.cpp SKIPPED std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp FAIL # allocator. -std/utilities/memory/default.allocator/allocator.ctor.pass.cpp FAIL +std/utilities/memory/default.allocator/allocator.ctor.pass.cpp:0 FAIL # path::value_type is char assumptions std/input.output/file.streams/fstreams/filebuf.members/open_path.pass.cpp FAIL @@ -494,17 +494,15 @@ std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp FAIL # C++20 P0784R7 "More constexpr containers" std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp FAIL -std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp FAIL +std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp:0 FAIL std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp FAIL -std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp FAIL +std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp:0 FAIL std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp FAIL -std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp FAIL -std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp FAIL -std/utilities/memory/default.allocator/allocator.globals/eq.pass.cpp FAIL -std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp:1 FAIL +std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp:0 FAIL +std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp FAIL -std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp FAIL +std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp FAIL # C++20 P0896R4 "" From 1d2715fcf0d8f48b58c1aac7fa76b7eada7fbe63 Mon Sep 17 00:00:00 2001 From: Curtis Jacques Bezault Date: Thu, 10 Dec 2020 16:40:39 -0800 Subject: [PATCH 23/54] Removed something incorrect from the XFAIL list --- tests/libcxx/expected_results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 65b72baf910..ecde37b9f7c 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -15,7 +15,7 @@ std/input.output/iostreams.base/ios.base/ios.base.storage/pword.pass.cpp SKIPPED std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/null.pass.cpp FAIL # allocator. -std/utilities/memory/default.allocator/allocator.ctor.pass.cpp:0 FAIL +std/utilities/memory/default.allocator/allocator.ctor.pass.cpp FAIL # path::value_type is char assumptions std/input.output/file.streams/fstreams/filebuf.members/open_path.pass.cpp FAIL From 0badddf7f0d8ae6243cdb88f75e6d6c1d18545a5 Mon Sep 17 00:00:00 2001 From: Curtis Jacques Bezault Date: Thu, 10 Dec 2020 16:42:13 -0800 Subject: [PATCH 24/54] Test now passes for both MSVC and Clang --- tests/libcxx/expected_results.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index ecde37b9f7c..8e2925f4f41 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -499,7 +499,6 @@ std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cp std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp:0 FAIL std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp FAIL std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp:0 FAIL -std/utilities/memory/default.allocator/allocator.members/allocate.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp:0 FAIL From 9fceac7740f5eab9b00eb40a321537ac99f3866b Mon Sep 17 00:00:00 2001 From: Curtis Jacques Bezault Date: Thu, 10 Dec 2020 17:26:40 -0800 Subject: [PATCH 25/54] One more unexpectedly passing test --- tests/libcxx/expected_results.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 8e2925f4f41..d48b8f4914e 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -493,7 +493,7 @@ std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp FAIL std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp FAIL # C++20 P0784R7 "More constexpr containers" -std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp FAIL +std/utilities/memory/allocator.traits/allocator.traits.members/allocate.pass.cpp:0 FAIL std/utilities/memory/allocator.traits/allocator.traits.members/allocate_hint.pass.cpp:0 FAIL std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cpp FAIL std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp:0 FAIL From cef7d11aa26749ccc335ea8ed1889bee8860ebe9 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 13:19:57 +0000 Subject: [PATCH 26/54] Apply some code review suggestions --- stl/inc/memory | 15 +++-- stl/inc/xmemory | 16 ++--- stl/inc/xutility | 9 +-- stl/inc/yvals_core.h | 6 +- .../test.cpp | 67 +++++++++++++++---- 5 files changed, 74 insertions(+), 39 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index a35e1a076ab..cc84492ed77 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -617,7 +617,8 @@ namespace ranges { #if _HAS_CXX17 // FUNCTION TEMPLATE destroy template -void destroy(const _NoThrowFwdIt _First, const _NoThrowFwdIt _Last) { // destroy all elements in [_First, _Last) +_CONSTEXPR20_DYNALLOC void destroy( + const _NoThrowFwdIt _First, const _NoThrowFwdIt _Last) { // destroy all elements in [_First, _Last) _Adl_verify_range(_First, _Last); _Destroy_range(_Get_unwrapped(_First), _Get_unwrapped(_Last)); } @@ -642,9 +643,9 @@ namespace ranges { using _Not_quite_object::_Not_quite_object; // clang-format off - template <_No_throw_input_iterator _It, _No_throw_sentinel_for<_It> _Se> - requires destructible> - /* _CONSTEXPR20_DYNALLOC */ _It operator()(_It _First, _Se _Last) const noexcept { + template <_No_throw_input_iterator _It, _No_throw_sentinel_for<_It> _Se> + requires destructible> + _CONSTEXPR20_DYNALLOC _It operator()(_It _First, _Se _Last) const noexcept { // clang-format on _Adl_verify_range(_First, _Last); _Seek_wrapped(_First, @@ -655,7 +656,7 @@ namespace ranges { // clang-format off template <_No_throw_input_range _Rng> requires destructible> - /* _CONSTEXPR20_DYNALLOC */ borrowed_iterator_t<_Rng> operator()(_Rng&& _Range) const noexcept { + _CONSTEXPR20_DYNALLOC borrowed_iterator_t<_Rng> operator()(_Rng&& _Range) const noexcept { // clang-format on auto _First = _RANGES begin(_Range); _Seek_wrapped(_First, _RANGES _Destroy_unchecked(_Get_unwrapped(_STD move(_First)), _Uend(_Range))); @@ -669,7 +670,7 @@ namespace ranges { // FUNCTION TEMPLATE destroy_n template -_NoThrowFwdIt destroy_n(_NoThrowFwdIt _First, const _Diff _Count_raw) { +_CONSTEXPR20_DYNALLOC _NoThrowFwdIt destroy_n(_NoThrowFwdIt _First, const _Diff _Count_raw) { // destroy all elements in [_First, _First + _Count) _Algorithm_int_t<_Diff> _Count = _Count_raw; if (_Count <= 0) { @@ -699,7 +700,7 @@ namespace ranges { // clang-format off template <_No_throw_input_iterator _It> requires destructible> - /* _CONSTEXPR20_DYNALLOC */ _It operator()(_It _First, const iter_difference_t<_It> _Count) const noexcept { + _CONSTEXPR20_DYNALLOC _It operator()(_It _First, const iter_difference_t<_It> _Count) const noexcept { // clang-format on if (_Count <= 0) { return _First; diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 8037fa8c8ad..b8b0843c9fd 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -73,7 +73,7 @@ _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty), // STRUCT _Default_allocate_traits struct _Default_allocate_traits { -#ifdef __clang__ +#ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation _CONSTEXPR20_DYNALLOC #endif // __clang__ __declspec(allocator) static void* _Allocate(const size_t _Bytes) { @@ -81,11 +81,11 @@ struct _Default_allocate_traits { } #ifdef __cpp_aligned_new -#ifdef __clang__ +#ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation _CONSTEXPR20_DYNALLOC #endif // __clang__ __declspec(allocator) static void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { -#ifdef __clang__ +#ifdef __clang__ // TRANSITION, MSVC support for constexpr ::operator new #ifdef __cpp_lib_is_constant_evaluated if (_STD is_constant_evaluated()) { return ::operator new(_Bytes); @@ -694,7 +694,7 @@ struct _Normal_allocator_traits { // defines traits for allocators #endif // _HAS_IF_CONSTEXPR #if _HAS_IF_CONSTEXPR - _NODISCARD static _CONSTEXPR20 _Alloc select_on_container_copy_construction(const _Alloc& _Al) { + _NODISCARD static _CONSTEXPR20_DYNALLOC _Alloc select_on_container_copy_construction(const _Alloc& _Al) { if constexpr (_Has_select_on_container_copy_construction<_Alloc>::value) { return _Al.select_on_container_copy_construction(); } else { @@ -806,11 +806,11 @@ struct _Default_allocator_traits { // traits for std::allocator } } - _NODISCARD static _CONSTEXPR20 size_type max_size(const _Alloc&) noexcept { + _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc&) noexcept { return static_cast(-1) / sizeof(value_type); } - _NODISCARD static _CONSTEXPR20 _Alloc select_on_container_copy_construction(const _Alloc& _Al) { + _NODISCARD static _CONSTEXPR20_DYNALLOC _Alloc select_on_container_copy_construction(const _Alloc& _Al) { return _Al; } }; @@ -957,12 +957,12 @@ public: }; template -_NODISCARD _CONSTEXPR20 bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { +_NODISCARD _CONSTEXPR20_DYNALLOC bool operator==(const allocator<_Ty>&, const allocator<_Other>&) noexcept { return true; } template -_NODISCARD _CONSTEXPR20 bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) noexcept { +_NODISCARD _CONSTEXPR20_DYNALLOC bool operator!=(const allocator<_Ty>&, const allocator<_Other>&) noexcept { return false; } diff --git a/stl/inc/xutility b/stl/inc/xutility index c82670640a2..85c46af842d 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -145,14 +145,7 @@ _CONSTEXPR20_DYNALLOC auto construct_at(_Ty* const _Location, _Types&&... _Args) // FUNCTION TEMPLATE _Construct_in_place template void _Construct_in_place(_Ty& _Obj, _Types&&... _Args) noexcept(is_nothrow_constructible_v<_Ty, _Types...>) { -#ifdef __cpp_lib_is_constant_evaluated - if (_STD is_constant_evaluated()) { - _STD construct_at(_STD addressof(_Obj), _STD forward<_Types>(_Args)...); - } else -#endif // __cpp_lib_is_constant_evaluated - { - ::new (_Voidify_iter(_STD addressof(_Obj))) _Ty(_STD forward<_Types>(_Args)...); - } + ::new (_Voidify_iter(_STD addressof(_Obj))) _Ty(_STD forward<_Types>(_Args)...); } // FUNCTION TEMPLATE _Default_construct_in_place diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 7758b67a1a1..29ecbf2b1f6 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -166,6 +166,7 @@ // P0758R1 is_nothrow_convertible // P0768R1 Library Support For The Spaceship Comparison Operator <=> // P0769R2 shift_left(), shift_right() +// P0784R7 More constexpr containers // P0811R3 midpoint(), lerp() // P0879R0 constexpr For Swapping Functions // P0887R1 type_identity @@ -1197,9 +1198,10 @@ #define __cpp_lib_constexpr_algorithms 201806L #define __cpp_lib_constexpr_complex 201711L -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) +#if defined(__cpp_constexpr_dynamic_alloc) \ + && (defined(__clang__) || defined(__EDG__)) // TRANSITION, MSVC support for constexpr dynamic allocation #define __cpp_lib_constexpr_dynamic_alloc 201907L -#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#endif // defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) #define __cpp_lib_constexpr_functional 201907L #define __cpp_lib_constexpr_iterator 201811L diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 514599d79f8..5831a33a2fb 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -147,7 +147,6 @@ static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); -#if _HAS_CXX20 static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); @@ -156,16 +155,13 @@ static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); static_assert(destroy_at_noexcept()); -#endif // _HAS_CXX20 struct throwing_dtor { ~throwing_dtor() noexcept(false) {} }; static_assert(destroy_at_noexcept()); -#if _HAS_CXX20 static_assert(destroy_at_noexcept()); -#endif // _HAS_CXX20 #ifdef __cpp_lib_concepts static_assert(!can_ranges_destroy_at); @@ -209,7 +205,6 @@ void test_array(const T& val) { constexpr int N = 42; (void) val; -#if _HAS_CXX20 alignas(T) unsigned char storage[sizeof(T) * N]; using U = conditional_t, const volatile T, T>; const auto ptr = reinterpret_cast(storage); @@ -231,10 +226,9 @@ void test_array(const T& val) { ranges::destroy_at(reinterpret_cast(const_cast(ptr))); #endif // TRANSITION, VSO-1049320 #endif // __cpp_lib_concepts -#endif // _HAS_CXX20 } -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) +#ifdef __cpp_constexpr_dynamic_alloc template struct storage_for { union { @@ -293,7 +287,52 @@ struct nontrivial_A { constexpr ~nontrivial_A() {} }; -#if defined(__clang__) || defined(__EDG__) +constexpr void test_compiletime_destroy_variants() { + { + A a[10]; + for (int i = 0; i < 10; i++) { + construct_at(&a[i].value, i); + } + destroy(begin(a), end(a)); + + for (int i = 0; i < 10; i++) { + ranges::construct_at(&a[i].value, i); + } + ranges::destroy(ranges::begin(a), ranges::end(a)); + + for (int i = 0; i < 10; i++) { + ranges::construct_at(&a[i].value, i); + } + ranges::destroy(a); + } + { + A a[10]; + for (int i = 0; i < 10; i++) { + construct_at(&a[i].value, i); + } + destroy_n(begin(a), 10); + + for (int i = 0; i < 10; i++) { + ranges::construct_at(&a[i].value, i); + } + ranges::destroy_n(ranges::begin(a), 10); + } + { + nontrivial_A a[10]; + for (int i = 0; i < 10; i++) { + construct_at(&a[i].value, i); + } + destroy_n(begin(a), 10); + + for (int i = 0; i < 10; i++) { + ranges::construct_at(&a[i].value, i); + } + ranges::destroy_n(ranges::begin(a), 10); + } +} +static_assert((test_compiletime_destroy_variants(), true)); + +#ifdef __cpp_lib_constexpr_dynamic_alloc template struct Alloc { using value_type = T; @@ -406,21 +445,21 @@ constexpr void test_compiletime_allocator() { } } static_assert((test_compiletime_allocator(), true)); -#endif // defined(__clang__ ) || defined(__EDG__) -#endif // _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) -#if _HAS_CXX20 constexpr void test_compiletime_operators() { { - auto allocatorA = std::allocator{}; - auto allocatorB = std::allocator{}; + auto allocatorA = std::allocator{}; + auto allocatorB = std::allocator{}; + constexpr auto allocatorC = allocatorA; static_assert(allocatorA == allocatorB); static_assert(!(allocatorA != allocatorB)); + static_assert(allocatorA == allocatorC); } } static_assert((test_compiletime_operators(), true)); -#endif // _HAS_CXX20 +#endif // __cpp_lib_constexpr_dynamic_alloc +#endif // __cpp_constexpr_dynamic_alloc int main() { test_runtime(1234); From 5b5d0a71cc64bddb2290dffea1a862446bba766e Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 13:31:28 +0000 Subject: [PATCH 27/54] Fix format --- stl/inc/memory | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index cc84492ed77..559cb8b74cc 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -643,8 +643,8 @@ namespace ranges { using _Not_quite_object::_Not_quite_object; // clang-format off - template <_No_throw_input_iterator _It, _No_throw_sentinel_for<_It> _Se> - requires destructible> + template <_No_throw_input_iterator _It, _No_throw_sentinel_for<_It> _Se> + requires destructible> _CONSTEXPR20_DYNALLOC _It operator()(_It _First, _Se _Last) const noexcept { // clang-format on _Adl_verify_range(_First, _Last); From d076d30e4ae360dde20d7fd9f9753213491f1fbf Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 13:52:06 +0000 Subject: [PATCH 28/54] Constain ranges::destroy and ranges::destroy_n tests --- .../test.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 5831a33a2fb..b4a7a09c569 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -295,6 +295,7 @@ constexpr void test_compiletime_destroy_variants() { } destroy(begin(a), end(a)); +#ifdef __cpp_lib_concepts for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } @@ -304,6 +305,7 @@ constexpr void test_compiletime_destroy_variants() { ranges::construct_at(&a[i].value, i); } ranges::destroy(a); +#endif // __cpp_lib_concepts } { A a[10]; @@ -312,10 +314,12 @@ constexpr void test_compiletime_destroy_variants() { } destroy_n(begin(a), 10); +#ifdef __cpp_lib_concepts for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } ranges::destroy_n(ranges::begin(a), 10); +#endif // __cpp_lib_concepts } { nontrivial_A a[10]; @@ -324,10 +328,12 @@ constexpr void test_compiletime_destroy_variants() { } destroy_n(begin(a), 10); +#ifdef __cpp_lib_concepts for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } ranges::destroy_n(ranges::begin(a), 10); +#endif // __cpp_lib_concepts } } static_assert((test_compiletime_destroy_variants(), true)); From a284ffbc31f60e61cca73560aaf565c09de92a07 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 14:36:55 +0000 Subject: [PATCH 29/54] Fix decrementing a const variable --- stl/inc/memory | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stl/inc/memory b/stl/inc/memory index 559cb8b74cc..b996542096d 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -700,8 +700,9 @@ namespace ranges { // clang-format off template <_No_throw_input_iterator _It> requires destructible> - _CONSTEXPR20_DYNALLOC _It operator()(_It _First, const iter_difference_t<_It> _Count) const noexcept { + _CONSTEXPR20_DYNALLOC _It operator()(_It _First, const iter_difference_t<_It> _Count_raw) const noexcept { // clang-format on + _Algorithm_int_t> _Count = _Count_raw; if (_Count <= 0) { return _First; } From 4f83b637fe12c0f377d5118a4998e15d5f75232f Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 15:51:00 +0000 Subject: [PATCH 30/54] Correct constraints for test --- .../test.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index b4a7a09c569..fe6aa5b5068 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -228,7 +228,7 @@ void test_array(const T& val) { #endif // __cpp_lib_concepts } -#ifdef __cpp_constexpr_dynamic_alloc +#ifdef __cpp_lib_constexpr_dynamic_alloc template struct storage_for { union { @@ -338,7 +338,6 @@ constexpr void test_compiletime_destroy_variants() { } static_assert((test_compiletime_destroy_variants(), true)); -#ifdef __cpp_lib_constexpr_dynamic_alloc template struct Alloc { using value_type = T; @@ -465,7 +464,6 @@ constexpr void test_compiletime_operators() { } static_assert((test_compiletime_operators(), true)); #endif // __cpp_lib_constexpr_dynamic_alloc -#endif // __cpp_constexpr_dynamic_alloc int main() { test_runtime(1234); From 82005996edb60600927a1e89c9562bea22ba6ad4 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 16:22:35 +0000 Subject: [PATCH 31/54] Bug fix --- .../test.cpp | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index fe6aa5b5068..21c4b4cfd5f 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -294,47 +294,56 @@ constexpr void test_compiletime_destroy_variants() { construct_at(&a[i].value, i); } destroy(begin(a), end(a)); - + } #ifdef __cpp_lib_concepts + { + A a[10]; for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } ranges::destroy(ranges::begin(a), ranges::end(a)); - + } + { + A a[10]; for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } ranges::destroy(a); -#endif // __cpp_lib_concepts } +#endif // __cpp_lib_concepts { A a[10]; for (int i = 0; i < 10; i++) { construct_at(&a[i].value, i); } destroy_n(begin(a), 10); - + } #ifdef __cpp_lib_concepts + { + A a[10]; for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } ranges::destroy_n(ranges::begin(a), 10); -#endif // __cpp_lib_concepts } +#endif // __cpp_lib_concepts { + A a[10]; nontrivial_A a[10]; for (int i = 0; i < 10; i++) { construct_at(&a[i].value, i); } destroy_n(begin(a), 10); - + } #ifdef __cpp_lib_concepts + { + A a[10]; for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } ranges::destroy_n(ranges::begin(a), 10); -#endif // __cpp_lib_concepts } +#endif // __cpp_lib_concepts } static_assert((test_compiletime_destroy_variants(), true)); From 0d35c3f6faf147d34846d9cb50fb99943d142568 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 16:43:21 +0000 Subject: [PATCH 32/54] One more bug fix --- .../test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 21c4b4cfd5f..42db9e430a1 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -328,7 +328,6 @@ constexpr void test_compiletime_destroy_variants() { } #endif // __cpp_lib_concepts { - A a[10]; nontrivial_A a[10]; for (int i = 0; i < 10; i++) { construct_at(&a[i].value, i); From 9feaf8daaa78308164ae04239d29275e7040f947 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 12 Dec 2020 20:29:07 +0000 Subject: [PATCH 33/54] Use construct_at and destroy_at in tests and adjust accordingly --- stl/inc/xmemory | 8 ++++---- .../test.cpp | 8 ++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index b8b0843c9fd..9f8b354da90 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -916,22 +916,22 @@ public: return static_cast<_Ty*>(_Allocate<_New_alignof<_Ty>>(_Get_size_of_n(_Count))); } - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD _CONSTEXPR20_DYNALLOC __declspec(allocator) _Ty* allocate( + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD __declspec(allocator) _Ty* allocate( _CRT_GUARDOVERFLOW const size_t _Count, const void*) { return allocate(_Count); } template - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _CONSTEXPR20_DYNALLOC void construct(_Objty* const _Ptr, _Types&&... _Args) { + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS void construct(_Objty* const _Ptr, _Types&&... _Args) { ::new (const_cast(static_cast(_Ptr))) _Objty(_STD forward<_Types>(_Args)...); } template - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _CONSTEXPR20_DYNALLOC void destroy(_Uty* const _Ptr) { + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS void destroy(_Uty* const _Ptr) { _Ptr->~_Uty(); } - _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD _CONSTEXPR20_DYNALLOC size_t max_size() const noexcept { + _CXX17_DEPRECATE_OLD_ALLOCATOR_MEMBERS _NODISCARD size_t max_size() const noexcept { return static_cast(-1) / sizeof(_Ty); } }; diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 42db9e430a1..732ddb5078c 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#ifdef __cpp_constexpr_dynamic_alloc -#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING -#endif // __cpp_constexpr_dynamic_alloc - #include #include #include @@ -364,11 +360,11 @@ struct Alloc { } constexpr void construct(value_type* ptr, value_type n) requires(Construct) { - allocator{}.construct(ptr, n); + construct_at(ptr, n); } constexpr void destroy(value_type* ptr) requires(Destroy) { - allocator{}.destroy(ptr); + destroy_at(ptr); } constexpr Alloc select_on_container_copy_construction() const noexcept { From 6207dbc9c7b9c3a62efae78be1d920587201f88c Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Tue, 15 Dec 2020 17:28:47 +0000 Subject: [PATCH 34/54] Add tracking comments for GH-1532 --- stl/inc/xmemory | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 9f8b354da90..dac1fbd6b43 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -178,7 +178,7 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) return nullptr; } -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Traits::_Allocate(_Bytes); } else @@ -198,7 +198,7 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) template __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0> _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { ::operator delete(_Ptr); } else @@ -225,7 +225,7 @@ template = 0> _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { ::operator delete(_Ptr); } else @@ -743,7 +743,7 @@ struct _Default_allocator_traits { // traits for std::allocator _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count) { -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Al.allocate(_Count); } else @@ -757,7 +757,7 @@ struct _Default_allocator_traits { // traits for std::allocator _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count, const_void_pointer) { -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Al.allocate(_Count); } else @@ -771,7 +771,7 @@ struct _Default_allocator_traits { // traits for std::allocator static _CONSTEXPR20_DYNALLOC void deallocate(_Alloc& _Al, const pointer _Ptr, const size_type _Count) { // no overflow check on the following multiply; we assume _Allocate did that check -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Al.deallocate(_Ptr, _Count); } else From 8fb45c0ef7b9a9e4e505a2d86d5e066c3f46b48b Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" Date: Sat, 19 Dec 2020 09:46:39 +0000 Subject: [PATCH 35/54] Apply suggestions from code review Co-authored-by: mnatsuhara <46756417+mnatsuhara@users.noreply.github.com> --- stl/inc/xmemory | 1 - tests/libcxx/expected_results.txt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index dac1fbd6b43..71579e4d098 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -214,7 +214,6 @@ _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept } } - #define _HAS_ALIGNED_NEW 1 #else // ^^^ __cpp_aligned_new ^^^ / vvv !__cpp_aligned_new vvv #define _HAS_ALIGNED_NEW 0 diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index d48b8f4914e..fdd4d3ccc31 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -502,7 +502,7 @@ std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp:0 FAIL -std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp FAIL +std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp:0 FAIL # C++20 P0896R4 "" std/language.support/support.limits/support.limits.general/algorithm.version.pass.cpp FAIL From 328000599ff6bbf38d15c34fabd3415626a75a1b Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 19 Dec 2020 11:35:06 +0000 Subject: [PATCH 36/54] Apply code review suggestions --- stl/inc/xmemory | 9 +-------- stl/inc/yvals_core.h | 3 ++- tests/libcxx/expected_results.txt | 2 ++ .../test.cpp | 10 ++++++---- .../test.compile.pass.cpp | 3 ++- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 71579e4d098..acbd171a9a2 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -795,14 +795,7 @@ struct _Default_allocator_traits { // traits for std::allocator template static _CONSTEXPR20_DYNALLOC void destroy(_Alloc&, _Uty* const _Ptr) { -#ifdef __cpp_lib_is_constant_evaluated - if (_STD is_constant_evaluated()) { - _STD destroy_at(_Ptr); - } else -#endif // __cpp_lib_is_constant_evaluated - { - _Ptr->~_Uty(); - } + _STD destroy_at(_Ptr); } _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc&) noexcept { diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 29ecbf2b1f6..3b1a847ba3b 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -555,7 +555,8 @@ #endif // ^^^ inline (not constexpr) in C++17 and earlier ^^^ // Functions that became constexpr in C++20 via P0784R7 -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) \ + && (defined(__clang__) || defined(__EDG__)) // TRANSITION, MSVC support for constexpr dynamic allocation #define _CONSTEXPR20_DYNALLOC constexpr #else #define _CONSTEXPR20_DYNALLOC inline diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index fdd4d3ccc31..3dae7431a06 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -499,6 +499,8 @@ std/utilities/memory/allocator.traits/allocator.traits.members/construct.pass.cp std/utilities/memory/allocator.traits/allocator.traits.members/deallocate.pass.cpp:0 FAIL std/utilities/memory/allocator.traits/allocator.traits.members/destroy.pass.cpp FAIL std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp:0 FAIL +std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp:0 FAIL +std/utilities/memory/default.allocator/allocator.globals/eq.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp:0 FAIL diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 732ddb5078c..3514accb8fb 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -293,11 +293,13 @@ constexpr void test_compiletime_destroy_variants() { } #ifdef __cpp_lib_concepts { - A a[10]; + auto alloc = allocator>{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - ranges::construct_at(&a[i].value, i); + ranges::construct_at(a + i); } - ranges::destroy(ranges::begin(a), ranges::end(a)); + ranges::destroy(a, a + 10); + alloc.deallocate(a, 10); } { A a[10]; @@ -332,7 +334,7 @@ constexpr void test_compiletime_destroy_variants() { } #ifdef __cpp_lib_concepts { - A a[10]; + nontrivial_A a[10]; for (int i = 0; i < 10; i++) { ranges::construct_at(&a[i].value, i); } diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index b5002f953fc..cb1b2801491 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -411,7 +411,8 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L); #endif #endif -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) +#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) \ + && (defined(__clang__) || defined(__EDG__)) // TRANSITION, MSVC support for constexpr dynamic allocation #ifndef __cpp_lib_constexpr_dynamic_alloc #error __cpp_lib_constexpr_dynamic_alloc is not defined #elif __cpp_lib_constexpr_dynamic_alloc != 201907L From 7286a4bbae96d25a4251d1fa6e909860e1c4898c Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 19 Dec 2020 11:51:35 +0000 Subject: [PATCH 37/54] Revert back _Default_allocator_traits::destroy --- stl/inc/xmemory | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index acbd171a9a2..71579e4d098 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -795,7 +795,14 @@ struct _Default_allocator_traits { // traits for std::allocator template static _CONSTEXPR20_DYNALLOC void destroy(_Alloc&, _Uty* const _Ptr) { - _STD destroy_at(_Ptr); +#ifdef __cpp_lib_is_constant_evaluated + if (_STD is_constant_evaluated()) { + _STD destroy_at(_Ptr); + } else +#endif // __cpp_lib_is_constant_evaluated + { + _Ptr->~_Uty(); + } } _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc&) noexcept { From 8f38fc3e252170683f9885628fccdb29c61fb0f2 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 19 Dec 2020 13:46:12 +0000 Subject: [PATCH 38/54] Update tests to avoid object lifetime errors --- .../test.cpp | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 3514accb8fb..7f7e3234de1 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -291,6 +291,13 @@ constexpr void test_compiletime_destroy_variants() { } destroy(begin(a), end(a)); } + { + nontrivial_A a[10]; + for (int i = 0; i < 10; i++) { + construct_at(&a[i].value, i); + } + destroy(begin(a), end(a)); + } #ifdef __cpp_lib_concepts { auto alloc = allocator>{}; @@ -302,11 +309,13 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - A a[10]; + auto alloc = allocator>{}; + nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - ranges::construct_at(&a[i].value, i); + ranges::construct_at(a + i); } - ranges::destroy(a); + ranges::destroy(a, a + 10); + alloc.deallocate(a, 10); } #endif // __cpp_lib_concepts { @@ -316,15 +325,6 @@ constexpr void test_compiletime_destroy_variants() { } destroy_n(begin(a), 10); } -#ifdef __cpp_lib_concepts - { - A a[10]; - for (int i = 0; i < 10; i++) { - ranges::construct_at(&a[i].value, i); - } - ranges::destroy_n(ranges::begin(a), 10); - } -#endif // __cpp_lib_concepts { nontrivial_A a[10]; for (int i = 0; i < 10; i++) { @@ -334,11 +334,22 @@ constexpr void test_compiletime_destroy_variants() { } #ifdef __cpp_lib_concepts { - nontrivial_A a[10]; + auto alloc = std::allocator>{}; + A* a = alloc.allocate(10); + for (int i = 0; i < 10; i++) { + ranges::construct_at(a + i); + } + ranges::destroy_n(a, 10); + alloc.deallocate(a, 10); + } + { + auto alloc = std::allocator>{}; + nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - ranges::construct_at(&a[i].value, i); + ranges::construct_at(a + i); } - ranges::destroy_n(ranges::begin(a), 10); + ranges::destroy_n(a, 10); + alloc.deallocate(a, 10); } #endif // __cpp_lib_concepts } From bc489eecb4543e72d288fec543b4c833ea65dd9a Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Sat, 19 Dec 2020 14:29:31 +0000 Subject: [PATCH 39/54] More test fixes --- tests/libcxx/expected_results.txt | 2 +- .../test.cpp | 32 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 3dae7431a06..8961a1cc341 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -502,7 +502,7 @@ std/utilities/memory/allocator.traits/allocator.traits.members/max_size.pass.cpp std/utilities/memory/allocator.traits/allocator.traits.members/select_on_container_copy_construction.pass.cpp:0 FAIL std/utilities/memory/default.allocator/allocator.globals/eq.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp FAIL -std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp FAIL +std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp:0 FAIL std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp:0 FAIL diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 7f7e3234de1..064abe104ad 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -285,18 +285,22 @@ struct nontrivial_A { constexpr void test_compiletime_destroy_variants() { { - A a[10]; + auto alloc = allocator>{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - construct_at(&a[i].value, i); + construct_at(a + i); } - destroy(begin(a), end(a)); + destroy(a, a + 10); + alloc.deallocate(a, 10); } { - nontrivial_A a[10]; + auto alloc = allocator>{}; + nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - construct_at(&a[i].value, i); + construct_at(a + i); } - destroy(begin(a), end(a)); + destroy(a, a + 10); + alloc.deallocate(a, 10); } #ifdef __cpp_lib_concepts { @@ -319,18 +323,22 @@ constexpr void test_compiletime_destroy_variants() { } #endif // __cpp_lib_concepts { - A a[10]; + auto alloc = allocator>{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - construct_at(&a[i].value, i); + construct_at(a + i); } - destroy_n(begin(a), 10); + destroy_n(a, 10); + alloc.deallocate(a, 10); } { - nontrivial_A a[10]; + auto alloc = allocator>{}; + nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; i++) { - construct_at(&a[i].value, i); + construct_at(a + i); } - destroy_n(begin(a), 10); + destroy_n(a, 10); + alloc.deallocate(a, 10); } #ifdef __cpp_lib_concepts { From 686b5198ee123c07153a9e4dfabddf4ab9fae1f5 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 01:15:15 +0000 Subject: [PATCH 40/54] Change _Default_allocator_traits::destroy --- stl/inc/xmemory | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 71579e4d098..604ef1fc670 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -795,14 +795,11 @@ struct _Default_allocator_traits { // traits for std::allocator template static _CONSTEXPR20_DYNALLOC void destroy(_Alloc&, _Uty* const _Ptr) { -#ifdef __cpp_lib_is_constant_evaluated - if (_STD is_constant_evaluated()) { - _STD destroy_at(_Ptr); - } else -#endif // __cpp_lib_is_constant_evaluated - { - _Ptr->~_Uty(); - } +#ifdef __cpp_lib_constexpr_dynamic_alloc + _STD destroy_at(_Ptr); +#else + _Ptr->~Uty(); +#endif // __cpp_lib_constexpr_dynamic_alloc } _NODISCARD static _CONSTEXPR20_DYNALLOC size_type max_size(const _Alloc&) noexcept { From 580db383fd6685a08a49259d8b86d76a30fab166 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 01:35:58 +0000 Subject: [PATCH 41/54] Fix a typo --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 604ef1fc670..f7d96f83bd6 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -798,7 +798,7 @@ struct _Default_allocator_traits { // traits for std::allocator #ifdef __cpp_lib_constexpr_dynamic_alloc _STD destroy_at(_Ptr); #else - _Ptr->~Uty(); + _Ptr->~_Uty(); #endif // __cpp_lib_constexpr_dynamic_alloc } From 0f9faf684936988cd35058181f150c5cc317efb9 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 03:34:38 +0000 Subject: [PATCH 42/54] Add missing test cases --- .../test.cpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 064abe104ad..50890ba625b 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -321,6 +321,26 @@ constexpr void test_compiletime_destroy_variants() { ranges::destroy(a, a + 10); alloc.deallocate(a, 10); } + { + auto alloc = allocator>{}; + A* a = alloc.allocate(10); + for (int i = 0; i < 10; i++) { + ranges::construct_at(a + i); + } + std::span s{a, 10}; + ranges::destroy(s); + alloc.deallocate(a, 10); + } + { + auto alloc = allocator>{}; + nontrivial_A* a = alloc.allocate(10); + for (int i = 0; i < 10; i++) { + ranges::construct_at(a + i); + } + std::span s{a, 10}; + ranges::destroy(s); + alloc.deallocate(a, 10); + } #endif // __cpp_lib_concepts { auto alloc = allocator>{}; From ed0a23369c4b834a615236c5fcf7d834e2ee8aab Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 18:02:17 +0000 Subject: [PATCH 43/54] Update transition comment to be unified --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index f7d96f83bd6..2d8c3c8c7c6 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -85,7 +85,7 @@ struct _Default_allocate_traits { _CONSTEXPR20_DYNALLOC #endif // __clang__ __declspec(allocator) static void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { -#ifdef __clang__ // TRANSITION, MSVC support for constexpr ::operator new +#ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation #ifdef __cpp_lib_is_constant_evaluated if (_STD is_constant_evaluated()) { return ::operator new(_Bytes); From 19f05588d789fb42698c24ca9cd9ae80fce440af Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 18:22:39 +0000 Subject: [PATCH 44/54] Add more test coverage and missing includes --- .../test.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 50890ba625b..b50840db0a1 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #pragma warning(disable : 4582) // '%s': constructor is not implicitly called #pragma warning(disable : 4583) // '%s': destructor is not implicitly called @@ -379,6 +380,16 @@ constexpr void test_compiletime_destroy_variants() { ranges::destroy_n(a, 10); alloc.deallocate(a, 10); } +#endif // __cpp_lib_concepts + { + A a[10] = {}; + destroy_at(&a); + } +#ifdef __cpp_lib_concepts + { + A a[10] = {}; + ranges::destroy_at(&a); + } #endif // __cpp_lib_concepts } static_assert((test_compiletime_destroy_variants(), true)); From c82d16003c369778177b557e3e043f4ea070529f Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 18:28:02 +0000 Subject: [PATCH 45/54] clang-format --- .../test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index b50840db0a1..42a5b9b46cd 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -3,12 +3,12 @@ #include #include +#include #include #include #include #include #include -#include #pragma warning(disable : 4582) // '%s': constructor is not implicitly called #pragma warning(disable : 4583) // '%s': destructor is not implicitly called From cf86b05c5e86e8a91cc67a57e622c55d06414091 Mon Sep 17 00:00:00 2001 From: "Michael S. Rizkalla" <33562048+MichaelRizkalla@users.noreply.github.com> Date: Wed, 30 Dec 2020 20:43:27 +0000 Subject: [PATCH 46/54] Update tests - Removing tests that are wrongly written --- .../test.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 42a5b9b46cd..844ff2732ac 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -380,17 +380,6 @@ constexpr void test_compiletime_destroy_variants() { ranges::destroy_n(a, 10); alloc.deallocate(a, 10); } -#endif // __cpp_lib_concepts - { - A a[10] = {}; - destroy_at(&a); - } -#ifdef __cpp_lib_concepts - { - A a[10] = {}; - ranges::destroy_at(&a); - } -#endif // __cpp_lib_concepts } static_assert((test_compiletime_destroy_variants(), true)); From 84467790303831c4b41e245decac106f43b5d177 Mon Sep 17 00:00:00 2001 From: MichaelRizkalla Date: Wed, 30 Dec 2020 21:42:12 +0000 Subject: [PATCH 47/54] Revert last 3 commits and add missing include file. --- .../test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 844ff2732ac..ffcd0465ae0 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -380,6 +380,7 @@ constexpr void test_compiletime_destroy_variants() { ranges::destroy_n(a, 10); alloc.deallocate(a, 10); } +#endif // __cpp_lib_concepts } static_assert((test_compiletime_destroy_variants(), true)); From 7457abb6748cde42e47e573ec98901b95d24967f Mon Sep 17 00:00:00 2001 From: MichaelRizkalla Date: Tue, 5 Jan 2021 21:59:03 +0000 Subject: [PATCH 48/54] Change macro contraint of _Default_allocator_traits members --- stl/inc/xmemory | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 2d8c3c8c7c6..78cd70362df 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -742,11 +742,11 @@ struct _Default_allocator_traits { // traits for std::allocator _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count) { -#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 +#ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Al.allocate(_Count); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { (void) _Al; return static_cast( @@ -756,11 +756,11 @@ struct _Default_allocator_traits { // traits for std::allocator _NODISCARD static _CONSTEXPR20_DYNALLOC __declspec(allocator) pointer allocate(_Alloc& _Al, _CRT_GUARDOVERFLOW const size_type _Count, const_void_pointer) { -#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 +#ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Al.allocate(_Count); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { (void) _Al; return static_cast( @@ -770,11 +770,11 @@ struct _Default_allocator_traits { // traits for std::allocator static _CONSTEXPR20_DYNALLOC void deallocate(_Alloc& _Al, const pointer _Ptr, const size_type _Count) { // no overflow check on the following multiply; we assume _Allocate did that check -#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 +#ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Al.deallocate(_Ptr, _Count); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { (void) _Al; _Deallocate<_New_alignof>(_Ptr, sizeof(value_type) * _Count); @@ -783,11 +783,11 @@ struct _Default_allocator_traits { // traits for std::allocator template static _CONSTEXPR20_DYNALLOC void construct(_Alloc&, _Objty* const _Ptr, _Types&&... _Args) { -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_constexpr_dynamic_alloc if (_STD is_constant_evaluated()) { _STD construct_at(_Ptr, _STD forward<_Types>(_Args)...); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { ::new (_Voidify_iter(_Ptr)) _Objty(_STD forward<_Types>(_Args)...); } From ad25f3903093ef4b4c962b26b0b9740a32771cb8 Mon Sep 17 00:00:00 2001 From: MichaelRizkalla Date: Wed, 6 Jan 2021 10:09:42 +0000 Subject: [PATCH 49/54] Changes to achieve consistency --- stl/inc/xmemory | 20 +++++++++---------- .../test.cpp | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 78cd70362df..4509c902eac 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -86,11 +86,11 @@ struct _Default_allocate_traits { #endif // __clang__ __declspec(allocator) static void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { #ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation -#ifdef __cpp_lib_is_constant_evaluated +#ifdef __cpp_lib_constexpr_dynamic_alloc if (_STD is_constant_evaluated()) { return ::operator new(_Bytes); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc #endif // __clang__ { return ::operator new (_Bytes, align_val_t{_Align}); @@ -178,11 +178,11 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) return nullptr; } -#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 +#ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { return _Traits::_Allocate(_Bytes); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { size_t _Passed_align = _Align; #if defined(_M_IX86) || defined(_M_X64) @@ -198,11 +198,11 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) template __STDCPP_DEFAULT_NEW_ALIGNMENT__), int> = 0> _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, const size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when __cpp_aligned_new && _Align > __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 +#ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { ::operator delete(_Ptr); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { size_t _Passed_align = _Align; #if defined(_M_IX86) || defined(_M_X64) @@ -224,9 +224,9 @@ template = _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization return _Allocate_manually_vector_aligned<_Traits>(_Bytes); @@ -244,11 +244,11 @@ __declspec(allocator) _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) template = 0> _CONSTEXPR20_DYNALLOC void _Deallocate(void* _Ptr, size_t _Bytes) noexcept { // deallocate storage allocated by _Allocate when !_HAS_ALIGNED_NEW || _Align <= __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#ifdef __cpp_lib_is_constant_evaluated // TRANSITION, GH-1532 +#ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { ::operator delete(_Ptr); } else -#endif // __cpp_lib_is_constant_evaluated +#endif // __cpp_lib_constexpr_dynamic_alloc { #if defined(_M_IX86) || defined(_M_X64) if (_Bytes >= _Big_allocation_threshold) { // boost the alignment of big allocations to help autovectorization diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index ffcd0465ae0..e01c9d18817 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -288,7 +288,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { construct_at(a + i); } destroy(a, a + 10); @@ -297,7 +297,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; nontrivial_A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { construct_at(a + i); } destroy(a, a + 10); @@ -307,7 +307,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } ranges::destroy(a, a + 10); @@ -316,7 +316,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; nontrivial_A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } ranges::destroy(a, a + 10); @@ -325,7 +325,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } std::span s{a, 10}; @@ -335,7 +335,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; nontrivial_A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } std::span s{a, 10}; @@ -346,7 +346,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { construct_at(a + i); } destroy_n(a, 10); @@ -355,7 +355,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = allocator>{}; nontrivial_A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { construct_at(a + i); } destroy_n(a, 10); @@ -365,7 +365,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = std::allocator>{}; A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } ranges::destroy_n(a, 10); @@ -374,7 +374,7 @@ constexpr void test_compiletime_destroy_variants() { { auto alloc = std::allocator>{}; nontrivial_A* a = alloc.allocate(10); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } ranges::destroy_n(a, 10); From 0705f3fece056a9aa1a014b9f0e3057e729e7aee Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 6 Jan 2021 21:17:28 -0800 Subject: [PATCH 50/54] Drop std qualification. --- .../test.cpp | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index e01c9d18817..1ea8350255e 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -328,7 +328,7 @@ constexpr void test_compiletime_destroy_variants() { for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } - std::span s{a, 10}; + span s{a, 10}; ranges::destroy(s); alloc.deallocate(a, 10); } @@ -338,7 +338,7 @@ constexpr void test_compiletime_destroy_variants() { for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } - std::span s{a, 10}; + span s{a, 10}; ranges::destroy(s); alloc.deallocate(a, 10); } @@ -363,7 +363,7 @@ constexpr void test_compiletime_destroy_variants() { } #ifdef __cpp_lib_concepts { - auto alloc = std::allocator>{}; + auto alloc = allocator>{}; A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); @@ -372,7 +372,7 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = std::allocator>{}; + auto alloc = allocator>{}; nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); @@ -387,7 +387,7 @@ static_assert((test_compiletime_destroy_variants(), true)); template struct Alloc { using value_type = T; - using size_type = std::size_t; + using size_type = size_t; constexpr Alloc(int id_) noexcept : id(id_) {} @@ -414,7 +414,7 @@ struct Alloc { } constexpr size_type max_size() noexcept { - return std::numeric_limits::max() / sizeof(value_type); + return numeric_limits::max() / sizeof(value_type); } int id; @@ -426,81 +426,81 @@ constexpr void test_compiletime_allocator_traits() { Alloc> alloc{10}; assert(alloc.id == 10); - auto result = std::allocator_traits>>::allocate(alloc, 10); + auto result = allocator_traits>>::allocate(alloc, 10); assert(result != nullptr); - std::allocator_traits>>::deallocate(alloc, result, 10); + allocator_traits>>::deallocate(alloc, result, 10); - std::allocator_traits>>::construct(alloc, &a.object); + allocator_traits>>::construct(alloc, &a.object); assert(a.object.value == 0); - std::allocator_traits>>::destroy(alloc, &a.object); + allocator_traits>>::destroy(alloc, &a.object); - assert(std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); + assert(allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); - assert(std::allocator_traits>>::max_size(alloc) - == std::numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); + assert(allocator_traits>>::max_size(alloc) + == numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); } { storage_for> a; Alloc> alloc{10}; assert(alloc.id == 10); - auto result = std::allocator_traits>>::allocate(alloc, 10); + auto result = allocator_traits>>::allocate(alloc, 10); assert(result != nullptr); - std::allocator_traits>>::deallocate(alloc, result, 10); + allocator_traits>>::deallocate(alloc, result, 10); - std::allocator_traits>>::construct(alloc, &a.object, 10); + allocator_traits>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); - std::allocator_traits>>::destroy(alloc, &a.object); + allocator_traits>>::destroy(alloc, &a.object); - assert(std::allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); + assert(allocator_traits>>::select_on_container_copy_construction(alloc).id == 11); - assert(std::allocator_traits>>::max_size(alloc) - == std::numeric_limits>::size_type>::max() + assert(allocator_traits>>::max_size(alloc) + == numeric_limits>::size_type>::max() / sizeof(Alloc>::value_type)); } { storage_for> a; Alloc, true> alloc{10}; - std::allocator_traits, true>>::construct(alloc, &a.object, 10); + allocator_traits, true>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); - std::allocator_traits, true>>::destroy(alloc, &a.object); + allocator_traits, true>>::destroy(alloc, &a.object); } { storage_for> a; Alloc, false, true> alloc{10}; - std::allocator_traits, false, true>>::construct(alloc, &a.object, 10); + allocator_traits, false, true>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); - std::allocator_traits, false, true>>::destroy(alloc, &a.object); + allocator_traits, false, true>>::destroy(alloc, &a.object); } { storage_for> a; Alloc, true, true> alloc{10}; - std::allocator_traits, true, true>>::construct(alloc, &a.object, 10); + allocator_traits, true, true>>::construct(alloc, &a.object, 10); assert(a.object.value == 10); - std::allocator_traits, true, true>>::destroy(alloc, &a.object); + allocator_traits, true, true>>::destroy(alloc, &a.object); } } static_assert((test_compiletime_allocator_traits(), true)); constexpr void test_compiletime_allocator() { { - auto result = std::allocator>{}.allocate(10); - std::allocator>{}.deallocate(result, 10); + auto result = allocator>{}.allocate(10); + allocator>{}.deallocate(result, 10); } { - auto result = std::allocator>{}.allocate(10); - std::allocator>{}.deallocate(result, 10); + auto result = allocator>{}.allocate(10); + allocator>{}.deallocate(result, 10); } } static_assert((test_compiletime_allocator(), true)); constexpr void test_compiletime_operators() { { - auto allocatorA = std::allocator{}; - auto allocatorB = std::allocator{}; + auto allocatorA = allocator{}; + auto allocatorB = allocator{}; constexpr auto allocatorC = allocatorA; static_assert(allocatorA == allocatorB); From d86dbd8ff5766cc28637e3840e1e3dbe38512a29 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 6 Jan 2021 20:36:08 -0800 Subject: [PATCH 51/54] Code review feedback. --- stl/inc/memory | 10 +++++----- stl/inc/xmemory | 15 ++++++++------- stl/inc/yvals_core.h | 17 ++++++++--------- tests/libcxx/skipped_tests.txt | 1 - .../test.cpp | 16 +++++++++++++++- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 4156e3ec7dd..91e7860b9c3 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -546,8 +546,8 @@ namespace ranges { #if _HAS_CXX17 // FUNCTION TEMPLATE destroy template -_CONSTEXPR20_DYNALLOC void destroy( - const _NoThrowFwdIt _First, const _NoThrowFwdIt _Last) { // destroy all elements in [_First, _Last) +_CONSTEXPR20_DYNALLOC void destroy(const _NoThrowFwdIt _First, const _NoThrowFwdIt _Last) { + // destroy all elements in [_First, _Last) _Adl_verify_range(_First, _Last); _Destroy_range(_Get_unwrapped(_First), _Get_unwrapped(_Last)); } @@ -574,7 +574,7 @@ namespace ranges { // clang-format off template <_No_throw_input_iterator _It, _No_throw_sentinel_for<_It> _Se> requires destructible> - _CONSTEXPR20_DYNALLOC _It operator()(_It _First, _Se _Last) const noexcept { + _CONSTEXPR20_DYNALLOC _It operator()(_It _First, _Se _Last) const noexcept { // clang-format on _Adl_verify_range(_First, _Last); _Seek_wrapped(_First, @@ -585,7 +585,7 @@ namespace ranges { // clang-format off template <_No_throw_input_range _Rng> requires destructible> - _CONSTEXPR20_DYNALLOC borrowed_iterator_t<_Rng> operator()(_Rng&& _Range) const noexcept { + _CONSTEXPR20_DYNALLOC borrowed_iterator_t<_Rng> operator()(_Rng&& _Range) const noexcept { // clang-format on auto _First = _RANGES begin(_Range); _Seek_wrapped(_First, _RANGES _Destroy_unchecked(_Get_unwrapped(_STD move(_First)), _Uend(_Range))); @@ -629,7 +629,7 @@ namespace ranges { // clang-format off template <_No_throw_input_iterator _It> requires destructible> - _CONSTEXPR20_DYNALLOC _It operator()(_It _First, const iter_difference_t<_It> _Count_raw) const noexcept { + _CONSTEXPR20_DYNALLOC _It operator()(_It _First, const iter_difference_t<_It> _Count_raw) const noexcept { // clang-format on _Algorithm_int_t> _Count = _Count_raw; if (_Count <= 0) { diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 55b82381237..1c081514ad5 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -73,18 +73,20 @@ _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty), // STRUCT _Default_allocate_traits struct _Default_allocate_traits { + __declspec(allocator) static #ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation - _CONSTEXPR20_DYNALLOC + _CONSTEXPR20_DYNALLOC #endif // __clang__ - __declspec(allocator) static void* _Allocate(const size_t _Bytes) { + void* _Allocate(const size_t _Bytes) { return ::operator new(_Bytes); } #ifdef __cpp_aligned_new + __declspec(allocator) static #ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation - _CONSTEXPR20_DYNALLOC + _CONSTEXPR20_DYNALLOC #endif // __clang__ - __declspec(allocator) static void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { + void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { #ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation #ifdef __cpp_lib_constexpr_dynamic_alloc if (_STD is_constant_evaluated()) { @@ -604,7 +606,6 @@ struct _Normal_allocator_traits { // defines traits for allocators template static _CONSTEXPR20_DYNALLOC void destroy(_Alloc& _Al, _Ty* _Ptr) { if constexpr (_Uses_default_destroy<_Alloc, _Ty*>::value) { - (void) _Al; #ifdef __cpp_lib_constexpr_dynamic_alloc _STD destroy_at(_Ptr); #else // __cpp_lib_constexpr_dynamic_alloc @@ -689,7 +690,7 @@ struct _Default_allocator_traits { // traits for std::allocator // no overflow check on the following multiply; we assume _Allocate did that check #ifdef __cpp_lib_constexpr_dynamic_alloc // TRANSITION, GH-1532 if (_STD is_constant_evaluated()) { - return _Al.deallocate(_Ptr, _Count); + _Al.deallocate(_Ptr, _Count); } else #endif // __cpp_lib_constexpr_dynamic_alloc { @@ -714,7 +715,7 @@ struct _Default_allocator_traits { // traits for std::allocator static _CONSTEXPR20_DYNALLOC void destroy(_Alloc&, _Uty* const _Ptr) { #ifdef __cpp_lib_constexpr_dynamic_alloc _STD destroy_at(_Ptr); -#else +#else // __cpp_lib_constexpr_dynamic_alloc _Ptr->~_Uty(); #endif // __cpp_lib_constexpr_dynamic_alloc } diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 67bd4c0baf1..31a2e8b84bc 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -166,7 +166,7 @@ // P0758R1 is_nothrow_convertible // P0768R1 Library Support For The Spaceship Comparison Operator <=> // P0769R2 shift_left(), shift_right() -// P0784R7 More constexpr containers +// P0784R7 Library Support For More constexpr Containers // P0811R3 midpoint(), lerp() // P0879R0 constexpr For Swapping Functions // P0887R1 type_identity @@ -551,14 +551,6 @@ #define _CONSTEXPR20 inline #endif // ^^^ inline (not constexpr) in C++17 and earlier ^^^ -// Functions that became constexpr in C++20 via P0784R7 -#if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) \ - && (defined(__clang__) || defined(__EDG__)) // TRANSITION, MSVC support for constexpr dynamic allocation -#define _CONSTEXPR20_DYNALLOC constexpr -#else -#define _CONSTEXPR20_DYNALLOC inline -#endif - // P0607R0 Inline Variables For The STL #if _HAS_CXX17 #define _INLINE_VAR inline @@ -1263,6 +1255,13 @@ #define __cpp_lib_experimental_erase_if 201411L #define __cpp_lib_experimental_filesystem 201406L +// Functions that became constexpr in C++20 via P0784R7 +#ifdef __cpp_lib_constexpr_dynamic_alloc +#define _CONSTEXPR20_DYNALLOC constexpr +#else +#define _CONSTEXPR20_DYNALLOC inline +#endif + #ifdef _RTC_CONVERSION_CHECKS_ENABLED #ifndef _ALLOW_RTCc_IN_STL #error /RTCc rejects conformant code, so it is not supported by the C++ Standard Library. Either remove this \ diff --git a/tests/libcxx/skipped_tests.txt b/tests/libcxx/skipped_tests.txt index b5172f6cdba..61b46acc242 100644 --- a/tests/libcxx/skipped_tests.txt +++ b/tests/libcxx/skipped_tests.txt @@ -501,7 +501,6 @@ utilities\memory\allocator.traits\allocator.traits.members\destroy.pass.cpp utilities\memory\allocator.traits\allocator.traits.members\max_size.pass.cpp utilities\memory\allocator.traits\allocator.traits.members\select_on_container_copy_construction.pass.cpp utilities\memory\default.allocator\allocator.globals\eq.pass.cpp -utilities\memory\default.allocator\allocator.members\allocate.pass.cpp utilities\memory\specialized.algorithms\specialized.construct\construct_at.pass.cpp utilities\memory\specialized.algorithms\specialized.destroy\destroy.pass.cpp utilities\memory\specialized.algorithms\specialized.destroy\destroy_at.pass.cpp diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index 1ea8350255e..fc78b4a5c08 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include #include #include @@ -389,8 +390,16 @@ struct Alloc { using value_type = T; using size_type = size_t; + template + struct rebind { + using other = Alloc; + }; + constexpr Alloc(int id_) noexcept : id(id_) {} + template + constexpr Alloc(const Alloc& al) noexcept : id(al.id) {} + constexpr value_type* allocate(size_t n) { assert(n == 10); return allocator{}.allocate(n); @@ -413,10 +422,15 @@ struct Alloc { return Alloc{id + 1}; } - constexpr size_type max_size() noexcept { + constexpr size_type max_size() const noexcept { return numeric_limits::max() / sizeof(value_type); } + template + constexpr bool operator==(const Alloc&) const noexcept { + return true; + } + int id; }; From a2bd52f94f9607ad1219bd15876cb94f40dc8c56 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 6 Jan 2021 20:38:35 -0800 Subject: [PATCH 52/54] Avoid verbose auto. --- .../test.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp index fc78b4a5c08..52da34b9f96 100644 --- a/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp +++ b/tests/std/tests/P0784R7_library_support_for_more_constexpr_containers/test.cpp @@ -287,8 +287,8 @@ struct nontrivial_A { constexpr void test_compiletime_destroy_variants() { { - auto alloc = allocator>{}; - A* a = alloc.allocate(10); + allocator> alloc{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { construct_at(a + i); } @@ -296,7 +296,7 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = allocator>{}; + allocator> alloc{}; nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { construct_at(a + i); @@ -306,8 +306,8 @@ constexpr void test_compiletime_destroy_variants() { } #ifdef __cpp_lib_concepts { - auto alloc = allocator>{}; - A* a = alloc.allocate(10); + allocator> alloc{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } @@ -315,7 +315,7 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = allocator>{}; + allocator> alloc{}; nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); @@ -324,8 +324,8 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = allocator>{}; - A* a = alloc.allocate(10); + allocator> alloc{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } @@ -334,7 +334,7 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = allocator>{}; + allocator> alloc{}; nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); @@ -345,8 +345,8 @@ constexpr void test_compiletime_destroy_variants() { } #endif // __cpp_lib_concepts { - auto alloc = allocator>{}; - A* a = alloc.allocate(10); + allocator> alloc{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { construct_at(a + i); } @@ -354,7 +354,7 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = allocator>{}; + allocator> alloc{}; nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { construct_at(a + i); @@ -364,8 +364,8 @@ constexpr void test_compiletime_destroy_variants() { } #ifdef __cpp_lib_concepts { - auto alloc = allocator>{}; - A* a = alloc.allocate(10); + allocator> alloc{}; + A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); } @@ -373,7 +373,7 @@ constexpr void test_compiletime_destroy_variants() { alloc.deallocate(a, 10); } { - auto alloc = allocator>{}; + allocator> alloc{}; nontrivial_A* a = alloc.allocate(10); for (int i = 0; i < 10; ++i) { ranges::construct_at(a + i); @@ -513,8 +513,8 @@ static_assert((test_compiletime_allocator(), true)); constexpr void test_compiletime_operators() { { - auto allocatorA = allocator{}; - auto allocatorB = allocator{}; + allocator allocatorA{}; + allocator allocatorB{}; constexpr auto allocatorC = allocatorA; static_assert(allocatorA == allocatorB); From bf1c2ece9aea8249e2981409128fbb82db2dc15d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 6 Jan 2021 20:45:23 -0800 Subject: [PATCH 53/54] Adjust compiler guards. --- stl/inc/xmemory | 13 ++----------- stl/inc/yvals_core.h | 4 ++-- .../test.compile.pass.cpp | 2 +- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 1c081514ad5..ec0e9b41cb1 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -73,27 +73,18 @@ _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty), // STRUCT _Default_allocate_traits struct _Default_allocate_traits { - __declspec(allocator) static -#ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation - _CONSTEXPR20_DYNALLOC -#endif // __clang__ - void* _Allocate(const size_t _Bytes) { + __declspec(allocator) static _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) { return ::operator new(_Bytes); } #ifdef __cpp_aligned_new - __declspec(allocator) static -#ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation - _CONSTEXPR20_DYNALLOC -#endif // __clang__ + __declspec(allocator) static _CONSTEXPR20_DYNALLOC void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { -#ifdef __clang__ // TRANSITION, MSVC support for constexpr dynamic allocation #ifdef __cpp_lib_constexpr_dynamic_alloc if (_STD is_constant_evaluated()) { return ::operator new(_Bytes); } else #endif // __cpp_lib_constexpr_dynamic_alloc -#endif // __clang__ { return ::operator new (_Bytes, align_val_t{_Align}); } diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 31a2e8b84bc..28011748cb5 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1183,9 +1183,9 @@ #define __cpp_lib_constexpr_complex 201711L #if defined(__cpp_constexpr_dynamic_alloc) \ - && (defined(__clang__) || defined(__EDG__)) // TRANSITION, MSVC support for constexpr dynamic allocation + && defined(__clang__) // TRANSITION, MSVC support for constexpr dynamic allocation #define __cpp_lib_constexpr_dynamic_alloc 201907L -#endif // defined(__cpp_constexpr_dynamic_alloc) && (defined(__clang__) || defined(__EDG__)) +#endif // defined(__cpp_constexpr_dynamic_alloc) && defined(__clang__) #define __cpp_lib_constexpr_functional 201907L #define __cpp_lib_constexpr_iterator 201811L diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index cb1b2801491..9a6cd10c972 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -412,7 +412,7 @@ STATIC_ASSERT(__cpp_lib_constexpr_complex == 201711L); #endif #if _HAS_CXX20 && defined(__cpp_constexpr_dynamic_alloc) \ - && (defined(__clang__) || defined(__EDG__)) // TRANSITION, MSVC support for constexpr dynamic allocation + && defined(__clang__) // TRANSITION, MSVC support for constexpr dynamic allocation #ifndef __cpp_lib_constexpr_dynamic_alloc #error __cpp_lib_constexpr_dynamic_alloc is not defined #elif __cpp_lib_constexpr_dynamic_alloc != 201907L From 4ccb165be0db8d597e2b0e566292cdb82543d05d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 7 Jan 2021 15:07:57 -0800 Subject: [PATCH 54/54] Fix compiler guards, add comments. --- stl/inc/xmemory | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index ec0e9b41cb1..38209d5c9cd 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -73,18 +73,27 @@ _INLINE_VAR constexpr size_t _New_alignof = (_STD max)(alignof(_Ty), // STRUCT _Default_allocate_traits struct _Default_allocate_traits { - __declspec(allocator) static _CONSTEXPR20_DYNALLOC void* _Allocate(const size_t _Bytes) { + __declspec(allocator) static +#ifdef __clang__ // Clang and MSVC implement P0784R7 differently; see GH-1532 + _CONSTEXPR20_DYNALLOC +#endif // __clang__ + void* _Allocate(const size_t _Bytes) { return ::operator new(_Bytes); } #ifdef __cpp_aligned_new - __declspec(allocator) static _CONSTEXPR20_DYNALLOC + __declspec(allocator) static +#ifdef __clang__ // Clang and MSVC implement P0784R7 differently; see GH-1532 + _CONSTEXPR20_DYNALLOC +#endif // __clang__ void* _Allocate_aligned(const size_t _Bytes, const size_t _Align) { +#ifdef __clang__ // Clang and MSVC implement P0784R7 differently; see GH-1532 #ifdef __cpp_lib_constexpr_dynamic_alloc if (_STD is_constant_evaluated()) { return ::operator new(_Bytes); } else #endif // __cpp_lib_constexpr_dynamic_alloc +#endif // __clang__ { return ::operator new (_Bytes, align_val_t{_Align}); }