pybind11/example/example12.cpp

102 lines
3.1 KiB
C++
Raw Normal View History

/*
example/example12.cpp -- overriding virtual functions from Python
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#include "example.h"
#include <pybind11/functional.h>
/* This is an example class that we'll want to be able to extend from Python */
class Example12 {
public:
Example12(int state) : state(state) {
cout << "Constructing Example12.." << endl;
}
~Example12() {
cout << "Destructing Example12.." << endl;
}
virtual int run(int value) {
std::cout << "Original implementation of Example12::run(state=" << state
<< ", value=" << value << ")" << std::endl;
return state + value;
}
virtual bool run_bool() = 0;
virtual void pure_virtual() = 0;
private:
int state;
};
/* This is a wrapper class that must be generated */
class PyExample12 : public Example12 {
public:
using Example12::Example12; /* Inherit constructors */
virtual int run(int value) {
/* Generate wrapping code that enables native function overloading */
PYBIND11_OVERLOAD(
int, /* Return type */
Example12, /* Parent class */
run, /* Name of function */
value /* Argument(s) */
);
}
virtual bool run_bool() {
PYBIND11_OVERLOAD_PURE(
bool, /* Return type */
Example12, /* Parent class */
run_bool, /* Name of function */
/* This function has no arguments. The trailing comma
in the previous line is needed for some compilers */
);
throw std::runtime_error("this will never be reached");
}
virtual void pure_virtual() {
PYBIND11_OVERLOAD_PURE(
void, /* Return type */
Example12, /* Parent class */
pure_virtual, /* Name of function */
/* This function has no arguments. The trailing comma
in the previous line is needed for some compilers */
);
}
};
int runExample12(Example12 *ex, int value) {
return ex->run(value);
}
bool runExample12Bool(Example12* ex) {
return ex->run_bool();
}
void runExample12Virtual(Example12 *ex) {
ex->pure_virtual();
}
void init_ex12(py::module &m) {
/* Important: use the wrapper type as a template
argument to class_<>, but use the original name
to denote the type */
py::class_<PyExample12>(m, "Example12")
/* Declare that 'PyExample12' is really an alias for the original type 'Example12' */
.alias<Example12>()
.def(py::init<int>())
/* Reference original class in function definitions */
.def("run", &Example12::run)
.def("run_bool", &Example12::run_bool)
.def("pure_virtual", &Example12::pure_virtual);
m.def("runExample12", &runExample12);
m.def("runExample12Bool", &runExample12Bool);
m.def("runExample12Virtual", &runExample12Virtual);
}