22// direction of an integration test, to ensure multiple components of pybind11 work together
33// correctly. It is also useful to show the type_caster<> interface virtually clutter-free.
44
5+ // The entire type_caster load logic is intentionally omitted. The only purpose of this test is to
6+ // trace the behavior of the `static handle cast()` functions and the type_caster `operator`s.
7+ // Variable names are intentionally terse, to not distract from the more important function
8+ // signatures: valu(e), ref(erence), ptr (pointer), r = rvalue, m = mutable, c = const.
9+
510#include " pybind11_tests.h"
611
7- #include < memory >
12+ #include < string >
813
914namespace pybind11_tests {
1015namespace type_caster_bare_interface {
1116
12- struct mpty {};
17+ struct atyp { // Short for "any type".
18+ std::string trace;
19+ atyp () : trace(" default" ) {}
20+ atyp (atyp const &other) { trace = other.trace + " _CpCtor" ; }
21+ atyp (atyp &&other) { trace = other.trace + " _MvCtor" ; }
22+ };
1323
1424// clang-format off
1525
16- mpty rtrn_valu () { mpty obj; return obj; }
17- mpty&& rtrn_rref() { static mpty obj; return std::move (obj); }
18- mpty const & rtrn_cref () { static mpty obj; return obj; }
19- mpty& rtrn_mref () { static mpty obj; return obj; }
20- mpty const * rtrn_cptr () { return new mpty; }
21- mpty* rtrn_mptr () { return new mpty; }
22-
23- const char * pass_valu (mpty) { return " load_valu" ; }
24- const char * pass_rref (mpty&&) { return " load_rref" ; }
25- const char * pass_cref (mpty const &) { return " load_cref" ; }
26- const char * pass_mref (mpty&) { return " load_mref" ; }
27- const char * pass_cptr (mpty const *) { return " load_cptr" ; }
28- const char * pass_mptr (mpty*) { return " load_mptr" ; }
29-
30- std::shared_ptr<mpty> rtrn_shmp () { return std::shared_ptr<mpty >(new mpty); }
31- std::shared_ptr<mpty const > rtrn_shcp () { return std::shared_ptr<mpty const >(new mpty); }
26+ atyp rtrn_valu () { static atyp obj; obj.trace = " valu" ; return obj; }
27+ atyp&& rtrn_rref() { static atyp obj; obj.trace = " rref" ; return std::move (obj); }
28+ atyp const & rtrn_cref () { static atyp obj; obj.trace = " cref" ; return obj; }
29+ atyp& rtrn_mref () { static atyp obj; obj.trace = " mref" ; return obj; }
30+ atyp const * rtrn_cptr () { static atyp obj; obj.trace = " cptr" ; return &obj; }
31+ atyp* rtrn_mptr () { static atyp obj; obj.trace = " mptr" ; return &obj; }
3232
33- const char * pass_shmp (std::shared_ptr<mpty>) { return " load_shmp" ; }
34- const char * pass_shcp (std::shared_ptr<mpty const >) { return " load_shcp" ; }
35-
36- std::unique_ptr<mpty> rtrn_uqmp () { return std::unique_ptr<mpty >(new mpty); }
37- std::unique_ptr<mpty const > rtrn_uqcp () { return std::unique_ptr<mpty const >(new mpty); }
38-
39- const char * pass_uqmp (std::unique_ptr<mpty>) { return " load_uqmp" ; }
40- const char * pass_uqcp (std::unique_ptr<mpty const >) { return " load_uqcp" ; }
33+ std::string pass_valu (atyp obj) { return " pass_valu:" + obj.trace ; }
34+ std::string pass_rref (atyp&& obj) { return " pass_rref:" + obj.trace ; }
35+ std::string pass_cref (atyp const & obj) { return " pass_cref:" + obj.trace ; }
36+ std::string pass_mref (atyp& obj) { return " pass_mref:" + obj.trace ; }
37+ std::string pass_cptr (atyp const * obj) { return " pass_cptr:" + obj->trace ; }
38+ std::string pass_mptr (atyp* obj) { return " pass_mptr:" + obj->trace ; }
4139
4240// clang-format on
4341
@@ -50,140 +48,68 @@ namespace detail {
5048using namespace pybind11_tests ::type_caster_bare_interface;
5149
5250template <>
53- struct type_caster <mpty > {
54- static constexpr auto name = _<mpty >();
51+ struct type_caster <atyp > {
52+ static constexpr auto name = _<atyp >();
5553
56- // static handle cast(mpty , ...)
54+ // static handle cast(atyp , ...)
5755 // is redundant (leads to ambiguous overloads).
5856
59- static handle cast (mpty && /* src*/ , return_value_policy /* policy*/ , handle /* parent*/ ) {
60- return str (" cast_rref" ).release ();
57+ static handle cast (atyp &&src, return_value_policy /* policy*/ , handle /* parent*/ ) {
58+ return str (" cast_rref: " + src. trace ).release ();
6159 }
6260
63- static handle cast (mpty const & /* src*/ , return_value_policy /* policy*/ , handle /* parent*/ ) {
64- return str (" cast_cref" ).release ();
61+ static handle cast (atyp const &src, return_value_policy /* policy*/ , handle /* parent*/ ) {
62+ return str (" cast_cref: " + src. trace ).release ();
6563 }
6664
67- static handle cast (mpty & /* src*/ , return_value_policy /* policy*/ , handle /* parent*/ ) {
68- return str (" cast_mref" ).release ();
65+ static handle cast (atyp & src, return_value_policy /* policy*/ , handle /* parent*/ ) {
66+ return str (" cast_mref: " + src. trace ).release ();
6967 }
7068
71- static handle cast (mpty const *src, return_value_policy /* policy*/ , handle /* parent*/ ) {
72- delete src;
73- return str (" cast_cptr" ).release ();
69+ static handle cast (atyp const *src, return_value_policy /* policy*/ , handle /* parent*/ ) {
70+ return str (" cast_cptr:" + src->trace ).release ();
7471 }
7572
76- static handle cast (mpty *src, return_value_policy /* policy*/ , handle /* parent*/ ) {
77- delete src;
78- return str (" cast_mptr" ).release ();
73+ static handle cast (atyp *src, return_value_policy /* policy*/ , handle /* parent*/ ) {
74+ return str (" cast_mptr:" + src->trace ).release ();
7975 }
8076
8177 template <typename T_>
8278 using cast_op_type = conditional_t <
83- std::is_same<remove_reference_t <T_>, mpty const *>::value,
84- mpty const *,
79+ std::is_same<remove_reference_t <T_>, atyp const *>::value,
80+ atyp const *,
8581 conditional_t <
86- std::is_same<remove_reference_t <T_>, mpty *>::value,
87- mpty *,
82+ std::is_same<remove_reference_t <T_>, atyp *>::value,
83+ atyp *,
8884 conditional_t <
89- std::is_same<T_, mpty const &>::value,
90- mpty const &,
91- conditional_t <std::is_same<T_, mpty &>::value,
92- mpty &,
93- conditional_t <std::is_same<T_, mpty &&>::value, mpty &&, mpty >>>>>;
85+ std::is_same<T_, atyp const &>::value,
86+ atyp const &,
87+ conditional_t <std::is_same<T_, atyp &>::value,
88+ atyp &,
89+ conditional_t <std::is_same<T_, atyp &&>::value, atyp &&, atyp >>>>>;
9490
9591 // clang-format off
9692
97- operator mpty () { return rtrn_valu () ; }
98- operator mpty &&() && { return rtrn_rref ( ); }
99- operator mpty const &() { return rtrn_cref () ; }
100- operator mpty &() { return rtrn_mref () ; }
101- operator mpty const *() { static mpty obj; return &obj; }
102- operator mpty *() { static mpty obj; return &obj; }
93+ operator atyp () { static atyp obj; obj. trace = " valu " ; return obj ; }
94+ operator atyp &&() { static atyp obj; obj. trace = " rref " ; return std::move (obj ); }
95+ operator atyp const &() { static atyp obj; obj. trace = " cref " ; return obj ; }
96+ operator atyp &() { static atyp obj; obj. trace = " mref " ; return obj ; }
97+ operator atyp const *() { static atyp obj; obj. trace = " cptr " ; return &obj; }
98+ operator atyp *() { static atyp obj; obj. trace = " mptr " ; return &obj; }
10399
104100 // clang-format on
105101
106- bool load (handle /* src*/ , bool /* convert*/ ) { return true ; }
107- };
108-
109- template <>
110- struct type_caster <std::shared_ptr<mpty>> {
111- static constexpr auto name = _<std::shared_ptr<mpty>>();
112-
113- static handle cast (const std::shared_ptr<mpty> & /* src*/ ,
114- return_value_policy /* policy*/ ,
115- handle /* parent*/ ) {
116- return str (" cast_shmp" ).release ();
117- }
118-
119- template <typename >
120- using cast_op_type = std::shared_ptr<mpty>;
121-
122- operator std::shared_ptr<mpty>() { return rtrn_shmp (); }
123-
124- bool load (handle /* src*/ , bool /* convert*/ ) { return true ; }
125- };
126-
127- template <>
128- struct type_caster <std::shared_ptr<mpty const >> {
129- static constexpr auto name = _<std::shared_ptr<mpty const >>();
130-
131- static handle cast (const std::shared_ptr<mpty const > & /* src*/ ,
132- return_value_policy /* policy*/ ,
133- handle /* parent*/ ) {
134- return str (" cast_shcp" ).release ();
135- }
136-
137- template <typename >
138- using cast_op_type = std::shared_ptr<mpty const >;
139-
140- operator std::shared_ptr<mpty const >() { return rtrn_shcp (); }
141-
142- bool load (handle /* src*/ , bool /* convert*/ ) { return true ; }
143- };
144-
145- template <>
146- struct type_caster <std::unique_ptr<mpty>> {
147- static constexpr auto name = _<std::unique_ptr<mpty>>();
148-
149- static handle
150- cast (std::unique_ptr<mpty> && /* src*/ , return_value_policy /* policy*/ , handle /* parent*/ ) {
151- return str (" cast_uqmp" ).release ();
152- }
153-
154- template <typename >
155- using cast_op_type = std::unique_ptr<mpty>;
156-
157- operator std::unique_ptr<mpty>() { return rtrn_uqmp (); }
158-
159- bool load (handle /* src*/ , bool /* convert*/ ) { return true ; }
160- };
161-
162- template <>
163- struct type_caster <std::unique_ptr<mpty const >> {
164- static constexpr auto name = _<std::unique_ptr<mpty const >>();
165-
166- static handle cast (std::unique_ptr<mpty const > && /* src*/ ,
167- return_value_policy /* policy*/ ,
168- handle /* parent*/ ) {
169- return str (" cast_uqcp" ).release ();
170- }
171-
172- template <typename >
173- using cast_op_type = std::unique_ptr<mpty const >;
174-
175- operator std::unique_ptr<mpty const >() { return rtrn_uqcp (); }
176-
102+ // The entire load logic is intentionally omitted.
177103 bool load (handle /* src*/ , bool /* convert*/ ) { return true ; }
178104};
179105
180106} // namespace detail
181107} // namespace pybind11
182108
183- namespace pybind11_tests {
184- namespace type_caster_bare_interface {
185-
186109TEST_SUBMODULE (type_caster_bare_interface, m) {
110+ namespace py = pybind11;
111+ using namespace pybind11_tests ::type_caster_bare_interface;
112+
187113 m.def (" rtrn_valu" , rtrn_valu);
188114 m.def (" rtrn_rref" , rtrn_rref);
189115 m.def (" rtrn_cref" , rtrn_cref);
@@ -197,19 +123,4 @@ TEST_SUBMODULE(type_caster_bare_interface, m) {
197123 m.def (" pass_mref" , pass_mref);
198124 m.def (" pass_cptr" , pass_cptr);
199125 m.def (" pass_mptr" , pass_mptr);
200-
201- m.def (" rtrn_shmp" , rtrn_shmp);
202- m.def (" rtrn_shcp" , rtrn_shcp);
203-
204- m.def (" pass_shmp" , pass_shmp);
205- m.def (" pass_shcp" , pass_shcp);
206-
207- m.def (" rtrn_uqmp" , rtrn_uqmp);
208- m.def (" rtrn_uqcp" , rtrn_uqcp);
209-
210- m.def (" pass_uqmp" , pass_uqmp);
211- m.def (" pass_uqcp" , pass_uqcp);
212126}
213-
214- } // namespace type_caster_bare_interface
215- } // namespace pybind11_tests
0 commit comments