|
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 | + explicit func_wrapper_base(func_handle &&hf) noexcept : hfunc(std::move(hf)) {} |
| 46 | +}; |
| 47 | + |
| 48 | +template <typename Return, typename... Args> |
| 49 | +struct func_wrapper : func_wrapper_base { |
| 50 | + using func_wrapper_base::func_wrapper_base; |
| 51 | + Return operator()(Args... args) const { |
| 52 | + gil_scoped_acquire acq; |
| 53 | + // casts the returned object as a rvalue to the return type |
| 54 | + return hfunc.f(std::forward<Args>(args)...).template cast<Return>(); |
| 55 | + } |
| 56 | +}; |
| 57 | + |
| 58 | +PYBIND11_NAMESPACE_END(type_caster_std_function_specializations) |
18 | 59 |
|
19 | 60 | template <typename Return, typename... Args> |
20 | 61 | struct type_caster<std::function<Return(Args...)>> { |
@@ -77,40 +118,8 @@ struct type_caster<std::function<Return(Args...)>> { |
77 | 118 | // See PR #1413 for full details |
78 | 119 | } |
79 | 120 |
|
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 | | - explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {} |
106 | | - Return operator()(Args... args) const { |
107 | | - gil_scoped_acquire acq; |
108 | | - // casts the returned object as a rvalue to the return type |
109 | | - return hfunc.f(std::forward<Args>(args)...).template cast<Return>(); |
110 | | - } |
111 | | - }; |
112 | | - |
113 | | - value = func_wrapper(func_handle(std::move(func))); |
| 121 | + value = type_caster_std_function_specializations::func_wrapper<Return, Args...>( |
| 122 | + type_caster_std_function_specializations::func_handle(std::move(func))); |
114 | 123 | return true; |
115 | 124 | } |
116 | 125 |
|
|
0 commit comments