From 11c7f13bf08df570ec28383e377a8878a599b82a Mon Sep 17 00:00:00 2001 From: cyy Date: Sun, 29 Sep 2024 22:36:45 +0800 Subject: [PATCH] Use if constexpr Signed-off-by: cyy --- include/pybind11/cast.h | 5 +++-- include/pybind11/detail/common.h | 8 ++++++++ include/pybind11/eigen/tensor.h | 9 +++++---- include/pybind11/pybind11.h | 17 +++++++++-------- include/pybind11/pytypes.h | 11 +++++++---- include/pybind11/stl.h | 8 ++++---- 6 files changed, 36 insertions(+), 22 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 3acb560b04..310b77b342 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -394,7 +394,8 @@ class type_caster : public type_caster { } /* Check if this is a C++ type */ - const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr()); + const auto &bases + = all_type_info(reinterpret_cast(type::handle_of(h).ptr())); if (bases.size() == 1) { // Only allowing loading from a single-value type value = values_and_holders(reinterpret_cast(h.ptr())).begin()->value_ptr(); return true; @@ -541,7 +542,7 @@ struct string_caster { const auto *buffer = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); - size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); + size_t length = static_cast(PYBIND11_BYTES_SIZE(utfNbytes.ptr())) / sizeof(CharT); // Skip BOM for UTF-16/32 if (UTF_N > 8) { buffer++; diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index ce9014a7e9..a622d44a83 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -95,6 +95,14 @@ # define PYBIND11_HAS_STD_LAUNDER 0 #endif +#if defined(__cpp_if_constexpr) +# define PYBIND11_HAS_IF_CONSTEXPR 1 +# define PYBIND11_IF_CONSTEXPR constexpr +#else +# define PYBIND11_HAS_IF_CONSTEXPR 0 +# define PYBIND11_IF_CONSTEXPR +#endif + #if defined(PYBIND11_CPP20) # define PYBIND11_CONSTINIT constinit # define PYBIND11_DTOR_CONSTEXPR constexpr diff --git a/include/pybind11/eigen/tensor.h b/include/pybind11/eigen/tensor.h index e5c8441032..58648e4182 100644 --- a/include/pybind11/eigen/tensor.h +++ b/include/pybind11/eigen/tensor.h @@ -33,6 +33,9 @@ static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0), PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_WARNING_DISABLE_MSVC(4127) +#if PYBIND11_HAS_IF_CONSTEXPR +PYBIND11_WARNING_DISABLE_MSVC(4702) +#endif PYBIND11_NAMESPACE_BEGIN(detail) @@ -274,10 +277,9 @@ struct type_caster::ValidType> { bool writeable = false; switch (policy) { case return_value_policy::move: - if (std::is_const::value) { + if PYBIND11_IF_CONSTEXPR (std::is_const::value) { pybind11_fail("Cannot move from a constant reference"); } - src = Helper::alloc(std::move(*src)); parent_object @@ -286,13 +288,12 @@ struct type_caster::ValidType> { break; case return_value_policy::take_ownership: - if (std::is_const::value) { + if PYBIND11_IF_CONSTEXPR (std::is_const::value) { // This cast is ugly, and might be UB in some cases, but we don't have an // alternative here as we must free that memory Helper::free(const_cast(src)); pybind11_fail("Cannot take ownership of a const reference"); } - parent_object = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast(ptr)); }); writeable = true; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index a2043b2647..dc176b73fb 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -399,7 +399,7 @@ class cpp_function : public function { auto *rec = unique_rec.get(); /* Store the capture object directly in the function record if there is enough space */ - if (sizeof(capture) <= sizeof(rec->data)) { + if PYBIND11_IF_CONSTEXPR (sizeof(capture) <= sizeof(rec->data)) { /* Without these pragmas, GCC warns that there might not be enough space to use the placement new operator. However, the 'if' statement above ensures that this is the case. */ @@ -417,7 +417,7 @@ class cpp_function : public function { // UB without std::launder, but without breaking ABI and/or // a significant refactoring it's "impossible" to solve. - if (!std::is_trivially_destructible::value) { + if PYBIND11_IF_CONSTEXPR (!std::is_trivially_destructible::value) { rec->free_data = [](function_record *r) { auto data = capture::from_data(r->data); (void) data; // suppress "unused variable" warnings @@ -2189,7 +2189,7 @@ class class_ : public detail::generic_type { generic_type::initialize(record); - if (has_alias) { + if PYBIND11_IF_CONSTEXPR (has_alias) { with_internals([&](internals &internals) { auto &local_internals = get_local_internals(); if (record.module_local) { @@ -2696,7 +2696,8 @@ inline str enum_name(handle arg) { struct enum_base { enum_base(const handle &base, const handle &parent) : m_base(base), m_parent(parent) {} - PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) { + template + PYBIND11_NOINLINE void init() { m_base.attr("__entries") = dict(); auto property = handle((PyObject *) &PyProperty_Type); auto static_property = handle((PyObject *) get_internals().static_property_type); @@ -2802,11 +2803,11 @@ struct enum_base { arg("other"), \ pos_only()) - if (is_convertible) { + if PYBIND11_IF_CONSTEXPR (is_convertible) { PYBIND11_ENUM_OP_CONV_LHS("__eq__", !b.is_none() && a.equal(b)); PYBIND11_ENUM_OP_CONV_LHS("__ne__", b.is_none() || !a.equal(b)); - if (is_arithmetic) { + if PYBIND11_IF_CONSTEXPR (is_arithmetic) { PYBIND11_ENUM_OP_CONV("__lt__", a < b); PYBIND11_ENUM_OP_CONV("__gt__", a > b); PYBIND11_ENUM_OP_CONV("__le__", a <= b); @@ -2827,7 +2828,7 @@ struct enum_base { PYBIND11_ENUM_OP_STRICT("__eq__", int_(a).equal(int_(b)), return false); PYBIND11_ENUM_OP_STRICT("__ne__", !int_(a).equal(int_(b)), return true); - if (is_arithmetic) { + if PYBIND11_IF_CONSTEXPR (is_arithmetic) { #define PYBIND11_THROW throw type_error("Expected an enumeration of matching type!"); PYBIND11_ENUM_OP_STRICT("__lt__", int_(a) < int_(b), PYBIND11_THROW); PYBIND11_ENUM_OP_STRICT("__gt__", int_(a) > int_(b), PYBIND11_THROW); @@ -2946,7 +2947,7 @@ class enum_ : public class_ { constexpr bool is_arithmetic = detail::any_of...>::value; constexpr bool is_convertible = std::is_convertible::value; - m_base.init(is_arithmetic, is_convertible); + m_base.init(); def(init([](Scalar i) { return static_cast(i); }), arg("value")); def_property_readonly("value", [](Type value) { return (Scalar) value; }, pos_only()); diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index b28692fd74..8c9f0b430d 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -34,6 +34,9 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_WARNING_DISABLE_MSVC(4127) +#if PYBIND11_HAS_IF_CONSTEXPR +PYBIND11_WARNING_DISABLE_MSVC(4702) +#endif /* A few forward declarations */ class handle; @@ -1859,7 +1862,7 @@ PYBIND11_NAMESPACE_BEGIN(detail) // unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes). template Unsigned as_unsigned(PyObject *o) { - if (sizeof(Unsigned) <= sizeof(unsigned long)) { + if PYBIND11_IF_CONSTEXPR (sizeof(Unsigned) <= sizeof(unsigned long)) { unsigned long v = PyLong_AsUnsignedLong(o); return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v; } @@ -1876,14 +1879,14 @@ class int_ : public object { template ::value, int> = 0> // NOLINTNEXTLINE(google-explicit-constructor) int_(T value) { - if (sizeof(T) <= sizeof(long)) { - if (std::is_signed::value) { + if PYBIND11_IF_CONSTEXPR (sizeof(T) <= sizeof(long)) { + if PYBIND11_IF_CONSTEXPR (std::is_signed::value) { m_ptr = PyLong_FromLong((long) value); } else { m_ptr = PyLong_FromUnsignedLong((unsigned long) value); } } else { - if (std::is_signed::value) { + if PYBIND11_IF_CONSTEXPR (std::is_signed::value) { m_ptr = PyLong_FromLongLong((long long) value); } else { m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value); diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 01be0b47c6..26ba798e79 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -203,7 +203,7 @@ struct set_caster { template static handle cast(T &&src, return_value_policy policy, handle parent) { - if (!std::is_lvalue_reference::value) { + if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference::value) { policy = return_value_policy_override::policy(policy); } pybind11::set s; @@ -272,7 +272,7 @@ struct map_caster { dict d; return_value_policy policy_key = policy; return_value_policy policy_value = policy; - if (!std::is_lvalue_reference::value) { + if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference::value) { policy_key = return_value_policy_override::policy(policy_key); policy_value = return_value_policy_override::policy(policy_value); } @@ -341,7 +341,7 @@ struct list_caster { public: template static handle cast(T &&src, return_value_policy policy, handle parent) { - if (!std::is_lvalue_reference::value) { + if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference::value) { policy = return_value_policy_override::policy(policy); } list l(src.size()); @@ -534,7 +534,7 @@ struct optional_caster { if (!src) { return none().release(); } - if (!std::is_lvalue_reference::value) { + if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference::value) { policy = return_value_policy_override::policy(policy); } // NOLINTNEXTLINE(bugprone-unchecked-optional-access)