From c4d900977985ddf8d8ce44595acc1936e5d52a6d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 25 Feb 2023 16:50:18 +0800 Subject: [PATCH 1/3] Implement LWG-3734 --- stl/inc/memory | 10 +++++++- tests/std/tests/P1132R7_out_ptr/test.cpp | 32 +++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 3ddb1c45401..65026476372 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -4179,7 +4179,15 @@ public: explicit out_ptr_t(_SmartPtr& _Smart_ptr_, _ArgsT... _Args_) noexcept( is_nothrow_constructible_v, _ArgsT...>) /* strengthened */ : _Smart_ptr(_Smart_ptr_), - _Mypair(_One_then_variadic_args_t{}, tuple<_ArgsT...>{_STD forward<_ArgsT>(_Args_)...}) {} + _Mypair(_One_then_variadic_args_t{}, tuple<_ArgsT...>{_STD forward<_ArgsT>(_Args_)...}) { + constexpr bool _Is_resettable = requires { _Smart_ptr_.reset(); }; // TRANSITION, DevCom-10291456 + if constexpr (_Is_resettable) { + _Smart_ptr_.reset(); + } else { + static_assert(is_constructible_v<_SmartPtr>, "the adapted pointer type must be default constructible."); + _Smart_ptr = _SmartPtr{}; + } + } out_ptr_t(const out_ptr_t&) = delete; diff --git a/tests/std/tests/P1132R7_out_ptr/test.cpp b/tests/std/tests/P1132R7_out_ptr/test.cpp index 32cc7e14225..c4989d03e30 100644 --- a/tests/std/tests/P1132R7_out_ptr/test.cpp +++ b/tests/std/tests/P1132R7_out_ptr/test.cpp @@ -75,9 +75,22 @@ void test_shared_ptr() { assert(count == 1); assert(*int_ptr == 32); } + // LWG-3734 Inconsistency in inout_ptr and out_ptr for empty case + { + const auto f = [](void** ptr) { *ptr = new int(42); }; + + { + auto temp_adaptor = out_ptr(int_ptr, deleter); + assert(int_ptr.get() == nullptr); + f(temp_adaptor); + } + + assert(count == 2); + assert(*int_ptr == 42); + } int_ptr.reset(); - assert(count == 2); + assert(count == 3); } template @@ -118,6 +131,18 @@ void test_smart_ptr(Args&&... args) { assert(*int_ptr == 19); } + // LWG-3734 Inconsistency in inout_ptr and out_ptr for empty case + { + const auto f = [](void** ptr) { *ptr = new int(42); }; + + { + auto temp_adaptor = out_ptr(int_ptr); + assert(int_ptr.get() == nullptr); + f(temp_adaptor); + } + + assert(*int_ptr == 42); + } // LWG-3594 inout_ptr - inconsistent release() in destructor { @@ -141,6 +166,10 @@ struct resettable_ptr { explicit resettable_ptr(int* p) : ptr(p) {} + void reset() { + ptr.reset(); + } + void reset(int* p, reset_tag) { ptr.reset(p); } @@ -163,6 +192,7 @@ struct constructible_ptr { unique_ptr ptr; + constructible_ptr() = default; explicit constructible_ptr(int* p) : ptr(p) {} explicit constructible_ptr(int* p, reset_tag) : ptr(p) {} From 6cc11f7461a68761e5af12c0ea5a077a4d92cd5e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 25 Feb 2023 12:46:40 -0800 Subject: [PATCH 2/3] Code review feedback. --- stl/inc/memory | 4 ++-- tests/std/tests/P1132R7_out_ptr/test.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index 65026476372..cbef1bf9f9d 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -4180,9 +4180,9 @@ public: is_nothrow_constructible_v, _ArgsT...>) /* strengthened */ : _Smart_ptr(_Smart_ptr_), _Mypair(_One_then_variadic_args_t{}, tuple<_ArgsT...>{_STD forward<_ArgsT>(_Args_)...}) { - constexpr bool _Is_resettable = requires { _Smart_ptr_.reset(); }; // TRANSITION, DevCom-10291456 + constexpr bool _Is_resettable = requires { _Smart_ptr.reset(); }; // TRANSITION, DevCom-10291456 if constexpr (_Is_resettable) { - _Smart_ptr_.reset(); + _Smart_ptr.reset(); } else { static_assert(is_constructible_v<_SmartPtr>, "the adapted pointer type must be default constructible."); _Smart_ptr = _SmartPtr{}; diff --git a/tests/std/tests/P1132R7_out_ptr/test.cpp b/tests/std/tests/P1132R7_out_ptr/test.cpp index c4989d03e30..c73a1f0726b 100644 --- a/tests/std/tests/P1132R7_out_ptr/test.cpp +++ b/tests/std/tests/P1132R7_out_ptr/test.cpp @@ -75,6 +75,7 @@ void test_shared_ptr() { assert(count == 1); assert(*int_ptr == 32); } + // LWG-3734 Inconsistency in inout_ptr and out_ptr for empty case { const auto f = [](void** ptr) { *ptr = new int(42); }; @@ -131,6 +132,7 @@ void test_smart_ptr(Args&&... args) { assert(*int_ptr == 19); } + // LWG-3734 Inconsistency in inout_ptr and out_ptr for empty case { const auto f = [](void** ptr) { *ptr = new int(42); }; From e7ad73a715aef8c19d0842f776603dba65c988ee Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sat, 25 Feb 2023 20:05:02 -0800 Subject: [PATCH 3/3] Don't brace-construct user-provided type `_SmartPtr` --- stl/inc/memory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/memory b/stl/inc/memory index cbef1bf9f9d..e7ca9c2cfc2 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -4185,7 +4185,7 @@ public: _Smart_ptr.reset(); } else { static_assert(is_constructible_v<_SmartPtr>, "the adapted pointer type must be default constructible."); - _Smart_ptr = _SmartPtr{}; + _Smart_ptr = _SmartPtr(); } }