23 class huge_unique_ptr {
24 std::unique_ptr<T> ptr;
28 explicit huge_unique_ptr(
T *
p) : ptr(
p) {}
29 T *
get() {
return ptr.get(); }
34 class custom_unique_ptr {
35 std::unique_ptr<T> impl;
38 explicit custom_unique_ptr(
T *
p) : impl(
p) {}
39 T *
get()
const {
return impl.get(); }
40 T *release_ptr() {
return impl.release(); }
47 class shared_ptr_with_addressof_operator {
48 std::shared_ptr<T> impl;
51 shared_ptr_with_addressof_operator() =
default;
52 explicit shared_ptr_with_addressof_operator(
T *
p) : impl(
p) {}
53 T *
get()
const {
return impl.get(); }
54 T **
operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
61 class unique_ptr_with_addressof_operator {
62 std::unique_ptr<T> impl;
65 unique_ptr_with_addressof_operator() =
default;
66 explicit unique_ptr_with_addressof_operator(
T *
p) : impl(
p) {}
67 T *
get()
const {
return impl.get(); }
68 T *release_ptr() {
return impl.release(); }
69 T **
operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
73 class MyObject1 :
public Object {
76 std::string
toString()
const override {
return "MyObject1[" + std::to_string(
value) +
"]"; }
88 MyObject2(
const MyObject2 &) =
default;
90 std::string toString()
const {
return "MyObject2[" + std::to_string(
value) +
"]"; }
98 class MyObject3 :
public std::enable_shared_from_this<MyObject3> {
100 MyObject3(
const MyObject3 &) =
default;
102 std::string toString()
const {
return "MyObject3[" + std::to_string(
value) +
"]"; }
109 template <
typename T>
110 std::unordered_set<T *> &pointer_set() {
112 static auto singleton =
new std::unordered_set<T *>();
122 pointer_set<MyObject4>().insert(
this);
126 static void cleanupAllInstances() {
127 auto tmp = std::move(pointer_set<MyObject4>());
128 pointer_set<MyObject4>().clear();
129 for (
auto *o : tmp) {
136 pointer_set<MyObject4>().erase(
this);
146 explicit MyObject4a(
int i) :
value{
i} {
148 pointer_set<MyObject4a>().insert(
this);
152 static void cleanupAllInstances() {
153 auto tmp = std::move(pointer_set<MyObject4a>());
154 pointer_set<MyObject4a>().clear();
155 for (
auto *o : tmp) {
161 virtual ~MyObject4a() {
162 pointer_set<MyObject4a>().erase(
this);
168 class MyObject4b :
public MyObject4a {
183 struct SharedPtrRef {
192 std::shared_ptr<A> shared = std::make_shared<A>();
196 struct SharedFromThisRef {
197 struct B : std::enable_shared_from_this<B> {
206 std::shared_ptr<B> shared = std::make_shared<B>();
210 struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
211 SharedFromThisVBase() =
default;
212 SharedFromThisVBase(
const SharedFromThisVBase &) =
default;
213 virtual ~SharedFromThisVBase() =
default;
215 struct SharedFromThisVirt :
virtual SharedFromThisVBase {};
224 struct TypeForHolderWithAddressOf {
226 TypeForHolderWithAddressOf(
const TypeForHolderWithAddressOf &) {
print_copy_created(
this); }
227 TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {
231 std::string toString()
const {
232 return "TypeForHolderWithAddressOf[" + std::to_string(
value) +
"]";
238 struct TypeForMoveOnlyHolderWithAddressOf {
241 std::string toString()
const {
242 return "MoveOnlyHolderWithAddressOf[" + std::to_string(
value) +
"]";
248 struct HeldByDefaultHolder {};
253 virtual ~ElementBase() =
default;
254 ElementBase() =
default;
255 ElementBase(
const ElementBase &) =
delete;
258 struct ElementA : ElementBase {
259 explicit ElementA(
int v) :
v(
v) {}
260 int value()
const {
return v; }
265 void add(
const std::shared_ptr<ElementBase> &
e) {
l.push_back(
e); }
266 std::vector<std::shared_ptr<ElementBase>>
l;
277 template <
typename T>
301 py::class_<Object, ref<Object>> obj(
m,
"Object");
304 py::class_<MyObject1, ref<MyObject1>>(
m,
"MyObject1", obj).def(py::init<int>());
305 py::implicitly_convertible<py::int_, MyObject1>();
307 m.def(
"make_object_1", []() ->
Object * {
return new MyObject1(1); });
309 m.def(
"make_myobject1_1", []() -> MyObject1 * {
return new MyObject1(4); });
315 m.def(
"print_myobject1_1", [](
const MyObject1 *obj) {
py::print(obj->toString()); });
321 m.def(
"cstats_ref", &ConstructorStats::get<ref_tag>);
323 py::class_<MyObject2, std::shared_ptr<MyObject2>>(
m,
"MyObject2").def(py::init<int>());
324 m.def(
"make_myobject2_1", []() {
return new MyObject2(6); });
325 m.def(
"make_myobject2_2", []() {
return std::make_shared<MyObject2>(7); });
326 m.def(
"print_myobject2_1", [](
const MyObject2 *obj) {
py::print(obj->toString()); });
328 m.def(
"print_myobject2_2", [](std::shared_ptr<MyObject2> obj) {
py::print(obj->toString()); });
329 m.def(
"print_myobject2_3",
330 [](
const std::shared_ptr<MyObject2> &obj) {
py::print(obj->toString()); });
331 m.def(
"print_myobject2_4",
332 [](
const std::shared_ptr<MyObject2> *obj) {
py::print((*obj)->toString()); });
334 py::class_<MyObject3, std::shared_ptr<MyObject3>>(
m,
"MyObject3").def(py::init<int>());
335 m.def(
"make_myobject3_1", []() {
return new MyObject3(8); });
336 m.def(
"make_myobject3_2", []() {
return std::make_shared<MyObject3>(9); });
337 m.def(
"print_myobject3_1", [](
const MyObject3 *obj) {
py::print(obj->toString()); });
339 m.def(
"print_myobject3_2", [](std::shared_ptr<MyObject3> obj) {
py::print(obj->toString()); });
340 m.def(
"print_myobject3_3",
341 [](
const std::shared_ptr<MyObject3> &obj) {
py::print(obj->toString()); });
342 m.def(
"print_myobject3_4",
343 [](
const std::shared_ptr<MyObject3> *obj) {
py::print((*obj)->toString()); });
346 m.def(
"test_object1_refcounting", []() {
348 bool good = o->getRefCount() == 1;
349 py::object o2 =
py::cast(o, py::return_value_policy::reference);
352 good &= o->getRefCount() == 2;
357 py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(
m,
"MyObject4")
358 .def(py::init<int>())
360 .def_static(
"cleanup_all_instances", &MyObject4::cleanupAllInstances);
363 py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(
m,
"MyObject4a")
364 .def(py::init<int>())
366 .def_static(
"cleanup_all_instances", &MyObject4a::cleanupAllInstances);
368 py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(
m,
"MyObject4b")
369 .def(py::init<int>());
372 py::class_<MyObject5, huge_unique_ptr<MyObject5>>(
m,
"MyObject5")
373 .def(py::init<int>())
378 py::class_<A, std::shared_ptr<A>>(
m,
"A");
379 py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(
m,
"SharedPtrRef")
382 .def_property_readonly(
384 .def_readonly(
"holder_ref", &SharedPtrRef::shared)
385 .def_property_readonly(
387 [](
const SharedPtrRef &
s) {
return s.shared; },
389 .def(
"set_ref", [](SharedPtrRef &,
const A &) {
return true; })
391 .def(
"set_holder", [](SharedPtrRef &, std::shared_ptr<A>) {
return true; });
395 py::class_<B, std::shared_ptr<B>>(
m,
"B");
396 py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(
m,
"SharedFromThisRef")
399 .def_property_readonly(
"ref",
400 [](
const SharedFromThisRef &
s) ->
const B & {
return *
s.shared; })
401 .def_property_readonly(
403 [](
const SharedFromThisRef &
s) {
return s.value; },
405 .def_readonly(
"holder_ref", &SharedFromThisRef::shared)
406 .def_property_readonly(
408 [](
const SharedFromThisRef &
s) {
return s.shared; },
410 .def(
"set_ref", [](SharedFromThisRef &,
const B &) {
return true; })
412 .def(
"set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) {
return true; });
415 static std::shared_ptr<SharedFromThisVirt> sft(
new SharedFromThisVirt());
416 py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(
m,
"SharedFromThisVirt")
417 .def_static(
"get", []() {
return sft.get(); });
420 py::class_<C, custom_unique_ptr<C>>(
m,
"TypeWithMoveOnlyHolder")
421 .def_static(
"make", []() {
return custom_unique_ptr<C>(
new C); })
422 .def_static(
"make_as_object", []() {
return py::cast(custom_unique_ptr<C>(
new C)); });
425 using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
426 py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(
m,
"TypeForHolderWithAddressOf")
427 .def_static(
"make", []() {
return HolderWithAddressOf(
new TypeForHolderWithAddressOf); })
428 .def(
"get", [](
const HolderWithAddressOf &
self) {
return self.get(); })
429 .def(
"print_object_1",
430 [](
const TypeForHolderWithAddressOf *obj) {
py::print(obj->toString()); })
432 .def(
"print_object_2", [](HolderWithAddressOf obj) {
py::print(obj.get()->toString()); })
433 .def(
"print_object_3",
434 [](
const HolderWithAddressOf &obj) {
py::print(obj.get()->toString()); })
435 .def(
"print_object_4",
436 [](
const HolderWithAddressOf *obj) {
py::print((*obj).get()->toString()); });
439 using MoveOnlyHolderWithAddressOf
440 = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;
441 py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(
442 m,
"TypeForMoveOnlyHolderWithAddressOf")
445 return MoveOnlyHolderWithAddressOf(
446 new TypeForMoveOnlyHolderWithAddressOf(0));
450 [](
const TypeForMoveOnlyHolderWithAddressOf *obj) {
py::print(obj->toString()); });
453 py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(
m,
"HeldByDefaultHolder")
456 .def_static(
"load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});
460 py::class_<ElementBase, std::shared_ptr<ElementBase>>(
m,
"ElementBase");
462 py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(
m,
"ElementA")
463 .def(py::init<int>())
466 py::class_<ElementList, std::shared_ptr<ElementList>>(
m,
"ElementList")
469 .def(
"get", [](ElementList &el) {
471 for (
auto &
e : el.l) {