Skip to content

Commit ced75c8

Browse files
committed
PYBIND11_SILENCE_MSVC_C4127 (more similar to the approach for C4100).
1 parent e87f9c4 commit ced75c8

File tree

5 files changed

+25
-13
lines changed

5 files changed

+25
-13
lines changed

include/pybind11/cast.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,11 @@ template <typename StringType, bool IsView = false> struct string_caster {
384384

385385
const auto *buffer = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
386386
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
387-
if (constexpr_bool(UTF_N > 8)) { buffer++; length--; } // Skip BOM for UTF-16/32
387+
// Skip BOM for UTF-16/32
388+
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {
389+
buffer++;
390+
length--;
391+
}
388392
value = StringType(buffer, length);
389393

390394
// If we're loading a string_view we need to keep the encoded Python object alive:
@@ -499,7 +503,7 @@ template <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type
499503
// out how long the first encoded character is in bytes to distinguish between these two
500504
// errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those
501505
// can fit into a single char value.
502-
if (constexpr_bool(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {
506+
if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {
503507
auto v0 = static_cast<unsigned char>(value[0]);
504508
// low bits only: 0-127
505509
// 0b110xxxxx - start of 2-byte sequence
@@ -524,7 +528,7 @@ template <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type
524528
// UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
525529
// surrogate pair with total length 2 instantly indicates a range error (but not a "your
526530
// string was too long" error).
527-
else if (constexpr_bool(StringCaster::UTF_N == 16) && str_len == 2) {
531+
else if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 16) && str_len == 2) {
528532
one_char = static_cast<CharT>(value[0]);
529533
if (one_char >= 0xD800 && one_char < 0xE000)
530534
throw value_error("Character code point not in range(0x10000)");
@@ -778,7 +782,7 @@ struct pyobject_caster {
778782
// For Python 2, without this implicit conversion, Python code would
779783
// need to be cluttered with six.ensure_text() or similar, only to be
780784
// un-cluttered later after Python 2 support is dropped.
781-
if (constexpr_bool(std::is_same<T, str>::value) && isinstance<bytes>(src)) {
785+
if (PYBIND11_SILENCE_MSVC_C4127(std::is_same<T, str>::value) && isinstance<bytes>(src)) {
782786
PyObject *str_from_bytes = PyUnicode_FromEncodedObject(src.ptr(), "utf-8", nullptr);
783787
if (!str_from_bytes) throw error_already_set();
784788
value = reinterpret_steal<type>(str_from_bytes);

include/pybind11/detail/common.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,16 @@ inline constexpr void workaround_incorrect_msvc_c4100(Args &&...) {}
941941
# define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)
942942
#endif
943943

944-
// Suppresses MSVC warning C4127: Conditional expression is constant
945-
constexpr inline bool constexpr_bool(bool cond) { return cond; }
944+
#if defined(_MSC_VER) // All versions (as of July 2021).
945+
946+
// warning C4127: Conditional expression is constant
947+
constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }
948+
949+
# define PYBIND11_SILENCE_MSVC_C4127(...) detail::silence_msvc_c4127(__VA_ARGS__)
950+
951+
#else
952+
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
953+
#endif
946954

947955
PYBIND11_NAMESPACE_END(detail)
948956
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

include/pybind11/detail/init.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ template <typename Class>
9696
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
9797
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
9898
no_nullptr(ptr);
99-
if (constexpr_bool(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
99+
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
100100
// We're going to try to construct an alias by moving the cpp type. Whether or not
101101
// that succeeds, we still need to destroy the original cpp pointer (either the
102102
// moved away leftover, if the alias construction works, or the value itself if we
@@ -136,7 +136,7 @@ void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
136136
auto *ptr = holder_helper<Holder<Class>>::get(holder);
137137
no_nullptr(ptr);
138138
// If we need an alias, check that the held pointer is actually an alias instance
139-
if (constexpr_bool(Class::has_alias) && need_alias && !is_alias<Class>(ptr))
139+
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr))
140140
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
141141
"is not an alias instance");
142142

@@ -153,7 +153,7 @@ void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
153153
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
154154
static_assert(std::is_move_constructible<Cpp<Class>>::value,
155155
"pybind11::init() return-by-value factory function requires a movable class");
156-
if (constexpr_bool(Class::has_alias) && need_alias)
156+
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias)
157157
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
158158
else
159159
v_h.value_ptr() = new Cpp<Class>(std::move(result));

include/pybind11/pybind11.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class cpp_function : public function {
163163
auto rec = unique_rec.get();
164164

165165
/* Store the capture object directly in the function record if there is enough space */
166-
if (constexpr_bool(sizeof(capture) <= sizeof(rec->data))) {
166+
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(capture) <= sizeof(rec->data))) {
167167
/* Without these pragmas, GCC warns that there might not be
168168
enough space to use the placement new operator. However, the
169169
'if' statement above ensures that this is the case. */

include/pybind11/pytypes.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -1191,9 +1191,9 @@ PYBIND11_NAMESPACE_BEGIN(detail)
11911191
// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).
11921192
template <typename Unsigned>
11931193
Unsigned as_unsigned(PyObject *o) {
1194-
if (constexpr_bool(sizeof(Unsigned) <= sizeof(unsigned long))
1194+
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))
11951195
#if PY_VERSION_HEX < 0x03000000
1196-
|| PyInt_Check(o)
1196+
|| PyInt_Check(o)
11971197
#endif
11981198
) {
11991199
unsigned long v = PyLong_AsUnsignedLong(o);
@@ -1212,7 +1212,7 @@ class int_ : public object {
12121212
template <typename T,
12131213
detail::enable_if_t<std::is_integral<T>::value, int> = 0>
12141214
int_(T value) {
1215-
if (detail::constexpr_bool(sizeof(T) <= sizeof(long))) {
1215+
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {
12161216
if (std::is_signed<T>::value)
12171217
m_ptr = PyLong_FromLong((long) value);
12181218
else

0 commit comments

Comments
 (0)