[libcxx-commits] [libcxx] [libc++] Avoid including pair in <__functional/hash.h> (PR #179635)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 11 10:46:02 PST 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/179635

>From 461911731125b858bff4ceb4ea7fc0b3d29b955f Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 4 Feb 2026 11:14:19 +0100
Subject: [PATCH] [libc++] Avoid including pair in <__functional/hash.h>

---
 libcxx/include/__functional/hash.h | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index d81ff1abbdaba..fa7181984f163 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -23,7 +23,6 @@
 #include <__type_traits/is_integral.h>
 #include <__type_traits/is_unqualified.h>
 #include <__type_traits/underlying_type.h>
-#include <__utility/pair.h>
 #include <__utility/swap.h>
 #include <cstdint>
 #include <cstring>
@@ -41,6 +40,11 @@ inline _LIBCPP_HIDE_FROM_ABI _Size __loadword(const void* __p) {
   return __r;
 }
 
+struct _PairT {
+  size_t first;
+  size_t second;
+};
+
 // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t
 // is 64 bits.  This is because cityhash64 uses 64bit x 64bit
 // multiplication, which can be very slow on 32-bit systems.
@@ -104,9 +108,9 @@ struct __murmur2_or_cityhash<_Size, 64> {
     _Size __y = std::__loadword<_Size>(__s + __len - 16) + std::__loadword<_Size>(__s + __len - 56);
     _Size __z =
         __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, std::__loadword<_Size>(__s + __len - 24));
-    pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
-    pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
-    __x                    = __x * __k1 + std::__loadword<_Size>(__s);
+    _PairT __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z);
+    _PairT __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x);
+    __x        = __x * __k1 + std::__loadword<_Size>(__s);
 
     // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
     __len = (__len - 1) & ~static_cast<_Size>(63);
@@ -192,7 +196,7 @@ struct __murmur2_or_cityhash<_Size, 64> {
 
   // Return a 16-byte hash for 48 bytes.  Quick and dirty.
   // Callers do best to use "random-looking" values for a and b.
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _PairT
   __weak_hash_len_32_with_seeds(_Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) {
     __a += __w;
     __b             = __rotate(__b + __a + __z, 21);
@@ -200,11 +204,14 @@ struct __murmur2_or_cityhash<_Size, 64> {
     __a += __x;
     __a += __y;
     __b += __rotate(__a, 44);
-    return pair<_Size, _Size>(__a + __z, __b + __c);
+    _PairT __ret;
+    __ret.first  = __a + __z;
+    __ret.second = __b + __c;
+    return __ret;
   }
 
   // Return a 16-byte hash for s[0] ... s[31], a, and b.  Quick and dirty.
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _PairT
   __weak_hash_len_32_with_seeds(const char* __s, _Size __a, _Size __b) {
     return __weak_hash_len_32_with_seeds(
         std::__loadword<_Size>(__s),
@@ -325,11 +332,6 @@ struct __scalar_hash<_Tp, 4> : public __unary_function<_Tp, size_t> {
   }
 };
 
-struct _PairT {
-  size_t first;
-  size_t second;
-};
-
 _LIBCPP_HIDE_FROM_ABI inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT {
   typedef __scalar_hash<_PairT> _HashT;
   const _PairT __p = {__lhs, __rhs};



More information about the libcxx-commits mailing list