blob: dbdd4218de3b2f6d8fe33a951a94cba5a2012f6e [file] [log] [blame]
Wenzel Jakob38bd7112015-07-05 20:05:44 +02001/*
Wenzel Jakoba576e6a2015-07-29 17:51:54 +02002 example/example8.cpp -- binding classes with custom reference counting,
3 implicit conversions between types
Wenzel Jakob38bd7112015-07-05 20:05:44 +02004
Wenzel Jakob8cb6cb32016-04-17 20:21:41 +02005 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
Wenzel Jakob38bd7112015-07-05 20:05:44 +02006
7 All rights reserved. Use of this source code is governed by a
8 BSD-style license that can be found in the LICENSE file.
9*/
10
11#include "example.h"
12#include "object.h"
13
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010014/// Custom object with builtin reference counting (see 'object.h' for the implementation)
15class MyObject1 : public Object {
Wenzel Jakob38bd7112015-07-05 20:05:44 +020016public:
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010017 MyObject1(int value) : value(value) {
Wenzel Jakob38bd7112015-07-05 20:05:44 +020018 std::cout << toString() << " constructor" << std::endl;
19 }
20
21 std::string toString() const {
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010022 return "MyObject1[" + std::to_string(value) + "]";
Wenzel Jakob38bd7112015-07-05 20:05:44 +020023 }
24
25protected:
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010026 virtual ~MyObject1() {
Wenzel Jakob38bd7112015-07-05 20:05:44 +020027 std::cout << toString() << " destructor" << std::endl;
28 }
29
30private:
31 int value;
32};
33
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010034/// Object managed by a std::shared_ptr<>
35class MyObject2 {
Wenzel Jakob6e213c92015-11-24 23:05:58 +010036public:
37 MyObject2(int value) : value(value) {
38 std::cout << toString() << " constructor" << std::endl;
39 }
40
41 std::string toString() const {
42 return "MyObject2[" + std::to_string(value) + "]";
43 }
44
45 virtual ~MyObject2() {
46 std::cout << toString() << " destructor" << std::endl;
47 }
48
49private:
50 int value;
51};
52
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010053/// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>
54class MyObject3 : public std::enable_shared_from_this<MyObject3> {
55public:
56 MyObject3(int value) : value(value) {
57 std::cout << toString() << " constructor" << std::endl;
58 }
59
60 std::string toString() const {
61 return "MyObject3[" + std::to_string(value) + "]";
62 }
63
64 virtual ~MyObject3() {
65 std::cout << toString() << " destructor" << std::endl;
66 }
67
68private:
69 int value;
70};
71
72/// Make pybind aware of the ref-counted wrapper type (s)
Wenzel Jakobb1b71402015-10-18 16:48:30 +020073PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>);
Wenzel Jakob6e213c92015-11-24 23:05:58 +010074PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);
Wenzel Jakob38bd7112015-07-05 20:05:44 +020075
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010076Object *make_object_1() { return new MyObject1(1); }
77ref<Object> make_object_2() { return new MyObject1(2); }
Wenzel Jakob38bd7112015-07-05 20:05:44 +020078
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010079MyObject1 *make_myobject1_1() { return new MyObject1(4); }
80ref<MyObject1> make_myobject1_2() { return new MyObject1(5); }
81
82MyObject2 *make_myobject2_1() { return new MyObject2(6); }
83std::shared_ptr<MyObject2> make_myobject2_2() { return std::make_shared<MyObject2>(7); }
84
85MyObject3 *make_myobject3_1() { return new MyObject3(8); }
86std::shared_ptr<MyObject3> make_myobject3_2() { return std::make_shared<MyObject3>(9); }
Wenzel Jakob6e213c92015-11-24 23:05:58 +010087
Wenzel Jakob38bd7112015-07-05 20:05:44 +020088void print_object_1(const Object *obj) { std::cout << obj->toString() << std::endl; }
89void print_object_2(ref<Object> obj) { std::cout << obj->toString() << std::endl; }
90void print_object_3(const ref<Object> &obj) { std::cout << obj->toString() << std::endl; }
91void print_object_4(const ref<Object> *obj) { std::cout << (*obj)->toString() << std::endl; }
92
Wenzel Jakobb2c2c792016-01-17 22:36:40 +010093void print_myobject1_1(const MyObject1 *obj) { std::cout << obj->toString() << std::endl; }
94void print_myobject1_2(ref<MyObject1> obj) { std::cout << obj->toString() << std::endl; }
95void print_myobject1_3(const ref<MyObject1> &obj) { std::cout << obj->toString() << std::endl; }
96void print_myobject1_4(const ref<MyObject1> *obj) { std::cout << (*obj)->toString() << std::endl; }
Wenzel Jakob38bd7112015-07-05 20:05:44 +020097
Wenzel Jakob6e213c92015-11-24 23:05:58 +010098void print_myobject2_1(const MyObject2 *obj) { std::cout << obj->toString() << std::endl; }
99void print_myobject2_2(std::shared_ptr<MyObject2> obj) { std::cout << obj->toString() << std::endl; }
100void print_myobject2_3(const std::shared_ptr<MyObject2> &obj) { std::cout << obj->toString() << std::endl; }
101void print_myobject2_4(const std::shared_ptr<MyObject2> *obj) { std::cout << (*obj)->toString() << std::endl; }
102
Wenzel Jakobb2c2c792016-01-17 22:36:40 +0100103void print_myobject3_1(const MyObject3 *obj) { std::cout << obj->toString() << std::endl; }
104void print_myobject3_2(std::shared_ptr<MyObject3> obj) { std::cout << obj->toString() << std::endl; }
105void print_myobject3_3(const std::shared_ptr<MyObject3> &obj) { std::cout << obj->toString() << std::endl; }
106void print_myobject3_4(const std::shared_ptr<MyObject3> *obj) { std::cout << (*obj)->toString() << std::endl; }
107
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200108void init_ex8(py::module &m) {
109 py::class_<Object, ref<Object>> obj(m, "Object");
110 obj.def("getRefCount", &Object::getRefCount);
111
Wenzel Jakobb2c2c792016-01-17 22:36:40 +0100112 py::class_<MyObject1, ref<MyObject1>>(m, "MyObject1", obj)
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200113 .def(py::init<int>());
114
115 m.def("make_object_1", &make_object_1);
116 m.def("make_object_2", &make_object_2);
Wenzel Jakobb2c2c792016-01-17 22:36:40 +0100117 m.def("make_myobject1_1", &make_myobject1_1);
118 m.def("make_myobject1_2", &make_myobject1_2);
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200119 m.def("print_object_1", &print_object_1);
120 m.def("print_object_2", &print_object_2);
121 m.def("print_object_3", &print_object_3);
122 m.def("print_object_4", &print_object_4);
Wenzel Jakobb2c2c792016-01-17 22:36:40 +0100123 m.def("print_myobject1_1", &print_myobject1_1);
124 m.def("print_myobject1_2", &print_myobject1_2);
125 m.def("print_myobject1_3", &print_myobject1_3);
126 m.def("print_myobject1_4", &print_myobject1_4);
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200127
Wenzel Jakob6e213c92015-11-24 23:05:58 +0100128 py::class_<MyObject2, std::shared_ptr<MyObject2>>(m, "MyObject2")
129 .def(py::init<int>());
130 m.def("make_myobject2_1", &make_myobject2_1);
131 m.def("make_myobject2_2", &make_myobject2_2);
132 m.def("print_myobject2_1", &print_myobject2_1);
133 m.def("print_myobject2_2", &print_myobject2_2);
134 m.def("print_myobject2_3", &print_myobject2_3);
135 m.def("print_myobject2_4", &print_myobject2_4);
136
Wenzel Jakobb2c2c792016-01-17 22:36:40 +0100137 py::class_<MyObject3, std::shared_ptr<MyObject3>>(m, "MyObject3")
138 .def(py::init<int>());
139 m.def("make_myobject3_1", &make_myobject3_1);
140 m.def("make_myobject3_2", &make_myobject3_2);
141 m.def("print_myobject3_1", &print_myobject3_1);
142 m.def("print_myobject3_2", &print_myobject3_2);
143 m.def("print_myobject3_3", &print_myobject3_3);
144 m.def("print_myobject3_4", &print_myobject3_4);
145
146 py::implicitly_convertible<py::int_, MyObject1>();
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200147}