Skip to content

Commit 4efd7e7

Browse files
committed
[skip ci] Copy and extend (raw_ptr, unique_ptr) reproducer from PR pybind#5796
1 parent 8f87bc9 commit 4efd7e7

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

tests/test_class_sh_mi_thunks.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,45 @@ DiamondAddrs diamond_addrs() {
8888
reinterpret_cast<uintptr_t>(static_cast<Right *>(sp.get()))};
8989
}
9090

91+
// Animal-Cat-Tiger reproducer copied from PR #5796.
92+
// clone_raw_ptr, clone_unique_ptr added in PR #5836.
93+
94+
class Animal {
95+
public:
96+
Animal() = default;
97+
Animal(const Animal &) = default;
98+
Animal &operator=(const Animal &) = default;
99+
virtual Animal *clone_raw_ptr() const = 0;
100+
virtual std::shared_ptr<Animal> clone_shared_ptr() const = 0;
101+
virtual std::unique_ptr<Animal> clone_unique_ptr() const = 0;
102+
virtual ~Animal() = default;
103+
};
104+
105+
class Cat : virtual public Animal {
106+
public:
107+
Cat() = default;
108+
Cat(const Cat &) = default;
109+
Cat &operator=(const Cat &) = default;
110+
~Cat() override = default;
111+
};
112+
113+
class Tiger : virtual public Cat {
114+
public:
115+
Tiger() = default;
116+
Tiger(const Tiger &) = default;
117+
Tiger &operator=(const Tiger &) = default;
118+
~Tiger() override = default;
119+
Animal *clone_raw_ptr() const override {
120+
return new Tiger(*this); // upcast
121+
}
122+
std::shared_ptr<Animal> clone_shared_ptr() const override {
123+
return std::make_shared<Tiger>(*this); // upcast
124+
}
125+
std::unique_ptr<Animal> clone_unique_ptr() const override {
126+
return std::unique_ptr<Tiger>(new Tiger(*this)); // upcast
127+
}
128+
};
129+
91130
} // namespace test_class_sh_mi_thunks
92131

93132
TEST_SUBMODULE(class_sh_mi_thunks, m) {
@@ -171,4 +210,12 @@ TEST_SUBMODULE(class_sh_mi_thunks, m) {
171210
.def_readonly("as_right", &DiamondAddrs::as_right);
172211

173212
m.def("diamond_addrs", &diamond_addrs);
213+
214+
py::classh<Animal>(m, "Animal");
215+
py::classh<Cat, Animal>(m, "Cat");
216+
py::classh<Tiger, Cat>(m, "Tiger", py::multiple_inheritance())
217+
.def(py::init<>())
218+
.def("clone_raw_ptr", &Tiger::clone_raw_ptr)
219+
.def("clone_shared_ptr", &Tiger::clone_shared_ptr)
220+
.def("clone_unique_ptr", &Tiger::clone_unique_ptr);
174221
}

tests/test_class_sh_mi_thunks.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,17 @@ def test_make_diamond_as_vbase(make_fn):
7171
# See PR #5836 for background
7272
vb = make_fn()
7373
assert vb.ping() == 7
74+
75+
76+
@pytest.mark.parametrize(
77+
"clone_fn",
78+
[
79+
m.Tiger.clone_raw_ptr,
80+
m.Tiger.clone_shared_ptr,
81+
m.Tiger.clone_unique_ptr,
82+
],
83+
)
84+
def test_animal_cat_tiger(clone_fn):
85+
tiger = m.Tiger()
86+
cloned = clone_fn(tiger)
87+
assert isinstance(cloned, m.Tiger)

0 commit comments

Comments
 (0)