blob: 4ba6a34f44a0bae056577e5d0fe8d7ef95a8094c [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) {
46 func.call();
47 return false;
48}
49
50int test_callback2(py::object func) {
Wenzel Jakob7b8e0322015-08-28 17:49:15 +020051 py::object result = func.call("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
Wenzel Jakob38bd7112015-07-05 20:05:44 +020063void init_ex5(py::module &m) {
64 py::class_<Pet> pet_class(m, "Pet");
65 pet_class
66 .def(py::init<std::string, std::string>())
67 .def("name", &Pet::name)
68 .def("species", &Pet::species);
69
Wenzel Jakob48548ea2016-01-17 22:36:44 +010070 /* One way of declaring a subclass relationship: reference parent's class_ object */
Wenzel Jakob38bd7112015-07-05 20:05:44 +020071 py::class_<Dog>(m, "Dog", pet_class)
72 .def(py::init<std::string>());
73
Wenzel Jakob48548ea2016-01-17 22:36:44 +010074 /* Another way of declaring a subclass relationship: reference parent's C++ type */
75 py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
76 .def(py::init<std::string>());
77
Wenzel Jakob38bd7112015-07-05 20:05:44 +020078 m.def("pet_print", pet_print);
79 m.def("dog_bark", dog_bark);
80
81 m.def("test_callback1", &test_callback1);
82 m.def("test_callback2", &test_callback2);
83 m.def("test_callback3", &test_callback3);
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020084 m.def("test_callback4", &test_callback4);
Wenzel Jakob19208fe2015-10-13 17:37:25 +020085
86 /* Test cleanup of lambda closure */
87
88 struct Payload {
89 Payload() {
90 std::cout << "Payload constructor" << std::endl;
91 }
92 ~Payload() {
93 std::cout << "Payload destructor" << std::endl;
94 }
95 Payload(const Payload &) {
96 std::cout << "Payload copy constructor" << std::endl;
97 }
98 Payload(Payload &&) {
99 std::cout << "Payload move constructor" << std::endl;
100 }
101 };
102
103 m.def("test_cleanup", []() -> std::function<void(void)> {
104 Payload p;
105
106 return [p]() {
107 /* p should be cleaned up when the returned function is garbage collected */
108 };
109 });
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200110}