diff --git a/include/pybind11/smart_holder_poc.h b/include/pybind11/smart_holder_poc.h index 4d14409cf..f3374f103 100644 --- a/include/pybind11/smart_holder_poc.h +++ b/include/pybind11/smart_holder_poc.h @@ -158,13 +158,21 @@ struct smart_holder { } template - const T& const_value_ref() const { - static const char* context = "const_value_ref"; + T& lvalue_ref() const { + static const char* context = "lvalue_ref"; ensure_compatible_rtti_held(context); ensure_has_pointee(context); return *static_cast(vptr.get()); } + template + T&& rvalue_ref() const { + static const char* context = "rvalue_ref"; + ensure_compatible_rtti_held(context); + ensure_has_pointee(context); + return std::move(*static_cast(vptr.get())); + } + template static smart_holder from_raw_ptr_take_ownership(T* raw_ptr) { smart_holder hld; diff --git a/tests/core/smart_holder_poc_test.cpp b/tests/core/smart_holder_poc_test.cpp index 9aebba62f..e696d9e53 100644 --- a/tests/core/smart_holder_poc_test.cpp +++ b/tests/core/smart_holder_poc_test.cpp @@ -7,6 +7,15 @@ using pybindit::memory::smart_holder; namespace helpers { +struct movable_int { + int valu; + movable_int(int v) : valu{v} {} + movable_int(movable_int&& other) { + valu = other.valu; + other.valu = 91; + } +}; + template struct functor_builtin_delete { void operator()(T* ptr) { delete ptr; } @@ -23,10 +32,20 @@ TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_unowned", "[S]") { REQUIRE(*hld.as_raw_ptr_unowned() == 19); } -TEST_CASE("from_raw_ptr_unowned+const_value_ref", "[S]") { +TEST_CASE("from_raw_ptr_unowned+lvalue_ref", "[S]") { static int value = 19; auto hld = smart_holder::from_raw_ptr_unowned(&value); - REQUIRE(hld.const_value_ref() == 19); + REQUIRE(hld.lvalue_ref() == 19); +} + +TEST_CASE("from_raw_ptr_unowned+rvalue_ref", "[S]") { + helpers::movable_int orig(19); + { + auto hld = smart_holder::from_raw_ptr_unowned(&orig); + helpers::movable_int othr(hld.rvalue_ref()); + REQUIRE(othr.valu == 19); + REQUIRE(orig.valu == 91); + } } TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_release_ownership", "[E]") { @@ -61,10 +80,10 @@ TEST_CASE("from_raw_ptr_unowned+as_shared_ptr", "[S]") { REQUIRE(*hld.as_shared_ptr() == 19); } -TEST_CASE("from_raw_ptr_take_ownership+const_value_ref", "[S]") { +TEST_CASE("from_raw_ptr_take_ownership+lvalue_ref", "[S]") { auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); REQUIRE(hld.has_pointee()); - REQUIRE(hld.const_value_ref() == 19); + REQUIRE(hld.lvalue_ref() == 19); } TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") { @@ -114,11 +133,11 @@ TEST_CASE("from_raw_ptr_take_ownership+as_shared_ptr", "[S]") { REQUIRE(*new_owner == 19); } -TEST_CASE("from_unique_ptr+const_value_ref", "[S]") { +TEST_CASE("from_unique_ptr+lvalue_ref", "[S]") { std::unique_ptr orig_owner(new int(19)); auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); - REQUIRE(hld.const_value_ref() == 19); + REQUIRE(hld.lvalue_ref() == 19); } TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") { @@ -180,12 +199,12 @@ TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") { REQUIRE(*new_owner == 19); } -TEST_CASE("from_unique_ptr_with_deleter+const_value_ref", "[S]") { +TEST_CASE("from_unique_ptr_with_deleter+lvalue_ref", "[S]") { std::unique_ptr> orig_owner( new int(19)); auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); - REQUIRE(hld.const_value_ref() == 19); + REQUIRE(hld.lvalue_ref() == 19); } TEST_CASE("from_unique_ptr_with_deleter+as_raw_ptr_release_ownership", "[E]") { @@ -242,10 +261,10 @@ TEST_CASE("from_unique_ptr_with_deleter+as_shared_ptr", "[S]") { REQUIRE(*new_owner == 19); } -TEST_CASE("from_shared_ptr+const_value_ref", "[S]") { +TEST_CASE("from_shared_ptr+lvalue_ref", "[S]") { std::shared_ptr orig_owner(new int(19)); auto hld = smart_holder::from_shared_ptr(orig_owner); - REQUIRE(hld.const_value_ref() == 19); + REQUIRE(hld.lvalue_ref() == 19); } TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") { @@ -296,6 +315,5 @@ TEST_CASE("error_incompatible_type", "[E]") { TEST_CASE("error_disowned_holder", "[E]") { auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); hld.as_unique_ptr(); - REQUIRE_THROWS_WITH(hld.const_value_ref(), - "Disowned holder (const_value_ref)."); + REQUIRE_THROWS_WITH(hld.lvalue_ref(), "Disowned holder (lvalue_ref)."); }