mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-27 18:21:30 +00:00
Squashed function_record_std_launder/manuscript — 57b9a0af815d19b236b74be06a172bc5c9956618 — 2025-03-30 20:14:21 -0700 (#5592)
[Browse function_record_std_launder/manuscript tree](57b9a0af81) [Browse function_record_std_launder/manuscript commits](57b9a0af81/)
This commit is contained in:
committed by
GitHub
parent
a34fcdc48d
commit
e03ec30632
@@ -272,6 +272,12 @@ struct function_record {
|
|||||||
/// Pointer to next overload
|
/// Pointer to next overload
|
||||||
function_record *next = nullptr;
|
function_record *next = nullptr;
|
||||||
};
|
};
|
||||||
|
// The main purpose of this macro is to make it easy to pin-point the critically related code
|
||||||
|
// sections.
|
||||||
|
#define PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(...) \
|
||||||
|
static_assert( \
|
||||||
|
__VA_ARGS__, \
|
||||||
|
"Violation of precondition for pybind11/functional.h performance optimizations!")
|
||||||
|
|
||||||
/// Special data structure which (temporarily) holds metadata about a bound class
|
/// Special data structure which (temporarily) holds metadata about a bound class
|
||||||
struct type_record {
|
struct type_record {
|
||||||
|
|||||||
@@ -123,6 +123,14 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))
|
||||||
|
# define PYBIND11_STD_LAUNDER std::launder
|
||||||
|
# define PYBIND11_HAS_STD_LAUNDER 1
|
||||||
|
#else
|
||||||
|
# define PYBIND11_STD_LAUNDER
|
||||||
|
# define PYBIND11_HAS_STD_LAUNDER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PYBIND11_CPP20)
|
#if defined(PYBIND11_CPP20)
|
||||||
# define PYBIND11_CONSTINIT constinit
|
# define PYBIND11_CONSTINIT constinit
|
||||||
# define PYBIND11_DTOR_CONSTEXPR constexpr
|
# define PYBIND11_DTOR_CONSTEXPR constexpr
|
||||||
|
|||||||
@@ -101,8 +101,14 @@ public:
|
|||||||
*reinterpret_cast<const std::type_info *>(rec->data[1]))) {
|
*reinterpret_cast<const std::type_info *>(rec->data[1]))) {
|
||||||
struct capture {
|
struct capture {
|
||||||
function_type f;
|
function_type f;
|
||||||
|
|
||||||
|
static capture *from_data(void **data) {
|
||||||
|
return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
value = ((capture *) &rec->data)->f;
|
PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(
|
||||||
|
std::is_standard_layout<capture>::value);
|
||||||
|
value = capture::from_data(rec->data)->f;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
rec = rec->next;
|
rec = rec->next;
|
||||||
|
|||||||
@@ -38,13 +38,6 @@
|
|||||||
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
|
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))
|
|
||||||
# define PYBIND11_STD_LAUNDER std::launder
|
|
||||||
# define PYBIND11_HAS_STD_LAUNDER 1
|
|
||||||
#else
|
|
||||||
# define PYBIND11_STD_LAUNDER
|
|
||||||
# define PYBIND11_HAS_STD_LAUNDER 0
|
|
||||||
#endif
|
|
||||||
#if defined(__GNUG__) && !defined(__clang__)
|
#if defined(__GNUG__) && !defined(__clang__)
|
||||||
# include <cxxabi.h>
|
# include <cxxabi.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -345,6 +338,10 @@ protected:
|
|||||||
using namespace detail;
|
using namespace detail;
|
||||||
struct capture {
|
struct capture {
|
||||||
remove_reference_t<Func> f;
|
remove_reference_t<Func> f;
|
||||||
|
|
||||||
|
static capture *from_data(void **data) {
|
||||||
|
return PYBIND11_STD_LAUNDER(reinterpret_cast<capture *>(data));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Store the function including any extra state it might have (e.g. a lambda capture
|
/* Store the function including any extra state it might have (e.g. a lambda capture
|
||||||
@@ -364,7 +361,7 @@ protected:
|
|||||||
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
|
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
new ((capture *) &rec->data) capture{std::forward<Func>(f)};
|
new (capture::from_data(rec->data)) capture{std::forward<Func>(f)};
|
||||||
|
|
||||||
#if !PYBIND11_HAS_STD_LAUNDER
|
#if !PYBIND11_HAS_STD_LAUNDER
|
||||||
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
||||||
@@ -374,8 +371,8 @@ protected:
|
|||||||
// a significant refactoring it's "impossible" to solve.
|
// a significant refactoring it's "impossible" to solve.
|
||||||
if (!std::is_trivially_destructible<capture>::value) {
|
if (!std::is_trivially_destructible<capture>::value) {
|
||||||
rec->free_data = [](function_record *r) {
|
rec->free_data = [](function_record *r) {
|
||||||
auto data = PYBIND11_STD_LAUNDER((capture *) &r->data);
|
auto data = capture::from_data(r->data);
|
||||||
(void) data;
|
(void) data; // suppress "unused variable" warnings
|
||||||
data->~capture();
|
data->~capture();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -492,6 +489,8 @@ protected:
|
|||||||
using FunctionType = Return (*)(Args...);
|
using FunctionType = Return (*)(Args...);
|
||||||
constexpr bool is_function_ptr
|
constexpr bool is_function_ptr
|
||||||
= std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);
|
= std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);
|
||||||
|
PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS(
|
||||||
|
!is_function_ptr || std::is_standard_layout<capture>::value);
|
||||||
if (is_function_ptr) {
|
if (is_function_ptr) {
|
||||||
rec->is_stateless = true;
|
rec->is_stateless = true;
|
||||||
rec->data[1]
|
rec->data[1]
|
||||||
|
|||||||
Reference in New Issue
Block a user