blob: 5cc8dc87c0252d2711b611b41e95e02e491c9140 [file] [log] [blame]
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +02001/*
2 example/example12.cpp -- overriding virtual functions from Python
3
Wenzel Jakob8cb6cb32016-04-17 20:21:41 +02004 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +02005
6 All rights reserved. Use of this source code is governed by a
7 BSD-style license that can be found in the LICENSE file.
8*/
9
10#include "example.h"
Wenzel Jakob8f4eb002015-10-15 18:13:33 +020011#include <pybind11/functional.h>
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020012
13/* This is an example class that we'll want to be able to extend from Python */
14class Example12 {
15public:
16 Example12(int state) : state(state) {
17 cout << "Constructing Example12.." << endl;
18 }
19
20 ~Example12() {
21 cout << "Destructing Example12.." << endl;
22 }
23
24 virtual int run(int value) {
25 std::cout << "Original implementation of Example12::run(state=" << state
26 << ", value=" << value << ")" << std::endl;
27 return state + value;
28 }
29
jmabille9cfa71f2016-02-23 22:41:07 +010030 virtual bool run_bool() = 0;
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020031 virtual void pure_virtual() = 0;
32private:
33 int state;
34};
35
36/* This is a wrapper class that must be generated */
37class PyExample12 : public Example12 {
38public:
39 using Example12::Example12; /* Inherit constructors */
40
41 virtual int run(int value) {
42 /* Generate wrapping code that enables native function overloading */
Wenzel Jakobb1b71402015-10-18 16:48:30 +020043 PYBIND11_OVERLOAD(
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020044 int, /* Return type */
45 Example12, /* Parent class */
46 run, /* Name of function */
47 value /* Argument(s) */
48 );
49 }
50
jmabille9cfa71f2016-02-23 22:41:07 +010051 virtual bool run_bool() {
52 PYBIND11_OVERLOAD_PURE(
Wenzel Jakob1dc940d2016-04-18 10:34:27 +020053 bool, /* Return type */
54 Example12, /* Parent class */
55 run_bool, /* Name of function */
56 /* This function has no arguments. The trailing comma
57 in the previous line is needed for some compilers */
jmabille9cfa71f2016-02-23 22:41:07 +010058 );
59 }
60
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020061 virtual void pure_virtual() {
Wenzel Jakobb1b71402015-10-18 16:48:30 +020062 PYBIND11_OVERLOAD_PURE(
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020063 void, /* Return type */
64 Example12, /* Parent class */
Wenzel Jakob1dc940d2016-04-18 10:34:27 +020065 pure_virtual, /* Name of function */
66 /* This function has no arguments. The trailing comma
67 in the previous line is needed for some compilers */
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020068 );
69 }
70};
71
72int runExample12(Example12 *ex, int value) {
73 return ex->run(value);
74}
75
jmabille9cfa71f2016-02-23 22:41:07 +010076bool runExample12Bool(Example12* ex) {
77 return ex->run_bool();
78}
79
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020080void runExample12Virtual(Example12 *ex) {
81 ex->pure_virtual();
82}
83
84void init_ex12(py::module &m) {
85 /* Important: use the wrapper type as a template
86 argument to class_<>, but use the original name
87 to denote the type */
88 py::class_<PyExample12>(m, "Example12")
89 /* Declare that 'PyExample12' is really an alias for the original type 'Example12' */
90 .alias<Example12>()
91 .def(py::init<int>())
Wenzel Jakob43b09af2016-05-21 01:11:11 +020092 /* Copy constructor (not needed in this case, but should generally be declared in this way) */
93 .def(py::init<const PyExample12 &>())
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020094 /* Reference original class in function definitions */
95 .def("run", &Example12::run)
jmabille9cfa71f2016-02-23 22:41:07 +010096 .def("run_bool", &Example12::run_bool)
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020097 .def("pure_virtual", &Example12::pure_virtual);
98
99 m.def("runExample12", &runExample12);
jmabille9cfa71f2016-02-23 22:41:07 +0100100 m.def("runExample12Bool", &runExample12Bool);
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +0200101 m.def("runExample12Virtual", &runExample12Virtual);
102}