Skip to content

Commit 39fbe46

Browse files
committed
Merge branch 'master' into sh_merge_master
Includes follow-on to #5189: Backport the smart_holder-specific changes from google/pybind11clif#30093 and google/pybind11clif#30098.
2 parents a8bc5f7 + a406a62 commit 39fbe46

7 files changed

+52
-4
lines changed

include/pybind11/detail/smart_holder_type_casters.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
653653

654654
static handle cast(T &&src, return_value_policy /*policy*/, handle parent) {
655655
// type_caster_base BEGIN
656-
return cast(&src, return_value_policy::move, parent);
656+
return cast(std::addressof(src), return_value_policy::move, parent);
657657
// type_caster_base END
658658
}
659659

@@ -663,7 +663,7 @@ struct smart_holder_type_caster : smart_holder_type_caster_load<T>,
663663
|| policy == return_value_policy::automatic_reference) {
664664
policy = return_value_policy::copy;
665665
}
666-
return cast(&src, policy, parent);
666+
return cast(std::addressof(src), policy, parent);
667667
// type_caster_base END
668668
}
669669

include/pybind11/detail/type_caster_base.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1107,11 +1107,11 @@ class type_caster_base : public type_caster_generic {
11071107
|| policy == return_value_policy::automatic_reference) {
11081108
policy = return_value_policy::copy;
11091109
}
1110-
return cast(&src, policy, parent);
1110+
return cast(std::addressof(src), policy, parent);
11111111
}
11121112

11131113
static handle cast(itype &&src, return_value_policy, handle parent) {
1114-
return cast(&src, return_value_policy::move, parent);
1114+
return cast(std::addressof(src), return_value_policy::move, parent);
11151115
}
11161116

11171117
// Returns a (pointer, type_info) pair taking care of necessary type lookup for a

tests/pybind11_tests.h

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <pybind11/eval.h>
44
#include <pybind11/pybind11.h>
55

6+
#include <memory>
7+
68
namespace py = pybind11;
79
using namespace pybind11::literals;
810

@@ -52,6 +54,17 @@ union IntFloat {
5254
float f;
5355
};
5456

57+
class UnusualOpRef {
58+
public:
59+
using NonTrivialType = std::shared_ptr<int>; // Almost any non-trivial type will do.
60+
// Overriding operator& should not break pybind11.
61+
NonTrivialType operator&() { return non_trivial_member; }
62+
NonTrivialType operator&() const { return non_trivial_member; }
63+
64+
private:
65+
NonTrivialType non_trivial_member;
66+
};
67+
5568
/// Custom cast-only type that casts to a string "rvalue" or "lvalue" depending on the cast
5669
/// context. Used to test recursive casters (e.g. std::tuple, stl containers).
5770
struct RValueCaster {};

tests/test_class_sh_basic.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,17 @@ struct SharedPtrStash {
129129
void Add(const std::shared_ptr<const atyp> &obj) { stash.push_back(obj); }
130130
};
131131

132+
class LocalUnusualOpRef : UnusualOpRef {}; // To avoid clashing with `py::class_<UnusualOpRef>`.
133+
py::object CastUnusualOpRefConstRef(const LocalUnusualOpRef &cref) { return py::cast(cref); }
134+
py::object CastUnusualOpRefMovable(LocalUnusualOpRef &&mvbl) { return py::cast(std::move(mvbl)); }
135+
132136
} // namespace class_sh_basic
133137
} // namespace pybind11_tests
134138

135139
PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::class_sh_basic::atyp)
136140
PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::class_sh_basic::uconsumer)
137141
PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::class_sh_basic::SharedPtrStash)
142+
PYBIND11_SMART_HOLDER_TYPE_CASTERS(pybind11_tests::class_sh_basic::LocalUnusualOpRef)
138143

139144
namespace pybind11_tests {
140145
namespace class_sh_basic {
@@ -227,6 +232,12 @@ TEST_SUBMODULE(class_sh_basic, m) {
227232
"rtrn_uq_automatic_reference",
228233
[]() { return std::unique_ptr<atyp>(new atyp("rtrn_uq_automatic_reference")); },
229234
pybind11::return_value_policy::automatic_reference);
235+
236+
py::classh<LocalUnusualOpRef>(m, "LocalUnusualOpRef");
237+
m.def("CallCastUnusualOpRefConstRef",
238+
[]() { return CastUnusualOpRefConstRef(LocalUnusualOpRef()); });
239+
m.def("CallCastUnusualOpRefMovable",
240+
[]() { return CastUnusualOpRefMovable(LocalUnusualOpRef()); });
230241
}
231242

232243
} // namespace class_sh_basic

tests/test_class_sh_basic.py

+6
Original file line numberDiff line numberDiff line change
@@ -218,3 +218,9 @@ def test_function_signatures(doc):
218218

219219
def test_unique_ptr_return_value_policy_automatic_reference():
220220
assert m.get_mtxt(m.rtrn_uq_automatic_reference()) == "rtrn_uq_automatic_reference"
221+
222+
223+
def test_unusual_op_ref():
224+
# Merely to test that this still exists and built successfully.
225+
assert m.CallCastUnusualOpRefConstRef().__class__.__name__ == "LocalUnusualOpRef"
226+
assert m.CallCastUnusualOpRefMovable().__class__.__name__ == "LocalUnusualOpRef"

tests/test_copy_move.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,13 @@ struct type_caster<CopyOnlyInt> {
157157
PYBIND11_NAMESPACE_END(detail)
158158
PYBIND11_NAMESPACE_END(pybind11)
159159

160+
namespace {
161+
162+
py::object CastUnusualOpRefConstRef(const UnusualOpRef &cref) { return py::cast(cref); }
163+
py::object CastUnusualOpRefMovable(UnusualOpRef &&mvbl) { return py::cast(std::move(mvbl)); }
164+
165+
} // namespace
166+
160167
TEST_SUBMODULE(copy_move_policies, m) {
161168
// test_lacking_copy_ctor
162169
py::class_<lacking_copy_ctor>(m, "lacking_copy_ctor")
@@ -293,6 +300,11 @@ TEST_SUBMODULE(copy_move_policies, m) {
293300

294301
// Make sure that cast from pytype rvalue to other pytype works
295302
m.def("get_pytype_rvalue_castissue", [](double i) { return py::float_(i).cast<py::int_>(); });
303+
304+
py::class_<UnusualOpRef>(m, "UnusualOpRef");
305+
m.def("CallCastUnusualOpRefConstRef",
306+
[]() { return CastUnusualOpRefConstRef(UnusualOpRef()); });
307+
m.def("CallCastUnusualOpRefMovable", []() { return CastUnusualOpRefMovable(UnusualOpRef()); });
296308
}
297309

298310
/*

tests/test_copy_move.py

+6
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,9 @@ def test_pytype_rvalue_cast():
132132

133133
value = m.get_pytype_rvalue_castissue(1.0)
134134
assert value == 1
135+
136+
137+
def test_unusual_op_ref():
138+
# Merely to test that this still exists and built successfully.
139+
assert m.CallCastUnusualOpRefConstRef().__class__.__name__ == "UnusualOpRef"
140+
assert m.CallCastUnusualOpRefMovable().__class__.__name__ == "UnusualOpRef"

0 commit comments

Comments
 (0)