Support loading `unique_ptr<Derived>` as `unique_ptr<Base>`. (#4031)

* Support loading unique_ptr<derived> as unique_ptr<base>.

* Fix incorrect test

* pre commit fix

* Fix clang tidy

* Resolve comments

* Resolve comments
This commit is contained in:
Xiaofei Wang 2022-06-27 22:21:28 -07:00 committed by GitHub
parent cf2c307e7b
commit c0cfe95b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 1 deletions

View File

@ -181,7 +181,9 @@ struct smart_holder {
+ ").");
}
ensure_vptr_is_using_builtin_delete(context);
} else if (!(*rtti_requested == *rtti_uqp_del)) {
} else if (!(*rtti_requested == *rtti_uqp_del)
&& !(vptr_is_using_builtin_delete
&& is_std_default_delete<T>(*rtti_requested))) {
throw std::invalid_argument(std::string("Incompatible unique_ptr deleter (") + context
+ ").");
}

View File

@ -37,6 +37,15 @@ private:
~indestructible_int() = default;
};
struct base {
virtual int get() { return 10; }
virtual ~base() = default;
};
struct derived : public base {
int get() override { return 100; }
};
} // namespace helpers
TEST_CASE("from_raw_ptr_unowned+as_raw_ptr_unowned", "[S]") {
@ -227,6 +236,25 @@ TEST_CASE("from_unique_ptr+as_shared_ptr", "[S]") {
REQUIRE(*new_owner == 19);
}
TEST_CASE("from_unique_ptr_derived+as_unique_ptr_base", "[S]") {
std::unique_ptr<helpers::derived> orig_owner(new helpers::derived());
auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
REQUIRE(orig_owner.get() == nullptr);
std::unique_ptr<helpers::base> new_owner = hld.as_unique_ptr<helpers::base>();
REQUIRE(!hld.has_pointee());
REQUIRE(new_owner->get() == 100);
}
TEST_CASE("from_unique_ptr_derived+as_unique_ptr_base2", "[E]") {
std::unique_ptr<helpers::derived, helpers::functor_other_delete<helpers::derived>> orig_owner(
new helpers::derived());
auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));
REQUIRE(orig_owner.get() == nullptr);
REQUIRE_THROWS_WITH(
(hld.as_unique_ptr<helpers::base, helpers::functor_builtin_delete<helpers::base>>()),
"Incompatible unique_ptr deleter (as_unique_ptr).");
}
TEST_CASE("from_unique_ptr_with_deleter+as_lvalue_ref", "[S]") {
std::unique_ptr<int, helpers::functor_builtin_delete<int>> orig_owner(new int(19));
auto hld = smart_holder::from_unique_ptr(std::move(orig_owner));