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
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 8d6859e..8ca7d84 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -375,14 +375,14 @@
 H hash_bytes(H hash_state, const T& value) {
   const unsigned char* start = reinterpret_cast<const unsigned char*>(&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 @@
     // 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 @@
   // 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.