diff --git a/include/pybind11/smart_holder_poc.h b/include/pybind11/smart_holder_poc.h index 5a30b7796..4d14409cf 100644 --- a/include/pybind11/smart_holder_poc.h +++ b/include/pybind11/smart_holder_poc.h @@ -75,16 +75,6 @@ struct smart_holder { bool vptr_is_using_builtin_delete : 1; bool vptr_is_external_shared_ptr : 1; - void clear() { - rtti_held = nullptr; - rtti_uqp_del = nullptr; - vptr.reset(); - vptr_deleter_guard_flag = false; - vptr_is_using_noop_deleter = false; - vptr_is_using_builtin_delete = false; - vptr_is_external_shared_ptr = false; - } - smart_holder() : rtti_held{nullptr}, rtti_uqp_del{nullptr}, @@ -151,11 +141,13 @@ struct smart_holder { } template - void from_raw_ptr_unowned(T* raw_ptr) { - clear(); - rtti_held = &typeid(T); - vptr_is_using_noop_deleter = true; - vptr.reset(raw_ptr, guarded_builtin_delete(&vptr_deleter_guard_flag)); + static smart_holder from_raw_ptr_unowned(T* raw_ptr) { + smart_holder hld; + hld.rtti_held = &typeid(T); + hld.vptr_is_using_noop_deleter = true; + hld.vptr.reset(raw_ptr, + guarded_builtin_delete(&hld.vptr_deleter_guard_flag)); + return hld; } template @@ -174,12 +166,14 @@ struct smart_holder { } template - void from_raw_ptr_take_ownership(T* raw_ptr) { - clear(); - rtti_held = &typeid(T); - vptr_deleter_guard_flag = true; - vptr_is_using_builtin_delete = true; - vptr.reset(raw_ptr, guarded_builtin_delete(&vptr_deleter_guard_flag)); + static smart_holder from_raw_ptr_take_ownership(T* raw_ptr) { + smart_holder hld; + hld.rtti_held = &typeid(T); + hld.vptr_deleter_guard_flag = true; + hld.vptr_is_using_builtin_delete = true; + hld.vptr.reset(raw_ptr, + guarded_builtin_delete(&hld.vptr_deleter_guard_flag)); + return hld; } template @@ -195,14 +189,15 @@ struct smart_holder { } template - void from_unique_ptr(std::unique_ptr&& unq_ptr) { - clear(); - rtti_held = &typeid(T); - vptr_deleter_guard_flag = true; - vptr_is_using_builtin_delete = true; - vptr.reset(unq_ptr.get(), - guarded_builtin_delete(&vptr_deleter_guard_flag)); + static smart_holder from_unique_ptr(std::unique_ptr&& unq_ptr) { + smart_holder hld; + hld.rtti_held = &typeid(T); + hld.vptr_deleter_guard_flag = true; + hld.vptr_is_using_builtin_delete = true; + hld.vptr.reset(unq_ptr.get(), + guarded_builtin_delete(&hld.vptr_deleter_guard_flag)); unq_ptr.release(); + return hld; } template @@ -211,14 +206,16 @@ struct smart_holder { } template - void from_unique_ptr_with_deleter(std::unique_ptr&& unq_ptr) { - clear(); - rtti_held = &typeid(T); - rtti_uqp_del = &typeid(D); - vptr_deleter_guard_flag = true; - vptr.reset(unq_ptr.get(), - guarded_custom_deleter(&vptr_deleter_guard_flag)); + static smart_holder from_unique_ptr_with_deleter( + std::unique_ptr&& unq_ptr) { + smart_holder hld; + hld.rtti_held = &typeid(T); + hld.rtti_uqp_del = &typeid(D); + hld.vptr_deleter_guard_flag = true; + hld.vptr.reset(unq_ptr.get(), + guarded_custom_deleter(&hld.vptr_deleter_guard_flag)); unq_ptr.release(); + return hld; } template @@ -234,11 +231,12 @@ struct smart_holder { } template - void from_shared_ptr(std::shared_ptr shd_ptr) { - clear(); - rtti_held = &typeid(T); - vptr_is_external_shared_ptr = true; - vptr = std::static_pointer_cast(shd_ptr); + static smart_holder from_shared_ptr(std::shared_ptr shd_ptr) { + smart_holder hld; + hld.rtti_held = &typeid(T); + hld.vptr_is_external_shared_ptr = true; + hld.vptr = std::static_pointer_cast(shd_ptr); + return hld; } template diff --git a/tests/core/smart_holder_poc_test.cpp b/tests/core/smart_holder_poc_test.cpp index e014757a9..9aebba62f 100644 --- a/tests/core/smart_holder_poc_test.cpp +++ b/tests/core/smart_holder_poc_test.cpp @@ -19,22 +19,19 @@ struct functor_other_delete : functor_builtin_delete {}; TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_unowned", "[S]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); REQUIRE(*hld.as_raw_ptr_unowned() == 19); } TEST_CASE("from_raw_ptr_unowned+const_value_ref", "[S]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); REQUIRE(hld.const_value_ref() == 19); } TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_release_ownership", "[E]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); REQUIRE_THROWS_WITH( hld.as_raw_ptr_release_ownership(), "Cannot disown non-owning holder (as_raw_ptr_release_ownership)."); @@ -42,16 +39,14 @@ TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_release_ownership", "[E]") { TEST_CASE("from_raw_ptr_unowned+as_unique_ptr", "[E]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); REQUIRE_THROWS_WITH(hld.as_unique_ptr(), "Cannot disown non-owning holder (as_unique_ptr)."); } TEST_CASE("from_raw_ptr_unowned+as_unique_ptr_with_deleter", "[E]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); auto condense_for_macro = [](smart_holder& hld) { hld.as_unique_ptr_with_deleter>(); }; @@ -62,21 +57,18 @@ TEST_CASE("from_raw_ptr_unowned+as_unique_ptr_with_deleter", "[E]") { TEST_CASE("from_raw_ptr_unowned+as_shared_ptr", "[S]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); REQUIRE(*hld.as_shared_ptr() == 19); } TEST_CASE("from_raw_ptr_take_ownership+const_value_ref", "[S]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); REQUIRE(hld.has_pointee()); REQUIRE(hld.const_value_ref() == 19); } TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); auto new_owner = std::unique_ptr(hld.as_raw_ptr_release_ownership()); REQUIRE(!hld.has_pointee()); @@ -84,8 +76,7 @@ TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership1", "[S]") { } TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership2", "[E]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); auto shd_ptr = hld.as_shared_ptr(); REQUIRE_THROWS_WITH( hld.as_raw_ptr_release_ownership(), @@ -93,24 +84,21 @@ TEST_CASE("from_raw_ptr_take_ownership+as_raw_ptr_release_ownership2", "[E]") { } TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr1", "[S]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); std::unique_ptr new_owner = hld.as_unique_ptr(); REQUIRE(!hld.has_pointee()); REQUIRE(*new_owner == 19); } TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr2", "[E]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); auto shd_ptr = hld.as_shared_ptr(); REQUIRE_THROWS_WITH(hld.as_unique_ptr(), "Cannot disown use_count != 1 (as_unique_ptr)."); } TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr_with_deleter", "[E]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); auto condense_for_macro = [](smart_holder& hld) { hld.as_unique_ptr_with_deleter>(); }; @@ -120,8 +108,7 @@ TEST_CASE("from_raw_ptr_take_ownership+as_unique_ptr_with_deleter", "[E]") { } TEST_CASE("from_raw_ptr_take_ownership+as_shared_ptr", "[S]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + auto hld = smart_holder::from_raw_ptr_take_ownership(new int(19)); std::shared_ptr new_owner = hld.as_shared_ptr(); REQUIRE(hld.has_pointee()); REQUIRE(*new_owner == 19); @@ -129,16 +116,14 @@ TEST_CASE("from_raw_ptr_take_ownership+as_shared_ptr", "[S]") { TEST_CASE("from_unique_ptr+const_value_ref", "[S]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); REQUIRE(hld.const_value_ref() == 19); } TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); auto new_owner = std::unique_ptr(hld.as_raw_ptr_release_ownership()); @@ -148,8 +133,7 @@ TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership1", "[S]") { TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership2", "[E]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); auto shd_ptr = hld.as_shared_ptr(); REQUIRE_THROWS_WITH( @@ -159,8 +143,7 @@ TEST_CASE("from_unique_ptr+as_raw_ptr_release_ownership2", "[E]") { TEST_CASE("from_unique_ptr+as_unique_ptr1", "[S]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); std::unique_ptr new_owner = hld.as_unique_ptr(); REQUIRE(!hld.has_pointee()); @@ -169,8 +152,7 @@ TEST_CASE("from_unique_ptr+as_unique_ptr1", "[S]") { TEST_CASE("from_unique_ptr+as_unique_ptr2", "[E]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); auto shd_ptr = hld.as_shared_ptr(); REQUIRE_THROWS_WITH(hld.as_unique_ptr(), @@ -179,8 +161,7 @@ TEST_CASE("from_unique_ptr+as_unique_ptr2", "[E]") { TEST_CASE("from_unique_ptr+as_unique_ptr_with_deleter", "[E]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); auto condense_for_macro = [](smart_holder& hld) { hld.as_unique_ptr_with_deleter>(); @@ -192,8 +173,7 @@ TEST_CASE("from_unique_ptr+as_unique_ptr_with_deleter", "[E]") { TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") { std::unique_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_unique_ptr(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); std::shared_ptr new_owner = hld.as_shared_ptr(); REQUIRE(hld.has_pointee()); @@ -203,8 +183,7 @@ TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") { TEST_CASE("from_unique_ptr_with_deleter+const_value_ref", "[S]") { std::unique_ptr> orig_owner( new int(19)); - smart_holder hld; - hld.from_unique_ptr_with_deleter(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); REQUIRE(hld.const_value_ref() == 19); } @@ -212,8 +191,7 @@ TEST_CASE("from_unique_ptr_with_deleter+const_value_ref", "[S]") { TEST_CASE("from_unique_ptr_with_deleter+as_raw_ptr_release_ownership", "[E]") { std::unique_ptr> orig_owner( new int(19)); - smart_holder hld; - hld.from_unique_ptr_with_deleter(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); REQUIRE_THROWS_WITH( hld.as_raw_ptr_release_ownership(), @@ -223,8 +201,7 @@ TEST_CASE("from_unique_ptr_with_deleter+as_raw_ptr_release_ownership", "[E]") { TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr", "[E]") { std::unique_ptr> orig_owner( new int(19)); - smart_holder hld; - hld.from_unique_ptr_with_deleter(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); REQUIRE_THROWS_WITH(hld.as_unique_ptr(), "Cannot disown custom deleter (as_unique_ptr)."); @@ -233,8 +210,7 @@ TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr", "[E]") { TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr_with_deleter1", "[S]") { std::unique_ptr> orig_owner( new int(19)); - smart_holder hld; - hld.from_unique_ptr_with_deleter(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); std::unique_ptr> new_owner = hld.as_unique_ptr_with_deleter> orig_owner( new int(19)); - smart_holder hld; - hld.from_unique_ptr_with_deleter(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); auto condense_for_macro = [](smart_holder& hld) { hld.as_unique_ptr_with_deleter>(); @@ -260,8 +235,7 @@ TEST_CASE("from_unique_ptr_with_deleter+as_unique_ptr_with_deleter2", "[E]") { TEST_CASE("from_unique_ptr_with_deleter+as_shared_ptr", "[S]") { std::unique_ptr> orig_owner( new int(19)); - smart_holder hld; - hld.from_unique_ptr_with_deleter(std::move(orig_owner)); + auto hld = smart_holder::from_unique_ptr_with_deleter(std::move(orig_owner)); REQUIRE(orig_owner.get() == nullptr); std::shared_ptr new_owner = hld.as_shared_ptr(); REQUIRE(hld.has_pointee()); @@ -270,15 +244,13 @@ TEST_CASE("from_unique_ptr_with_deleter+as_shared_ptr", "[S]") { TEST_CASE("from_shared_ptr+const_value_ref", "[S]") { std::shared_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_shared_ptr(orig_owner); + auto hld = smart_holder::from_shared_ptr(orig_owner); REQUIRE(hld.const_value_ref() == 19); } TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") { std::shared_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_shared_ptr(orig_owner); + auto hld = smart_holder::from_shared_ptr(orig_owner); REQUIRE_THROWS_WITH( hld.as_raw_ptr_release_ownership(), "Cannot disown external shared_ptr (as_raw_ptr_release_ownership)."); @@ -286,16 +258,14 @@ TEST_CASE("from_shared_ptr+as_raw_ptr_release_ownership", "[E]") { TEST_CASE("from_shared_ptr+as_unique_ptr", "[E]") { std::shared_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_shared_ptr(orig_owner); + auto hld = smart_holder::from_shared_ptr(orig_owner); REQUIRE_THROWS_WITH(hld.as_unique_ptr(), "Cannot disown external shared_ptr (as_unique_ptr)."); } TEST_CASE("from_shared_ptr+as_unique_ptr_with_deleter", "[E]") { std::shared_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_shared_ptr(orig_owner); + auto hld = smart_holder::from_shared_ptr(orig_owner); auto condense_for_macro = [](smart_holder& hld) { hld.as_unique_ptr_with_deleter>(); }; @@ -306,8 +276,7 @@ TEST_CASE("from_shared_ptr+as_unique_ptr_with_deleter", "[E]") { TEST_CASE("from_shared_ptr+as_shared_ptr", "[S]") { std::shared_ptr orig_owner(new int(19)); - smart_holder hld; - hld.from_shared_ptr(orig_owner); + auto hld = smart_holder::from_shared_ptr(orig_owner); REQUIRE(*hld.as_shared_ptr() == 19); } @@ -319,15 +288,13 @@ TEST_CASE("error_unpopulated_holder", "[E]") { TEST_CASE("error_incompatible_type", "[E]") { static int value = 19; - smart_holder hld; - hld.from_raw_ptr_unowned(&value); + auto hld = smart_holder::from_raw_ptr_unowned(&value); REQUIRE_THROWS_WITH(hld.as_unique_ptr(), "Incompatible type (as_unique_ptr)."); } TEST_CASE("error_disowned_holder", "[E]") { - smart_holder hld; - hld.from_raw_ptr_take_ownership(new int(19)); + 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).");