@@ -83,6 +83,24 @@ class const_only_shared_ptr {
8383 // for demonstration purpose only, this imitates smart pointer with a const-only pointer
8484};
8585
86+ template <typename T>
87+ class shared_ptr_as_custom_holder {
88+ std::shared_ptr<T> ptr_;
89+
90+ public:
91+ using element_type = T;
92+
93+ shared_ptr_as_custom_holder () = default ;
94+
95+ explicit shared_ptr_as_custom_holder (T *) {
96+ throw std::runtime_error (" invalid shared_ptr_as_custom_holder constructor call" );
97+ }
98+
99+ explicit shared_ptr_as_custom_holder (std::shared_ptr<T> ptr) : ptr_(std::move(ptr)) {}
100+
101+ T *get () const { return ptr_.get (); }
102+ };
103+
86104// Custom object with builtin reference counting (see 'object.h' for the implementation)
87105class MyObject1 : public Object {
88106public:
@@ -239,6 +257,17 @@ struct SharedFromThisRef {
239257 std::shared_ptr<B> shared = std::make_shared<B>();
240258};
241259
260+ class Issue6064UnsafePath {
261+ public:
262+ static std::shared_ptr<Issue6064UnsafePath> create () {
263+ return {new Issue6064UnsafePath (), [](Issue6064UnsafePath *ptr) { delete ptr; }};
264+ }
265+
266+ private:
267+ Issue6064UnsafePath () = default ;
268+ ~Issue6064UnsafePath () = default ;
269+ };
270+
242271// Issue #865: shared_from_this doesn't work with virtual inheritance
243272struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
244273 SharedFromThisVBase () = default ;
@@ -341,6 +370,7 @@ struct holder_helper<ref<T>> {
341370// Make pybind aware of the ref-counted wrapper type (s):
342371PYBIND11_DECLARE_HOLDER_TYPE (T, ref<T>, true )
343372PYBIND11_DECLARE_HOLDER_TYPE(T, const_only_shared_ptr<T>, true )
373+ PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_as_custom_holder<T>)
344374// The following is not required anymore for std::shared_ptr, but it should compile without error:
345375PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>)
346376PYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>)
@@ -501,6 +531,10 @@ TEST_SUBMODULE(smart_ptr, m) {
501531 .def (py::init ([](const std::string &value) { return MyObject6::createObject (value); }))
502532 .def_property_readonly (" value" , &MyObject6::value);
503533
534+ py::class_<Issue6064UnsafePath, shared_ptr_as_custom_holder<Issue6064UnsafePath>>(
535+ m, " Issue6064UnsafePath" );
536+ m.def (" get_issue6064_unsafe_path_shared_ptr" , []() { return Issue6064UnsafePath::create (); });
537+
504538 // test_shared_ptr_and_references
505539 using A = SharedPtrRef::A;
506540 py::class_<A, std::shared_ptr<A>>(m, " A" );
@@ -559,6 +593,7 @@ TEST_SUBMODULE(smart_ptr, m) {
559593 py::class_<C, custom_unique_ptr<C>>(m, " TypeWithMoveOnlyHolder" )
560594 .def_static (" make" , []() { return custom_unique_ptr<C>(new C); })
561595 .def_static (" make_as_object" , []() { return py::cast (custom_unique_ptr<C>(new C)); });
596+ m.def (" get_type_with_move_only_holder_shared_ptr" , []() { return std::make_shared<C>(); });
562597
563598 // test_holder_with_addressof_operator
564599 using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
0 commit comments