20 class huge_unique_ptr {
21 std::unique_ptr<T> ptr;
25 explicit huge_unique_ptr(
T *
p) : ptr(
p) {}
26 T *
get() {
return ptr.get(); }
31 class custom_unique_ptr {
32 std::unique_ptr<T> impl;
35 explicit custom_unique_ptr(
T *
p) : impl(
p) {}
36 T *
get()
const {
return impl.get(); }
37 T *release_ptr() {
return impl.release(); }
44 class shared_ptr_with_addressof_operator {
45 std::shared_ptr<T> impl;
48 shared_ptr_with_addressof_operator() =
default;
49 explicit shared_ptr_with_addressof_operator(
T *
p) : impl(
p) {}
50 T *
get()
const {
return impl.get(); }
51 T **
operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
58 class unique_ptr_with_addressof_operator {
59 std::unique_ptr<T> impl;
62 unique_ptr_with_addressof_operator() =
default;
63 explicit unique_ptr_with_addressof_operator(
T *
p) : impl(
p) {}
64 T *
get()
const {
return impl.get(); }
65 T *release_ptr() {
return impl.release(); }
66 T **
operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
70 class MyObject1 :
public Object {
73 std::string
toString()
const override {
return "MyObject1[" + std::to_string(
value) +
"]"; }
85 MyObject2(
const MyObject2 &) =
default;
87 std::string toString()
const {
return "MyObject2[" + std::to_string(
value) +
"]"; }
95 class MyObject3 :
public std::enable_shared_from_this<MyObject3> {
97 MyObject3(
const MyObject3 &) =
default;
99 std::string toString()
const {
return "MyObject3[" + std::to_string(
value) +
"]"; }
106 template <
typename T>
107 std::unordered_set<T *> &pointer_set() {
109 static auto singleton =
new std::unordered_set<T *>();
119 pointer_set<MyObject4>().insert(
this);
123 static void cleanupAllInstances() {
124 auto tmp = std::move(pointer_set<MyObject4>());
125 pointer_set<MyObject4>().clear();
126 for (
auto *o : tmp) {
133 pointer_set<MyObject4>().erase(
this);
143 explicit MyObject4a(
int i) :
value{
i} {
145 pointer_set<MyObject4a>().insert(
this);
149 static void cleanupAllInstances() {
150 auto tmp = std::move(pointer_set<MyObject4a>());
151 pointer_set<MyObject4a>().clear();
152 for (
auto *o : tmp) {
158 virtual ~MyObject4a() {
159 pointer_set<MyObject4a>().erase(
this);
165 class MyObject4b :
public MyObject4a {
180 struct SharedPtrRef {
189 std::shared_ptr<A> shared = std::make_shared<A>();
193 struct SharedFromThisRef {
194 struct B : std::enable_shared_from_this<B> {
203 std::shared_ptr<B> shared = std::make_shared<B>();
207 struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
208 SharedFromThisVBase() =
default;
209 SharedFromThisVBase(
const SharedFromThisVBase &) =
default;
210 virtual ~SharedFromThisVBase() =
default;
212 struct SharedFromThisVirt :
virtual SharedFromThisVBase {};
221 struct TypeForHolderWithAddressOf {
223 TypeForHolderWithAddressOf(
const TypeForHolderWithAddressOf &) {
print_copy_created(
this); }
224 TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {
228 std::string toString()
const {
229 return "TypeForHolderWithAddressOf[" + std::to_string(
value) +
"]";
235 struct TypeForMoveOnlyHolderWithAddressOf {
238 std::string toString()
const {
239 return "MoveOnlyHolderWithAddressOf[" + std::to_string(
value) +
"]";
245 struct HeldByDefaultHolder {};
250 virtual ~ElementBase() =
default;
251 ElementBase() =
default;
252 ElementBase(
const ElementBase &) =
delete;
255 struct ElementA : ElementBase {
256 explicit ElementA(
int v) :
v(
v) {}
257 int value()
const {
return v; }
262 void add(
const std::shared_ptr<ElementBase> &
e) {
l.push_back(
e); }
263 std::vector<std::shared_ptr<ElementBase>>
l;
274 template <
typename T>
298 py::class_<Object, ref<Object>> obj(
m,
"Object");
301 py::class_<MyObject1, ref<MyObject1>>(
m,
"MyObject1", obj).def(py::init<int>());
302 py::implicitly_convertible<py::int_, MyObject1>();
304 m.def(
"make_object_1", []() ->
Object * {
return new MyObject1(1); });
306 m.def(
"make_myobject1_1", []() -> MyObject1 * {
return new MyObject1(4); });
312 m.def(
"print_myobject1_1", [](
const MyObject1 *obj) {
py::print(obj->toString()); });
318 m.def(
"cstats_ref", &ConstructorStats::get<ref_tag>);
320 py::class_<MyObject2, std::shared_ptr<MyObject2>>(
m,
"MyObject2").def(py::init<int>());
321 m.def(
"make_myobject2_1", []() {
return new MyObject2(6); });
322 m.def(
"make_myobject2_2", []() {
return std::make_shared<MyObject2>(7); });
323 m.def(
"print_myobject2_1", [](
const MyObject2 *obj) {
py::print(obj->toString()); });
325 m.def(
"print_myobject2_2", [](std::shared_ptr<MyObject2> obj) {
py::print(obj->toString()); });
326 m.def(
"print_myobject2_3",
327 [](
const std::shared_ptr<MyObject2> &obj) {
py::print(obj->toString()); });
328 m.def(
"print_myobject2_4",
329 [](
const std::shared_ptr<MyObject2> *obj) {
py::print((*obj)->toString()); });
331 py::class_<MyObject3, std::shared_ptr<MyObject3>>(
m,
"MyObject3").def(py::init<int>());
332 m.def(
"make_myobject3_1", []() {
return new MyObject3(8); });
333 m.def(
"make_myobject3_2", []() {
return std::make_shared<MyObject3>(9); });
334 m.def(
"print_myobject3_1", [](
const MyObject3 *obj) {
py::print(obj->toString()); });
336 m.def(
"print_myobject3_2", [](std::shared_ptr<MyObject3> obj) {
py::print(obj->toString()); });
337 m.def(
"print_myobject3_3",
338 [](
const std::shared_ptr<MyObject3> &obj) {
py::print(obj->toString()); });
339 m.def(
"print_myobject3_4",
340 [](
const std::shared_ptr<MyObject3> *obj) {
py::print((*obj)->toString()); });
343 m.def(
"test_object1_refcounting", []() {
345 bool good = o->getRefCount() == 1;
346 py::object o2 =
py::cast(o, py::return_value_policy::reference);
349 good &= o->getRefCount() == 2;
354 py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(
m,
"MyObject4")
355 .def(py::init<int>())
357 .def_static(
"cleanup_all_instances", &MyObject4::cleanupAllInstances);
360 py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(
m,
"MyObject4a")
361 .def(py::init<int>())
363 .def_static(
"cleanup_all_instances", &MyObject4a::cleanupAllInstances);
365 py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(
m,
"MyObject4b")
366 .def(py::init<int>());
369 py::class_<MyObject5, huge_unique_ptr<MyObject5>>(
m,
"MyObject5")
370 .def(py::init<int>())
375 py::class_<A, std::shared_ptr<A>>(
m,
"A");
376 py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(
m,
"SharedPtrRef")
379 .def_property_readonly(
381 .def_readonly(
"holder_ref", &SharedPtrRef::shared)
382 .def_property_readonly(
384 [](
const SharedPtrRef &
s) {
return s.shared; },
386 .def(
"set_ref", [](SharedPtrRef &,
const A &) {
return true; })
388 .def(
"set_holder", [](SharedPtrRef &, std::shared_ptr<A>) {
return true; });
392 py::class_<B, std::shared_ptr<B>>(
m,
"B");
393 py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(
m,
"SharedFromThisRef")
396 .def_property_readonly(
"ref",
397 [](
const SharedFromThisRef &
s) ->
const B & {
return *
s.shared; })
398 .def_property_readonly(
400 [](
const SharedFromThisRef &
s) {
return s.value; },
402 .def_readonly(
"holder_ref", &SharedFromThisRef::shared)
403 .def_property_readonly(
405 [](
const SharedFromThisRef &
s) {
return s.shared; },
407 .def(
"set_ref", [](SharedFromThisRef &,
const B &) {
return true; })
409 .def(
"set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) {
return true; });
412 static std::shared_ptr<SharedFromThisVirt> sft(
new SharedFromThisVirt());
413 py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(
m,
"SharedFromThisVirt")
414 .def_static(
"get", []() {
return sft.get(); });
417 py::class_<C, custom_unique_ptr<C>>(
m,
"TypeWithMoveOnlyHolder")
418 .def_static(
"make", []() {
return custom_unique_ptr<C>(
new C); })
419 .def_static(
"make_as_object", []() {
return py::cast(custom_unique_ptr<C>(
new C)); });
422 using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
423 py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(
m,
"TypeForHolderWithAddressOf")
424 .def_static(
"make", []() {
return HolderWithAddressOf(
new TypeForHolderWithAddressOf); })
425 .def(
"get", [](
const HolderWithAddressOf &
self) {
return self.get(); })
426 .def(
"print_object_1",
427 [](
const TypeForHolderWithAddressOf *obj) {
py::print(obj->toString()); })
429 .def(
"print_object_2", [](HolderWithAddressOf obj) {
py::print(obj.get()->toString()); })
430 .def(
"print_object_3",
431 [](
const HolderWithAddressOf &obj) {
py::print(obj.get()->toString()); })
432 .def(
"print_object_4",
433 [](
const HolderWithAddressOf *obj) {
py::print((*obj).get()->toString()); });
436 using MoveOnlyHolderWithAddressOf
437 = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;
438 py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(
439 m,
"TypeForMoveOnlyHolderWithAddressOf")
442 return MoveOnlyHolderWithAddressOf(
443 new TypeForMoveOnlyHolderWithAddressOf(0));
447 [](
const TypeForMoveOnlyHolderWithAddressOf *obj) {
py::print(obj->toString()); });
450 py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(
m,
"HeldByDefaultHolder")
453 .def_static(
"load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});
457 py::class_<ElementBase, std::shared_ptr<ElementBase>>(
m,
"ElementBase");
459 py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(
m,
"ElementA")
460 .def(py::init<int>())
463 py::class_<ElementList, std::shared_ptr<ElementList>>(
m,
"ElementList")
466 .def(
"get", [](ElementList &el) {
468 for (
auto &
e : el.l) {