enable_shared_from_this_from_raw_ptr_take_ownership_guard: better static_assert that also triggers for derived classes.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2021-06-02 11:04:44 -07:00 committed by Ralf W. Grosse-Kunstleve
parent 24c223ad8e
commit 2a265860a7
2 changed files with 14 additions and 5 deletions

View File

@ -101,6 +101,16 @@ inline bool is_std_default_delete(const std::type_info &rtti_deleter) {
|| rtti_deleter == typeid(std::default_delete<T const>);
}
inline void enable_shared_from_this_from_raw_ptr_take_ownership_guard(...) {}
template <typename AnyBaseOfT>
inline void enable_shared_from_this_from_raw_ptr_take_ownership_guard(
const std::enable_shared_from_this<AnyBaseOfT> *) {
// This static_assert will always trigger if this template function is instantiated.
static_assert(!std::is_base_of<std::enable_shared_from_this<AnyBaseOfT>, AnyBaseOfT>::value,
"Ownership must not be transferred via a raw pointer.");
}
struct smart_holder {
const std::type_info *rtti_uqp_del = nullptr;
std::shared_ptr<void> vptr;
@ -235,8 +245,7 @@ struct smart_holder {
template <typename T>
static smart_holder from_raw_ptr_take_ownership(T *raw_ptr) {
static_assert(!std::is_base_of<std::enable_shared_from_this<T>, T>::value,
"Ownership must not be transferred via a raw pointer.");
enable_shared_from_this_from_raw_ptr_take_ownership_guard(raw_ptr);
ensure_pointee_is_destructible<T>("from_raw_ptr_take_ownership");
smart_holder hld;
hld.vptr.reset(raw_ptr, make_guarded_builtin_delete<T>(true));

View File

@ -52,7 +52,7 @@ TEST_SUBMODULE(class_sh_shared_from_this, m) {
m.def("print_myobject3_1", [](const MyObject3 *obj) { py::print(obj->toString()); });
m.def("print_myobject3_2", [](std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); });
m.def("print_myobject3_3", [](const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); });
//m.def("print_myobject3_4", [](const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });
// m.def("print_myobject3_4", [](const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });
using B = SharedFromThisRef::B;
// py::classh<B>(m, "B");
@ -69,6 +69,6 @@ TEST_SUBMODULE(class_sh_shared_from_this, m) {
.def("set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) { return true; });
static std::shared_ptr<SharedFromThisVirt> sft(new SharedFromThisVirt());
py::classh<SharedFromThisVirt>(m, "SharedFromThisVirt")
.def_static("get", []() { return sft.get(); }, py::return_value_policy::reference);
// py::classh<SharedFromThisVirt>(m, "SharedFromThisVirt")
// .def_static("get", []() { return sft.get(); }, py::return_value_policy::reference);
}