From 6eedf4ab257a74e0f65f821056047020c48a5b7c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 00:19:23 +0800 Subject: [PATCH 01/21] Implement LWG-3525 I think the resolution should be applied back to pre-C++20, so some implementation details are provided in all modes. --- stl/inc/xmemory | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 9e8f84edf5..f3ccc1aad7 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2066,6 +2066,30 @@ typename _Container::size_type _Erase_nodes_if(_Container& _Cont, _Pr _Pred) { return _Old_size - _Cont.size(); } +template +void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); + +template +_INLINE_VAR constexpr bool _Cannot_as_pair = true; + +template +_INLINE_VAR constexpr bool _Cannot_as_pair<_Ty, void_t()))>> = false; + +template +const _Ty& _Normally_bind(const _Ty&); + +template +_Ty&& _Normally_bind(_Ty&&); + +template +using _Normally_bound_ref = decltype(_STD _Normally_bind(_STD declval<_Uty>())); + +template +_INLINE_VAR constexpr bool _Is_normally_bindable = false; + +template +_INLINE_VAR constexpr bool _Is_normally_bindable<_Ty, _Uty, void_t<_Normally_bound_ref<_Ty, _Uty>>> = false; + #if _HAS_CXX20 template , int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Types&&... _Args) noexcept { @@ -2098,6 +2122,10 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, co template , int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>&& _Pair) noexcept; +template && _Cannot_as_pair<_Uty>, int> = 0> +_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept; + template , int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args( const _Alloc& _Al, piecewise_construct_t, _Tuple1&& _Tup1, _Tuple2&& _Tup2) noexcept { @@ -2168,6 +2196,44 @@ constexpr _Ty* uninitialized_construct_using_allocator(_Ty* _Ptr, const _Alloc& }, _STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); } + +template && _Cannot_as_pair<_Uty&>, int>> +_NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept { + struct _Pair_remaker { + using _Pair_t = remove_cv_t<_Ty>; + + const _Alloc& _Al; + _Uty& _Ux; + + constexpr operator _Pair_t() const { + static_assert(_Is_normally_bindable<_Pair_t, _Uty>, + "The argument must be bindable to a reference to the std::pair type."); + + using _Pair_first_t = typename _Pair_t::first_type; + using _Pair_second_t = typename _Pair_t::second_type; + using _Pair_ref_t = _Normally_bound_ref<_Pair_t, _Uty>; + _Pair_ref_t _Pair_ref = _STD forward<_Uty>(_Ux); + if constexpr (is_same_v<_Pair_ref_t, const _Pair_t&>) { + // equivalent to + // return _STD make_obj_using_allocator<_Pair_t>(_Al, _Pair_ref); + return _STD make_tuple(piecewise_construct, + _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _Pair_ref.first), + _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _Pair_ref.second)); + } else { + // equivalent to + // return _STD make_obj_using_allocator<_Pair_t>(_Al, _STD move(_Pair_ref)); + return _STD make_tuple(piecewise_construct, + _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _STD get<0>(_STD move(_Pair_ref))), + _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))); + } + } + }; + + // equivalent to + // return _STD make_tuple(_Pair_remaker{_Al, _Ux}); + return tuple<_Pair_remaker>({_Al, _Ux}); +} #endif // _HAS_CXX20 _STD_END From 9cf052fbd51fa10fb4b6173ba88133fa0c7d96c1 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 00:46:43 +0800 Subject: [PATCH 02/21] Implement LWG-3525 in pre-C++20 modes --- stl/inc/xpolymorphic_allocator.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/stl/inc/xpolymorphic_allocator.h b/stl/inc/xpolymorphic_allocator.h index 733bae6409..019402e607 100644 --- a/stl/inc/xpolymorphic_allocator.h +++ b/stl/inc/xpolymorphic_allocator.h @@ -104,6 +104,26 @@ void _Uses_allocator_construct( _Uses_allocator_construct_pair(_Ptr, _Outer, _Inner, _STD forward_as_tuple(_STD forward<_Uty>(_Pair.first)), _STD forward_as_tuple(_STD forward<_Vty>(_Pair.second))); } + +template , int> = 0> +void _Uses_allocator_construct( + pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, _Uty&& _Ux) { + // uses-allocator construction of pair by alloc _Outer propagating alloc _Inner, non-pair argument + static_assert(_Is_normally_bindable, _Uty>, + "The argument must be bindable to a reference to the std::pair type."); + + using _Pair_ref_t = _Normally_bound_ref, _Uty>; + _Pair_ref_t _Pair_ref = _STD forward<_Uty>(_Ux); + if constexpr (is_same_v<_Pair_ref_t, const pair<_Ty1, _Ty2>&>) { + _Uses_allocator_construct_pair( + _Ptr, _Outer, _Inner, _STD forward_as_tuple(_Pair_ref.first), _STD forward_as_tuple(_Pair_ref.second)); + } else { + _Uses_allocator_construct_pair( + _Ptr, _Outer, _Inner, _STD forward_as_tuple(_STD forward<_Ty1>(_Pair_ref.first)), + _STD forward_as_tuple(_STD forward<_Ty2>(_Pair_ref.second))); + } +} #endif // !_HAS_CXX20 #if _HAS_CXX17 From b71ce5fa96a79cb7b15605e7a8a1ae724e4350a0 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 01:33:44 +0800 Subject: [PATCH 03/21] Add test cases for LWG-3525 --- .../test.cpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp b/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp index 2f07716f71..72fb8fdf16 100644 --- a/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp +++ b/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp @@ -1451,6 +1451,35 @@ namespace { pmr_container_test(); } } // namespace containers + + namespace map_containers { + template + void pair_conversion_test() { + struct pair_conv { + operator pair() const { + return {}; + } + }; + + struct mem_pair_conv { + pair pair_{1, 42}; + operator const pair&() const { + return pair_; + } + }; + + T cont; + cont.emplace(pair_conv{}); + cont.emplace(mem_pair_conv{}); + } + + void test() { + pair_conversion_test>(); + pair_conversion_test>(); + pair_conversion_test>(); + pair_conversion_test>(); + } + } // namespace map_containers } // unnamed namespace int main() { @@ -1491,4 +1520,6 @@ int main() { pool::allocate_deallocate::test(); containers::test(); + + map_containers::test(); } From 19acb451048916a78b4c5d5efbe57688a26879d0 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 01:35:41 +0800 Subject: [PATCH 04/21] Add std:: for pair --- .../std/tests/P0220R1_polymorphic_memory_resources/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp b/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp index 72fb8fdf16..0f48053e20 100644 --- a/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp +++ b/tests/std/tests/P0220R1_polymorphic_memory_resources/test.cpp @@ -1456,14 +1456,14 @@ namespace { template void pair_conversion_test() { struct pair_conv { - operator pair() const { + operator std::pair() const { return {}; } }; struct mem_pair_conv { - pair pair_{1, 42}; - operator const pair&() const { + std::pair pair_{1, 42}; + operator const std::pair&() const { return pair_; } }; From ba29803c97047f5ddf18bda8d4f3b3c1d945cc8b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 01:45:57 +0800 Subject: [PATCH 05/21] Fix _Is_normally_bindable --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index f3ccc1aad7..11d71c0d33 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2088,7 +2088,7 @@ template _INLINE_VAR constexpr bool _Is_normally_bindable = false; template -_INLINE_VAR constexpr bool _Is_normally_bindable<_Ty, _Uty, void_t<_Normally_bound_ref<_Ty, _Uty>>> = false; +_INLINE_VAR constexpr bool _Is_normally_bindable<_Ty, _Uty, void_t<_Normally_bound_ref<_Ty, _Uty>>> = true; #if _HAS_CXX20 template , int> = 0> From 01e500682f4d809576d4506c5f2359039667733f Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 01:48:37 +0800 Subject: [PATCH 06/21] Spaces --- stl/inc/xmemory | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 11d71c0d33..700140f70e 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2066,28 +2066,28 @@ typename _Container::size_type _Erase_nodes_if(_Container& _Cont, _Pr _Pred) { return _Old_size - _Cont.size(); } -template +template void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); -template +template _INLINE_VAR constexpr bool _Cannot_as_pair = true; -template +template _INLINE_VAR constexpr bool _Cannot_as_pair<_Ty, void_t()))>> = false; -template +template const _Ty& _Normally_bind(const _Ty&); -template +template _Ty&& _Normally_bind(_Ty&&); -template +template using _Normally_bound_ref = decltype(_STD _Normally_bind(_STD declval<_Uty>())); -template +template _INLINE_VAR constexpr bool _Is_normally_bindable = false; -template +template _INLINE_VAR constexpr bool _Is_normally_bindable<_Ty, _Uty, void_t<_Normally_bound_ref<_Ty, _Uty>>> = true; #if _HAS_CXX20 From 65c901fc89639144574fe12ac9fb9c8708fb3901 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 12:18:24 +0800 Subject: [PATCH 07/21] Missing template argument --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 700140f70e..e6bf09a6bd 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2082,7 +2082,7 @@ template _Ty&& _Normally_bind(_Ty&&); template -using _Normally_bound_ref = decltype(_STD _Normally_bind(_STD declval<_Uty>())); +using _Normally_bound_ref = decltype(_STD _Normally_bind<_Ty>(_STD declval<_Uty>())); template _INLINE_VAR constexpr bool _Is_normally_bindable = false; From b1c37c6aa82a1f7f0ee500b61b10564828fc5024 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 12:29:15 +0800 Subject: [PATCH 08/21] clang-format --- stl/inc/xmemory | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index e6bf09a6bd..379023df82 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2122,8 +2122,8 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, co template , int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pair<_Uty1, _Uty2>&& _Pair) noexcept; -template && _Cannot_as_pair<_Uty>, int> = 0> +template && _Cannot_as_pair<_Uty>, int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept; template , int> = 0> @@ -2197,12 +2197,12 @@ constexpr _Ty* uninitialized_construct_using_allocator(_Ty* _Ptr, const _Alloc& _STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); } -template && _Cannot_as_pair<_Uty&>, int>> +template && _Cannot_as_pair<_Uty&>, int>> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept { struct _Pair_remaker { using _Pair_t = remove_cv_t<_Ty>; - + const _Alloc& _Al; _Uty& _Ux; @@ -2224,8 +2224,8 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U // equivalent to // return _STD make_obj_using_allocator<_Pair_t>(_Al, _STD move(_Pair_ref)); return _STD make_tuple(piecewise_construct, - _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _STD get<0>(_STD move(_Pair_ref))), - _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))); + _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _STD get<0>(_STD move(_Pair_ref))), + _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))); } } }; From cd1a21b64db70a5b5868629c26b191faaeb604b9 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 12:30:34 +0800 Subject: [PATCH 09/21] clang-format --- stl/inc/xpolymorphic_allocator.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stl/inc/xpolymorphic_allocator.h b/stl/inc/xpolymorphic_allocator.h index 019402e607..3b1703d56c 100644 --- a/stl/inc/xpolymorphic_allocator.h +++ b/stl/inc/xpolymorphic_allocator.h @@ -98,8 +98,7 @@ void _Uses_allocator_construct( } template -void _Uses_allocator_construct( - pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, pair<_Uty, _Vty>&& _Pair) { +void _Uses_allocator_construct(pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, pair<_Uty, _Vty>&& _Pair) { // uses-allocator construction of pair by alloc _Outer propagating alloc _Inner, rvalue pair argument _Uses_allocator_construct_pair(_Ptr, _Outer, _Inner, _STD forward_as_tuple(_STD forward<_Uty>(_Pair.first)), _STD forward_as_tuple(_STD forward<_Vty>(_Pair.second))); @@ -119,8 +118,7 @@ void _Uses_allocator_construct( _Uses_allocator_construct_pair( _Ptr, _Outer, _Inner, _STD forward_as_tuple(_Pair_ref.first), _STD forward_as_tuple(_Pair_ref.second)); } else { - _Uses_allocator_construct_pair( - _Ptr, _Outer, _Inner, _STD forward_as_tuple(_STD forward<_Ty1>(_Pair_ref.first)), + _Uses_allocator_construct_pair(_Ptr, _Outer, _Inner, _STD forward_as_tuple(_STD forward<_Ty1>(_Pair_ref.first)), _STD forward_as_tuple(_STD forward<_Ty2>(_Pair_ref.second))); } } From d4eb17f9a17eae4bcc99217026272085a6299b95 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 12:40:14 +0800 Subject: [PATCH 10/21] clang-format (fix the wrong fix) --- stl/inc/xpolymorphic_allocator.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xpolymorphic_allocator.h b/stl/inc/xpolymorphic_allocator.h index 3b1703d56c..c7cdde9523 100644 --- a/stl/inc/xpolymorphic_allocator.h +++ b/stl/inc/xpolymorphic_allocator.h @@ -98,7 +98,8 @@ void _Uses_allocator_construct( } template -void _Uses_allocator_construct(pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, pair<_Uty, _Vty>&& _Pair) { +void _Uses_allocator_construct( + pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, pair<_Uty, _Vty>&& _Pair) { // uses-allocator construction of pair by alloc _Outer propagating alloc _Inner, rvalue pair argument _Uses_allocator_construct_pair(_Ptr, _Outer, _Inner, _STD forward_as_tuple(_STD forward<_Uty>(_Pair.first)), _STD forward_as_tuple(_STD forward<_Vty>(_Pair.second))); @@ -106,8 +107,7 @@ void _Uses_allocator_construct(pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Oute template , int> = 0> -void _Uses_allocator_construct( - pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, _Uty&& _Ux) { +void _Uses_allocator_construct(pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, _Uty&& _Ux) { // uses-allocator construction of pair by alloc _Outer propagating alloc _Inner, non-pair argument static_assert(_Is_normally_bindable, _Uty>, "The argument must be bindable to a reference to the std::pair type."); From 57d4a4e15d0ceddcc215456085e6942f18007115 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 12:40:27 +0800 Subject: [PATCH 11/21] clang-format --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 379023df82..e428a3a920 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2229,7 +2229,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U } } }; - + // equivalent to // return _STD make_tuple(_Pair_remaker{_Al, _Ux}); return tuple<_Pair_remaker>({_Al, _Ux}); From 5e6d0d6f4f9c6f6448ecad43e9fe480a56d0a3cf Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 12:56:05 +0800 Subject: [PATCH 12/21] Reorder to avoid errors? --- stl/inc/xmemory | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index e428a3a920..b5839d0649 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2183,20 +2183,6 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pa _STD uses_allocator_construction_args(_Al, _STD get<1>(_STD move(_Pair)))); } -template -_NODISCARD constexpr _Ty make_obj_using_allocator(const _Alloc& _Al, _Types&&... _Args) { - return _STD make_from_tuple<_Ty>(_STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); -} - -template -constexpr _Ty* uninitialized_construct_using_allocator(_Ty* _Ptr, const _Alloc& _Al, _Types&&... _Args) { - return _STD apply( - [&](auto&&... _Construct_args) { - return _STD construct_at(_Ptr, _STD forward(_Construct_args)...); - }, - _STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); -} - template && _Cannot_as_pair<_Uty&>, int>> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept { @@ -2234,6 +2220,20 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U // return _STD make_tuple(_Pair_remaker{_Al, _Ux}); return tuple<_Pair_remaker>({_Al, _Ux}); } + +template +_NODISCARD constexpr _Ty make_obj_using_allocator(const _Alloc& _Al, _Types&&... _Args) { + return _STD make_from_tuple<_Ty>(_STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); +} + +template +constexpr _Ty* uninitialized_construct_using_allocator(_Ty* _Ptr, const _Alloc& _Al, _Types&&... _Args) { + return _STD apply( + [&](auto&&... _Construct_args) { + return _STD construct_at(_Ptr, _STD forward(_Construct_args)...); + }, + _STD uses_allocator_construction_args<_Ty>(_Al, _STD forward<_Types>(_Args)...)); +} #endif // _HAS_CXX20 _STD_END From 1c82cf020ddc32aba6749607379a6c81120bf5f4 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 13:20:22 +0800 Subject: [PATCH 13/21] Fix mismatched _Uty& --- stl/inc/xmemory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index b5839d0649..6fe2bc51bd 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2123,7 +2123,7 @@ template && _Pair) noexcept; template && _Cannot_as_pair<_Uty>, int> = 0> + enable_if_t<_Is_specialization_v<_Ty, pair> && _Cannot_as_pair<_Uty&>, int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept; template , int> = 0> From be6a82edc5e8825bc8d9e3d535c2413524e9c745 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 13:46:46 +0800 Subject: [PATCH 14/21] Construct a _Pair_t --- stl/inc/xmemory | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 6fe2bc51bd..2bbe771dcd 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2203,13 +2203,13 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U if constexpr (is_same_v<_Pair_ref_t, const _Pair_t&>) { // equivalent to // return _STD make_obj_using_allocator<_Pair_t>(_Al, _Pair_ref); - return _STD make_tuple(piecewise_construct, + return _Pair_t(piecewise_construct, _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _Pair_ref.first), _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _Pair_ref.second)); } else { // equivalent to // return _STD make_obj_using_allocator<_Pair_t>(_Al, _STD move(_Pair_ref)); - return _STD make_tuple(piecewise_construct, + return _Pair_t(piecewise_construct, _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _STD get<0>(_STD move(_Pair_ref))), _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))); } From bcd4a52796e8c415669c632f7a8bbc1ca0d52569 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 14:11:33 +0800 Subject: [PATCH 15/21] Wunused-local-typedef? --- stl/inc/xmemory | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 2bbe771dcd..f51d8537b5 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2187,12 +2187,11 @@ template && _Cannot_as_pair<_Uty&>, int>> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept { struct _Pair_remaker { - using _Pair_t = remove_cv_t<_Ty>; - const _Alloc& _Al; _Uty& _Ux; - constexpr operator _Pair_t() const { + constexpr operator remove_cv_t<_Ty>() const { + using _Pair_t = remove_cv_t<_Ty>; static_assert(_Is_normally_bindable<_Pair_t, _Uty>, "The argument must be bindable to a reference to the std::pair type."); From b720252177ab0ef07d2d4e136fb0eec37a4b6616 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 23:24:49 +0800 Subject: [PATCH 16/21] _Is_not_deducible_as_pair --- stl/inc/xmemory | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index f51d8537b5..bfb58b1809 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2070,10 +2070,11 @@ template void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); template -_INLINE_VAR constexpr bool _Cannot_as_pair = true; +_INLINE_VAR constexpr bool _Is_not_deducible_as_pair = true; template -_INLINE_VAR constexpr bool _Cannot_as_pair<_Ty, void_t()))>> = false; +_INLINE_VAR constexpr bool + _Is_not_deducible_as_pair<_Ty, void_t()))>> = false; template const _Ty& _Normally_bind(const _Ty&); @@ -2123,7 +2124,7 @@ template && _Pair) noexcept; template && _Cannot_as_pair<_Uty&>, int> = 0> + enable_if_t<_Is_specialization_v<_Ty, pair> && _Is_not_deducible_as_pair<_Uty&>, int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept; template , int> = 0> @@ -2184,7 +2185,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pa } template && _Cannot_as_pair<_Uty&>, int>> + enable_if_t<_Is_specialization_v<_Ty, pair> && _Is_not_deducible_as_pair<_Uty&>, int>> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept { struct _Pair_remaker { const _Alloc& _Al; From 4b7718b66ef67fd476f87203df300ae63c183dcf Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 23:25:33 +0800 Subject: [PATCH 17/21] _Is_not_deducible_as_pair --- stl/inc/xpolymorphic_allocator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xpolymorphic_allocator.h b/stl/inc/xpolymorphic_allocator.h index c7cdde9523..5fb5c8cfc4 100644 --- a/stl/inc/xpolymorphic_allocator.h +++ b/stl/inc/xpolymorphic_allocator.h @@ -106,7 +106,7 @@ void _Uses_allocator_construct( } template , int> = 0> + enable_if_t<_Is_not_deducible_as_pair<_Uty>, int> = 0> void _Uses_allocator_construct(pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, _Uty&& _Ux) { // uses-allocator construction of pair by alloc _Outer propagating alloc _Inner, non-pair argument static_assert(_Is_normally_bindable, _Uty>, From 2585213cbb2d81b60bb95d64a865d249451dc9ad Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Tue, 5 Apr 2022 23:31:13 +0800 Subject: [PATCH 18/21] clang-format --- stl/inc/xmemory | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index bfb58b1809..005c05fbdc 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2073,8 +2073,8 @@ template _INLINE_VAR constexpr bool _Is_not_deducible_as_pair = true; template -_INLINE_VAR constexpr bool - _Is_not_deducible_as_pair<_Ty, void_t()))>> = false; +_INLINE_VAR constexpr bool _Is_not_deducible_as_pair<_Ty, void_t()))>> = + false; template const _Ty& _Normally_bind(const _Ty&); From dfb82cab61a12c72540e07f117ba5b12f4bfc7f6 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 20 Apr 2022 21:05:01 -0700 Subject: [PATCH 19/21] Code review feedback. --- stl/inc/xmemory | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 40f2230bc7..81c4cb3641 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2068,23 +2068,23 @@ typename _Container::size_type _Erase_nodes_if(_Container& _Cont, _Pr _Pred) { } template -void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); +void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); // not defined template _INLINE_VAR constexpr bool _Is_not_deducible_as_pair = true; template -_INLINE_VAR constexpr bool _Is_not_deducible_as_pair<_Ty, void_t()))>> = +_INLINE_VAR constexpr bool _Is_not_deducible_as_pair<_Ty, void_t()))>> = false; template -const _Ty& _Normally_bind(const _Ty&); +const _Ty& _Normally_bind(_Identity_t); // not defined template -_Ty&& _Normally_bind(_Ty&&); +_Ty&& _Normally_bind(_Identity_t<_Ty&&>); // not defined template -using _Normally_bound_ref = decltype(_STD _Normally_bind<_Ty>(_STD declval<_Uty>())); +using _Normally_bound_ref = decltype(_Normally_bind<_Ty>(_STD declval<_Uty>())); template _INLINE_VAR constexpr bool _Is_normally_bindable = false; @@ -2192,8 +2192,9 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U const _Alloc& _Al; _Uty& _Ux; - constexpr operator remove_cv_t<_Ty>() const { - using _Pair_t = remove_cv_t<_Ty>; + using _Pair_t = remove_cv_t<_Ty>; + + constexpr operator _Pair_t() const { static_assert(_Is_normally_bindable<_Pair_t, _Uty>, "The argument must be bindable to a reference to the std::pair type."); @@ -2204,15 +2205,15 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U if constexpr (is_same_v<_Pair_ref_t, const _Pair_t&>) { // equivalent to // return _STD make_obj_using_allocator<_Pair_t>(_Al, _Pair_ref); - return _Pair_t(piecewise_construct, + return _Pair_t{piecewise_construct, _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _Pair_ref.first), - _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _Pair_ref.second)); + _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _Pair_ref.second)}; } else { // equivalent to // return _STD make_obj_using_allocator<_Pair_t>(_Al, _STD move(_Pair_ref)); - return _Pair_t(piecewise_construct, + return _Pair_t{piecewise_construct, _STD uses_allocator_construction_args<_Pair_first_t>(_Al, _STD get<0>(_STD move(_Pair_ref))), - _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))); + _STD uses_allocator_construction_args<_Pair_second_t>(_Al, _STD get<1>(_STD move(_Pair_ref)))}; } } }; From 7b3e93030e2599528a6aa1424c52cba30a066d76 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 20 Apr 2022 21:28:46 -0700 Subject: [PATCH 20/21] Restore original location of _Pair_t. --- stl/inc/xmemory | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 81c4cb3641..071164f0ee 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2192,9 +2192,8 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _U const _Alloc& _Al; _Uty& _Ux; - using _Pair_t = remove_cv_t<_Ty>; - - constexpr operator _Pair_t() const { + constexpr operator remove_cv_t<_Ty>() const { + using _Pair_t = remove_cv_t<_Ty>; static_assert(_Is_normally_bindable<_Pair_t, _Uty>, "The argument must be bindable to a reference to the std::pair type."); From 628fe8450f8a789ecfc4907a72965ad165fe8690 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 27 Apr 2022 17:01:03 -0700 Subject: [PATCH 21/21] Casey's review comments --- stl/inc/xmemory | 9 ++++----- stl/inc/xpolymorphic_allocator.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 071164f0ee..96b7a76d98 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2071,11 +2071,10 @@ template void _Deduce_as_pair(const pair<_Ty1, _Ty2>&); // not defined template -_INLINE_VAR constexpr bool _Is_not_deducible_as_pair = true; +_INLINE_VAR constexpr bool _Is_deducible_as_pair = false; template -_INLINE_VAR constexpr bool _Is_not_deducible_as_pair<_Ty, void_t()))>> = - false; +_INLINE_VAR constexpr bool _Is_deducible_as_pair<_Ty, decltype(_Deduce_as_pair(_STD declval<_Ty>()))> = true; template const _Ty& _Normally_bind(_Identity_t); // not defined @@ -2125,7 +2124,7 @@ template && _Pair) noexcept; template && _Is_not_deducible_as_pair<_Uty&>, int> = 0> + enable_if_t<_Is_specialization_v<_Ty, pair> && !_Is_deducible_as_pair<_Uty&>, int> = 0> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept; template , int> = 0> @@ -2186,7 +2185,7 @@ _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, pa } template && _Is_not_deducible_as_pair<_Uty&>, int>> + enable_if_t<_Is_specialization_v<_Ty, pair> && !_Is_deducible_as_pair<_Uty&>, int>> _NODISCARD constexpr auto uses_allocator_construction_args(const _Alloc& _Al, _Uty&& _Ux) noexcept { struct _Pair_remaker { const _Alloc& _Al; diff --git a/stl/inc/xpolymorphic_allocator.h b/stl/inc/xpolymorphic_allocator.h index 5fb5c8cfc4..1701dedbdf 100644 --- a/stl/inc/xpolymorphic_allocator.h +++ b/stl/inc/xpolymorphic_allocator.h @@ -106,7 +106,7 @@ void _Uses_allocator_construct( } template , int> = 0> + enable_if_t, int> = 0> void _Uses_allocator_construct(pair<_Ty1, _Ty2>* const _Ptr, _Outer_alloc& _Outer, _Inner_alloc& _Inner, _Uty&& _Ux) { // uses-allocator construction of pair by alloc _Outer propagating alloc _Inner, non-pair argument static_assert(_Is_normally_bindable, _Uty>,