Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,8 @@ class type_caster<void> : public type_caster<void_type> {
}

/* 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<PyTypeObject *>(type::handle_of(h).ptr()));
if (bases.size() == 1) { // Only allowing loading from a single-value type
value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();
return true;
Expand Down Expand Up @@ -541,7 +542,7 @@ struct string_caster {

const auto *buffer
= reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
size_t length = static_cast<size_t>(PYBIND11_BYTES_SIZE(utfNbytes.ptr())) / sizeof(CharT);
// Skip BOM for UTF-16/32
if (UTF_N > 8) {
buffer++;
Expand Down
8 changes: 8 additions & 0 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions include/pybind11/eigen/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -274,10 +277,9 @@ struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
bool writeable = false;
switch (policy) {
case return_value_policy::move:
if (std::is_const<C>::value) {
if PYBIND11_IF_CONSTEXPR (std::is_const<C>::value) {
pybind11_fail("Cannot move from a constant reference");
}

src = Helper::alloc(std::move(*src));

parent_object
Expand All @@ -286,13 +288,12 @@ struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
break;

case return_value_policy::take_ownership:
if (std::is_const<C>::value) {
if PYBIND11_IF_CONSTEXPR (std::is_const<C>::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<Type *>(src));
pybind11_fail("Cannot take ownership of a const reference");
}

parent_object
= capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });
writeable = true;
Expand Down
17 changes: 9 additions & 8 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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<capture>::value) {
if PYBIND11_IF_CONSTEXPR (!std::is_trivially_destructible<capture>::value) {
rec->free_data = [](function_record *r) {
auto data = capture::from_data(r->data);
(void) data; // suppress "unused variable" warnings
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 <bool is_arithmetic, bool is_convertible>
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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -2946,7 +2947,7 @@ class enum_ : public class_<Type> {

constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;
constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value;
m_base.init(is_arithmetic, is_convertible);
m_base.init<is_arithmetic, is_convertible>();

def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value"));
def_property_readonly("value", [](Type value) { return (Scalar) value; }, pos_only());
Expand Down
11 changes: 7 additions & 4 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 <typename Unsigned>
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;
}
Expand All @@ -1876,14 +1879,14 @@ class int_ : public object {
template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
// NOLINTNEXTLINE(google-explicit-constructor)
int_(T value) {
if (sizeof(T) <= sizeof(long)) {
if (std::is_signed<T>::value) {
if PYBIND11_IF_CONSTEXPR (sizeof(T) <= sizeof(long)) {
if PYBIND11_IF_CONSTEXPR (std::is_signed<T>::value) {
m_ptr = PyLong_FromLong((long) value);
} else {
m_ptr = PyLong_FromUnsignedLong((unsigned long) value);
}
} else {
if (std::is_signed<T>::value) {
if PYBIND11_IF_CONSTEXPR (std::is_signed<T>::value) {
m_ptr = PyLong_FromLongLong((long long) value);
} else {
m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value);
Expand Down
8 changes: 4 additions & 4 deletions include/pybind11/stl.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ struct set_caster {

template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
if (!std::is_lvalue_reference<T>::value) {
if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference<T>::value) {
policy = return_value_policy_override<Key>::policy(policy);
}
pybind11::set s;
Expand Down Expand Up @@ -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<T>::value) {
if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference<T>::value) {
policy_key = return_value_policy_override<Key>::policy(policy_key);
policy_value = return_value_policy_override<Value>::policy(policy_value);
}
Expand Down Expand Up @@ -341,7 +341,7 @@ struct list_caster {
public:
template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
if (!std::is_lvalue_reference<T>::value) {
if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference<T>::value) {
policy = return_value_policy_override<Value>::policy(policy);
}
list l(src.size());
Expand Down Expand Up @@ -534,7 +534,7 @@ struct optional_caster {
if (!src) {
return none().release();
}
if (!std::is_lvalue_reference<T>::value) {
if PYBIND11_IF_CONSTEXPR (!std::is_lvalue_reference<T>::value) {
policy = return_value_policy_override<Value>::policy(policy);
}
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
Expand Down
Loading