| 302 | |
| 303 | /// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object |
| 304 | class cpp_function : public function { |
| 305 | public: |
| 306 | cpp_function() = default; |
| 307 | // NOLINTNEXTLINE(google-explicit-constructor) |
| 308 | cpp_function(std::nullptr_t) {} |
| 309 | cpp_function(std::nullptr_t, const is_setter &) {} |
| 310 | |
| 311 | /// Construct a cpp_function from a vanilla function pointer |
| 312 | template <typename Return, typename... Args, typename... Extra> |
| 313 | // NOLINTNEXTLINE(google-explicit-constructor) |
| 314 | cpp_function(Return (*f)(Args...), const Extra &...extra) { |
| 315 | initialize(f, f, extra...); |
| 316 | } |
| 317 | |
| 318 | /// Construct a cpp_function from a lambda function (possibly with internal state) |
| 319 | template <typename Func, |
| 320 | typename... Extra, |
| 321 | typename = detail::enable_if_t<detail::is_lambda<Func>::value>> |
| 322 | // NOLINTNEXTLINE(google-explicit-constructor) |
| 323 | cpp_function(Func &&f, const Extra &...extra) { |
| 324 | initialize( |
| 325 | std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, extra...); |
| 326 | } |
| 327 | |
| 328 | /// Construct a cpp_function from a class method (non-const, no ref-qualifier) |
| 329 | template <typename Return, typename Class, typename... Arg, typename... Extra> |
| 330 | // NOLINTNEXTLINE(google-explicit-constructor) |
| 331 | cpp_function(Return (Class::*f)(Arg...), const Extra &...extra) { |
| 332 | initialize( |
| 333 | [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); }, |
| 334 | (Return (*)(Class *, Arg...)) nullptr, |
| 335 | extra...); |
| 336 | } |
| 337 | |
| 338 | /// Construct a cpp_function from a class method (non-const, lvalue ref-qualifier) |
| 339 | /// A copy of the overload for non-const functions without explicit ref-qualifier |
| 340 | /// but with an added `&`. |
| 341 | template <typename Return, typename Class, typename... Arg, typename... Extra> |
| 342 | // NOLINTNEXTLINE(google-explicit-constructor) |
| 343 | cpp_function(Return (Class::*f)(Arg...) &, const Extra &...extra) { |
| 344 | initialize( |
| 345 | [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); }, |
| 346 | (Return (*)(Class *, Arg...)) nullptr, |
| 347 | extra...); |
| 348 | } |
| 349 | |
| 350 | /// Construct a cpp_function from a class method (const, no ref-qualifier) |
| 351 | template <typename Return, typename Class, typename... Arg, typename... Extra> |
| 352 | // NOLINTNEXTLINE(google-explicit-constructor) |
| 353 | cpp_function(Return (Class::*f)(Arg...) const, const Extra &...extra) { |
| 354 | initialize([f](const Class *c, |
| 355 | Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); }, |
| 356 | (Return (*)(const Class *, Arg...)) nullptr, |
| 357 | extra...); |
| 358 | } |
| 359 | |
| 360 | /// Construct a cpp_function from a class method (const, lvalue ref-qualifier) |
| 361 | /// A copy of the overload for const functions without explicit ref-qualifier |
no outgoing calls