functional.h
Go to the documentation of this file.
1 /*
2  pybind11/functional.h: std::function<> support
3 
4  Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
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 #pragma once
11 
12 #define PYBIND11_HAS_TYPE_CASTER_STD_FUNCTION_SPECIALIZATIONS
13 
14 #include "pybind11.h"
15 
16 #include <functional>
17 
20 PYBIND11_NAMESPACE_BEGIN(type_caster_std_function_specializations)
21 
22 // ensure GIL is held during functor destruction
23 struct func_handle {
24  function f;
25 #if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17))
26  // This triggers a syntax error under very special conditions (very weird indeed).
27  explicit
28 #endif
29  func_handle(function &&f_) noexcept
30  : f(std::move(f_)) {
31  }
32  func_handle(const func_handle &f_) { operator=(f_); }
35  f = f_.f;
36  return *this;
37  }
40  function kill_f(std::move(f));
41  }
42 };
43 
44 // to emulate 'move initialization capture' in C++11
47  explicit func_wrapper_base(func_handle &&hf) noexcept : hfunc(hf) {}
48 };
49 
50 template <typename Return, typename... Args>
53  Return operator()(Args... args) const {
55  // casts the returned object as a rvalue to the return type
56  return hfunc.f(std::forward<Args>(args)...).template cast<Return>();
57  }
58 };
59 
60 PYBIND11_NAMESPACE_END(type_caster_std_function_specializations)
61 
62 template <typename Return, typename... Args>
63 struct type_caster<std::function<Return(Args...)>> {
64  using type = std::function<Return(Args...)>;
66  using function_type = Return (*)(Args...);
67 
68 public:
69  bool load(handle src, bool convert) {
70  if (src.is_none()) {
71  // Defer accepting None to other overloads (if we aren't in convert mode):
72  if (!convert) {
73  return false;
74  }
75  return true;
76  }
77 
78  if (!isinstance<function>(src)) {
79  return false;
80  }
81 
82  auto func = reinterpret_borrow<function>(src);
83 
84  /*
85  When passing a C++ function as an argument to another C++
86  function via Python, every function call would normally involve
87  a full C++ -> Python -> C++ roundtrip, which can be prohibitive.
88  Here, we try to at least detect the case where the function is
89  stateless (i.e. function pointer or lambda function without
90  captured variables), in which case the roundtrip can be avoided.
91  */
92  if (auto cfunc = func.cpp_function()) {
93  auto *cfunc_self = PyCFunction_GET_SELF(cfunc.ptr());
94  if (cfunc_self == nullptr) {
95  PyErr_Clear();
96  } else if (isinstance<capsule>(cfunc_self)) {
97  auto c = reinterpret_borrow<capsule>(cfunc_self);
98 
99  function_record *rec = nullptr;
100  // Check that we can safely reinterpret the capsule into a function_record
102  rec = c.get_pointer<function_record>();
103  }
104 
105  while (rec != nullptr) {
106  if (rec->is_stateless
107  && same_type(typeid(function_type),
108  *reinterpret_cast<const std::type_info *>(rec->data[1]))) {
109  struct capture {
111  };
112  value = ((capture *) &rec->data)->f;
113  return true;
114  }
115  rec = rec->next;
116  }
117  }
118  // PYPY segfaults here when passing builtin function like sum.
119  // Raising an fail exception here works to prevent the segfault, but only on gcc.
120  // See PR #1413 for full details
121  }
122 
123  value = type_caster_std_function_specializations::func_wrapper<Return, Args...>(
124  type_caster_std_function_specializations::func_handle(std::move(func)));
125  return true;
126  }
127 
128  template <typename Func>
129  static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {
130  if (!f_) {
131  return none().release();
132  }
133 
134  auto result = f_.template target<function_type>();
135  if (result) {
136  return cpp_function(*result, policy).release();
137  }
138  return cpp_function(std::forward<Func>(f_), policy).release();
139  }
140 
142  const_name("Callable[[")
145  + const_name("]"));
146 };
147 
function_record
Definition: attr.h:191
func_wrapper
Definition: functional.h:51
const_name
constexpr descr< N - 1 > const_name(char const (&text)[N])
Definition: descr.h:60
return_value_policy
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
Definition: wrap/pybind11/include/pybind11/detail/common.h:518
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
type_caster_generic::value
void * value
Definition: type_caster_base.h:783
func_wrapper::operator()
Return operator()(Args... args) const
Definition: functional.h:53
PYBIND11_NAMESPACE_END
#define PYBIND11_NAMESPACE_END(name)
Definition: wrap/pybind11/include/pybind11/detail/common.h:80
type
Definition: pytypes.h:1527
detail
Definition: testSerializationNonlinear.cpp:69
PYBIND11_NAMESPACE_BEGIN
#define PYBIND11_NAMESPACE_BEGIN(name)
Definition: wrap/pybind11/include/pybind11/detail/common.h:76
type_caster< std::function< Return(Args...)> >::function_type
Return(*)(Args...) function_type
Definition: functional.h:66
result
Values result
Definition: OdometryOptimize.cpp:8
function_record::data
void * data[3]
Storage for the wrapped function pointer and captured data, if any.
Definition: attr.h:213
conditional_t
typename std::conditional< B, T, F >::type conditional_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:675
same_type
bool same_type(const std::type_info &lhs, const std::type_info &rhs)
Definition: internals.h:116
handle
Definition: pytypes.h:226
type_caster
Definition: cast.h:38
type_caster< std::function< Return(Args...)> >::retval_type
conditional_t< std::is_same< Return, void >::value, void_type, Return > retval_type
Definition: functional.h:65
func_handle::operator=
func_handle & operator=(const func_handle &f_)
Definition: functional.h:33
func_handle::func_handle
func_handle(function &&f_) noexcept
Definition: functional.h:29
object::release
handle release()
Definition: pytypes.h:385
func_wrapper_base
Definition: functional.h:45
func_handle::f
function f
Definition: functional.h:24
conftest.capture
def capture(capsys)
Definition: conftest.py:140
func_wrapper_base::hfunc
func_handle hfunc
Definition: functional.h:46
function_record::next
function_record * next
Pointer to next overload.
Definition: attr.h:268
func_wrapper_base::func_wrapper_base
func_wrapper_base(func_handle &&hf) noexcept
Definition: functional.h:47
type_caster< std::function< Return(Args...)> >::cast
static handle cast(Func &&f_, return_value_policy policy, handle)
Definition: functional.h:129
func_handle::func_handle
func_handle(const func_handle &f_)
Definition: functional.h:32
PYBIND11_NAMESPACE
Definition: test_custom_type_casters.cpp:24
concat
constexpr descr< 0 > concat()
Definition: descr.h:139
cpp_function
Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object.
Definition: pybind11.h:107
gil_scoped_acquire
Definition: gil.h:53
is_function_record_capsule
bool is_function_record_capsule(const capsule &cap)
Definition: internals.h:725
function_record::is_stateless
bool is_stateless
True if this is a stateless function pointer.
Definition: attr.h:228
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
PYBIND11_TYPE_CASTER
#define PYBIND11_TYPE_CASTER(type, py_name)
Definition: cast.h:87
pybind11.h
func_handle::~func_handle
~func_handle()
Definition: functional.h:38
std
Definition: BFloat16.h:88
void_type
Helper type to replace 'void' in some expressions.
Definition: wrap/pybind11/include/pybind11/detail/common.h:834
args
Definition: pytypes.h:2212
function
Definition: pytypes.h:2254
type_caster< std::function< Return(Args...)> >::load
bool load(handle src, bool convert)
Definition: functional.h:69
none
Definition: pytypes.h:1788
func
Definition: benchGeometry.cpp:23
gtsam::convert
static BinaryMeasurement< Rot3 > convert(const BetweenFactor< Pose3 >::shared_ptr &f)
Definition: ShonanAveraging.cpp:995
func_handle
Definition: functional.h:23


gtsam
Author(s):
autogenerated on Wed Mar 19 2025 03:01:41