mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Factor out readable function signatures to avoid duplication (#5857)
* Centralize readable function signatures to avoid duplication This seems to reduce size costs of adding enum_-specific implementations of dunder methods, but also should provide a nice to have size optimization for programs that use pybind11 in general. * gate disabling of -Wdeprecated-redundant-constexpr-static-def to clang 17+ * fix gating to include Apple Clang 15 * Make GCC happy with types * fix apple clang gating again. suppress -Wdeprecated for GCC * Gate warning suppressions to C++17. Suppress -Wdeprecated for clang as well. * hopefully fix last straggler CI job * attempt to address readability review feedback from @rwgk * drop warning suppressions and instead just gate compilation the pre-C++17 compat code
This commit is contained in:
@@ -248,6 +248,49 @@ inline std::string generate_type_signature() {
|
||||
# define PYBIND11_COMPAT_STRDUP strdup
|
||||
#endif
|
||||
|
||||
#define PYBIND11_READABLE_FUNCTION_SIGNATURE_EXPR \
|
||||
detail::const_name("(") + cast_in::arg_names + detail::const_name(") -> ") + cast_out::name
|
||||
|
||||
// We factor out readable function signatures to a specific template
|
||||
// so that they don't get duplicated across different instantiations of
|
||||
// cpp_function::initialize (which is templated on more types).
|
||||
template <typename cast_in, typename cast_out>
|
||||
class ReadableFunctionSignature {
|
||||
public:
|
||||
using sig_type = decltype(PYBIND11_READABLE_FUNCTION_SIGNATURE_EXPR);
|
||||
|
||||
private:
|
||||
// We have to repeat PYBIND11_READABLE_FUNCTION_SIGNATURE_EXPR in decltype()
|
||||
// because C++11 doesn't allow functions to return `auto`. (We don't
|
||||
// know the type because it's some variant of detail::descr<N> with
|
||||
// unknown N.)
|
||||
static constexpr sig_type sig() { return PYBIND11_READABLE_FUNCTION_SIGNATURE_EXPR; }
|
||||
|
||||
public:
|
||||
static constexpr sig_type kSig = sig();
|
||||
// We can only stash the result of detail::descr::types() in a
|
||||
// constexpr variable if we aren't on MSVC (see
|
||||
// PYBIND11_DESCR_CONSTEXPR).
|
||||
#if !defined(_MSC_VER)
|
||||
using types_type = decltype(sig_type::types());
|
||||
static constexpr types_type kTypes = sig_type::types();
|
||||
#endif
|
||||
};
|
||||
#undef PYBIND11_READABLE_FUNCTION_SIGNATURE_EXPR
|
||||
|
||||
// Prior to C++17, we don't have inline variables, so we have to
|
||||
// provide an out-of-line definition of the class member.
|
||||
#if !defined(PYBIND11_CPP17)
|
||||
template <typename cast_in, typename cast_out>
|
||||
constexpr typename ReadableFunctionSignature<cast_in, cast_out>::sig_type
|
||||
ReadableFunctionSignature<cast_in, cast_out>::kSig;
|
||||
# if !defined(_MSC_VER)
|
||||
template <typename cast_in, typename cast_out>
|
||||
constexpr typename ReadableFunctionSignature<cast_in, cast_out>::types_type
|
||||
ReadableFunctionSignature<cast_in, cast_out>::kTypes;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object
|
||||
@@ -481,9 +524,14 @@ protected:
|
||||
|
||||
/* Generate a readable signature describing the function's arguments and return
|
||||
value types */
|
||||
static constexpr auto signature
|
||||
= const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name;
|
||||
PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();
|
||||
static constexpr const auto &signature
|
||||
= detail::ReadableFunctionSignature<cast_in, cast_out>::kSig;
|
||||
#if !defined(_MSC_VER)
|
||||
static constexpr const auto &types
|
||||
= detail::ReadableFunctionSignature<cast_in, cast_out>::kTypes;
|
||||
#else
|
||||
PYBIND11_DESCR_CONSTEXPR auto types = std::decay<decltype(signature)>::type::types();
|
||||
#endif
|
||||
|
||||
/* Register the function with Python from generic (non-templated) code */
|
||||
// Pass on the ownership over the `unique_rec` to `initialize_generic`. `rec` stays valid.
|
||||
|
||||
Reference in New Issue
Block a user