Fix 128-bit text output for library types; use numeric_limits in MaskToNBits `WriteIntegerToTextStream` subscripted its digit table with the value being printed, which does not compile when `EMBOSS_UINT128_T` is overridden with a class type such as `absl::uint128`, as `emboss_defines.h` advertises. Cast the digit (always below the numeric base) to `int` first. `MaskToNBits` rejected signed types with `std::is_signed<T>`, which is false for `__int128` under a strict `-std=c++NN`, so the check was silently skipped there. Use `std::numeric_limits<T>::is_signed` instead, which the runtime already relies on for 128-bit types.
diff --git a/runtime/cpp/emboss_bit_util.h b/runtime/cpp/emboss_bit_util.h index f9b031c..d8b7a92 100644 --- a/runtime/cpp/emboss_bit_util.h +++ b/runtime/cpp/emboss_bit_util.h
@@ -18,6 +18,7 @@ #define EMBOSS_RUNTIME_CPP_EMBOSS_BIT_UTIL_H_ #include <cstdint> +#include <limits> #include <type_traits> #include "runtime/cpp/emboss_defines.h" @@ -58,16 +59,19 @@ #if EMBOSS_HAS_INT128 inline constexpr EMBOSS_UINT128_T ByteSwap(EMBOSS_UINT128_T x) { - return (static_cast<EMBOSS_UINT128_T>(ByteSwap(static_cast<::std::uint64_t>(x))) + return (static_cast<EMBOSS_UINT128_T>( + ByteSwap(static_cast</**/ ::std::uint64_t>(x))) << 64) | - ByteSwap(static_cast<::std::uint64_t>(x >> 64)); + ByteSwap(static_cast</**/ ::std::uint64_t>(x >> 64)); } #endif // EMBOSS_HAS_INT128 // Masks the given value to the given number of bits. template <typename T> inline constexpr T MaskToNBits(T value, unsigned bits) { - static_assert(!::std::is_signed<T>::value, + // numeric_limits, not is_signed: the latter is false for __int128 under a + // strict -std=c++NN, which would silently disable this check. + static_assert(!::std::numeric_limits<T>::is_signed, "MaskToNBits only works on unsigned values."); return bits < sizeof value * 8 ? value & ((static_cast<T>(1) << bits) - 1) : value;
diff --git a/runtime/cpp/emboss_text_util.h b/runtime/cpp/emboss_text_util.h index 061ea31..e8dea00 100644 --- a/runtime/cpp/emboss_text_util.h +++ b/runtime/cpp/emboss_text_util.h
@@ -307,7 +307,7 @@ digit = 0; ++value; } - buffer_char(digits[digit]); + buffer_char(digits[static_cast<int>(digit)]); ++digit_count; } else { value = -value; @@ -317,7 +317,7 @@ if (digit_count && digit_count % grouping == 0 && digit_grouping) { buffer_char('_'); } - buffer_char(digits[value % base]); + buffer_char(digits[static_cast<int>(value % base)]); value /= base; ++digit_count; }