11#if defined(_MSC_VER) && _MSC_VER < 1910
12# pragma warning(disable : 4702)
24class huge_unique_ptr {
25 std::unique_ptr<T> ptr;
29 explicit huge_unique_ptr(T *p) : ptr(p) {}
30 T *get() {
return ptr.get(); }
35class custom_unique_ptr {
36 std::unique_ptr<T> impl;
39 explicit custom_unique_ptr(T *p) : impl(p) {}
40 T *get()
const {
return impl.get(); }
41 T *release_ptr() {
return impl.release(); }
48class shared_ptr_with_addressof_operator {
49 std::shared_ptr<T> impl;
52 shared_ptr_with_addressof_operator() =
default;
53 explicit shared_ptr_with_addressof_operator(T *p) : impl(p) {}
54 T *get()
const {
return impl.get(); }
55 T **operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
62class unique_ptr_with_addressof_operator {
63 std::unique_ptr<T> impl;
66 unique_ptr_with_addressof_operator() =
default;
67 explicit unique_ptr_with_addressof_operator(T *p) : impl(p) {}
68 T *get()
const {
return impl.get(); }
69 T *release_ptr() {
return impl.release(); }
70 T **operator&() {
throw std::logic_error(
"Call of overloaded operator& is not expected"); }
74class MyObject1 :
public Object {
77 std::string
toString()
const override {
return "MyObject1[" + std::to_string(value) +
"]"; }
89 MyObject2(
const MyObject2 &) =
default;
91 std::string
toString()
const {
return "MyObject2[" + std::to_string(value) +
"]"; }
99class MyObject3 :
public std::enable_shared_from_this<MyObject3> {
101 MyObject3(
const MyObject3 &) =
default;
103 std::string
toString()
const {
return "MyObject3[" + std::to_string(value) +
"]"; }
113std::unordered_set<MyObject4 *> myobject4_instances;
116 explicit MyObject4(
int value) :
value{
value} {
118 myobject4_instances.insert(
this);
122 static void cleanupAllInstances() {
123 auto tmp = std::move(myobject4_instances);
124 myobject4_instances.clear();
125 for (
auto *o : tmp) {
132 myobject4_instances.erase(
this);
141std::unordered_set<MyObject4a *> myobject4a_instances;
144 explicit MyObject4a(
int i) :
value{
i} {
146 myobject4a_instances.insert(
this);
150 static void cleanupAllInstances() {
151 auto tmp = std::move(myobject4a_instances);
152 myobject4a_instances.clear();
153 for (
auto *o : tmp) {
159 virtual ~MyObject4a() {
160 myobject4a_instances.erase(
this);
166class MyObject4b :
public MyObject4a {
168 explicit MyObject4b(
int i) : MyObject4a(
i) {
print_created(
this); }
190 std::shared_ptr<A> shared = std::make_shared<A>();
194struct SharedFromThisRef {
195 struct B : std::enable_shared_from_this<B> {
204 std::shared_ptr<B> shared = std::make_shared<B>();
208struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
209 SharedFromThisVBase() =
default;
210 SharedFromThisVBase(
const SharedFromThisVBase &) =
default;
211 virtual ~SharedFromThisVBase() =
default;
213struct SharedFromThisVirt :
virtual SharedFromThisVBase {};
222struct TypeForHolderWithAddressOf {
224 TypeForHolderWithAddressOf(
const TypeForHolderWithAddressOf &) {
print_copy_created(
this); }
225 TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {
230 return "TypeForHolderWithAddressOf[" + std::to_string(value) +
"]";
236struct TypeForMoveOnlyHolderWithAddressOf {
240 return "MoveOnlyHolderWithAddressOf[" + std::to_string(value) +
"]";
246struct HeldByDefaultHolder {};
251 virtual ~ElementBase() =
default;
252 ElementBase() =
default;
253 ElementBase(
const ElementBase &) =
delete;
256struct ElementA : ElementBase {
257 explicit ElementA(
int v) : v(v) {}
258 int value()
const {
return v; }
263 void add(
const std::shared_ptr<ElementBase> &e) { l.push_back(e); }
264 std::vector<std::shared_ptr<ElementBase>> l;
299 py::class_<Object, ref<Object>> obj(m,
"Object");
302 py::class_<MyObject1, ref<MyObject1>>(m,
"MyObject1", obj).def(py::init<int>());
303 py::implicitly_convertible<py::int_, MyObject1>();
305 m.def(
"make_object_1", []() ->
Object * {
return new MyObject1(1); });
307 m.def(
"make_myobject1_1", []() -> MyObject1 * {
return new MyObject1(4); });
309 m.def(
"print_object_1", [](
const Object *obj) { py::print(obj->toString()); });
310 m.def(
"print_object_2", [](
ref<Object> obj) { py::print(obj->toString()); });
311 m.def(
"print_object_3", [](
const ref<Object> &obj) { py::print(obj->toString()); });
312 m.def(
"print_object_4", [](
const ref<Object> *obj) { py::print((*obj)->toString()); });
313 m.def(
"print_myobject1_1", [](
const MyObject1 *obj) { py::print(obj->toString()); });
314 m.def(
"print_myobject1_2", [](
ref<MyObject1> obj) { py::print(obj->toString()); });
315 m.def(
"print_myobject1_3", [](
const ref<MyObject1> &obj) { py::print(obj->toString()); });
316 m.def(
"print_myobject1_4", [](
const ref<MyObject1> *obj) { py::print((*obj)->toString()); });
319 m.def(
"cstats_ref", &ConstructorStats::get<ref_tag>);
321 py::class_<MyObject2, std::shared_ptr<MyObject2>>(m,
"MyObject2").def(py::init<int>());
322 m.def(
"make_myobject2_1", []() {
return new MyObject2(6); });
323 m.def(
"make_myobject2_2", []() {
return std::make_shared<MyObject2>(7); });
324 m.def(
"print_myobject2_1", [](
const MyObject2 *obj) { py::print(obj->toString()); });
326 m.def(
"print_myobject2_2", [](std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); });
327 m.def(
"print_myobject2_3",
328 [](
const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); });
329 m.def(
"print_myobject2_4",
330 [](
const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); });
332 py::class_<MyObject3, std::shared_ptr<MyObject3>>(m,
"MyObject3").def(py::init<int>());
333 m.def(
"make_myobject3_1", []() {
return new MyObject3(8); });
334 m.def(
"make_myobject3_2", []() {
return std::make_shared<MyObject3>(9); });
335 m.def(
"print_myobject3_1", [](
const MyObject3 *obj) { py::print(obj->toString()); });
337 m.def(
"print_myobject3_2", [](std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); });
338 m.def(
"print_myobject3_3",
339 [](
const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); });
340 m.def(
"print_myobject3_4",
341 [](
const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });
344 m.def(
"test_object1_refcounting", []() {
346 bool good = o->getRefCount() == 1;
347 py::object o2 = py::cast(o, py::return_value_policy::reference);
350 good &= o->getRefCount() == 2;
355 py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(m,
"MyObject4")
356 .def(py::init<int>())
357 .def_readwrite(
"value", &MyObject4::value)
358 .def_static(
"cleanup_all_instances", &MyObject4::cleanupAllInstances);
361 py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(m,
"MyObject4a")
362 .def(py::init<int>())
363 .def_readwrite(
"value", &MyObject4a::value)
364 .def_static(
"cleanup_all_instances", &MyObject4a::cleanupAllInstances);
366 py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(m,
"MyObject4b")
367 .def(py::init<int>());
370 py::class_<MyObject5, huge_unique_ptr<MyObject5>>(m,
"MyObject5")
371 .def(py::init<int>())
372 .def_readwrite(
"value", &MyObject5::value);
375 using A = SharedPtrRef::A;
376 py::class_<A, std::shared_ptr<A>>(m,
"A");
377 py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(m,
"SharedPtrRef")
379 .def_readonly(
"ref", &SharedPtrRef::value)
380 .def_property_readonly(
381 "copy", [](
const SharedPtrRef &s) {
return s.value; }, py::return_value_policy::copy)
382 .def_readonly(
"holder_ref", &SharedPtrRef::shared)
383 .def_property_readonly(
385 [](
const SharedPtrRef &s) {
return s.shared; },
386 py::return_value_policy::copy)
387 .def(
"set_ref", [](SharedPtrRef &,
const A &) {
return true; })
389 .def(
"set_holder", [](SharedPtrRef &, std::shared_ptr<A>) {
return true; });
392 using B = SharedFromThisRef::B;
393 py::class_<B, std::shared_ptr<B>>(m,
"B");
394 py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(m,
"SharedFromThisRef")
396 .def_readonly(
"bad_wp", &SharedFromThisRef::value)
397 .def_property_readonly(
"ref",
398 [](
const SharedFromThisRef &s) ->
const B & {
return *s.shared; })
399 .def_property_readonly(
401 [](
const SharedFromThisRef &s) {
return s.value; },
402 py::return_value_policy::copy)
403 .def_readonly(
"holder_ref", &SharedFromThisRef::shared)
404 .def_property_readonly(
406 [](
const SharedFromThisRef &s) {
return s.shared; },
407 py::return_value_policy::copy)
408 .def(
"set_ref", [](SharedFromThisRef &,
const B &) {
return true; })
410 .def(
"set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) {
return true; });
413 static std::shared_ptr<SharedFromThisVirt> sft(
new SharedFromThisVirt());
414 py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(m,
"SharedFromThisVirt")
415 .def_static(
"get", []() {
return sft.get(); });
418 py::class_<C, custom_unique_ptr<C>>(m,
"TypeWithMoveOnlyHolder")
419 .def_static(
"make", []() {
return custom_unique_ptr<C>(
new C); })
420 .def_static(
"make_as_object", []() {
return py::cast(custom_unique_ptr<C>(
new C)); });
423 using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;
424 py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(m,
"TypeForHolderWithAddressOf")
425 .def_static(
"make", []() {
return HolderWithAddressOf(
new TypeForHolderWithAddressOf); })
426 .def(
"get", [](
const HolderWithAddressOf &
self) {
return self.get(); })
427 .def(
"print_object_1",
428 [](
const TypeForHolderWithAddressOf *obj) { py::print(obj->toString()); })
430 .def(
"print_object_2", [](HolderWithAddressOf obj) { py::print(obj.get()->toString()); })
431 .def(
"print_object_3",
432 [](
const HolderWithAddressOf &obj) { py::print(obj.get()->toString()); })
433 .def(
"print_object_4",
434 [](
const HolderWithAddressOf *obj) { py::print((*obj).get()->toString()); });
437 using MoveOnlyHolderWithAddressOf
438 = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;
439 py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(
440 m,
"TypeForMoveOnlyHolderWithAddressOf")
443 return MoveOnlyHolderWithAddressOf(
444 new TypeForMoveOnlyHolderWithAddressOf(0));
446 .def_readwrite(
"value", &TypeForMoveOnlyHolderWithAddressOf::value)
448 [](
const TypeForMoveOnlyHolderWithAddressOf *obj) { py::print(obj->toString()); });
451 py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(m,
"HeldByDefaultHolder")
454 .def_static(
"load_shared_ptr", [](std::shared_ptr<HeldByDefaultHolder>) {});
458 py::class_<ElementBase, std::shared_ptr<ElementBase>>(m,
"ElementBase");
460 py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m,
"ElementA")
461 .def(py::init<int>())
462 .def(
"value", &ElementA::value);
464 py::class_<ElementList, std::shared_ptr<ElementList>>(m,
"ElementList")
466 .def(
"add", &ElementList::add)
467 .def(
"get", [](ElementList &el) {
469 for (
auto &e : el.l) {
Reference counted object base class.
int getRefCount() const
Return the current reference count.
virtual std::string toString() const =0
Reference counting helper.
T * get_ptr()
Return a const pointer to the referenced object.
std::string toString(const URI &aURI)
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type,...)
Create a specialization for custom holder types (silently ignores std::shared_ptr)
void print_copy_created(T *inst, Values &&...values)
void print_created(T *inst, Values &&...values)
void print_destroyed(T *inst, Values &&...values)
void print_move_created(T *inst, Values &&...values)
#define TEST_SUBMODULE(name, variable)
Helper class which abstracts away certain actions.
static const T * get(const ref< T > &p)