blob: a5a3b83387287d523d029017d5227c783a02b109 [file] [log] [blame]
Wenzel Jakob38bd7112015-07-05 20:05:44 +02001/*
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -04002 example/example-callbacks.cpp -- callbacks
Wenzel Jakob38bd7112015-07-05 20:05:44 +02003
Wenzel Jakob8cb6cb32016-04-17 20:21:41 +02004 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
Wenzel Jakob38bd7112015-07-05 20:05:44 +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"
Jason Rhinelander3f589372016-08-07 13:05:26 -040011#include "constructor-stats.h"
Wenzel Jakob8f4eb002015-10-15 18:13:33 +020012#include <pybind11/functional.h>
Wenzel Jakob38bd7112015-07-05 20:05:44 +020013
14
Wenzel Jakob38bd7112015-07-05 20:05:44 +020015bool test_callback1(py::object func) {
Wenzel Jakob6c03beb2016-05-08 14:34:09 +020016 func();
Wenzel Jakob38bd7112015-07-05 20:05:44 +020017 return false;
18}
19
20int test_callback2(py::object func) {
Wenzel Jakob6c03beb2016-05-08 14:34:09 +020021 py::object result = func("Hello", 'x', true, 5);
Wenzel Jakob38bd7112015-07-05 20:05:44 +020022 return result.cast<int>();
23}
24
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020025void test_callback3(const std::function<int(int)> &func) {
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020026 cout << "func(43) = " << func(43)<< std::endl;
27}
28
Wenzel Jakoba2f6fde2015-10-01 16:46:03 +020029std::function<int(int)> test_callback4() {
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020030 return [](int i) { return i+1; };
31}
32
Brad Harmon835fc062016-06-16 13:19:15 -050033py::cpp_function test_callback5() {
34 return py::cpp_function([](int i) { return i+1; },
35 py::arg("number"));
36}
37
Wenzel Jakob954b7932016-07-10 10:13:18 +020038int dummy_function(int i) { return i + 1; }
39int dummy_function2(int i, int j) { return i + j; }
40std::function<int(int)> roundtrip(std::function<int(int)> f) {
Wenzel Jakob8de04372016-08-18 11:18:12 +020041 if (!f)
42 std::cout << "roundtrip (got None).." << std::endl;
43 else
44 std::cout << "roundtrip.." << std::endl;
Wenzel Jakob954b7932016-07-10 10:13:18 +020045 return f;
46}
47
48void test_dummy_function(const std::function<int(int)> &f) {
49 using fn_type = int (*)(int);
50 auto result = f.target<fn_type>();
51 if (!result) {
52 std::cout << "could not convert to a function pointer." << std::endl;
53 auto r = f(1);
54 std::cout << "eval(1) = " << r << std::endl;
55 } else if (*result == dummy_function) {
56 std::cout << "argument matches dummy_function" << std::endl;
57 auto r = (*result)(1);
58 std::cout << "eval(1) = " << r << std::endl;
59 } else {
60 std::cout << "argument does NOT match dummy_function. This should never happen!" << std::endl;
61 }
62}
63
Jason Rhinelander3f589372016-08-07 13:05:26 -040064struct Payload {
65 Payload() {
66 print_default_created(this);
67 }
68 ~Payload() {
69 print_destroyed(this);
70 }
71 Payload(const Payload &) {
72 print_copy_created(this);
73 }
74 Payload(Payload &&) {
75 print_move_created(this);
76 }
77};
78
Jason Rhinelanderb3f3d792016-07-18 16:43:18 -040079void init_ex_callbacks(py::module &m) {
Wenzel Jakob38bd7112015-07-05 20:05:44 +020080 m.def("test_callback1", &test_callback1);
81 m.def("test_callback2", &test_callback2);
82 m.def("test_callback3", &test_callback3);
Wenzel Jakob281aa0e2015-07-30 15:29:00 +020083 m.def("test_callback4", &test_callback4);
Brad Harmon835fc062016-06-16 13:19:15 -050084 m.def("test_callback5", &test_callback5);
Wenzel Jakob19208fe2015-10-13 17:37:25 +020085
86 /* Test cleanup of lambda closure */
87
Wenzel Jakob19208fe2015-10-13 17:37:25 +020088 m.def("test_cleanup", []() -> std::function<void(void)> {
89 Payload p;
90
91 return [p]() {
92 /* p should be cleaned up when the returned function is garbage collected */
93 };
94 });
Wenzel Jakob954b7932016-07-10 10:13:18 +020095
96 /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */
97 m.def("dummy_function", &dummy_function);
98 m.def("dummy_function2", &dummy_function2);
99 m.def("roundtrip", &roundtrip);
100 m.def("test_dummy_function", &test_dummy_function);
Jason Rhinelander3f589372016-08-07 13:05:26 -0400101 // Export the payload constructor statistics for testing purposes:
102 m.def("payload_cstats", &ConstructorStats::get<Payload>);
Wenzel Jakob38bd7112015-07-05 20:05:44 +0200103}