9
9
namespace pybind11_tests {
10
10
namespace potentially_slicing_shared_ptr {
11
11
12
+ template <int > // Using int as a trick to easily generate multiple types.
12
13
struct VirtBase {
13
14
virtual ~VirtBase () = default ;
14
15
virtual int get_code () { return 100 ; }
15
16
};
16
17
17
- struct PyVirtBase : VirtBase, py::trampoline_self_life_support {
18
- using VirtBase::VirtBase;
19
- int get_code () override { PYBIND11_OVERRIDE (int , VirtBase, get_code); }
18
+ using VirtBaseSH = VirtBase<0 >; // for testing with py::smart_holder
19
+ using VirtBaseSP = VirtBase<1 >; // for testing with std::shared_ptr as holder
20
+
21
+ struct PyVirtBaseSH : VirtBaseSH, py::trampoline_self_life_support {
22
+ using VirtBaseSH::VirtBaseSH;
23
+ int get_code () override { PYBIND11_OVERRIDE (int , VirtBaseSH, get_code); }
24
+ };
25
+
26
+ struct PyVirtBaseSP : VirtBaseSP { // self-life-support not available
27
+ using VirtBaseSP::VirtBaseSP;
28
+ int get_code () override { PYBIND11_OVERRIDE (int , VirtBaseSP, get_code); }
20
29
};
21
30
22
- std::shared_ptr<VirtBase> rtrn_obj_cast_shared_ptr (py::handle obj) {
23
- return obj.cast <std::shared_ptr<VirtBase>>();
31
+ template <typename VB>
32
+ std::shared_ptr<VB> rtrn_obj_cast_shared_ptr (py::handle obj) {
33
+ return obj.cast <std::shared_ptr<VB>>();
24
34
}
25
35
26
- std::shared_ptr<VirtBase> rtrn_potentially_slicing_shared_ptr (py::handle obj) {
27
- return py::potentially_slicing_shared_ptr<VirtBase>(obj);
36
+ template <typename VB>
37
+ std::shared_ptr<VB> rtrn_potentially_slicing_shared_ptr (py::handle obj) {
38
+ return py::potentially_slicing_shared_ptr<VB>(obj);
28
39
}
29
40
41
+ template <typename VB>
30
42
struct SpOwner {
31
- void set_sp (const std::shared_ptr<VirtBase > &sp_) { sp = sp_; }
43
+ void set_sp (const std::shared_ptr<VB > &sp_) { sp = sp_; }
32
44
33
45
int get_code () {
34
46
if (!sp) {
@@ -38,11 +50,12 @@ struct SpOwner {
38
50
}
39
51
40
52
private:
41
- std::shared_ptr<VirtBase > sp;
53
+ std::shared_ptr<VB > sp;
42
54
};
43
55
56
+ template <typename VB>
44
57
struct WpOwner {
45
- void set_wp (const std::shared_ptr<VirtBase > &sp) { wp = sp; }
58
+ void set_wp (const std::shared_ptr<VB > &sp) { wp = sp; }
46
59
47
60
int get_code () {
48
61
auto sp = wp.lock ();
@@ -53,33 +66,56 @@ struct WpOwner {
53
66
}
54
67
55
68
private:
56
- std::weak_ptr<VirtBase > wp;
69
+ std::weak_ptr<VB > wp;
57
70
};
58
71
72
+ template <typename VB>
73
+ void wrap (py::module_ &m,
74
+ const char *roc_pyname,
75
+ const char *rps_pyname,
76
+ const char *spo_pyname,
77
+ const char *wpo_pyname) {
78
+ m.def (roc_pyname, rtrn_obj_cast_shared_ptr<VB>);
79
+ m.def (rps_pyname, rtrn_potentially_slicing_shared_ptr<VB>);
80
+
81
+ py::classh<SpOwner<VB>>(m, spo_pyname)
82
+ .def (py::init<>())
83
+ .def (" set_sp" , &SpOwner<VB>::set_sp)
84
+ .def (" get_code" , &SpOwner<VB>::get_code);
85
+
86
+ py::classh<WpOwner<VB>>(m, wpo_pyname)
87
+ .def (py::init<>())
88
+ .def (" set_wp" , &WpOwner<VB>::set_wp)
89
+ .def (" set_wp_potentially_slicing" ,
90
+ [](WpOwner<VB> &self, py::handle obj) {
91
+ self.set_wp (py::potentially_slicing_shared_ptr<VB>(obj));
92
+ })
93
+ .def (" get_code" , &WpOwner<VB>::get_code);
94
+ }
95
+
59
96
} // namespace potentially_slicing_shared_ptr
60
97
} // namespace pybind11_tests
61
98
62
99
using namespace pybind11_tests ::potentially_slicing_shared_ptr;
63
100
64
101
TEST_SUBMODULE (potentially_slicing_shared_ptr, m) {
65
- py::classh<VirtBase, PyVirtBase>(m, " VirtBase" )
66
- .def (py::init<>())
67
- .def (" get_code" , &VirtBase::get_code);
68
-
69
- m.def (" rtrn_obj_cast_shared_ptr" , rtrn_obj_cast_shared_ptr);
70
- m.def (" rtrn_potentially_slicing_shared_ptr" , rtrn_potentially_slicing_shared_ptr);
71
-
72
- py::classh<SpOwner>(m, " SpOwner" )
102
+ py::classh<VirtBaseSH, PyVirtBaseSH>(m, " VirtBaseSH" )
73
103
.def (py::init<>())
74
- .def (" set_sp" , &SpOwner::set_sp)
75
- .def (" get_code" , &SpOwner::get_code);
104
+ .def (" get_code" , &VirtBaseSH::get_code);
76
105
77
- py::classh<WpOwner> (m, " WpOwner " )
106
+ py::class_<VirtBaseSP, std::shared_ptr<VirtBaseSP>, PyVirtBaseSP> (m, " VirtBaseSP " )
78
107
.def (py::init<>())
79
- .def (" set_wp" , &WpOwner::set_wp)
80
- .def (" set_wp_potentially_slicing" ,
81
- [](WpOwner &self, py::handle obj) {
82
- self.set_wp (py::potentially_slicing_shared_ptr<VirtBase>(obj));
83
- })
84
- .def (" get_code" , &WpOwner::get_code);
108
+ .def (" get_code" , &VirtBaseSP::get_code);
109
+
110
+ wrap<VirtBaseSH>(m,
111
+ " SH_rtrn_obj_cast_shared_ptr" ,
112
+ " SH_rtrn_potentially_slicing_shared_ptr" ,
113
+ " SH_SpOwner" ,
114
+ " SH_WpOwner" );
115
+
116
+ wrap<VirtBaseSP>(m,
117
+ " SP_rtrn_obj_cast_shared_ptr" ,
118
+ " SP_rtrn_potentially_slicing_shared_ptr" ,
119
+ " SP_SpOwner" ,
120
+ " SP_WpOwner" );
85
121
}
0 commit comments