|
15 | 15 |
|
16 | 16 | PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
17 | 17 | PYBIND11_NAMESPACE_BEGIN(detail) |
| 18 | +PYBIND11_NAMESPACE_BEGIN(type_caster_std_function_specializations) |
| 19 | + |
| 20 | +// ensure GIL is held during functor destruction |
| 21 | +struct func_handle { |
| 22 | + function f; |
| 23 | +#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17)) |
| 24 | + // This triggers a syntax error under very special conditions (very weird indeed). |
| 25 | + explicit |
| 26 | +#endif |
| 27 | + func_handle(function &&f_) noexcept |
| 28 | + : f(std::move(f_)) { |
| 29 | + } |
| 30 | + func_handle(const func_handle &f_) { operator=(f_); } |
| 31 | + func_handle &operator=(const func_handle &f_) { |
| 32 | + gil_scoped_acquire acq; |
| 33 | + f = f_.f; |
| 34 | + return *this; |
| 35 | + } |
| 36 | + ~func_handle() { |
| 37 | + gil_scoped_acquire acq; |
| 38 | + function kill_f(std::move(f)); |
| 39 | + } |
| 40 | +}; |
| 41 | + |
| 42 | +// to emulate 'move initialization capture' in C++11 |
| 43 | +struct func_wrapper_base { |
| 44 | + func_handle hfunc; |
| 45 | + return_value_policy_pack rvpp; |
| 46 | + explicit func_wrapper_base(func_handle &&hf, const return_value_policy_pack &rvpp) noexcept |
| 47 | + : hfunc(hf), rvpp(rvpp) {} |
| 48 | +}; |
| 49 | + |
| 50 | +template <typename Return, typename... Args> |
| 51 | +struct func_wrapper : func_wrapper_base { |
| 52 | + using func_wrapper_base::func_wrapper_base; |
| 53 | + Return operator()(Args... args) const { |
| 54 | + gil_scoped_acquire acq; |
| 55 | + // casts the returned object as a rvalue to the return type |
| 56 | + return hfunc.f.call_with_policies(rvpp, std::forward<Args>(args)...) |
| 57 | + .template cast<Return>(); |
| 58 | + } |
| 59 | +}; |
| 60 | + |
| 61 | +PYBIND11_NAMESPACE_END(type_caster_std_function_specializations) |
18 | 62 |
|
19 | 63 | template <typename Return, typename... Args> |
20 | 64 | struct type_caster<std::function<Return(Args...)>> { |
@@ -77,43 +121,8 @@ struct type_caster<std::function<Return(Args...)>> { |
77 | 121 | // See PR #1413 for full details |
78 | 122 | } |
79 | 123 |
|
80 | | - // ensure GIL is held during functor destruction |
81 | | - struct func_handle { |
82 | | - function f; |
83 | | -#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17)) |
84 | | - // This triggers a syntax error under very special conditions (very weird indeed). |
85 | | - explicit |
86 | | -#endif |
87 | | - func_handle(function &&f_) noexcept |
88 | | - : f(std::move(f_)) { |
89 | | - } |
90 | | - func_handle(const func_handle &f_) { operator=(f_); } |
91 | | - func_handle &operator=(const func_handle &f_) { |
92 | | - gil_scoped_acquire acq; |
93 | | - f = f_.f; |
94 | | - return *this; |
95 | | - } |
96 | | - ~func_handle() { |
97 | | - gil_scoped_acquire acq; |
98 | | - function kill_f(std::move(f)); |
99 | | - } |
100 | | - }; |
101 | | - |
102 | | - // to emulate 'move initialization capture' in C++11 |
103 | | - struct func_wrapper { |
104 | | - func_handle hfunc; |
105 | | - return_value_policy_pack rvpp; |
106 | | - func_wrapper(func_handle &&hf, const return_value_policy_pack &rvpp) noexcept |
107 | | - : hfunc(std::move(hf)), rvpp(rvpp) {} |
108 | | - Return operator()(Args... args) const { |
109 | | - gil_scoped_acquire acq; |
110 | | - // casts the returned object as a rvalue to the return type |
111 | | - return hfunc.f.call_with_policies(rvpp, std::forward<Args>(args)...) |
112 | | - .template cast<Return>(); |
113 | | - } |
114 | | - }; |
115 | | - |
116 | | - value = func_wrapper(func_handle(std::move(func)), fpp.rvpp); |
| 124 | + value = type_caster_std_function_specializations::func_wrapper<Return, Args...>( |
| 125 | + type_caster_std_function_specializations::func_handle(std::move(func)), fpp.rvpp); |
117 | 126 | return true; |
118 | 127 | } |
119 | 128 |
|
|
0 commit comments