2
2
// direction of an integration test, to ensure multiple components of pybind11 work together
3
3
// correctly. It is also useful to show the type_caster<> interface virtually clutter-free.
4
4
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
+
5
10
#include " pybind11_tests.h"
6
11
7
- #include < memory >
12
+ #include < string >
8
13
9
14
namespace pybind11_tests {
10
15
namespace type_caster_bare_interface {
11
16
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
+ };
13
23
14
24
// clang-format off
15
25
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; }
32
32
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 ; }
41
39
42
40
// clang-format on
43
41
@@ -50,140 +48,68 @@ namespace detail {
50
48
using namespace pybind11_tests ::type_caster_bare_interface;
51
49
52
50
template <>
53
- struct type_caster <mpty > {
54
- static constexpr auto name = _<mpty >();
51
+ struct type_caster <atyp > {
52
+ static constexpr auto name = _<atyp >();
55
53
56
- // static handle cast(mpty , ...)
54
+ // static handle cast(atyp , ...)
57
55
// is redundant (leads to ambiguous overloads).
58
56
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 ();
61
59
}
62
60
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 ();
65
63
}
66
64
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 ();
69
67
}
70
68
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 ();
74
71
}
75
72
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 ();
79
75
}
80
76
81
77
template <typename T_>
82
78
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 *,
85
81
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 *,
88
84
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 >>>>>;
94
90
95
91
// clang-format off
96
92
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; }
103
99
104
100
// clang-format on
105
101
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.
177
103
bool load (handle /* src*/ , bool /* convert*/ ) { return true ; }
178
104
};
179
105
180
106
} // namespace detail
181
107
} // namespace pybind11
182
108
183
- namespace pybind11_tests {
184
- namespace type_caster_bare_interface {
185
-
186
109
TEST_SUBMODULE (type_caster_bare_interface, m) {
110
+ namespace py = pybind11;
111
+ using namespace pybind11_tests ::type_caster_bare_interface;
112
+
187
113
m.def (" rtrn_valu" , rtrn_valu);
188
114
m.def (" rtrn_rref" , rtrn_rref);
189
115
m.def (" rtrn_cref" , rtrn_cref);
@@ -197,19 +123,4 @@ TEST_SUBMODULE(type_caster_bare_interface, m) {
197
123
m.def (" pass_mref" , pass_mref);
198
124
m.def (" pass_cptr" , pass_cptr);
199
125
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);
212
126
}
213
-
214
- } // namespace type_caster_bare_interface
215
- } // namespace pybind11_tests
0 commit comments