mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +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
|
||||
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
|
||||
struct type_record {
|
||||
|
||||
@@ -123,6 +123,14 @@
|
||||
# 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)
|
||||
# define PYBIND11_CONSTINIT constinit
|
||||
# define PYBIND11_DTOR_CONSTEXPR constexpr
|
||||
|
||||
@@ -101,8 +101,14 @@ public:
|
||||
*reinterpret_cast<const std::type_info *>(rec->data[1]))) {
|
||||
struct capture {
|
||||
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;
|
||||
}
|
||||
rec = rec->next;
|
||||
|
||||
@@ -38,13 +38,6 @@
|
||||
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
|
||||
#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__)
|
||||
# include <cxxabi.h>
|
||||
#endif
|
||||
@@ -345,6 +338,10 @@ protected:
|
||||
using namespace detail;
|
||||
struct capture {
|
||||
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
|
||||
@@ -364,7 +361,7 @@ protected:
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
|
||||
#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
|
||||
PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
|
||||
@@ -374,8 +371,8 @@ protected:
|
||||
// a significant refactoring it's "impossible" to solve.
|
||||
if (!std::is_trivially_destructible<capture>::value) {
|
||||
rec->free_data = [](function_record *r) {
|
||||
auto data = PYBIND11_STD_LAUNDER((capture *) &r->data);
|
||||
(void) data;
|
||||
auto data = capture::from_data(r->data);
|
||||
(void) data; // suppress "unused variable" warnings
|
||||
data->~capture();
|
||||
};
|
||||
}
|
||||
@@ -492,6 +489,8 @@ protected:
|
||||
using FunctionType = Return (*)(Args...);
|
||||
constexpr bool is_function_ptr
|
||||
= 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) {
|
||||
rec->is_stateless = true;
|
||||
rec->data[1]
|
||||
|
||||
Reference in New Issue
Block a user