MCPcopy Create free account
hub / github.com/pybind/pybind11 / initialize

Method initialize

include/pybind11/pybind11.h:481–648  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

479 /// Special internal constructor for functors, lambda functions, etc.
480 template <typename Func, typename Return, typename... Args, typename... Extra>
481 void initialize(Func &&f, Return (*)(Args...), const Extra &...extra) {
482 using namespace detail;
483 struct capture {
484 remove_reference_t<Func> f;
485
486 static capture *from_data(void **data) {
487 return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
488 }
489 };
490
491 /* Store the function including any extra state it might have (e.g. a lambda capture
492 * object) */
493 // The unique_ptr makes sure nothing is leaked in case of an exception.
494 auto unique_rec = make_function_record();
495 auto *rec = unique_rec.get();
496
497 /* Store the capture object directly in the function record if there is enough space */
498 if (sizeof(capture) <= sizeof(rec->data)) {
499 /* Without these pragmas, GCC warns that there might not be
500 enough space to use the placement new operator. However, the
501 'if' statement above ensures that this is the case. */
502 PYBIND11_WARNING_PUSH
503
504#if defined(__GNUG__) && __GNUC__ >= 6
505 PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
506#endif
507
508 new (capture::from_data(rec->data)) capture{std::forward<Func>(f)};
509
510#if !PYBIND11_HAS_STD_LAUNDER
511 PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
512#endif
513
514 // UB without std::launder, but without breaking ABI and/or
515 // a significant refactoring it's "impossible" to solve.
516 if (!std::is_trivially_destructible<capture>::value) {
517 rec->free_data = [](function_record *r) {
518 auto data = capture::from_data(r->data);
519 (void) data; // suppress "unused variable" warnings
520 data->~capture();
521 };
522 }
523 PYBIND11_WARNING_POP
524 } else {
525 rec->data[0] = new capture{std::forward<Func>(f)};
526 rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
527 }
528
529 /* Type casters for the function arguments and return value */
530 using cast_in = argument_loader<Args...>;
531 using cast_out
532 = make_caster<conditional_t<std::is_void<Return>::value, void_type, Return>>;
533
534 static_assert(
535 expected_num_args<Extra...>(
536 sizeof...(Args), cast_in::args_pos >= 0, cast_in::has_kwargs),
537 "The number of argument annotations does not match the number of function arguments");
538

Callers

nothing calls this directly

Calls 9

moveFunction · 0.85
noneClass · 0.85
initFunction · 0.85
constexpr_sumFunction · 0.85
load_argsMethod · 0.80
releaseMethod · 0.80
castFunction · 0.70
getMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected