From a99acb577f48a3e0b2564ea673562c383b5620fa Mon Sep 17 00:00:00 2001 From: Victor Derks Date: Thu, 20 Feb 2025 11:32:27 -0800 Subject: [PATCH] PR #1830: C++17 improvement: use if constexpr in internal/hash.h Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/1830 As the minimal supported C++ version of Abseil is now C++17, it has become possible to use if constexpr statements. Apply usage of if constexpr in the header file hash.h. Benefits of using if constexpr are: - Improved readability: explicit that the expression will be evaluated at compile time. - Required code is generated during compile phase instead of selected in optimizer phase. Improved guarantee that if statement is not checked at runtime. - Prevents MSVC warning C4127: conditional expression is constant (when this warning is explicitly enabled when building Abseil with MSVC). Remark: there are other header files that could be updated for if constexpr. This PR only addresses hash.h as recommended by the contributing guidelines to keep PRs small. Thank you for your contribution to Abseil! Before submitting this PR, please be sure to read our [contributing guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md). If you are a Googler, please also note that it is required that you send us a Piper CL instead of using the GitHub pull-request process. The code propagation process will deliver the change to GitHub. Merge a41f7652e5ae2b7ab54462eafbf8dc52428fd7e6 into dc1ec89b0f99cda973f4ac428812c8008ca6f956 Merging this change closes #1830 COPYBARA_INTEGRATE_REVIEW=https://github.com/abseil/abseil-cpp/pull/1830 from vbaderks:constexpr-hash-internal a41f7652e5ae2b7ab54462eafbf8dc52428fd7e6 PiperOrigin-RevId: 729188454 Change-Id: I124f5f352bc6caf9dd58dd6075404783172c9941 --- absl/hash/internal/hash.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 8d6859ef829..8ca7d843630 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -375,14 +375,14 @@ template (&value); uint64_t v; - if (sizeof(T) == 1) { + if constexpr (sizeof(T) == 1) { v = *start; - } else if (sizeof(T) == 2) { + } else if constexpr (sizeof(T) == 2) { v = absl::base_internal::UnalignedLoad16(start); - } else if (sizeof(T) == 4) { + } else if constexpr (sizeof(T) == 4) { v = absl::base_internal::UnalignedLoad32(start); } else { - assert(sizeof(T) == 8); + static_assert(sizeof(T) == 8); v = absl::base_internal::UnalignedLoad64(start); } return CombineRaw()(std::move(hash_state), v); @@ -512,7 +512,7 @@ H AbslHashValue(H hash_state, T C::*ptr) { // padding (namely when they have 1 or 3 ints). The value below is a lower // bound on the number of salient, non-padding bytes that we use for // hashing. - if (alignof(T C::*) == alignof(int)) { + if constexpr (alignof(T C::*) == alignof(int)) { // No padding when all subobjects have the same size as the total // alignment. This happens in 32-bit mode. return n; @@ -1299,7 +1299,7 @@ class ABSL_DLL MixingHashState : public HashStateBase { // helps ensure that low bits still have high quality. ABSL_ATTRIBUTE_ALWAYS_INLINE static uint64_t WeakMix(uint64_t n) { // WeakMix doesn't work well on 32-bit platforms so just use Mix. - if (sizeof(size_t) < 8) return Mix(n, kMul); + if constexpr (sizeof(size_t) < 8) return Mix(n, kMul); #ifdef __ARM_ACLE // gbswap_64 compiles to `rev` on ARM, but `rbit` is better because it // reverses bits rather than reversing bytes.