blob: 0e1d2cd132720c3d4c04111fc8a7099c14220f79 [file] [log] [blame]
Wenzel Jakob38bd7112015-07-05 20:05:44 +02001/*
Wenzel Jakoba576e6a2015-07-29 17:51:54 +02002 example/example5.cpp -- inheritance, callbacks, acquiring and releasing the
3 global interpreter lock
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"
Wenzel Jakob8f4eb002015-10-15 18:13:33 +020012#include <pybind11/functional.h>
Wenzel Jakob38bd7112015-07-05 20:05:44 +020013
14
15class Pet {
16public:
17 Pet(const std::string &name, const std::string &species)
18 : m_name(name), m_species(species) {}
19 std::string name() const { return m_name; }
20 std::string species() const { return m_species; }
21private:
22 std::string m_name;
23 std::string m_species;
24};
25
26class Dog : public Pet {
27public:
28 Dog(const std::string &name) : Pet(name, "dog") {}
29 void bark() const { std::cout << "Woof!" << std::endl; }
30};
31
Wenzel Jakob48548ea2016-01-17 22:36:44 +010032class Rabbit : public Pet {
33public:
34 Rabbit(const std::string &name) : Pet(name, "parrot") {}
35};
36
Wenzel Jakob38bd7112015-07-05 20:05:44 +020037void pet_print(const Pet &pet) {
38 std::cout << pet.name() + " is a " + pet.species() << std::endl;
39}
40
41void dog_bark(const Dog &dog) {
42 dog.bark();
43}
44
Wenzel Jakob38bd7112015-07-05 20:05:44 +020045bool test_callback1(py::object func) {
Wenzel Jakob6c03beb2016-05-08 14:34:09 +020046 func();
Wenzel Jakob38bd7112015-07-05 20:05:44 +020047 return false;
48}
49
50int test_callback2(py::object func) {
Wenzel Jakob6c03beb2016-05-08 14:34:09 +020051 py::object result = func("Hello", 'x', true, 5);
Wenzel Jakob38bd7112015-07-05 20:05:44 +020052 return result.cast<int>();
53}
54
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020055void test_callback3(const std::function<int(int)> &func) {
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020056 cout << "func(43) = " << func(43)<< std::endl;
57}
58
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020059std::function<int(int)> test_callback4() {
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020060 return [](int i) { return i+1; };
61}
62
Brad Harmon835fc062016-06-16 13:19:15 -050063py::cpp_function test_callback5() {
64 return py::cpp_function([](int i) { return i+1; },
65 py::arg("number"));
66}
67
Wenzel Jakob38bd7112015-07-05 20:05:44 +020068void init_ex5(py::module &m) {
69 py::class_<Pet> pet_class(m, "Pet");
70 pet_class
71 .def(py::init<std::string, std::string>())
72 .def("name", &Pet::name)
73 .def("species", &Pet::species);
74
Wenzel Jakob48548ea2016-01-17 22:36:44 +010075 /* One way of declaring a subclass relationship: reference parent's class_ object */
Wenzel Jakob38bd7112015-07-05 20:05:44 +020076 py::class_<Dog>(m, "Dog", pet_class)
77 .def(py::init<std::string>());
78
Wenzel Jakob48548ea2016-01-17 22:36:44 +010079 /* Another way of declaring a subclass relationship: reference parent's C++ type */
80 py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
81 .def(py::init<std::string>());
82
Wenzel Jakob38bd7112015-07-05 20:05:44 +020083 m.def("pet_print", pet_print);
84 m.def("dog_bark", dog_bark);
85
86 m.def("test_callback1", &test_callback1);
87 m.def("test_callback2", &test_callback2);
88 m.def("test_callback3", &test_callback3);
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020089 m.def("test_callback4", &test_callback4);
Brad Harmon835fc062016-06-16 13:19:15 -050090 m.def("test_callback5", &test_callback5);
Wenzel Jakob19208fe2015-10-13 17:37:25 +020091
92 /* Test cleanup of lambda closure */
93
94 struct Payload {
95 Payload() {
96 std::cout << "Payload constructor" << std::endl;
97 }
98 ~Payload() {
99 std::cout << "Payload destructor" << std::endl;
100 }
101 Payload(const Payload &) {
102 std::cout << "Payload copy constructor" << std::endl;
103 }
104 Payload(Payload &&) {
105 std::cout << "Payload move constructor" << std::endl;
106 }
107 };
108
109 m.def("test_cleanup", []() -> std::function<void(void)> {
110 Payload p;
111
112 return [p]() {
113 /* p should be cleaned up when the returned function is garbage collected */
114 };
115 });
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200116}