Skip to content

Commit

Permalink
Implement LWG-3734 Inconsistency in inout_ptr and out_ptr for emp…
Browse files Browse the repository at this point in the history
…ty case (#3503)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
Co-authored-by: Casey Carter <cartec69@gmail.com>
  • Loading branch information
3 people authored Mar 3, 2023
1 parent 8be719c commit 7155ea6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
10 changes: 9 additions & 1 deletion stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -4179,7 +4179,15 @@ public:
explicit out_ptr_t(_SmartPtr& _Smart_ptr_, _ArgsT... _Args_) noexcept(
is_nothrow_constructible_v<tuple<_ArgsT...>, _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;

Expand Down
34 changes: 33 additions & 1 deletion tests/std/tests/P1132R7_out_ptr/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,22 @@ void test_shared_ptr() {
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 <class Ptr, class Pointer = void, class... Args>
Expand Down Expand Up @@ -119,6 +133,19 @@ 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*>(int_ptr);
assert(int_ptr.get() == nullptr);
f(temp_adaptor);
}

assert(*int_ptr == 42);
}

// LWG-3594 inout_ptr - inconsistent release() in destructor
{
const auto f = [](int** ptr) {
Expand All @@ -141,6 +168,10 @@ struct resettable_ptr {

explicit resettable_ptr(int* p) : ptr(p) {}

void reset() {
ptr.reset();
}

void reset(int* p, reset_tag) {
ptr.reset(p);
}
Expand All @@ -163,6 +194,7 @@ struct constructible_ptr {

unique_ptr<int> ptr;

constructible_ptr() = default;
explicit constructible_ptr(int* p) : ptr(p) {}
explicit constructible_ptr(int* p, reset_tag) : ptr(p) {}

Expand Down

0 comments on commit 7155ea6

Please sign in to comment.